User Exit para VA01 y VA02
Hola amigos reciban un cordial saludo, en esta oportunidad voy a presentar una User Exit que será de mucha utilidad cuando queramos implementar validaciones y ampliaciones en el código standard de SAP para las Transacciones VA01 y VA02, así ajustamos el código a las necesidades específicas del Cliente.
Descripción del Caso:
Programa: SAPMV45A
Include: MV45AFZZ
FORM: USEREXIT_SAVE_DOCUMENT_PREPARE
Presentaré un caso en el que al modificar el Pedido por la Transacción (VA02) Mostrará un mensaje de error siempre y cuando el Pedido a grabar tenga Stock Parcial.
*&------------------------------------------------------------------------------&*
* Al crear y/o modificar un Pedido, por cada posición debe tener sólo un reparto
* y la cantidad del pedido con la cantidad confirmada deben ser iguales
* Veamos el siguiente ejemplo:
*&------------------------------------------------------------------------------&*
* y la cantidad del pedido con la cantidad confirmada deben ser iguales
* Veamos el siguiente ejemplo:
*&------------------------------------------------------------------------------&*
Pedido: 5650
*--------------------------------------------------------------------------------*
*Posiciones
*--------------------------------------------------------------------------------*
*POSNR MATERIAL CANT. PEDIDO UME
* 10 12000096 641 UN
* 20 14000043 83 UN
*--------------------------------------------------------------------------------*
*Repartos
*--------------------------------------------------------------------------------*
*POSNR MATERIAL CANT. PEDIDO CANT. CONFIRMADA UME
* 10 12000096 641 641 UN
* 20 14000043 83 83 UN
*&------------------------------------------------------------------------------&*
Luego clic en el icono Ampliar que tiene forma de espiral.
En mi caso ya esta creado un ENHANCEMENT dentro del Form indicado... caso contrario hubiesen tenido que crear el Enhancement con un nombre que empiece con 'Z'.
*---------------------------------------------------------------*
* Field Symbol
*---------------------------------------------------------------*
*---------------------------------------------------------------*
* Variables Locales
*---------------------------------------------------------------*
Aqui el mismo código pero en imagenes:
Vemos que tiene 2 posiciones
Veremos los repartos para la posición 10, para ello haremos clic en el ícono 'Repartos para la posición' que se encuentra en la parte inferior.
Visualizamos que sólo tiene un reparto, lo cual hasta ahí... Según el objetivo indicado inicialmente: 'cada posición deber tener un sólo reparto'; esta bien... Pero, vemos que la cantidad del pedido y la cantidad confirmada son diferentes:
Luego hacemos clic en el botón Grabar:
*Posiciones
*--------------------------------------------------------------------------------*
*POSNR MATERIAL CANT. PEDIDO UME
* 10 12000096 641 UN
* 20 14000043 83 UN
*--------------------------------------------------------------------------------*
*Repartos
*--------------------------------------------------------------------------------*
*POSNR MATERIAL CANT. PEDIDO CANT. CONFIRMADA UME
* 10 12000096 641 641 UN
* 20 14000043 83 83 UN
*&------------------------------------------------------------------------------&*
En la Tx: SE38 en la campo de texto Programa escribimos: MV45AFZZ y le damos clic en Visualizar:
Luego clic en el icono Ampliar que tiene forma de espiral.
Luego clic en el Menú Tratar, clic en menú Item Operaciones ampliación, finalmente en el menú item Insertar puntos de ampliación implícitos.
Nos ubicamos en el Form USEREXIT_SAVE_DOCUMENT_PREPARE
Cada vez que el usuario haga clic en el botón Grabar dentro de las Tx. VA01 o VA02; automáticamente el programa ingresará a esta rutina ejecutando las validaciones implementadas.
En mi caso ya esta creado un ENHANCEMENT dentro del Form indicado... caso contrario hubiesen tenido que crear el Enhancement con un nombre que empiece con 'Z'.
Cómo ya tengo creado el ENHANCEMENT lo que haré será ubicar el cursor donde esta el nombre del Enhancement:
Luego haré clic en Modificar la implementación:
Automáticamente el código fuente estará disponible para ser editado... Aqui les dejo el código para la validación indicada:
CONSTANTS: lc_va01 type sy-tcode value 'VA01', "VA01: Crear Pedido
lc_va02 type sy-tcode value 'VA02'. "VA02: Modificar Pedido
IF sy-tcode EQ lc_va01 or sy-tcode eq lc_va02.
*---------------------------------------------------------------*
* Declaración Tablas Internas
*---------------------------------------------------------------*
DATA: lt_vbep type STANDARD TABLE OF vbep,
* Declaración Tablas Internas
*---------------------------------------------------------------*
DATA: lt_vbep type STANDARD TABLE OF vbep,
lt_xvbep type STANDARD TABLE OF vbep,
lt_posi type STANDARD TABLE OF vbep,
lt_return type table of BAPIRET2.
*---------------------------------------------------------------*
* Field Symbol
*---------------------------------------------------------------*
FIELD-SYMBOLS: <vbep> LIKE LINE OF lt_vbep,
<xvbep> LIKE LINE OF lt_xvbep,
<posi> LIKE LINE OF lt_posi,
<return> LIKE LINE OF lt_return.
*---------------------------------------------------------------*
* Variables Locales
*---------------------------------------------------------------*
DATA: lv_contador TYPE i,
lv_repartos TYPE i,
lv_posnr TYPE posnr_va,
lv_message TYPE string.
FREE lt_return.
REFRESH lt_return.
lt_xvbep[] = xvbep[]. "Pasamos las posiciones
LOOP AT ivbep."IVBEP: contiene los repartos
APPEND INITIAL LINE TO lt_vbep ASSIGNING <vbep>.
MOVE-CORRESPONDING ivbep TO <vbep>.
APPEND INITIAL LINE TO lt_posi ASSIGNING <posi>.
MOVE-CORRESPONDING ivbep TO <posi>.
ENDLOOP.
DELETE ADJACENT DUPLICATES FROM lt_posi comparing posnr.
DESCRIBE TABLE lt_vbep LINES lv_repartos.
"Recorremos todas las posiciones para ver si por cada posición existe más de un reparto
"Recorremos todas las posiciones para ver si por cada posición existe más de un reparto
LOOP AT lt_posi ASSIGNING <posi>. "10,20,30
lv_contador = 0.
LOOP AT lt_vbep ASSIGNING <vbep> WHERE posnr = <posi>-posnr.
ADD 1 TO lv_contador.
ENDLOOP.
IF lv_contador GT 1.
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_OUTPUT' "Para no mostrar ceros a la izquierda
EXPORTING
input = <posi>-posnr
IMPORTING
OUTPUT = lv_posnr.
CONCATENATE 'La posición' lv_posnr 'tiene más de una línea de reparto'
INTO lv_message SEPARATED BY space.
INTO lv_message SEPARATED BY space.
APPEND INITIAL LINE TO lt_return ASSIGNING <return>.
<return>-id = '8Z'.
<return>-number = '000'.
<return>-type = 'E'.
<return>-message_v1 = lv_message.
exit.
ENDIF.
"Leo la tabla de Repartos LT_XVBEP para la posición que estamos analizando
READ TABLE ivbep WITH KEY posnr = <posi>-posnr.
IF sy-subrc EQ 0.
READ TABLE lt_xvbep ASSIGNING <xvbep> index ivbep-tabix.
IF sy-subrc EQ 0. "Si encuentra la posición entonces validaremos que la cantidad pedido y confirmada sean iguales
IF <xvbep>-BMENG "Cantidad confirmada
NE
<xvbep>-WMENG."Cantidad pedida por el cliente en UMV
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_OUTPUT'
EXPORTING
input = <xvbep>-posnr
IMPORTING
OUTPUT = lv_posnr.
CONCATENATE 'En la posición' lv_posnr 'Falta cantidad confirmada'
INTO lv_message SEPARATED BY space.
INTO lv_message SEPARATED BY space.
APPEND INITIAL LINE TO lt_return ASSIGNING <return>.
<return>-id = '8Z'.
<return>-number = '000'.
<return>-type = 'E'.
<return>-message_v1 = lv_message.
exit.
ENDIF.
ENDIF.
ENDIF.
ENDLOOP.
ENDIF.
*Invocamos a la función standard: 'C14ALD_BAPIRET2_SHOW'
*para si fuese el caso mostrar múltiples mensajes de diferentes tipos en una única ventana
IF lt_return[] IS NOT INITIAL.
CALL FUNCTION 'C14ALD_BAPIRET2_SHOW'
TABLES
i_bapiret2_tab = lt_return.
ENDIF.
Aqui el mismo código pero en imagenes:
Ahora probaremos lo que hemos implementado ingresando desde la Tx: VA02, veamos:
A modo de ejemplo, ingresamos el Pedido 5650
Vemos que tiene 2 posiciones
Veremos los repartos para la posición 10, para ello haremos clic en el ícono 'Repartos para la posición' que se encuentra en la parte inferior.
Visualizamos que sólo tiene un reparto, lo cual hasta ahí... Según el objetivo indicado inicialmente: 'cada posición deber tener un sólo reparto'; esta bien... Pero, vemos que la cantidad del pedido y la cantidad confirmada son diferentes:
Por ende al grabar este pedido nos debería saltar el mensaje de error de nuestra validación implementada:
Para ello simularemos que estamos modificando el motivo de Pedido:
Luego hacemos clic en el botón Grabar:
Y finalmente comprobamos que se visualiza el mensaje que hemos implementado
Ahora si deseas que la validación también se muestre como advertencia, osea NO al momento de Grabar SINO cada vez que se modifica valores en cada posición; en ese caso el mismo código sólo que con mensaje de tipo warning 'W' lo pondríamos dentro de:
FORM: USEREXIT_FIELD_MODIFICATION.
En el caso que deseen bloquear algún campo de las posiciones según alguna validación definida, podrían tomar como referencia el siguiente ejemplo:
FORM USEREXIT_FIELD_MODIFICATION.
IF SCREEN-NAME = 'VBAP-ZMENG' AND ( SY-TCODE EQ 'VA01' OR SY-TCODE EQ 'VA02' ).
SCREEN-INPUT = 0.
ENDIF.
ENDFORM. "USEREXIT_FIELD_MODIFICATION
Nos vemos en siguiente Blog ;)
MAGALEX
saludos Alex, muy buenos aportes sigue asi.
ResponderEliminarGracias por los saludos anchpwz, éxitos!
ResponderEliminarTengo varias consultas, siendo lagunas mentales en este momento. ¿Tienes tiempo y skype?
ResponderEliminarHola Alex, acabo de visitar su blog, le dire que está excelente, muy muy bueno, quisiera ver si me da una manito, necesito en la va01 crear un campo nuevo al screen, en la pestaña condiciones, es decir seria de posición, pero con que user exit lo puedo hacer? favor su ayuda. muchas gracias, un abrazo
ResponderEliminarExcelente aporte.. Gracias
ResponderEliminarHola, se ha creado una validación en las rutinas de formulas para una clase de condición hace sus cálculos pero no actualiza los precios de las condiciones cuando paseo por las posiciones , al darle boton actualizar coloca las cifras de forma correcta, pero se quiere q lo haga de forma automatica, estoy tratando de ubicara por debugge cual es la función q llama ese boton de actualizara y no lo hallo o si existe otra forma de hacerlo puede ayudarme, gracias
ResponderEliminara esto es en la VA01
Eliminar