:::: MENU ::::

este blog tiene como objetivo de compartir los conocimientos prácticos de cada lenguaje de programación más conocidos.

  • Lo mejor está por suceder

  • Easy to Customize

  • Customizable fonts.

jueves, 1 de septiembre de 2016

La creación de estructuras internas ayudan mucho para no manejar ni crear demasiadas tablas internas, pero debemos de tener mucho cuidado a la hora de utilizarlas y acceder a la data, ya que podríamos confundirnos con los niveles.

El código es el siguiente:

types: begin of ty_est1,
            campo1 type char1,
            campo2 type char3,
          end of ty_est1,

      begin of ty_est2,
            campo3 type char4,
            campo4 type char5,
            campo5 type char2,
            end of ty_est2.
            
    types:  begin of ty_est3.
            INCLUDE type ty_est1.
            INCLUDE type ty_est2.
     TYPES:   end of ty_est3.

     data: td_tabla3 type table of ty_est3,
           td_tabla type table of ty_est1,
           td_tab2 type table of ty_est2.

Hay muchas formas de crear ayudas de búsqueda, una de ellas es poder crearlas desde código y asociarla a un parámetro de selección.

El código de la ayuda de búsqueda es la siguiente:


AT SELECTION-SCREEN ON VALUE-REQUEST FOR s_desti-low.
  PERFORM ayuda_desti CHANGING s_desti-low.

  TYPES: BEGIN OF ty_desti,
    desti TYPE zostb_destimate-desti,
  END OF ty_desti.

  DATA: lt_desti TYPE TABLE OF ty_desti WITH HEADER LINE.
  DATA: BEGIN OF ihelp_fields OCCURS 0.
          INCLUDE STRUCTURE help_value.
  DATA: END OF ihelp_fields.
  DATA: BEGIN OF helptab OCCURS 0,
              feld(50) TYPE c,
        END OF helptab.

  REFRESH ihelp_fields.
  REFRESH helptab.
  CLEAR ihelp_fields.
  CLEAR helptab.

* Campos a mostrar en la ayuda
  MOVE 'ZOSTB_DESTIMATE'  TO ihelp_fields-tabname.
  MOVE 'DESTI'            TO ihelp_fields-fieldname.
  MOVE 'X'                TO ihelp_fields-selectflag.
  APPEND ihelp_fields.

* Obtener datos
  SELECT DISTINCT desti
  FROM zostb_destimate
  INTO TABLE lt_desti.

  CHECK sy-subrc EQ 0.


* Cargar valores a tabla de salida
  LOOP AT lt_desti.
    MOVE lt_desti-desti TO helptab.
    APPEND helptab.
  ENDLOOP.

* Mostrar ayuda
  CALL FUNCTION 'HELP_VALUES_GET_WITH_TABLE'                "#EC *
    IMPORTING
      select_value = po_desti
    TABLES
      fields       = ihelp_fields
      valuetab     = helptab.

 Se utiliza el siguiente código:



PARAMETERS:
    p_zona(5) AS LISTBOX VISIBLE LENGTH 5 OBLIGATORY.                " Zona


INITIALIZATION.
 PERFORM fill_listbox CHANGING p_zona.




FORM fill_listbox CHANGING p_zona.

  TYPES: BEGIN OF ty_zona,
    codzo TYPE zostb_zonapesca-codzo,
  END OF ty_zona.


  DATA: lt_zona TYPE STANDARD TABLE OF ty_zona WITH HEADER LINE,
        wa_zona LIKE LINE OF lt_zona.

  TYPE-POOLS: VRM.
  DATA: name  TYPE vrm_id,
        list  TYPE vrm_values,
        value LIKE LINE OF list.


  SELECT * INTO CORRESPONDING FIELDS OF TABLE lt_zona
  FROM zostb_zonapesca.

  LOOP AT lt_zona INTO wa_zona.
    value-key =  wa_zona-codzo.
    value-text = wa_zona-codzo.
    APPEND value TO list.
  ENDLOOP.

name = 'p_zona'.

CALL FUNCTION 'VRM_SET_VALUES'
  EXPORTING
    ID                    =  name
    VALUES                =  list
 EXCEPTIONS
   ID_ILLEGAL_NAME        = 1
   OTHERS                 = 2
          .
IF SY-SUBRC <> 0.
 "Implement suitable error handling here
ENDIF.


ENDFORM.                    " FILL_LISTBOX

Es muy importante manejar el try-catch como parte estándar de un desarrollo. Se utiliza para capturar un error, que no se genere un dump y los usuarios no salgan corriendo, creyendo que el programa exploto (es mi parte irónica).... en fin, una forma de arreglar este problemilla es capturar dichos errores y mostrarlos como mensajes.

El código es el siguiente:


TRY.

     SELECT *
     INTO TABLE g_ti_marc
     FROM           marc
     FOR ALL ENTRIES IN g_ti_mara    
     WHERE matnr EQ g_ti_mara-matnr.

*.Capturamos el error y lo llevamos a la instancia lr_cx_root.
   CATCH CX_ROOT INTO lr_cx_root.

*.....Luego extraemos el mensaje de error que arroja el sistema accediendo al metodo *.....if_message~get_longtext( ).

       l_c_message = lr_cx_root->if_message~get_longtext( ).

*.....Por ultimo podremos realizar ya lo que queramos con el mensaje de error por ejemplo *.....imprimirlo.

       MESSAGE l_c_message TYPE 'E'.

  END TRY.
Anteriormente publique los pasos para ubicar user's exit's que pasaran por nuestros  procesos e implementar el exit encontrado, estos pasos son bastante efectivos, pero, en el peor de los casos, tendremos que revisar todos los exit's uno por uno y eso nos tomará mucho tiempo. Por lo tanto encontré un código que si bien, no es más efectivo que la publicación comentada (Buscar User Exit's),  pero es más eficaz, ya que nos ayuda a ahorrar tiempo y tal vez, ubicar más rápido nuestra exit. Espero que les sea de utilidad.

Solo tienen que crear un programa Z, por ejemplo ZBUSCA_EXIT y copiar el siguiente código:


TABLES : tstc, tadir, modsapt, modact, trdir, tfdir, enlfdir.
TABLES : tstct.
DATA : jtab LIKE tadir OCCURS 0 WITH HEADER LINE.
DATA : field1(30).
DATA : v_devclass LIKE tadir-devclass.
PARAMETERS : p_tcode LIKE tstc-tcode OBLIGATORY.

SELECT SINGLE * FROM tstc WHERE tcode EQ p_tcode.
IF sy-subrc EQ 0.
  SELECT SINGLE * FROM tadir WHERE pgmid = 'R3TR'
                   AND object = 'PROG'
                   AND obj_name = tstc-pgmna.
  MOVE : tadir-devclass TO v_devclass.
  IF sy-subrc NE 0.
    SELECT SINGLE * FROM trdir WHERE name = tstc-pgmna.
    IF trdir-subc EQ 'F'.
      SELECT SINGLE * FROM tfdir WHERE pname = tstc-pgmna.
      SELECT SINGLE * FROM enlfdir WHERE funcname =
      tfdir-funcname.
      SELECT SINGLE * FROM tadir WHERE pgmid = 'R3TR'
                         AND object = 'FUGR'
                         AND obj_name EQ enlfdir-area.

      MOVE : tadir-devclass TO v_devclass.
    ENDIF.
  ENDIF.
  SELECT * FROM tadir INTO TABLE jtab
                WHERE pgmid = 'R3TR'
                  AND object = 'SMOD'
                  AND devclass = v_devclass.
  SELECT SINGLE * FROM tstct WHERE sprsl EQ sy-langu AND
                                   tcode EQ p_tcode.
  FORMAT COLOR COL_POSITIVE INTENSIFIED OFF.
  WRITE:/(19) 'Transaction Code – ',
       20(20) p_tcode,
       45(50) tstct-ttext.
  SKIP.
  IF NOT jtab[] IS INITIAL.
    WRITE:/(95) sy-uline.
    FORMAT COLOR COL_HEADING INTENSIFIED ON.
    WRITE:/1 sy-vline,
           2 'Exit Name',
          21 sy-vline ,
          22 'Description',
          95 sy-vline.
    WRITE:/(95) sy-uline.
    LOOP AT jtab.
      SELECT SINGLE * FROM modsapt
             WHERE sprsl = sy-langu AND
                    name = jtab-obj_name.
      FORMAT COLOR COL_NORMAL INTENSIFIED OFF.
      WRITE:/1 sy-vline,
             2 jtab-obj_name HOTSPOT ON,
            21 sy-vline ,
            22 modsapt-modtext,
            95 sy-vline.
    ENDLOOP.
    WRITE:/(95) sy-uline.
    DESCRIBE TABLE jtab.
    SKIP.
    FORMAT COLOR COL_TOTAL INTENSIFIED ON.
    WRITE:/ 'No of Exits:' , sy-tfill.
  ELSE.
    FORMAT COLOR COL_NEGATIVE INTENSIFIED ON.
    WRITE:/(95) 'No User Exit exists'.
  ENDIF.
ELSE.
  FORMAT COLOR COL_NEGATIVE INTENSIFIED ON.
  WRITE:/(95) 'Transaction Code Does Not Exist'.
ENDIF.

AT LINE-SELECTION.
  GET CURSOR FIELD field1.
  CHECK field1(4) EQ 'JTAB'.
  SET PARAMETER ID 'MON' FIELD sy-lisel+1(10).
  CALL TRANSACTION 'SMOD' AND SKIP FIRST   SCREEN.

Ingresar a la tx. CMOD



Agregar el paquete (buscar el paquete del programa que se quiere agregar el exit) y lo ejecutas



Se listan los exit's de ese paquete



Lo que se tiene que hacer es visualizar cada descripción y y ver si referencia a lo que estamos buscando, luego seleccionamos el exit y hacemos el siguiente paso:

vamos a la tensacción SMOD




Damos en visualizar y veremos la lista de user exit's 



Le damos doble clic y veremos el código del exit, aquí podemos revisar la estructura y el campo que estemos buscando, en caso de que si exista le damos doble clic al include y lo creamos, luego agregamos un BREAK POINT para probar que esté implementando dentro de nuestro proceso. 

Podemos agregar una OT de prueba, esto por si el exit no funciona, en ese caso tenemos que eliminar el include creado buscándolo desde la se80 ingresando el paquete, le damos clic derecho y lo eliminamos, también nos vamos a la OT de prueba y borramos el include que no nos servirá.




Muchas veces he tenido que desarrollar ALV's dinámicos, los casos en lo que lo he necesitado es cuando he tenido que mostrar data con meses como columnas o días, tipo calendario donde muestre valores o importes por mes, años o días.

Para dar un ejemplo de como implementar he desarrollado un código de prueba que pueden probar y adaptar según sus necesidades.

El código es el siguiente:

TYPE-POOLS: slis.


 FIELD-SYMBOLS: <t_dyntable>   TYPE STANDARD TABLE,
                <t_prueba>     TYPE STANDARD TABLE,     " Dynamic internal table name
                <fs_dyntable>,
                <t_dinamic>,                          " Field symbol to create work area
                <fs_fldval>    TYPE any.                " Field symbol to assign values

 PARAMETERS: p_cols(5) TYPE c,                          " Input number of columns
             p_rows(5) TYPE c.


 DATA: t_newtable   TYPE REF TO data,
       t_newline    TYPE REF TO data,
       t_newline2   TYPE REF TO data,
       fs_fldcat    TYPE slis_t_fieldcat_alv,
       t_fldcat     TYPE lvc_t_fcat,
       wa_it_fldcat TYPE lvc_s_fcat,
       wa_colno(2)  TYPE n,
       wa_flname(5) TYPE c.


* Create fields .

     wa_it_fldcat-fieldname = 'CAMPO1'.
     wa_it_fldcat-datatype  = 'CHAR'.
     wa_it_fldcat-intlen    = 10.

     APPEND wa_it_fldcat TO t_fldcat.

     wa_it_fldcat-fieldname = 'CAMPO2'.
     wa_it_fldcat-datatype  = 'CHAR'.
     wa_it_fldcat-intlen    = 10.

     APPEND wa_it_fldcat TO t_fldcat.

  DO p_cols TIMES.

     CLEAR wa_it_fldcat.

     MOVE sy-index TO wa_colno.
     CONCATENATE 'COL'
                  wa_colno
            INTO  wa_flname.

     wa_it_fldcat-fieldname = wa_flname.
     wa_it_fldcat-datatype  = 'CHAR'.
     wa_it_fldcat-intlen    = 10.

     APPEND wa_it_fldcat TO t_fldcat.

  ENDDO.

* Crea tabla interna dinamica y asigna a FieldSymbols

  CALL METHOD cl_alv_table_create=>create_dynamic_table
  EXPORTING
  it_fieldcatalog = t_fldcat
  IMPORTING
  ep_table = t_newtable.

  ASSIGN t_newtable->* TO <t_dyntable>.
* Create dynamic work area and assign to FS
  CREATE DATA t_newline LIKE LINE OF <t_dyntable>.
  ASSIGN t_newline->*   TO <fs_dyntable>.

************************
** Tablas

************************

  DATA: fieldname(20) TYPE c.
  DATA: fieldvalue(10) TYPE c.
  DATA: lv_numcol TYPE i.
  DATA: lv_numfil TYPE i.
  DATA: INDEX2    TYPE char3,
        acu       TYPE CHAR3,
        lv_acu    TYPE i.
data: x_filcat LIKE LINE OF t_fldcat.

DATA : ti_details TYPE abap_compdescr_tab, "<- Aqui tenemos la estructura.
        wa_details TYPE abap_compdescr.

DATA : ref_table_des TYPE REF TO cl_abap_structdescr.

types: BEGIN OF TY_PRUEBA,
      INDEx TYPE CHAR5,
      codigo type char1,
      END OF TY_PRUEBA.

types: itty TYPE ty_prueba.

DATA:   IT TYPE TY_PRUEBA,
        TB TYPE STANDARD TABLE OF ITTY,
        WA LIKE LINE OF tb.

FIELD-SYMBOLS: <f> LIKE LINE OF t_fldcat.

ref_table_des ?= cl_abap_typedescr=>describe_by_data( IT ).
*ref_table_des ?= cl_abap_typedescr=>DESCRIBE_BY_NAME( wa-index ).
ti_details[] = ref_table_des->components[].

  DESCRIBE TABLE t_fldcat LINES lv_numcol.
  READ TABLE t_fldcat into x_filcat INDEX 1.
  DO p_rows TIMES.
      index2 = sy-index.
       lv_acu = 0.
       DO p_cols TIMES.

       while lv_acu < lv_numcol.
             lv_acu = lv_acu + 1.
             acu = lv_acu.

      condense ACU NO-GAPS.
        READ TABLE t_fldcat into wa_it_fldcat index lv_acu.
        ASSIGN COMPONENT lv_acu OF STRUCTURE t_fldcat TO <f>.
        " Se Asigna el valor
        CONCATENATE 'VALUE '
                    index2
                    '-'
                    acu
              INTO  fieldvalue.

        CONDENSE fieldvalue NO-GAPS.

        ASSIGN COMPONENT wa_it_fldcat-fieldname
            OF STRUCTURE <fs_dyntable>
                      TO <fs_fldval>.

        <fs_fldval> = fieldvalue.
        ENDWHILE.

       ENDDO.

       APPEND <fs_dyntable> TO <t_dyntable>.
  ENDDO.


************************
** Muestra tabla interna
************************

DATA: wa_cat LIKE LINE OF fs_fldcat.

  wa_cat-fieldname = 'CAMPO1'.
  wa_cat-seltext_s = 'CAMPO1'.
  wa_cat-outputlen = '10'.
  APPEND wa_cat TO fs_fldcat.

  wa_cat-fieldname = 'CAMPO2'.
  wa_cat-seltext_s = 'CAMPO2'.
  wa_cat-outputlen = '10'.
  APPEND wa_cat TO fs_fldcat.

  DO p_cols TIMES.
  CLEAR wa_cat.
  MOVE sy-index TO wa_colno.
  CONCATENATE 'COL'
  wa_colno
  INTO wa_flname.
  wa_cat-fieldname = wa_flname.
  wa_cat-seltext_s = wa_flname.
  wa_cat-outputlen = '10'.
  APPEND wa_cat TO fs_fldcat.
  ENDDO.

* Muestra lista

  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
  EXPORTING
  it_fieldcat = fs_fldcat
  TABLES
  t_outtab = <t_dyntable>."<t_dyntable>.

A call-to-action text Contact us