BADI – Como encontrar una BADI

Caso: se desea conocer que implementaciones de BADIs hay en un programa o transacción (en nuestro caso ejecutamos la transacción MIRO).

Solución:

1. Ingresamos a la transacción SE24 (Class Builder o Generador de Clases). Allí indicamos la clase CL_EXITHANDLER y presionamos VISUALIZAR.

2. Ingresamos al método GET_INSTANCE con doble click:

3. En el método CALL METHOD cl_exithandler=>get_class_name_by_interface ponemos un BREAKPOINT de sesión y salimos.

4. Ejecutamos la transacción o programa que deseamos rastrear. Al detenerse en el BREAKPOINT que creamos, podemos ver la variable EXIT_NAME y allí encontraremos las BADIs que están implementadas para ese programa.

Hay que ir pasando por todas las BADIs, pero bueh…

TRY CATCH – Ejemplo básico de excepción

Caso: se desea capturar y mostrar el error de la excepción al realizar una división por cero. Es un ejemplo básico que encontré, pero útil para usarlo cuando necesitemos capturar excepciones

Solución: Vamos primero a mostrar la división y el error que nos genera sin capturar la excepción:

REPORT  zprueba_abap.
* Prueba de división por cero sin capturar excepción
 
DATA: resultado TYPE p DECIMALS 2,
      ref_exc   TYPE REF TO CX_ROOT,
      error     TYPE STRING.
 
PARAMETERS: p_num1 TYPE i DEFAULT '10',
            p_num2 TYPE i DEFAULT '0'.
 
resultado = p_num1 / p_num2.
WRITE: 'El resultado es: ', resultado.

Ahora si agregamos la sentencia TRY-ENDTRY y con CATCH capturamos la excepción para que muestre un MESSAGE tipo Información:

REPORT  zprueba_abap.
* Prueba de división por cero capturando la excepción
 
DATA: resultado TYPE p DECIMALS 2,
      ref_exc   TYPE REF TO CX_ROOT,
      error     TYPE STRING.
 
PARAMETERS: p_num1 TYPE i DEFAULT '10',
            p_num2 TYPE i DEFAULT '0'.
 
TRY.
    resultado = p_num1 / p_num2.
    WRITE: 'El resultado es: ', resultado.
  CATCH cx_sy_zerodivide INTO ref_exc.
    error = ref_exc->get_text( ).
    MESSAGE error TYPE 'I'.
ENDTRY.
 

Links:

http://www.teknodatips.com.ar/sap-netweaver/267-abap-objects-tutorial-manejo-excepciones.html

NUMERIC_CHECK – Validar valor numérico

Caso: se desea validar que el valor ingresado en pantalla por el usuario sea numérico.

Solución: Usando la función NUMERICK_CHECK puedo validar según los caracteres que deseo aceptar (por ejemplo puedo querer la coma pero no el punto)

CALL FUNCTION ‘NUMERIC_CHECK’
EXPORTING
string_in = ls_mod_cell-VALUE
IMPORTING
htype = lc_tipo
EXCEPTIONS
OTHERS = 1.

CHECK lc_tipo NE ‘CHAR’ OR ( lc_tipo EQ ‘CHAR’ AND ls_mod_cell-VALUE CO ‘ ,.0123456789′ ).

Categorías:ABAP/4 Etiquetas: ,

Crear ALV con columnas dinámicas

Caso: se desea utilizar un ALV dinámico, es decir con columnas dinámicas. Encontré un ejemplo por Internet, dejo la fuente al pie del post, realmente me sirvió para lo que necesitaba.

Solución: El ejemplo permite indicar la cantidad de filas y columnas y luego genera un ALV con dicha información

REPORT  zprueba_alv_dinamico.
 
TYPE-POOLS: slis.
 
*& Título........: Test Alv Dinámico
*& Descripción...: Segun la cantidad de columnas incrementar el catálogo de campos del ALV
 
FIELD-SYMBOLS:
<gt_dyntable> TYPE STANDARD TABLE, "Nombre de la tabla interna dinámica
<gs_dyntable>, "Field symbol para crear un área de trabajo
<gv_fldval> TYPE ANY. "Field Symbol para asignar valores
 
DATA: gt_fieldcat TYPE slis_t_fieldcat_alv, "Lo utilizaremos al momento de invocar al ALV
      gt_fcat     TYPE lvc_t_fcat."Lo utilizaremos al momento de crear la tabla dinámica
 
DATA: gv_colno(2)  TYPE n,  "Nro de columna
      gv_flname(5) TYPE c. "Nombre del campo del catálogo
 
PARAMETERS: pa_cols(5) TYPE c,  "Campo de Texto para ingresar el número de columnas
            pa_rows(5) TYPE c. "Campo de Texto para ingresar el número de filas
 
*----------------------------------------------------------------------*
*START-OF-SELECTION                                            *
*----------------------------------------------------------------------*
"Al Ejecutar el reporte se invocarán las siguientes rutinas
PERFORM fill_dynamic_catalog.  "Llena el catálogo de campos de la tabla dinámica
PERFORM crea_dynamic_itable. "Crea la tabla interna dinámica
PERFORM crea_dynamic_warea."Crear el área de trabajo para la tabla interna dinámica
PERFORM fill_itable. "Llena de valores la tabla interna que se visualizará en el ALV
PERFORM display_alv. "Visualiza el ALV
 
*&---------------------------------------------------------------------*
*& Form FILL_DYNAMIC_CATALOG
*&---------------------------------------------------------------------*
*"Llena el catálogo de campos de la tabla dinámica
*----------------------------------------------------------------------*
FORM fill_dynamic_catalog.
  DATA: ls_fcat TYPE lvc_s_fcat. "área de trabajo local para el catálogo de campos
 
  "La primera columna
  ls_fcat-fieldname = 'DESCRIPCION'.
  ls_fcat-datatype = 'CHAR'.
  ls_fcat-intlen = 15.
  APPEND ls_fcat TO gt_fcat.
 
  "Segun el número de columnas ingresado por el usuario en pantalla.
  DO pa_cols TIMES.
    CLEAR ls_fcat.
    MOVE sy-index TO gv_colno.
    CONCATENATE 'COL' gv_colno INTO ls_fcat-fieldname.
    ls_fcat-datatype = 'CHAR'.
    ls_fcat-intlen = 10.
    APPEND ls_fcat TO gt_fcat.
  ENDDO.
ENDFORM. " FILL_DYNAMIC_CATALOG
 
*&-----------------------------------------------------------------------*
*& Form CREA_DYNAMIC_ITABLE
*&-----------------------------------------------------------------------*
*"Crea la tabla interna dinámica y asignamos a un field-symbol
*&-----------------------------------------------------------------------*
FORM crea_dynamic_itable .
  "Referencia de un Objeto
  DATA lo_newtable TYPE REF TO data. "Para la tabla interna dinámica
 
  "Invocamos al método 'create_dynamic_table' de la clase cl_alv_table_create
  "Como es una clase estática accedemos directamente desde la clase al método.
  CALL METHOD cl_alv_table_create=>create_dynamic_table
    EXPORTING
      it_fieldcatalog = gt_fcat
    IMPORTING
      ep_table        = lo_newtable.
 
  ASSIGN lo_newtable->* TO <gt_dyntable>.
ENDFORM. " CREA_DYNAMIC_ITABLE
 
*&----------------------------------------------------------------------------------------------------*
*& Form CREA_DYNAMIC_WAREA
*&----------------------------------------------------------------------------------------------------*
*"Crear el área de trabajo para la tabla interna dinámica y asignamos a un field-symbol
*&----------------------------------------------------------------------------------------------------*
FORM crea_dynamic_warea.
  "Referencia de un Objeto
  DATA lo_newline TYPE REF TO data. "Para el área de trabajo de la tabla interna dinámica.
 
  CREATE DATA lo_newline LIKE LINE OF <gt_dyntable>.
  ASSIGN lo_newline->* TO <gs_dyntable>.
ENDFORM. " CREA_DYNAMIC_WAREA
 
*&-----------------------------------------------------------------------*
*& Form FILL_ITABLE
*&-----------------------------------------------------------------------*
*"Llena de valores la tabla interna que se visualizará en el ALV
*&-----------------------------------------------------------------------*
FORM fill_itable.
 
  DATA: lv_index_row(3) TYPE c,  "Nro de fila que se esta tratando
        lv_index_col(3) TYPE c,  "Nro de columna que se esta tratando
        lv_fldval(10)   TYPE c.  "Valor que será asignado en dicha celda de la fila y columna
 
  DO pa_rows TIMES. "Recorremos tantas filas se haya ingresado por pantalla
    lv_index_row = sy-index.
 
*<gv_fldval> apuntará a la columna DESCRIPCION y por cada fila asignará su valor correspondiente
*Por ejemplo si se tratase de un ALV dinámico que muestra las características de un vehículo sería bueno
*que antes se haya definido primero una tabla interna que contega los nombres de cada característica por *ejemplo: COLOR, MODELO, AÑO DE FABRICACIÓN
*etc. de tal manera que aquí lo que se haría es
*hacer un read table a dicha tabla interna y según la fila que se este analizando leeríamos el texto.
 
    ASSIGN COMPONENT 'DESCRIPCION' OF STRUCTURE <gs_dyntable> TO <gv_fldval>.
    CONCATENATE 'FILA-' lv_index_row INTO lv_fldval.
    CONDENSE lv_fldval NO-GAPS. "NO-GAPS es para eliminar los espacios en blanco entre carácter
    <gv_fldval> = lv_fldval.
 
    DO pa_cols TIMES. "Por cada fila recorremos tantas columnas se haya ingresado por pantalla
      lv_index_col = sy-index.
 
      MOVE lv_index_col TO gv_colno.
      CONCATENATE 'COL' gv_colno INTO gv_flname.
      "<gv_fldval> apuntará a la columna COL01, COL02, COL03 y así sucesivamente según la columna que      "se este analizando y ahí se almacenará el nuevo valor correspondiente.
      ASSIGN COMPONENT gv_flname OF STRUCTURE <gs_dyntable> TO <gv_fldval>.
 
      CONCATENATE 'VALOR' lv_index_row '-' lv_index_col INTO lv_fldval.
      CONDENSE lv_fldval NO-GAPS."NO-GAPS es para eliminar los espacios en blanco entre carácter
      <gv_fldval> = lv_fldval.
 
    ENDDO. "Cierra el Do del recorrido de Columnas por la fila en análisis
 
    APPEND <gs_dyntable> TO <gt_dyntable>."Añadimos la línea d valores a nuestra tabla interna dinámica
 
  ENDDO."Cierra el Do del recorrido de Filas
 
ENDFORM. " FILL_ITABLE
 
*&---------------------------------------------------------------------*
*& Form DISPLAY_ALV
*&---------------------------------------------------------------------*
*"Visualiza el ALV
*----------------------------------------------------------------------*
FORM display_alv.
 
  PERFORM fill_catalog_alv.
 
  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      it_fieldcat = gt_fieldcat
    TABLES
      t_outtab    = <gt_dyntable>.
 
ENDFORM. " DISPLAY_ALV
 
*&---------------------------------------------------------------------*
*& Form FILL_CATALOG_ALV
*&---------------------------------------------------------------------*
*LLena el catálogo de campos del ALV a visualizar en Pantalla
*----------------------------------------------------------------------*
FORM fill_catalog_alv .
  DATA: ls_fieldcat TYPE slis_fieldcat_alv.
 
  ls_fieldcat-fieldname = 'DESCRIPCION'.
  ls_fieldcat-seltext_l = 'Nro de Fila'.
  ls_fieldcat-outputlen = '15'.
  APPEND ls_fieldcat TO gt_fieldcat.
 
  DO pa_cols TIMES.
    CLEAR ls_fieldcat.
    MOVE sy-index TO gv_colno.
    CONCATENATE 'COL' gv_colno INTO gv_flname.
    ls_fieldcat-fieldname = gv_flname.
    ls_fieldcat-seltext_s = gv_flname.
    ls_fieldcat-outputlen = '10'.
    APPEND ls_fieldcat TO gt_fieldcat.
  ENDDO.
 
ENDFORM. " FILL_CATALOG_ALV

Links:

http://aalcantaraq.blogspot.com/2014/02/alv-dinamico-explicado-paso-paso.html

http://abaputiles.blogspot.com/2009/05/crear-un-alv-con-columnas-dinamicas.html

Categorías:ABAP/4 Etiquetas: ,

SO10 – Crear texto estándar y usarlo

Caso: se desea utilizar la funcionalidad de textos para agregar un texto largo y usarlo en un smartform, paso a paso.

Solución:

1. Ingresamos a la transacción SO10, en donde definimos el nombre del texto a crear.

La ruta es: Herramientas / Imprimir formularios / SAPscript / SO10 – Textos estándar

Los textos creados aquí se deben transportar como más adelante veremos, es decir que una modificación en el texto debe realizarse desde el entorno de desarrollo y actualizar a los otros mandantes mediante transporte de órdenes.

Sin embargo, podrían modificarse en el ambiente de producción, si utilizamos funciones de texto para editarlos, un poco de eso explico en el post:

http://abapers.wordpress.com/2011/02/07/manejo-de-textos-en-sap/

Al crear el texto, ingresamos el texto necesario y si deseamos partes variables, lo indicamos. En mi caso era una carta al proveedor, en donde se le indica el resultado de su evaluación.

2. Incluimos el texto en una orden de transporte, con el programa RSTXTRAN por la transacción SE38.

La ruta es: Herramientas / Workbench ABAP / Desarrollo / SE38 – Editor ABAP

Allí indicamos el nombre del texto recién creado y ejecutamos.

Nos aparecerá/n el/los textos filtrados, en dicha pantalla debemos sólo presionar ENTER:

Aparece otra pantalla y allí ponemos “Pasar txt a correc.” y allí nos pedirá la orden de transporte (o crearemos una nueva)

Nota: también otra posibilidad es crear la orden de transporte manualmente o agregar el texto a una orden ya existente (ver nota 65253)

Nota: Si lo que se necesita es copiar textos dentro de un sistema de un mandante a otro mandante, se puede utilizar el programa RSTXTCPY.

Finalmente, agrego el texto en el smartform:

smartform

Links:

http://scn.sap.com/community/spanish/blog/2013/01/16/uso-de-textos-est%C3%A1ndar-en-programas-abap

http://www.teknodatips.com.ar/sap-netweaver/128-como-asociar-en-abap-texto-standard-a-una-tarea-de-una-orden-de-transporte.html

http://www.blogdesap.com/2013/10/transporte-textos-estandar.html

Categorías:ABAP/4 Etiquetas: , , , ,

Texto largo en DYNPRO (TEXTEDIT)

Caso: se requiere crear un POPUP en donde pueda agregar un texto largo, similar al texto libre usado en MM (ej: texto de cabecera en Solicitudes de Pedido, ME51n).

Solución: Usando la clase cl_gui_textedit, vamos a crear una DYNPRO como la de la figura siguiente, que contiene un Custom Container, un botón de volver y otro de grabar datos, además de unos botones estándar que contiene un importar/exportar texto y las funciones de copiar, pegar, etc.

1. Creamos la DYNPRO

Creamos en el Screen Painter una DYNPRO con un Control Custom Container llamado TEXTEDITOR1 y con un botón para volver a la pantalla anterior (VOLVER) y otro para grabar los datos (GRABAR).

2. Armamos el código asociado

CLASS cl_gui_cfw DEFINITION LOAD. 
DATA: g_editor TYPE REF TO cl_gui_textedit,
      g_editor_container     TYPE REF TO cl_gui_custom_container,
      g_mytable(line_length) TYPE c OCCURS 0,
      g_mycontainer(30)      TYPE c  VALUE 'TEXTEDITOR1'.
 
 
En la DYNPRO creada (la mía era la 0020):
 
PROCESS BEFORE OUTPUT.
  MODULE pbo_0020.
*
PROCESS AFTER INPUT.
  MODULE user_command_0020.
 
 
*&---------------------------------------------------------------------*
*&      Module  PBO_0020  OUTPUT
*&---------------------------------------------------------------------*
MODULE pbo_0020 OUTPUT.
 
  IF g_editor IS INITIAL.
 
*   Crea el control container
    CREATE OBJECT g_editor_container
      EXPORTING
        container_name              = g_mycontainer
      EXCEPTIONS
        cntl_error                  = 1
        cntl_system_error           = 2
        create_error                = 3
        lifetime_error              = 4
        lifetime_dynpro_dynpro_link = 5.
    IF sy-subrc NE 0.
*      add your handling
    ENDIF.
 
*   TextEdit Control
    CREATE OBJECT g_editor
          EXPORTING
           parent = g_editor_container
           wordwrap_mode =
*             cl_gui_textedit=>wordwrap_off
              cl_gui_textedit=>wordwrap_at_fixed_position
*             cl_gui_textedit=>WORDWRAP_AT_WINDOWBORDER
           wordwrap_position = line_length
           wordwrap_to_linebreak_mode = cl_gui_textedit=>true.
 
    REFRESH g_mytable.  " Para inicializar la tabla 
 
  ENDIF.
 
ENDMODULE.                 " PBO_0020  OUTPUT
 
*&---------------------------------------------------------------------*
*&      Module  PAI_0020  INPUT
*&---------------------------------------------------------------------*
module user_command_0020 input.
 
  g_okcode = sy-ucomm.
  CLEAR sy-ucomm.
  CASE g_okcode.
    WHEN 'BACK' OR 'CANCEL' OR 'EXIT' or 'VOLVER'.
      CLEAR g_okcode.
      LEAVE TO SCREEN 0.
 
    WHEN 'GRABAR'.
*   Obtengo la tabla desde el control
      CALL METHOD g_editor->get_text_as_r3table
              IMPORTING table = g_mytable.
 
 
 
      CALL METHOD cl_gui_cfw=>flush
          EXCEPTIONS
              OTHERS = 1.
      IF sy-subrc NE 0.
*        
      ENDIF.
 
    WHEN 'CARGAR'.
*   Devuelvo la tabla al control
      CALL METHOD g_editor->set_text_as_r3table
              EXPORTING table = g_mytable.
 
  ENDCASE.
 
endmodule.                 " PAI_0020  INPUT
 

3. Grabamos y recuperamos la info a la base de datos.

En el GRABAR, la tabla con los resultados está en g_mytable, que es una tabla interna char de 256 (luego tendría que grabar eso en la base de datos), asimismo en el CARGAR vemos que levanto el texto para visualizarlo en pantalla.

Color en columna de ALV

Caso: Se desea ponerle color a una columna de un ALV.

Solución: Para pintar una columna, podemos utilizar, en el fieldcat del ALV el campo EMPHASIZE, por ejemplo:

lw_fieldcat-emphasize = ‘C500′.

En el siguiente programa podemos listar las distintas posibilidades de color que hay.

REPORT  zprueba_color_alv.
 
TYPE-POOLS: slis.
 
* Tabla interna de prueba (se agrega el campo CELLCOLORS.
TYPES: BEGIN OF tty_salida,
        cod_color             TYPE char4,
        cellcolors            TYPE lvc_t_scol,
      END OF   tty_salida.
 
TYPES: ty_salida   TYPE STANDARD TABLE OF tty_salida.
 
DATA:  t_salida       TYPE ty_salida,
       wa_salida      TYPE LINE OF ty_salida,
       i_fieldcat     TYPE slis_t_fieldcat_alv,
       r_layout       TYPE slis_layout_alv,
       lv_color       TYPE numc1,
       lv_intensidad  TYPE numc2,
       lv_contador    TYPE numc3,
       lv_i           TYPE c,
       lv_j           TYPE c,
       lv_k           TYPE c.
 
INITIALIZATION.
* Agrego los códigos de color
  lv_color      = '1'.
  WHILE ( lv_color <= 7 ).
    lv_intensidad = '00'.
    WHILE ( lv_intensidad < 20 ).
      CONCATENATE 'C' lv_color lv_intensidad INTO wa_salida-cod_color.
      APPEND wa_salida TO t_salida.
      ADD 1 TO lv_intensidad.
 
    ENDWHILE.
    ADD 1 TO lv_color.
  ENDWHILE.
 
* CARGO FIELDCAT.
  REFRESH i_fieldcat.
  PERFORM f_init_fieldcat     TABLES i_fieldcat.
 
* LAYOUT, AGREGO COLORES DEPENDIENDO DE LA CELDA
  CLEAR r_layout.
  PERFORM f_init_layout       CHANGING r_layout.
 
* ALV GRID
  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      i_callback_program      = sy-repid
      i_callback_user_command = 'F_USER_COMMAND_01'
      is_layout               = r_layout
      it_fieldcat             = i_fieldcat[]
    TABLES
      t_outtab                = t_salida
    EXCEPTIONS
      program_error           = 1
      OTHERS                  = 2.
  IF sy-subrc <> 0.
    EXIT.
  ENDIF.
 
*&---------------------------------------------------------------------*
*&      Form  f_init_fieldcat
*&---------------------------------------------------------------------*
FORM f_init_fieldcat  TABLES ptc_fieldcat TYPE slis_t_fieldcat_alv.
 
  DATA: r_fieldcat  TYPE slis_fieldcat_alv,
        l_pos       TYPE i VALUE 0.
 
  CLEAR r_fieldcat.
  l_pos = l_pos + 1.
  r_fieldcat-col_pos       = l_pos.
  r_fieldcat-fieldname     = 'COD_COLOR'.
  r_fieldcat-tabname       = 'T_SALIDA'.
  r_fieldcat-seltext_l     = 'Material'.
  APPEND r_fieldcat TO ptc_fieldcat.
 
ENDFORM.                    " f_init_fieldcat
 
*&---------------------------------------------------------------------*
*&      Form  f_init_layout
*&---------------------------------------------------------------------*
FORM f_init_layout  CHANGING playout TYPE slis_layout_alv.
* Variables
  DATA l_color               TYPE lvc_s_scol.
 
 
* Field-Symbols
  FIELD-SYMBOLS <fs_report>  LIKE LINE OF t_salida.
 
* ASIGNAMOS EL CAMPO CELLCOLORS AL LAYOUT
  playout-coltab_fieldname  = 'CELLCOLORS'.
 
  UNASSIGN <fs_report>.
 
  LOOP AT t_salida ASSIGNING <fs_report>.
    lv_i = <fs_report>-cod_color+1(1).
    lv_j = <fs_report>-cod_color+2(1).
    lv_k = <fs_report>-cod_color+3(1).
 
    l_color-fname     = 'COD_COLOR' .
    l_color-color-col = lv_i. "COLOR
    l_color-color-int = lv_j. "INTENSIDAD
    l_color-color-inv = lv_k. "INVERSO
    APPEND l_color TO <fs_report>-cellcolors.
 
  ENDLOOP.
ENDFORM.                    " f_init_layout
 

 

Seguir

Recibe cada nueva publicación en tu buzón de correo electrónico.