domingo, 18 de mayo de 2014

Añadir nuevos campos a las transacciones ME21N / ME22N / ME23N

En esta entrada, voy a explicar con un ejemplo como añadir nuevos campos a las transacciones ME21N, ME22N y ME23N.

Las transacciones ME21N / ME22N y ME23N pertenecen al componente compras, que a su vez pertenece al modulo de Gestión de Materiales MM. Este modulo se encarga de dar soporte a todas la fases de gestión de materiales Planificación de necesidades y control, compras, entrada de mercancías, gestión de stocks y verificación de facturas.

Estas transacciones dan soporte para crear, modificar y visualizar pedidos de compra de materiales a proveedores. Aunque el estándar cubre la mayoría de escenarios, es posible, realizar cambios a medida para adaptar estas transacciones a las necesidades del cliente.

Por ejemplo, el cliente necesita dos campos nuevos en las posiciones de los pedidos de compras:
  • ZZSOCIO: número de socio de la cooperativa que realiza la compra
  • ZZFACT:   número de doc. de compra del socio
Estos campos deben ser visibles y editables desde las transacciones de compras.


1. AÑADIR LOS NUEVOS CAMPOS A LA BASE DE DATOS
Desde la transacción SE11. Crear o modificar las siguientes estructuras de datos: :
  • CI_EKKODB: Si queremos añadir nuevos campos a la cabecera de los pedidos de compra 
  • CI_EKPODB: Si queremos añadir nuevos campos a las posiciones de los pedidos de compras
Los dos nuevos campos  pertenece a las posiciones del pedido de compra.
Añadir los nuevos campos a la estructura CI_EKPODB.

 Los nuevos campos para posiciones de pedidos de compra
Activar la estructura,  los nuevos campos aparecerán en la tabla EKPO.

EKPO con los nuevos campos
Crear una nueva estructura de datos, por ejemplo ZCI_EKPO_DB, con los siguientes campos:
  • MANDT
  • EBELN
  • EBELP
  • Todos nuestros campos a medida


2. GRUPO DE FUNCIONES MEPOBADIEX:
Es un grupo de funciones de ejemplo, no lo modifiquéis, copiarlo y utilizar la copia para los nuevos campos.
  1. Ejecutarla transacción SE80 
  2. Seleccionar grupo de funciones en el despegable
  3. Copiamos el grupo de funciones MEPOBADIEX y lo llamamos ZZMEPOBADIEX
  4. Copiamos todas las bapis de MEPOBADIEX. Añadir "ZZ" al principio del nombre de todas las funciones.




Variable y estructuras globales del grupo de funciones ZZMEPOBADIEX.

Accedemos al include LZZMEPOBADIEXTOP, cambiar el codigo por

* dynpro output structure
TABLES:  ZCI_EKPO_DB.                                        "Antes mepo_badi_struct.

* persistent data
DATA: gt_persistent_data TYPE SORTED TABLE OF  ZCI_EKPO_DB   "Antes mepo_badi_exampl
                         WITH UNIQUE KEY mandt ebeln ebelp,

* actual data
      gt_data            TYPE SORTED TABLE OF   ZCI_EKPO_DB  "Antes mepo_badi_exampl
                         WITH UNIQUE KEY mandt ebeln ebelp.

* definitions required for dynpro/framework integration
DATA: ok-code TYPE sy-ucomm.
INCLUDE lmeviewsf01.

Creamos una nueva dynpro con los campos a medida.

  1. Ejecutamos el screen painter, transacción SE51.
  2. Como programa, indicamos el prog de control del grupo de funciones: SAPLZZMEPOBADIEX.
  3. Indicar el numero de la nueva dynpro.
  4. En la pestaña Atributos marcar Tipo de dynpro -> Subscreen
  5. Diseñar la nueva dynpro.
  6. Añadir dos módulos a la lógica de proceso de la dynpro:
    • CUST_EVENT_PBO
    • CUST_EVENT_PAI
     6. Guardar  y activar la dynpro.


transaccion SE51 - Screen painter

SAPLZZMEPOBADIEX: Programa de control del grupo de funciones ZZMEPOBADIEX
Como origen de los campos :  ZCI_EKPO_DB  del include  LZZMEPOBADIEXTOP .

Dynpro con los nuevos campos a medida
Módulos PBO y PAI

Repito, muy  importante, comprobar que la estructura de los campos es ZCI_EKPO_DB y que no se referencia a la estructura del diccionario.

campos a medida de la dynpro 0100
Include LZZMEPOBADIEXTOP: variables globales del grupo de funciones ZZMEPOBADIEX.
  • Remplazamos MEPO_BADI_STRUCT  por  ZCI_EKPO_DB
  • Si no existe , incluir la instrucción  "TABLES:  ZCI_EKPO_DB".     
LZZMEPOBADIEXTOP
Continuamos con las bapis contenidas en el grupo de funciones ZZMEPOBADIEX.
Adaptamos el código  y parámetros de las bapis a nuestras necesidades.

Nos centramos en las siguientes funciones:

  • ZZMEPOBADIEX_INIT
  • ZZMEPOBADIEX_OPEN
  • ZZMEPOBADIEX_GET_DATA
  • ZZMEPOBADIEX_PUSH
  • ZZMEPOBADIEX_POP
  • ZZMEPOBADIEX_SET_DATA
En todas las Bapis reemplazamos:
  • Remplazamos MEPO_BADI_STRUCT  por  ZCI_EKPO_DB.
  • Remplazamos MEPO_BADI_EXAMPL por  ZCI_EKPO_DB. 
Cambiamos el SELECT de  ZZMEPOBADIEX_OPEN por otro que recupere nuestros campos a medida:

CHECK NOT im_ebeln IS INITIAL.

  SELECT mandt ebeln ebelp ZZSOCIO ZZFACT
    FROM ekpo
    INTO CORRESPONDING FIELDS OF TABLE gt_persistent_data
    WHERE ebeln = im_ebeln.

  gt_data = gt_persistent_data.


Cambiamos el código de ZZMEPOBADIEX_SET_DATA por:

DATA: ls_data LIKE LINE OF gt_data.

  FIELD-SYMBOLS: <data> LIKE LINE OF gt_data.

  CHECK NOT im_data-ebelp IS INITIAL.

  IF NOT im_physical_delete_request IS INITIAL.
* delete a line from gt_data
    DELETE TABLE gt_data WITH TABLE KEY mandt = sy-mandt
                                        ebeln = im_data-ebeln
                                        ebelp = im_data-ebelp.
  ELSE.
* update customer data
    READ TABLE gt_data ASSIGNING <data> WITH TABLE KEY
                                        mandt = sy-mandt
                                        ebeln = im_data-ebeln
                                        ebelp = im_data-ebelp.
    IF sy-subrc IS INITIAL.
     <data>-ZZSOCIO = im_data-ZZSOCIO.
     <data>-ZZFACT  = im_data-ZZFACT.
    ELSE.
      ls_data = im_data.
      ls_data-mandt = sy-mandt.
      INSERT ls_data INTO TABLE gt_data.
    ENDIF.
  ENDIF.

3. BADIS ME_GUI_PO_CUST / ME_PROCESS_PO_CUST:
  • Badi ME_GUI_PO_CUST:  controla el aspecto gráfico de la nueva pestaña
  • Badi ME_PROCESS_PO_CUST: para tratar los datos de la cabecea o de posición
Implementación de la Badi ME_GUI_PO_CUST

Esta badi contiene los métodos para poder añadir una nueva pestaña a nivel de cabecera o posición.

También contiene los métodos que permiten controlar el flujo de datos entre la Base de Datos y la Pestaña.

Voy a explicar las dos formas que conozco de implementar la badi.

Implementación a través de la SPRO:

Transacción SPRO -> Gestión de materiales -> Compras -> Add-ins empresariales para compras -> BAdI: Pantallas propias del cliente en el pedido (transacc.EnjoySAP)

Es necesario comprobar si ya existe alguna implementacíón de la Badi. Recordar que aunque la Badi se puede implementar más de una vez, soló una implementación puede estar activa al mismo tiempo. Si hay dos o mas implementaciones activas al mismo tiempo, saltara un DUMP al ejecutar cualquier transacción de compras.

Implementaciones existentes de la badi 
  • Crear una nueva implementación: Pulsar sobre el icono Crear.  El sistema solicitara introducir un  nombre para nueva implementación de la Badi. 
  • Modificar una implementación ya existente: Doble click sobre el nombre de la implementación.
Implementación a traves de la transaccion SE18:

Transaccion SE18 -> Nre.Badi -> ME_GUI_PO_CUST

Para ver la implementaciones existentes Menu superior -> Implementación ampliacion -> Resumen
Para crear una nueva implementación Pulsar sobre el icono Crear.




lo primero es modificar los atributos de la clase ->  Pestaña Interface.
Doble click sobre la clase que aparece en el campo Nombre de la clase de implementación.
Una vez dentro de la clase -> Pasar a -> Secciones -> Área publica.

Añadir las siguientes lineas debajo de PUBLIC SECTION.

type-pools MMMFD .
constants SUBSCREEN1 type MEPO_NAME value 'ITEMSCREEN1' .

Repetimos el proceso, pero esta vez seleccionamos Área Privada.
Añadir las siguientes a la  PRIVATE SECTION.

data DYNP_DATA_PBO type ZMEPO_CEB.
data DYNP_DATA_PAI type ZMEPO_CEB 

Clase de la implenetación

Acceso a los atributos Públicos


Acceso a los atributos Privados

Volvemos a la pestaña Interface. Tenemos que implementar los siguientes métodos:
  • SUBSCRIBE 
  • MAP_DYNPRO_FIELDS
  • TRANSPORT_FROM_MODEL
  • TRANSPORT_TO_DYNP
  • TRANSPORT_FROM_DYNP
  • TRANSPORT_TO_MODEL

Implementación de métodos de la Badi ME_GUI_PO_CUST
METODO SUBSCRIBE 


Permite configurar parámetros clave de la nueva pestaña y campos a medida.
La tabla RE_SUBSCRIBERS debe contener un registro por cada nueva pestaña que queramos añadir.
Siguiendo con el  ejemplo, añadimos una nueva pestaña a las posiciones del pedido de compra.

DATA: ls_subscriber LIKE LINE OF re_subscribers.

CHECK im_application = 'PO'.
CHECK im_element     = 'ITEM'.  "para cabecera -> 'HEADER'.

CLEAR re_subscribers[].

ls_subscriber-name = SUBSCREEN1.
ls_subscriber-program = 'SAPLZZMEPOBADIEX'. "El programa que contiene la dynpro
ls_subscriber-dynpro  = '0100'.             "Dynpro con los campos a medida
ls_subscriber-struct_name = 'ZCI_EKPO_DB'.  "Estructura campos dynpro
ls_subscriber-label = text-001.             "Texto de la pestaña
ls_subscriber-position = 13.                "Posición de la pestaña
ls_subscriber-height = 7.
APPEND ls_subscriber TO re_subscribers.

METODO  MAP_DYNPRO_FIELDS

Tenemos que crear un mapeo para los nuevos campos a medida con metafields, a cada nuevo campo le asignaremos un metafield existente en el grupo de tipos MMFD. La función de estos metafileds es la selección de campos y manejo de errores y excepciones que se puedan producir.

* Mapeo de los nuevos campos de la pestaña nueva en las trans. de compra
* Las definiciones standard se pueden encontrar en type pool MMMFD
* TODO  campo definido por el cliente debe 
* tener un mapeo superior a 90000000

FIELD-SYMBOLS: <mapping> LIKE LINE OF ch_mapping.

  LOOP AT ch_mapping ASSIGNING <mapping> .

    CASE <mapping>-fieldname.

      WHEN 'ZZSOCIO'.    <mapping>-metafield = mmmfd_cust_01.
      WHEN 'ZZFACT'.     <mapping>-metafield = mmmfd_cust_02.

    ENDCASE.

  ENDLOOP.

Grupo de tipos MMMFD y las definiciones estándar para mapear nuevos campos

Los siguientes métodos son para controlar el flujo entre la BBDD <---> Dynpro.

METODO TRANSPORT_FROM_MODEL.

Carga los datos desde la BBDD a la estructura de datos interna de


DATA: l_item       TYPE REF TO if_purchase_order_item_mm,
      ls_mepoitem  TYPE mepoitem,
      ls_customer  TYPE ZCI_EKPO_DB.

  CASE im_name.

    WHEN subscreen1.

      mmpur_dynamic_cast l_item im_model.
      CHECK NOT l_item IS INITIAL.

*     Recuperamos los datos actuales de la BD
      ls_mepoitem = l_item->get_data( ).

*     Recuperamos los actules de la transacción, pueden diferir
*     de los datos anteriores....
      CALL FUNCTION 'ZZMEPOBADIEX_GET_DATA'
        EXPORTING
          im_ebeln = ls_mepoitem-ebeln
          im_ebelp = ls_mepoitem-ebelp
        IMPORTING
          ex_data  = ls_customer.

      MOVE-CORRESPONDING ls_mepoitem TO dynp_data_pbo.
      MOVE ls_customer-ZZSOCIO TO dynp_data_pbo-ZZSOCIO.
      MOVE ls_customer-ZZFACT  TO dynp_data_pbo-ZZFACT.

    WHEN OTHERS.

  ENDCASE.

METODO TRANSPORT_TO_DYNP.

Actualiza los datos que nosotros vemos en la dynpro con los datos de la estructura interna

CASE im_name.

    WHEN subscreen1.

      CALL FUNCTION 'ZZMEPOBADIEX_PUSH'
        EXPORTING
          im_dynp_data = dynp_data_pbo.

    WHEN OTHERS.
  ENDCASE.

METODO TRANSPORT_FROM_DYNP.

Vuelca el contenido de los campos a medida en la dynpro a la estructura interna.

CASE im_name.

    WHEN subscreen1.

      CALL FUNCTION 'ZMEPOBADIEX_POP'
        IMPORTING
          ex_dynp_data = dynp_data_pai.

      IF dynp_data_pai NE dynp_data_pbo.
*       Si ha cambiado los datos, habra que notificarlo a la dynpro
        re_changed = mmpur_yes.
      ENDIF.

    WHEN OTHERS.

  ENDCASE.

METODO TRANSPORT_TO_MODEL.

Guardamos el contenido de la estructura dynp_data_pai en la BBDD

DATA: l_item       TYPE REF TO if_purchase_order_item_mm,
        ls_mepoitem  TYPE mepoitem,
        ls_customer  TYPE ZCI_EKPO_DB.


  CASE im_name.

    WHEN subscreen1.

*     ¿ Es un ITEM ? descartamos las cabeceras
      mmpur_dynamic_cast l_item im_model.
      CHECK NOT l_item IS INITIAL.

*     Recuperamos los datos
      ls_mepoitem = l_item->get_data( ).


*     Han Cambiado los datos ???? 
      IF ( dynp_data_pbo-ZZSOCIO NE dynp_data_pai-ZZSOCIO ) OR
         ( dynp_data_pbo-ZZFACT  NE dynp_data_pai-ZZFACT  ),


          CALL FUNCTION 'ZZMEPOBADIEX_GET_DATA'
            EXPORTING
             im_ebeln = ls_mepoitem-ebeln
             im_ebelp = ls_mepoitem-ebelp
           IMPORTING
             ex_data  = ls_customer.

         ls_customer-ZZSOCIO    = dynp_data_pai-ZZSOCIO.
         ls_customer-ZZFACT     = dynp_data_pai-FACT.

         CALL FUNCTION 'ZZMEPOBADIEX_SET_DATA'
           EXPORTING
              im_data = ls_customer.

ls_mepoitem-ZZSOCIO    = dynp_data_pai-ZZSOCIO.
         ls_mepoitem-ZZFACT     = dynp_data_pai-FACT.
         CALL METHOD l_item->set_data( ls_mepoitem ).
ENDIF. WHEN OTHERS. * ... ENDCASE.


Implementación de la Badi ME_PROCESS_PO_CUST
Para implementar la badi, comprobamos si ya hay implementaciones activas:
Desde la transacción SE18 -> Punto de ampliación -> ME_PROCESS_PO_CUST -> Visualizar


Bajo la pestaña Enhancem.Implementations aparecen las implementaciones existentes y las implementaciones activas.

implementaciones existentes y activas de ME_PROCESS_PO_CUST
Al igual que la anterior Badi, se puede implementar más de 1 vez, pero sólo una implementación puede estar activa al mismo tiempo. Si hay dos o mas implementaciones activas al mismo tiempo, saltara un DUMP al ejecutar cualquier transacción de compras.

Debemos crear una nueva implementación o modificamos una existente.

Para modificar una implementación existente, doble click soble la implementación en la pestaña Enhancem.Implementations del punto de ampliación ME_PROCESS_PO_CUST.

Para crear una nueva implementacion de la badi:

  1. Transacción SE18->Nre.Badi->ME_PROCESS_PO_CUST -> Visualizar.
  2. Dentro de la badi, en el menu superior Implementación -> Crear
  3. Introducir el nuevo nombre de la implementación. Por comprensión, suele ser el  ZZ + nombre de la badi.
  4. Introducir una descripción para la nueva implementación


Crear una nueva implementación de ME_PROCESS_PO_CUST
Nombre dela nueva implementación
Descripción de la nueva implementación

Dentro de la Badi, en la pestaña Interface, Es necesario implementar los siguientes métodos.
  • INITIALIZE
  • OPEN
  • PROCESS_ITEM
  • FIELDSELECTION_ITEM
Para implementarlos , hacer doble clic sobre el nombre del método
Implementación de métodos de la Badi ME_PROCESS_PO_CUST
METODO INITIALIZATE

* Rutinas de inicialización para los campos a medida
CALL FUNCTION 'ZZMEPOBADIEX_INIT'.




METODO OPEN

* Leer los datos del pedido de compra y cargar los datos
* de los campos a medida de la base de datos

DATA: ls_mepoheader TYPE mepoheader.

CHECK im_trtyp EQ 'V' OR im_trtyp EQ 'A'.

ls_mepoheader = im_header->get_data( ).

  CALL FUNCTION 'ZZMEPOBADIEX_OPEN'
    EXPORTING
      im_ebeln = ls_mepoheader-ebeln.

METODO PROCESS_ITEM

    DATA: ls_mepoitem TYPE mepoitem,
          ls_customer TYPE ZCI_EKPO_DB.


    ls_mepoitem = im_item->get_data( ).

    CALL FUNCTION 'ZZMEPOBADIEX_GET_DATA'
      EXPORTING
        im_ebeln = ls_mepoitem-ebeln
        im_ebelp = ls_mepoitem-ebelp
      IMPORTING
        ex_data  = ls_customer.

    MOVE ls_customer-ZZSOCIO TO ls_mepoitem-ZZSOCIO.
    MOVE ls_customer-ZZFACT  TO ls_mepoitem-ZZFACT.

    CALL METHOD im_item->set_data( ls_mepoitem ).

METODO FIELDSELECTION_ITEM 
Este método es muy importante porque determina las características de visualización de los campos dependiendo de la transacción que estemos ejecutando. Si no lo implementáis, los campos a medida serán editables en todas las transacciones y aunque nos encontremos en el modo de visualizar documento.
* Características de visualización de los campos
* '-' Field is suppressed
* '*' Field is purely a display field
* '.' Input field
* '+' Mandatory field

    DATA: wc_status  TYPE c.
    DATA: l_changeable TYPE mmpur_bool.
    FIELD-SYMBOLS:  <mapping> LIKE LINE OF ch_fieldselection.

    BREAK-POINT.

    l_changeable = IM_HEADER->is_changeable( ).
    IF l_changeable = 'X'.
      wc_status = '.'. " READY FOR INPUT
    ELSE.
      wc_status = '*'. " view
    ENDIF.

    LOOP AT ch_fieldselection ASSIGNING <mapping>.

      CASE <mapping>-metafield.
        WHEN mmmfd_cust_01.
          <mapping>-fieldstatus = wc_status.
        WHEN mmmfd_cust_02.
          <mapping>-fieldstatus = wc_status.
      ENDCASE.
    ENDLOOP.

Y si no hemos cometido algún error:
nuevos campos a medida en ME21N/ME22N/ME23
Campos a medida en la tabla EKPO



Algunos errores comunes:

  • La pestaña solo aparece en la ME23N
Comprueba el método ME_PROCESS_PO_CUST~FIELDSELECTION_ITEM.

  • Los campos son editables en la ME23N
Comprueba el método ME_PROCESS_PO_CUST~FIELDSELECTION_ITEM.
Comprueba los campos de la dynpro, que estén bien referenciados a la estructura.
Comprueba el método ME_GUI_PO_CUST~SUSCRIBE.

  • No se guardan los datos en la BD
Comprueba la bapi ZZMEPOBADIEX_SET_DATA.

38 comentarios:

  1. Hola, excelente documentacion.
    Aun me queda una duda: como se actualiza la CI_EKPODB? Tan solo porque la Tabla ZCI_EKPODB contiene los campos ZZ...?
    Gracias de antemano por tu comentario... mi correo = rafaelvives@web.de

    ResponderEliminar
    Respuestas
    1. CI_EKPODB y CI_EKKODB no son tablas , son solamente estructuras, no guardan ningún dato.
      Solo se utilizan para añadir los campos ZZ a las tablas EKKO / EKPO para no modificarlas directamente.

      Eliminar
    2. Hola David, correcto... Pero en ningún momento utilizamos la CI_EKPODB.
      En cambio utilizamos la ZCI_EKPODB.
      Cómo llegan los datos a la ekpo?
      En qué punto se pasan los datos a la CI_EKPODB ó a la EKPO?
      saludos
      rafael

      Eliminar
    3. Hola David, correcto...
      Sólo me falta entender en qué punto se pasan los datos a la CI_EKPODB o a la EKPO ara guardarlos en la EKPO?
      Es que solamente usamos la ZCI_EKPODB?

      Eliminar
    4. Si te refieres al CUANDO SE MUEVEN LOS DATOS ENTRE DYNPRO / TABLA es cuando se produce uno de los eventos de la badi que hemos creado al principio, por ejemplo TRANSPORT_FROM_DYNP / TRANSPORT_TO model principalmente, dentro de esos eventos llamas a las funciones del grupo de funciones ZZMEPOBADIEX ( funciones como ZMEPOBADIEX_POP / ZMEPOBADIEX_PUSH / etc... )

      Eliminar
    5. Si quieres ver la documentacion de la badi, por ejemplo la ME_GUI_PO_CUST:
      1.- transacción SE18 -> Nre.Badi -> ME_GUI_PO_CUST
      2.- En el menú superior Pasar a -> Documentación -> Visualizar
      3.- Te aparecerá la documentación de la Badi, si bajas el scroll, al final tienes la documentación de los métodos

      Eliminar
  2. Pregunta , ya tengo agregados los campos en la structuras , tengo que implementar la badi ? , ya existe una pantalla con user exit y ocupa la 101.

    ResponderEliminar
    Respuestas
    1. Las Badis no están disponibles en versiones 46C e inferiores, en esos casos se programa con las user-exit.
      Podrías implementar la BADI y "en teoría" no se interfieren o podrías modificar las user-exit ya existentes para añadir tus campos.

      Eliminar
  3. ya hice todo exactamente igual, sin embargo no logro modificar el estatus del campo (.*+_) y cuando doy salvar me manda el mensaje que no se han realizado modificaciones, ya revise los puntos que sugieres y ademas el resto tanto de las badis como el modulo de funcnioes

    ResponderEliminar
    Respuestas
    1. Puedes describirlo mas detalladamente, si te refieres a que el campo sea modificable comprueba que estén activadas las badis y sus metodos. En la badi te aparecera un mensaje "La implementación se llamara" si esta activa.

      Eliminar
    2. pues el campo en me23n es modificable, en me22n manda el mensaje que no se ha modificado ningun campo, es puesto break points en todos los metodos de las badis y no los esta recorriendo todos, lo he debbugueado y se asigna la constante 90000000 al campo, en el campo de estatus se asigna * que es modo vista, sin embargo no tiene efecto, las badis y sus métodos están activos y también lo esta el grupo de funciones y sus modulos

      Eliminar
    3. ¿Esta bien implementado el método SUBSCRIBE de la implementación de la badi ME_GUI_PO_CUST ?
      Comprueba los campos de la dynpro, que estén bien referenciados a la estructura.
      Si estas siguiendo el ejemplo, los campos de la dynpro deben referenciar a la estructura ZCI_EKPO_DB

      Eliminar
    4. Posiblemente no hayas creado los eventos PBO y PAI. Si has seguido los pasos que aquí, de forma inmejorable, se ten han indicado los procesos de la dynpro nueva (0100) deben quedar como los del standard que has copiado:

      MODULE custo_event_pbo OUTPUT.
      CALL METHOD call_view->handle_event( 'PBO' ).
      WKAFIELDS = text-002.
      ENDMODULE.
      *&---------------------------------------------------------------------*
      *& Module CUSTO_EVENT_PAI INPUT
      *&---------------------------------------------------------------------*
      * text
      *----------------------------------------------------------------------*
      MODULE custo_event_pai INPUT.
      CALL METHOD call_view->handle_event( 'PAI' ).
      ENDMODULE.

      Eliminar
    5. Hola, estoy teniendo el mismo problema y no se como solucionarlo. Cuando edito el campo de la vista Z y doy grabar me dice que no hay cambios para guardar. Ahora si voy y todo un texto o un campo de la solapa direccion si me guarda.

      Eliminar
    6. Revisa los metodos TRANSPORT_TO_MODEL y SET_DATA es posible que los datos de la dynpro no se esten traspasando a tus campos Z.

      Eliminar
  4. Hola tenes alguna informacion para agregar en la IW31/IW32/IW33 en la pestaña Datos complementarios de la modificacion de aviso ? Gracias

    ResponderEliminar
    Respuestas
    1. Prueba con la exit IWO10018. Aqui tienes más información:
      http://wiki.scn.sap.com/wiki/display/ABAP/New+field+List+display+at+IW38+or+IW39+when+activating+screen+exit+at+IW31+Maintenance+Order+create

      Eliminar
  5. Hola David: debo crear una tabla transparente z para remplazar mepo_badi_exampl? porque tengo el mensaje al activar ZZMEPOBADIEX_COMMIT:

    "ZCI_EKKO_DB" is not defined in the ABAP Dictionary as a table, projection view, or database view.
    En tab TABLA:
    IMT_DATA_NEW LIKE ZCI_EKKO_DB
    IMT_DATA_OLD LIKE ZCI_EKKO_DB

    ResponderEliminar
    Respuestas
    1. Nunca he usado esa badi. Creo que su función es actualizar los campos a medida cuando los tienes en una tabla aparte de las estándar EKKO, EKPO... Si te fijas en el código que trae de ejemplo actualiza las entradas en al tabla MEPO_BADI_EXAMPL que deberías sustituir por tu tabla.

      Si tienes los campos a medida en la tablas EKKO, EKPO... te recomiendo que no uses esa bapi y que uses las bapis GET_DATA/SET_DATA como aparece en el post dentro de los métodos de la badi.

      Eliminar
  6. Hola David, siguiendo tu ejemplo, adaptándolo a Header, todo funciona bien pero no logro que la pestaña no aparezca dependiendo de las condiciones que le dé, he logrado quitar los campos pero me deja la pestaña bacía. lo hago en el metodo "IF_EX_ME_PROCESS_PO_CUST~FIELDSELECTION_HEADER".

    ResponderEliminar
    Respuestas
    1. Probá poniendo todos los campos con status supress en este ejemplo los muestra solo para el pedido estandard. Me funciono con los items.

      DATA(ls_header) = im_header->get_data( )
      IF ls_header-bsart EQ 'NB'.
      wc_status = '*'. " view
      ELSE.
      wc_status = '-'. " supress
      ENDIF.

      LOOP AT ch_fieldselection ASSIGNING .

      CASE -metafield.

      WHEN mmmfd_cust_01.
      -fieldstatus = wc_status.

      WHEN mmmfd_cust_02.
      -fieldstatus = wc_status.

      ENDCASE.
      ENDLOOP.

      Eliminar
  7. Si señor...esto es un buen ejemplo, y además bien explicado.
    Muchas gracias.

    ResponderEliminar
  8. Hola , segui los pasos pero tengo el siguiente problema , los datos en la nueva pestaña no los visualizo, pero si los recupero y si los graba en la tabla ekpo.

    ResponderEliminar
  9. hola , buenas tardes.
    Segui paso a paso el doc y logre crear la pestaña y que los datos se graben en la tabla EKPO, pero no logro que se visualizen en la pestaña creada.

    ResponderEliminar
  10. Hola, alguna vez os ha dado actualización interrumpida en SM13: System error: error during delete Table MEPO_BADI_EXAMPL en el FM ZZMEPOBADIEX_COMMIT?

    ResponderEliminar
    Respuestas
    1. MEPO_BADI_EXAMPL es la tabal de ejemplo que viene en el codigo de sap. Si te fijas en el código que trae de ejemplo actualiza las entradas en al tabla MEPO_BADI_EXAMPL que deberías sustituir por tu tabla.

      Eliminar
  11. Hola, sigo todos los pasos pero al poner un break point en todos los TRANSPORT no pasa por ahí ( Teniendo la BADI Activa ) El suscribe el map y el execute sí que pasa por ahi...

    Muchas gracias
    Slds

    ResponderEliminar
  12. quiero saber como se pudo activar en detalle de posición de los pedidos una pestañas nuevas como SLS, INDIA , BRASIL,Y OTRAS como servicios limites expedición o variantes dependen del tipo de pedido

    ResponderEliminar
    Respuestas
    1. Entiendo que SLS, INDIA , BRASIL,Y OTRAS son pestañas a medida y quieres que aparezcan o se oculten dependiendo de unos parámetros o quieres saber donde se han registrado.
      - Para registar una pestaña a medida Método SUSCRIBE de la badi ME_GUI_PO_CUST. En este método de dan de alta las nuevas pestañas a medida, dynpro, texto de la pestaña, etc...
      - En el método FIELDSELECTION_HEADER o FIELDSELECTION_ITEM de la badi ME_PROCESS_PO_CUST dependiendo del caso. Debes dejar inactivos TODOS LOS CAMPOS de la pestaña que quieres ocultar asignando el fieldstatus = '-'.
      Cuando una pestaña tiene TODOS SUS CAMPOS inactivos, el sistema oculta automáticamente esa pestaña. Así puedes ocultar o activar pestañas dependiendo del caso

      Eliminar
  13. Hola Estimado! Segui paso a paso tu descripción y me funcionó sin problemas, muchas gracias!!!

    Una duda aparte, si quieres tener una nueva pestaña tanto en la cabecera como en las posiciones, ¿creas un grupo de funciones Z para cada uno o utilizas el mismo para los dos?

    En caso de usar el mismo, ¿significa que todo se debe duplicar, como los parámetros de las funciones o las variables globales?

    gracias!

    ResponderEliminar
  14. Buenas noches muy interesante el tutorial, yo cree el campo de cliente activando la dynpro 0111 del grupo de funciones X06 y active los metodos IF_EX_ME_PROCESS_PO_CUST~CHECK y IF_EX_ME_PROCESS_PO_CUST~PROCESS_ITEM, tengo una pregunta como puedo invocar el metodo PROCESS_ITEM desde la pestaña de cliente, esto con el fin de realizar una operacion cuando ingreso el campo de cliente, de antemano agradezco la ayuda que puedan prestarme.
    Cordialmente,

    Jose Luis Holguin S.

    ResponderEliminar
  15. no lo puedo ver la nueva pestaña del header q hemos creado en la me21n me22n solo lo veo en la me23n

    ResponderEliminar
  16. no lo puedo ver la nueva pestaña del header q hemos creado en la me21n me22n solo lo veo en la me23n

    ResponderEliminar
  17. no lo puedo ver la nueva pestaña del header q hemos creado en la me21n me22n solo lo veo en la me23n

    ResponderEliminar
  18. Me ayudooo mucho me salió todo conforme, agregue un campo en EKPO
    solo tengo unas observaciones del documento donde
    1. METODO TRANSPORT_FROM_DYNP.
    Dice: CALL FUNCTION 'ZMEPOBADIEX_POP'
    Debe decir: CALL FUNCTION 'ZZMEPOBADIEX_POP'
    2. En todas las Bapis reemplazamos:
    Remplazamos MEPO_BADI_STRUCT por ZCI_EKPO_DB.
    Remplazamos MEPO_BADI_EXAMPL por ZCI_EKPO_DB.
    Existe unas pestañas "Export" y "Import" también cambiaremos la columna "tipo Ref." a ZCI_EKPO_DB

    ResponderEliminar
  19. Tengo un problema, al momento de grabar en la ME21N, los campos nuevos permanecen con los valores ingresados...
    Cómo o en que badi se deben inicializar los campos nuevos que se agregaron?...
    De antemano gracias...

    ResponderEliminar
  20. Buenas noches, esto sirve para la MIGO? GRacias, saludos!

    ResponderEliminar
  21. Hola, Gracias por la Guía me ayudó un montón.

    Recientemente tuve que usar la BAPI BAPI_PO_CHANGE para cambiar valores en los campos Z de usuario y tenía un problema, donde no da error al ejecutar la BAPI pero los cambios no se reflejan.

    Creo haber encontrado el problema y es que el método PROCESS_ITEM no se debe hacer el llamado a: CALL FUNCTION 'ZZMEPOBADIEX_GET_DATA'

    Los datos que se envían por la BAPI ya están reflejados en 'ls_mepoitem' y al usar la función 'ZZMEPOBADIEX_GET_DATA' te estás trayendo los datos actuales del documento y no los nuevos(bapi).

    Espero que le ayude a alguien que este usando la bapi: BAPI_PO_CHANGE para cambiar campos Z de Usuario.

    ResponderEliminar