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.

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.

Descripción del Caso:
*&------------------------------------------------------------------------------&*
* 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:
*&------------------------------------------------------------------------------&*
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
*&------------------------------------------------------------------------------&*

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: 

CONSTANTSlc_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,
             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 
      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.

          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.

             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

Comentarios

  1. saludos Alex, muy buenos aportes sigue asi.

    ResponderEliminar
  2. Gracias por los saludos anchpwz, éxitos!

    ResponderEliminar
  3. Tengo varias consultas, siendo lagunas mentales en este momento. ¿Tienes tiempo y skype?

    ResponderEliminar
  4. Hola 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

    ResponderEliminar
  5. Hola, 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

    ResponderEliminar

Publicar un comentario

Entradas populares de este blog

Modificando Vista de Actualización SM30

Buttons and events in ALV GRID and ALV GRID OO