jueves, 29 de septiembre de 2016

Pasos para hacer una búsqueda global en Webdynpro

Introducción

SAP ABAP da opción a una búsqueda global en la mayoría de sus componentes. Pero cuando llegamos a ABAP Webdynpro no hay dicha opción de búsqueda global. Entonces cuando se requiere buscar una parte de código o una variable específica el desarrollador tiene que ir manualmente por cada componente o método de la vista o ventana y buscalos. Buscar por cada uno de los componentes/vista/ventana es una tarea tediosa y un proceso que consume mucho tiempo.

Tutorial

Los pasos a seguir se detallan a continuación:
  • Ve a la transacción SE24 e introduce la clase CL_WDY_WB_NAMING_SERVICE y ejecuta. Esta es una clase estándar de SAP que se usa para para buscar la clase asociada al componente webdynpro. Ahora en la ventana del Class Builder ejecuta TEST(F8).
  • En la ventana test de la clase selecciona el botón correspondiente al método GET_CLASSNAME_FOR_COMPONENT.
     
  • En la siguiente ventana introduce el nombre de la webdynpro de la que deseas hacer la búsqueda global. La webdynpro FPM_REQUEST_DIALOG se usa como ejemplo y ejecuta.
  • El resultado de este método buscará la clase creada por SAP para el componente webdynpro (el nombre de la clase para este componente se ha generado como /1BCWDY/L2U4HZFJ4MQYUW5YG4OB).
  • Ahora usa esta clase en la SE24 y visualízala. Esta clase es un repositorio de todo el código añadido en la webdynpro. Pulsa el botón e búsqueda global.
  • Supongamos que tenemos que buscar dónde se usa el dato de la interfaz "lr_window" en la webdynpro. En la ventana de búsqueda introducimos el valor "lr_window" y ejecutamos.
  • Se muestran todas las coincidencias encontradas de "lr_window".
  • Doble click en cualquiera de las líneas donde se marca "lr_window" y nos llevará al componente/vista/método de la webydnpro donde la clave de búsqueda se usa en el código.

Restringir autorización a la transacción FB01 por clase de documento


Para restringir la transacción FB01 por clase de documento (el campo señalado en la captura de arriba). Primero tenemos que crear un grupo de autorizaciones.

- Transacción SE54: crear / modificar


- Añadimos una nueva entrada con nuestro nuevo grupo de autorización:

- Transacción OBA7: seleccionamos haciendo doble click la clase de documento que queremos meter en el grupo de autorización

- Indicamos en grupo de autorizaciones el nuevo grupo:

- Transacción PFCG: dentro del rol donde se encuentra el objeto F_BKPF_BLA, añadimos nuestro grupo de autorizaciones


Recuerda que si una clase de documento no tiene grupo de autorizaciones esta podrá verla cualquier usuario independientemente de lo que haya en el objeto de autorización.







jueves, 25 de agosto de 2016

Cómo crear un punto de ampliación en Web Dynpro ABAP

Introducción:

En este artículo veremos paso a paso el procedimiento para crear puntos de ampliación en WD ABAP para ampliar un componente de WD estándar con código o elementos UI. Abarcaremos las siguientes cosas:

  • Crear implementación para ampliar los elementos UI estándar de WD.
  • Cómo usar la implementación  para ampliar métodos estándar en vistas/componentes. 
  • Crear vista/ventana como ampliación.
  • Borrar implementación.

Crear ampliación:

Para crear una implementación realiza los siguientes pasos:
  1. Abre el componente WD para ampliar desde la SE80.
  2. Doble click en el COMPONENTCONTROLLER.
  3. Click en el icono del menu 
  4. Pon el nombre de la ampliación en el pop-up y haz click en
  5. Guárdalo en una orden igual que en otras aplicaciones SAP.
  6. Ahora cada vez que necesites hacer cambios como ampliaciones en el componente WD. Sólo haz click en el icono del menú 
  7. Selecciona la implementación de la ampliación y haz click en el botón 


  8. Ahora se mostrará el nombre del componente seleccionado con el estatus de ampliación como en la siguiente imagen:


Ampliar Elementos UI:

La única cosa que se puede hacer en los elementos UI estándar desde el editor del layout es borrarlos como se muestra a continuación:


Después del borrado una marca  aparecerá al lado del elemento UI borrado.
Después de borrar el elemento UI, puedes crear otro elemento UI bajo la ampliación, con las mismas propiedades que el borrado, añadiendo los cambios que necesites.
Para recuperar el item borrado haz click derecho en el elemento UI en la jerarquía y haz click en "undo deletion" como se muestra a continuación:

Después de hacer estos cambios guarda la ampliación y actívala.


Ampliar métodos estándar:

Abre el componente/vista para ampliar y haz click en el botón  en el menú. Elije la implementación de la ampliación donde quieras ampliar el componente WD.
Para ampliar métodos estándar desplázate hacia la izquierda en la etiqueta de métodos a las columnas "pre-exit", "post-exit" y "overwrite-exit". Puedes escribir tu propio código para ejecutarlo antes/después de estos métodos en los métodos "pre-exit/post-exit" creados como ampliaciones.
Haz click sobre el botón "pre-exit" del método que quieras ampliar si quieres escribir el código antes que el código del método que se ejecuta o "post-exit" si quieres escribir el código después que el código del método que se ejecuta. 
En caso de que quieras borrar el método estándar completamente por tu código, haz click en el botón "overwrite-exit". Esto sobrescribirá el código en el método estándar con el nuevo método creado.
Para borrar los métodos pre-exit, post-exit y overwrite-exit haz click sobre cualquier método estándar y elije el botón de borrado pre-exit  , el botón de borrado post-exit  o el botón de borrado overwrite-exit . Estos borrarán el código ampliado.


Crear una vista/ventana como ampliación:

Para crear una vista como ampliación, click derecho en las vistas y selecciona "Crear como ampliación", y elije la ampliación sobre la que quieres ampliar el componente.
Parecido a crear una ventana como ampliación, click derecho en ventanas y selecciona "Crear como ampliación", y elike la ampliación sobre la que quieres ampliar el componente.


Borrar implementación de ampliación.

Para borrar una implementación de una ampliación localízala en el paquete.
Para hacer eso:

  1. Ve a la SE80.
  2. Selecciona el paquete donde se guarda la ampliación.
  3. Selecciona la implementación dentro de la carpeta como se muestra:

    Una vez borrada la implementación, los cambios hechos en la ampliación serán revertidos en el componente WD.

SAP Comunity Network












miércoles, 24 de agosto de 2016

Cómo implementar eventos en la actualización de una tabla

Implementar eventos en la actualización de una tabla es muy útil mientras creamos nuevas entradas en una tabla. Se pueden ejecutar muchas validaciones y checks mientras creamos o guardamos entradas en una tabla.

Contenido de la tabla:

Consideremos un escenario, donde una tabla de customizing se tiene que actualizar con la fecha y hora de creación / modificación.

Paso 1: Crear una tabla ZTAB con los siguientes campos:


Campo Tipo Descripción
MANDT MANDT Cliente
PAIS LAND1 Clave del país
CREATEDATE CREATEDATE Fecha creación / modificación
CREATETIME CREATETIME Hora creación / modificación

Paso 2: Generar imagen de actualización para la tabla:

Utilidades> Generador actualiz. tab.

Grupo de autorización: &NC&
Grupo de funciones: ZTAB (o cualquiera disponible)
Tipo de actualización: 2 niveles
Nº Imagen actualiz : pantalla general 8005 
                                  pantalla simple 8006

Crear.

Paso 3: Crear evento en la actualización:

Entorno> Modificación> Eventos> Entradas nuevas.
Lista de eventos disponibles:


Selecciona 05 para el evento al "Al crear una nueva entrada".
Este evento saltará al crear una nueva entrada en la SM30 o usando TCODE.
Nombre del FORM: AT_NEWENTRY
Doble click en el editor.

FORM at_newentry.
    ztab-pais = ‘India’.
    ztab-createdate = sy-datum.
    ztab-createtime = sy-uzeit.
ENDFORM.

Crear otro evento: 02 "Tras grabar lo datos en la base de datos".

FORM after_save.
  ztab-mandt = extract+0(3).
  ztab-ZCOUNTRY = extract+3(3)..
  ztab-ZCREATEDATE = sy-datum.
  ztab-ZCREATETIME = sy-uzeit.

  MODIFY ztab.
ENDFORM. 

Paso 4: Crear código de transacción

Ir a la tx. SE93
Código de transacción: ZTAB
Texto: Evento actualización de tabla test
Transacción: SM30, saltar primera screen
Valores por defecto:
VIEWNAME: ZTAB
UPDATE: X

Después de esto cuando ejecutes la transacción ZTAB, y crees una nueva entrada, actualizará la fecha y la hora del sistema en la tabla ZTAB.
Por otra parte si alguna de las entradas se modifican, se actualizará con las nuevas entradas.

SDN Contribution

martes, 23 de agosto de 2016

Problema con los datos de tipo "PACKED" en extensionin

Todo aquel que haya usado la tabla extensionin para crear / modificar un pedido o solicitud puede encontrarse con el problema de que SAP no admite tipos como CURRENCY. A continuación explicaré la implementación para las bapis de creación y solicitud de pedidos pero es aplicable para otras BAPIS que utilicen este método para actualizar los campos Z* de las tablas estándar.

Solicitudes:

  • Añadir los campos Z* a las estructuras CI_EBANDB y CI_EBANDBX
  • BADI a implementar → ME_BAPI_PR_CUST, método MAP2I_EXTENSIONIN
Pedidos:

  • Añadir los campos Z* a las estructuras CI_EKKODB y CI_EKKODBX o CI_EKPODB y CI_EKPODBX dependiendo de si los campos están en la cabecera o en la posición. 
  • BADI a implementar → ME_BAPI_PO_CUST, MAP2I_EXTENSIONIN
A continuación os detallo 2 implementaciones diferentes:

Solicitudes:

*  define local data
  DATAlr_struct TYPE REF TO cl_abap_structdescr,
        lt_comp   TYPE cl_abap_structdescr=>component,
        lf_done   TYPE mmpur_bool.  "conversion done
*  define local field symbol
  FIELD-SYMBOLS:  <comp>                LIKE LINE OF cl_abap_structdescr=>components.

*  perform mapping only if there is at least one packed field
  CHECK im_error EQ cl_mmpur_constants=>yes.

  " código antiguo:
**  get type for name
*    lr_struct ?= cl_abap_typedescr=>describe_by_name( im_name ).
*    CHECK lr_struct IS BOUND.
*    LOOP AT lr_struct->components ASSIGNING <comp>.
**  perform conversion...
**  needes to be implemented
*      lf_done = cl_mmpur_constants=>yes.
*    ENDLOOP.
  "código nuevo:

  CALL METHOD cl_abap_container_utilities=>read_container_c
    EXPORTING
      im_container           im_container
    IMPORTING
      ex_value               ch_struc
    EXCEPTIONS
      illegal_parameter_type 1
      OTHERS                 2.
  IF sy-subrc 0.
    lf_done 'X'.
  ENDIF.

*  conversion has been done successful -> prevent system to do any
*  conversion
  CHECK lf_done EQ cl_mmpur_constants=>yes.
  RAISE EXCEPTION TYPE cx_mmpur_root.

Pedidos:

  DATA:
    lr_struct                TYPE REF TO cl_abap_structdescr,
    lt_comp                  TYPE cl_abap_structdescr=>component,
    lf_done                  TYPE mmpur_bool.

  FIELD-SYMBOLS:
     <comp>                  LIKE LINE OF cl_abap_structdescr=>components,
     <ls_bapi_te_mepoheader> TYPE any,
     <ls_bapi_te_mepopositi> TYPE any,
     <field>                 TYPE any,
     <field_info>            TYPE any.

  CHECK im_error EQ cl_mmpur_constants=>yes.

  IF im_name EQ 'CI_EKKODB'.

    ASSIGN im_container TO <ls_bapi_te_mepoheader> CASTING TYPE bapi_te_mepoheader.

*   Get type for name
    lr_struct ?= cl_abap_typedescr=>describe_by_nameim_name ).

    CHECK lr_struct IS BOUND.
    LOOP AT lr_struct->components ASSIGNING <comp>.

      ASSIGN COMPONENT <comp>-name OF STRUCTURE ch_struc                TO <field>.
      ASSIGN COMPONENT <comp>-name OF STRUCTURE <ls_bapi_te_mepoheader> TO <field_info>.

      <field> <field_info>.

      lf_done cl_mmpur_constants=>yes.

    ENDLOOP.

    CHECK lf_done EQ cl_mmpur_constants=>yes.

*   No permitir conversión estandar
    RAISE EXCEPTION TYPE cx_mmpur_root.

  ENDIF.

  IF im_name EQ 'CI_EKPODB'.

    ASSIGN im_container TO <ls_bapi_te_mepopositi> CASTING TYPE bapi_te_mepoitem.

*   Get type for name
    lr_struct ?= cl_abap_typedescr=>describe_by_nameim_name ).

    CHECK lr_struct IS BOUND.
    LOOP AT lr_struct->components ASSIGNING <comp>.

      ASSIGN COMPONENT <comp>-name OF STRUCTURE ch_struc                TO <field>.
      ASSIGN COMPONENT <comp>-name OF STRUCTURE <ls_bapi_te_mepopositi> TO <field_info>.

      <field> <field_info>.

      lf_done cl_mmpur_constants=>yes.

    ENDLOOP.

    CHECK lf_done EQ cl_mmpur_constants=>yes.

*   Añadir posición
    ASSIGN COMPONENT 'PO_ITEM'  OF STRUCTURE ch_struc                TO <field>.
    ASSIGN COMPONENT 'PO_ITEM'  OF STRUCTURE <ls_bapi_te_mepopositi> TO <field_info>.
    <field> <field_info>.

*   No permitir conversión estandar
    RAISE EXCEPTION TYPE cx_mmpur_root.

  ENDIF.

Una vez hecha la implementación de la BADI pasamos la tabla de la siguiente manera:

Solicitudes:

DATA:
    e_itempr                TYPE  bapi_te_mereqitem,
    e_itemprx               TYPE  bapi_te_mereqitemx.
FIELD-SYMBOLS<fs_extensionin> TYPE bapiparex.
        APPEND INITIAL LINE TO extensionin
                     ASSIGNING <fs_extensionin>.

*        CLEAR: w_extensionin, e_string.
        <fs_extensionin>-structure         'BAPI_TE_MEREQITEM'.
        e_itempr-preq_item                 ls_pr_pos-bnfpo.
        e_itempr-zzpre_asig                ls_pr_pos-zzpre_asig.
        CALL METHOD cl_abap_container_utilities=>fill_container_c
          EXPORTING
            im_value               e_itempr
          IMPORTING
            ex_container           <fs_extensionin>+30
          EXCEPTIONS
            illegal_parameter_type 1
            OTHERS                 2.
        IF sy-subrc <> 0.
*          APPEND w_extensionin TO extensionin.
        ENDIF.

        APPEND INITIAL LINE TO extensionin
                     ASSIGNING <fs_extensionin>.

*        CLEAR: w_extensionin.
        <fs_extensionin>-structure        'BAPI_TE_MEREQITEMX'.
        e_itemprx-preq_item               ls_pr_pos-bnfpo.
        e_itemprx-zzpre_asig              'X'.
        <fs_extensionin>-valuepart1         e_itemprx.
Pedidos:
DATA:
    ls_bapi_te_meoutheader   TYPE bapi_te_meoutheader,
    ls_bapi_te_meoutheaderx  TYPE bapi_te_meoutheaderx.

w_extensionin-structure 'BAPI_TE_MEOUTHEADER'.
        CLEARls_bapi_te_meoutheader.
        ls_bapi_te_meoutheader-zenvio       ls_po_head-zenvio.
       

        CALL METHOD cl_abap_container_utilities=>fill_container_c
          EXPORTING
            im_value               ls_bapi_te_meoutheader
          IMPORTING
            ex_container           w_extensionin-valuepart1
          EXCEPTIONS
            illegal_parameter_type 1
            OTHERS                 2.
        IF sy-subrc EQ 0.
          APPEND w_extensionin TO extensionin.
        ENDIF.

        CLEARw_extensionin.
        w_extensionin-structure 'BAPI_TE_MEOUTHEADERX'.
        CLEARls_bapi_te_meoutheaderx.
        ls_bapi_te_meoutheaderx-zenvio       'X'.
       
        w_extensionin-valuepart1 ls_bapi_te_meoutheaderx.
        APPEND w_extensionin TO extensionin.

Las estructuras CI_*DB son includes de las tablas estándares de las solicitudes y los pedidos (EKKO, EKPO Y EBAN).

lunes, 18 de julio de 2016

Habilitar guardar preliminarmente en solicitudes de pedidos

Para habilitar el gaurdado preliminarmente se debe realizar los siguientes pasos:

- Ejecutar transacción SFW5:
Esta transacción activa Business function, en nuestro caso necesitaremos activar LOG_MM_CI_3, para ello marcamos el check y activamos:
Una vez activado aparecerá la bombilla encendida:


- Ejecutamos la transacción de customizing SPRO:
Gestión de materiales>Compras>Datos de entorno>Activar registro de forma preliminar y retener en documento de compras y marcamos el flag Asig. prev. y marca act.

Una vez hecho esto ya podremos guardar de manera preliminar en las transacciones de la ME51N / ME52N.

NOTA: Es posible que genere un DUMP CX_SY_CONVERSION_OVERFLOW, para ello debes aplicar la nota 1833227.

En caso de querer guardar preliminarmente mediante BAPI (BAPI_PR_CREATE) debemos usar los siguientes campos:

MEMORY = X
Os detallo una tabla con las diferencias estre HOLD / PARK / GUARDADO

Hold
Park
Save
AC Commitment
MM Errors
X


Not Updated
FM Errors
X
X

Not Updated
No Errors
X
X
X
Updated


MEMORYTYPE = H o P (dependiendo qué hemos elegido, si Hold o Park).

También debemos marcar en la estructura BAPIMEREQHEADERX los flags corresponidiente a lo que hayamos rellenado en la primera.

NOTA: Esta configuración no evita que se determine estrategia y se lance WF, para ello debemos implementar la nota 575387.

miércoles, 29 de junio de 2016

DUMP CONVT_NO_NUMBER

REPORT  zscript.
DATAc_num TYPE char3 VALUE '1,2'.
DATAamount TYPE ekpo-zzpre_asig,
      lv_pos TYPE i,
      lv_char TYPE char15.


END-OF-SELECTION.

* value definition is fixed at 2 decimal places
  REPLACE ALL OCCURRENCES OF '.' IN c_num WITH ' '.
  REPLACE ALL OCCURRENCES OF ',' IN c_num WITH '.'.
  CONDENSE c_num NO-GAPS.
  MOVE c_num TO amount.
  WRITE:/ amount.