Nueva Solapa en tx ME51n/ME52n/ME53n

La ampliación es la MEREQ001 – Para usarle es necesario crear un projecto en la CMOD.

clip_image002

1 - Primero hay que ampliar el include CI_EBANDB con los campos que nosotros vamos a desear. (esto extenderá la tabla EBAN).

Ejemplo ZLAND1 y ZXBLNR

clip_image004

2- Modificamos la Screen, la ampliación hay que modificar la subscreen 0111

clip_image006

Ejemplo simple

clip_image008

3- Modificamos principalmente las funciones EXIT_SAPLMEREQ_001 y EXIT_SAPLMEREQ_003

La EXIT_SAPLMEREQ_001 es para pasar la información al customer exit y la EXIT_SAPLMEREQ_003 para grabar los datos de exit a las tablas.

 

EXIT_SAPLMEREQ_001

*&---------------------------------------------------------------------*
*&  Include           ZXM02U01
*&---------------------------------------------------------------------*
data   :  i_mereq_item type mereq_item,
          gf_aktyp type aktyp,
          lc_garg type eqegraarg,
          lc_edit(1),
          ls_head type mereq_header,
          lc_header type ref to if_purchase_requisition,
          ti_enq type table of seqg3 .
CLEAR lc_edit.
if im_req_item is initial.
else.
  i_mereq_item = im_req_item->get_data( ).
endif.
" Chequeo para visualizar/modificar el campo (ya que por default está simpre editable
if sy-tcode eq 'ME53N'.
    lc_header = im_req_item->get_requisition( ).
concatenate sy-mandt ls_head-banfn '*****' into lc_garg.
call function 'ENQUEUE_READ'
exporting
        gclient = sy-mandt
        gname   = 'EBAN'
        garg    = lc_garg
        guname  = sy-uname
tables
        enq     = ti_enq.
if ti_enq[] is not initial.
      lc_edit = 'X'.
else.
clear lc_edit.
endif.
endif.
EXPORT g_edit = lc_edit TO MEMORY ID 'FLAG_EDIT'.

 

EXIT_SAPLMEREQ_003

*&---------------------------------------------------------------------*

*&  Include           ZXM02U03
*&---------------------------------------------------------------------*
tables: ci_ebandb.
data : l_mereq_item type mereq_item.
if not im_req_item is initial.
   l_mereq_item = im_req_item->get_data( ).
if ( ci_ebandb-zland1 ne l_mereq_item-zland1 ).
   move-corresponding  ci_ebandb to l_mereq_item .
   call method im_req_item->set_data( l_mereq_item ).
   ex_changed = 'X'.
endif.
endif.

En el PBO de la SubScreen agrego la lógica para determinar si hay que grisar el campo o no.

module status_0111 output.
*  SET PF-STATUS 'xxxxxxxx'.
set titlebar 'TEST'.
data: l_edit(1).
* se chequea que se esté en la ME51N/2 o 3 en modo edición
import g_edit to l_edit from memory id 'FLAG_EDIT'.
loop at screen.
if  sy-tcode = 'ME51N' or sy-tcode = 'ME52N' or ( sy-tcode = 'ME53N' and l_edit = 'X' ).
screen-input = 1.
else.
screen-input = 0.
endif.
modify screen.
endloop.
endmodule.                 " STATUS_0111  OUTPUT

 

 

RESULTADO FINAL

Visualización

clip_image010

Modificación

clip_image012

Al grabar se grabará el campo creado en la EBAN.

 

 

 

A modo informativo dejo la función del resto de las funciones, sirven para hacer validaciones, mostrar mensajes, etc.

Function exits

The screen is linked to the standard program via function modules. There are function modules that:

o Provide your subscreen with data (export)

- EXIT_SAPLMEREQ_001 Export Data to Customer Subscreen for Purchase Requisition(PBO)

- EXIT_SAPLMEREQ_002 Prepare Customer Subscreen for Requisition (PAI Before Subscreen PAI)

o Get data from your subscreens (import)

- EXIT_SAPLMEREQ_003 Import Data from Customer Subscreen for Purchase Requisition

You can set or supply your own data fields in the PBO function modules.You receive the current (possibly changed in comparison to the PBO call) standard program data in the PAI function module. You can return your fields to the standard program in the import function modules. For this purpose, read the current status of the purchase requisition object using the method get_data in a local structure of type mereq_item. Now write the customer data in this structure and reset the data in the purchase requisition object using the method set_data.

You should note that function exits 001, 002, and 003 are determined for dialog purposes only and are not headed for when creating purchase requisitions using function modules or BAPIs. Do not issue any error messages in these function modules either. There is a separate function exit for verifying the customer fields (EXIT_SAPLMEREQ_005 Checking Customer's Own Purchase Requisition Data (Without Dialog)). The object reference, the new data, the data from the last verification, and the database status of the purchase requisition items are available to you here. Parameter IM-FULL_CHECK is set if the user has chosen to update or check explicitly. Parameter IM_ITEM_HAS_ERRORS informs you whether the purchase requisition item has been classified by the standard program as containing errors.

The task of this function exit is to ensure the consistency of the customer-specific fields. You can also change standard fields using the public interface if_purchase_requisition_item. The fields listed in structure MEREQ_ITEM_S_CUST_ALLOWED are available for changing. You fill the return table EX_MESSAGES to issue the errors and warnings to the standard program and the user. The fields TYPE, ID, NUMBER, and MESSAGE_V1 thru MESSAGE_V4 are analyzed and added to the standard error log. You have to set the return parameter EX_RECHECK_ITEM if you have changed standard fields. The standard program checks the purchase requisition

item after exiting the function exit again. You should note that the functions exits are chosen again when this is done. To avoid endless loops, you should not set this parameter every time. The purchase requisition is updated in two steps. In the first step (PREPARE), the function exit EXIT_SAPLMEREQ_008 (Prepare for Update of Customer's Own Purchase Requisition Data) is called up. The system tells you the old (temporary) purchase requisition number and the new purchase requisition number. In addition, the changes are given to tables EBAN and EBKN. You can no longer change the fields here. You use this module to prepare for updating your own data and tables. Do not execute any database operations or call any function modules for the update (in update task). Make a note of which data you want to update in your function group. You should note that more than one purchase requisition can be processed at the same time (for example, source of supply assignment or collective release). This function exit is processed once for each header in the purchase requisition. The second step in the update process performs the database operations  or calls the update modules. Function exit EXIT_SAPLMEREQ_006 (Update o Customer's Own Purchase Requisition Data for all PReqs Prepared). This function exit is called up only once for all purchase requisitions that have been changed. You now update the data that you noted in the first step. When all purchase requisitions have been successfully updated, function exit EXIT_SAPLMEREQ_004 (Reset Customer Data After Updating All Purchas Requisitions (Without Dialog)). You reset the data for your function group(s) here.

If you want to read your own tables for this, you should use the function module EXIT_SAPLMEREQ_007. This is called when the purchase requisition is read from the database. You receive the transaction type via the purchase requisition header. The interface if_purchase_requsition_item provides a method,  GET_REQUISITION, that returns the purchase requisition header. Using method GET_TRANSACTION_STATE for interface if_purchase_requisition, you can determine the transaction type from field ex_document.

o A Display

o V Change

o H Create

Crear un AUTHORITY-CHECK

1 -Creamos en la SU20 un ámbito de autorización (elemento de dato) que luego usaremos en el objeto. image

Nombre del campo Z____ y ponemos el elemento de Dato correspondiente a ese campo.

image

y luego image

2 –Creamos la clase de autorización en la SU21

image

image

y luego posicionandonoss en la clase recién creada

image

Elegimos el nombre del objeto y ponemos el campo creado en el punto 1.

image

Grabamos y salimos.

3- Definimos los valores posibles de nuestro campo definido y el BASIS asignará a los roles de los usuarios el objeto de autorización creado y pondrá los valores de cada usuario.

4- En el código fuente

  AUTHORITY-CHECK OBJECT ‘ZBOTONES’    “Objeto creado
      ID ‘ZUCOMM’ FIELD ‘SAVE’.                  “sy-ucomm que tengo que verificar.
  IF sy-subrc EQ 0.
      “El usuario tiene el valor SAVE para dicho campo en su rol
  ELSE.
      “El usuario no tiene el valor SAVE para dicho campo en su rol
  ENDIF.

Redondeo y decimales en ABAP

Muchas veces tenesmo problemas con el redondeo, acá hay algunas instrucciones útiles para el manejo de los mismos.

 

DATA N TYPE P DECIMALS 2.
DATA M TYPE P DECIMALS 2 VALUE '-5.55'.
N = ABS( M ). WRITE: 'ABS: ', N.
N = SIGN( M ). WRITE: / 'SIGN: ', N.
N = CEIL( M ). WRITE: / 'CEIL: ', N.
N = FLOOR( M ). WRITE: / 'FLOOR:', N.
N = TRUNC( M ). WRITE: / 'TRUNC:', N.
N = FRAC( M ). WRITE: / 'FRAC: ', N.
* The output appears as follows:
*
* ABS: 5.55 (nro absoluto)
*
* SIGN: 1.00-
*
* CEIL: 5.00- (redondea hacia arriba)
*
* FLOOR: 6.00- (redondea hacia abajo)
*
* TRUNC: 5.00- (parte entera)
*
* FRAC: 0.55- (parte decimal)

Salvar datos en ALV editable con un status bar Z

El otro día me cruce con un error muy bizarro. Yo tenía un ALV editable al cual tuve que agregarle un status bar Z por agregar un botón nuevo.

Copie la status bar standard a mi programa y lo modifique. La status bar STANDARD que esta en el grupo de funciones SALV, no tiene definido el Function Code del boton Grabar (SAVE). entonces le setee el nombre &SAVE.

Que paso ? Si yo cambiaba el valor de algun campo editable del ALV al llegar al USER_COMMAND no veía el nuevo valor ingresado sino que veía el antiguo. Y eso andaba bien por lo cual el error debía estar en la status bar. Y efectivamente así fue.

Para que los datos de un ALV editable sea visibles en el FORM USER_COMMAND, el function code de la status bar tiene que ser &DATA_SAVE. De tener otro nombre la información no es pasada al USER_COMMAND.

Colores en ALV

Si corremos el reporte DEMO_LIST_FORMAT_COLOR_1, podemos ver los números que podemos usar para los determinados colores en el ALV

 

CODIFICACION DE COLORES: El color del ALV sigue el siguiente formato CXYZ donde...
C-> indica que es un color
X-> indica el numero de color, que debe ser del 1 al 9
Y-> indica la intensidad: ('0'=off / '1'=on).
X-> indica si el color es inverso ('0'=off / '1'=on).

Ejemplo para ver facilmente

image

 

Por ejemplo C500 mostrará un verde claro.

MD_STOCK_REQUIREMENTS_LIST_API - MD04 - listado de doc. por Material/Centro

Esta función nos permite ver la información de la tx MD04.

 

Mi req. era realizar un reporte con las cantidades disponibles en Ordenes de compra, Ordenes previsionales, Ordenes de producción y Solped. Pero la función trae muchos más doc. se pueden ver todos en el dominio DELKZ.

 

A la función ingresamos con Material y centro y en la tabla MDEZX estará la información necesaria.

Separar un texto largo cada X cantidad de char o por un símbolo de retorno de carro a una tabla

Esta función RKD_WORD_WRAP , nos permitirá partir un texto largo en X cantidad de caracteres y además podremos tener otro corte de control por un CHAR que le pasemos.

 

Ejemplo:

image

El resultado de esta corrida será una tabla de 7 registros, notese que si no existe el char de retorno de carro nos separará cada 5 chars, si encuentra el simbolo cortará en ese simbolo y comenzará otro renglón.

image

Pasar el signo negativo de la derecha a la izq

Esto puede resultar tonto, pero hay veces en que los clientes quieren que los números negativos tengan el signo a la izquierda y no a la der. Si bien esto podemos hacerlo trabajando con la cadena de caracteres hay una función que nos simplifica la vida.

CLOI_PUT_SIGN_IN_FRONT

Ejemplo:

image

Función para ver características y clasificaciones de un Material - Lote

La función QC01_BATCH_VALUES_READ nos permite ver facilmente las características de un Material-Lote

Le pasamos Material, Centro (opcional) y Lote. Además del idioma y fecha del día.

CALL FUNCTION 'QC01_BATCH_VALUES_READ'
EXPORTING
            I_VAL_MATNR    = I_DOCUMENT_DATA-MATNR
            I_VAL_WERKS    = I_DOCUMENT_DATA-WERKS
            I_VAL_CHARGE   = I_DOCUMENT_DATA-CHARG
            I_LANGUAGE     = I_LANGUAGE
            I_DATE             = I_DATE
IMPORTING
            E_CLASS             = L_CLASS
            E_CLASS_TYPE   = L_CLASS_TYPE
TABLES
            T_VAL_TAB        = L_VAL_TAB
            T_CHAR_TAB     = L_CHAR_TAB
            T_ATT_TAB       = L_ATT_TAB
EXCEPTIONS
            NO_CLASS              = 01
            INTERNAL_ERROR = 02
            NO_VALUES           = 03
            NO_CHARS             = 04.

Nos devuelve 3 tablas:

1- Tiene todas las características con valor ese Material-Lote

2- La siguiente nos pasa todas las características posibles que posee ese Material - Lote marcándonos cuales son las que están cargadas

3- La última posee los atributos técnicos de las características (si es numérico, char, etc)

Lista de materiales de un material en particular

Dejo esta lógica para obtener la lista de materiales de un material. Se que hay funciones para lograr lo mismo porque las he usado pero hoy en día no las tengo a mano.

* Funcion para traer el num de material en el formato del sistema
CALL FUNCTION 'CONVERSION_EXIT_MATN1_INPUT'
        EXPORTING
          input  = wa_archivo-material
        IMPORTING
          output = l_material.

SELECT SINGLE stlal stlnr
       INTO (wa_stlal, wa_stlnr)
       FROM mast
       WHERE matnr EQ l_material.

SELECT stlkn
       FROM stas
       INTO CORRESPONDING FIELDS OF TABLE it_stas
       WHERE stlnr EQ wa_stlnr AND
                   stlal EQ wa_stlal.
IF it_stas[] IS NOT INITIAL.
   SELECT idnrk posnr
        FROM stpo
        INTO CORRESPONDING FIELDS OF TABLE it_stpo
        FOR ALL ENTRIES IN it_stas
        WHERE stlnr EQ wa_stlnr AND
                   stlkn EQ it_stas-stlkn.
ENDIF.

En la tabla it_stpo el campo IDNRK es el número de material.

Radio Buttons dinámicos y ocultar/mostrar grupos de parámetros de selección

Una vez necesite hacer una pantalla de selección dinámica, es decir que si elegía un radio button debía mostrar X cantidad de parámetros y ocultar otros, y viceversa sin la necesidad de que tengamos que apretar un ENTER para que se dispare el evento AT-SELECTION-SCREEN.

El siguiente código lo arme como modo ejemplo para que se den cuenta de como usarlo

 

REPORT ZRADIO_BUTTONS.
PARAMETERS: p_1(10) MODIF ID A,
                       p_2(2)   MODIF ID B,
                       p_3(5).
PARAMETERS: p_A RADIOBUTTON GROUP rad1 USER-COMMAND ACT DEFAULT 'X',
                       p_B RADIOBUTTON GROUP rad1.

AT SELECTION-SCREEN OUTPUT.
LOOP AT screen.
  IF p_A = 'X'.
     IF screen-group1 = 'B'.
     screen-active = 0.
     ENDIF.
  ELSEIF p_B = 'X'.
    IF screen-group1 = 'A'.
    screen-active = 0.
    ENDIF.
  ENDIF.

  MODIFY screen.
ENDLOOP.

 

El MODIF ID lo que hace es darle un identificador a cada parámetro por lo cual no es necesario ocultar cada uno de los parámetros, sino que es más práctico ocultar directamente todos los elementos de un grupo.

La adición USER-COMMAND es la que permite que la selección sea dinámica y que no haya que apretar un enter para ejecutar un PAI.

NOTA: Al usar este método es muy molesto tener parámetros de selección OBLIGATORIOS, porque de no estar completos nos va a saltar la validación y los radio button no funcionarán de la forma deseada. Así que de usar Radio buttons dinámicos la validaciones las deberemos hacer manualmente nosotros mismos.

Saltear falta de autorización para una transacción

Existe una función llamada: RS_HDSYS_CALL_TC_VARIANT

Ir a la SE37, ejecutar la función, en el parámetro TCODE ponemos la transacción deseada y le sacamos la X al parámetro AUTHORITY-CHECK.

 

NOTA: No es infalible, puede ser que igualmente no podamos usarlo y ojo porque queda en log el acceso.

Programa para la regeneración de fórmulas

Luego de Crear alguna formula o de algún cambio a nivel de activación. Necesitaremos correr el siguiente reporte

RV80HGEN

Este regenera las fórmulas, al no hacer esto seguramente nos aparezcan Dump al momento de usar fórmulas nuevas. Como buena práctica siempre que se agregan fórmulas debería de correrse.

Fórmulas de SD - VOFM - Agrupación y separación

En la transacción VOFM encontramos varios menues donde entrar esto sirve para el uso de rutinas, que sirven para agrupaciones, calculo de condiciones, etc.

La agrupación y separación sirve para que al momento de facturar pedidos o entregas por ejemplo tenga un cierto criterio de agrupación. Por ejemplo se desea que si varias entregas tienen mismo destinatario (cliente) se agrupen en una sola factura para no hacer una por por cada entrega.

 

Se va a la sección

image

 

La rutina que elegimos tiene que estar seteada en el customizing por el funcional SD

 

FORM DATEN_KOPIEREN_901.
*Criterio de Agrupamiento
  DATA: BEGIN OF ZUK,
          KUNNR TYPE LIKP-KUNNR,
        END OF ZUK.

ZUK-KUNNR = LIKP-KUNNR.

VBRK-ZUKRI = ZUK.

ENDFORM.

Con esta subrutina se va a agrupar las entregas por cliente (KUNNR). Todos los campos que se agreguen a la estrutura ZUK (ZUKRI) van a ser criterios de agrupación. Si dos entregas no coinciden en alguno de los campos especificados se hace una separación.

Tabla útiles de CRM

  • CRMD_ORDERADM_H - Cabecera de Orden
  • CRMD_ORDERADM_I - Posición
  • BUT000 -La tabla de donde salen los nombres de los códigos de Partner, se accede por el código de Partner.
  • SCPRIOT - Prioridades de una Orden
  • QPCT - Texto de Categorías
  • AGR_1251 - Clase de operación, entrando por roles - Function para ver roles de un user "/OSP/GET_R3_ROLES"
  • TJ30T - Textos para status de usuarios

 

Generalmente las tablas comienzan con CRMD* las que tienen que ver con ordenes.

 

También se puede usar la función CRM_ORDER_READ para obtener todos los detalles de una determinada orden.

Bajada de PDF de forma local

Si bien existen las funciones para bajar un OTF (SapScript o Smartforms) a PDF de esta manera es mucho más sencilla, este programa ya tiene el proceso de conversión a  PDF, simplemente le pasamos la orden de SPOOL y la ruta donde queremos el archivo y listo.

 

SUBMIT rstxpdft4
USING SELECTION-SCREEN '1000'
WITH spoolno EQ w_spool_num
WITH download EQ 'X'
WITH p_file EQ 'c:\download.pdf'
EXPORTING LIST TO MEMORY
AND RETURN.