Encontrar modificaciones de tablas del customizing de SAP

Caso: surgió la necesidad de detectar si una tabla del customizing (para nuestro caso la transacción OKB9) había sido modificada y se requería encontrar la orden de transporte que contenía la modificación.

Solución:

1. Primero buscamos los datos técnicos de la tabla de customizing, para nuestro caso vemos que es la vista V_TKA3A

2. Haciendo doble click en el nombre de la vista, vemos que la tabla relacionada es la TKA3A.

3. Ingresamos a la SE03 y seleccionamos "Buscar objetos en órdenes/tareas"

4. Usamos el tipo de objeto CDAT, seleccionamos los modificables y/o liberados y luego para nuestro caso filtro sólo las ordenes de customizing y ejecutamos.

5. Nos aparecerá la lista de órdenes relacionadas con las tablas indicadas.

Ingresando con doble click en la orden, podemos ver el código de objeto y las modificaciones que incluye.

Se pueden modificar los parámetros para poder filtrar y buscar otros objetos también, como programas, clases, tablas etc. aunque para estos casos también podemos hacerlo desde el mismo objeto en "Gestión de versiones", caso que en el customizing no existe.

EBAN – Crear estructura Append en Solicitud de Pedido

Caso: Se desea agregar un campo Z en pantalla en la ME51n, en el cual cuando el usuario completa ciertos datos de una posición de SOLPE, aparezca un dato en ese campo Z.

Solución: Se crea un nuevo campo ZZ_COMPRADOR en la tabla EBAN.

1. En la SE11, vamos a la tabla EBAN y buscamos el elemento de datos CI_EBANDB. Hacemos doble click en el.

2. Agregamos el/los campos Z que deseamos en la estructura. El nombre del campo debe comenzar con ZZ o YY.

Definimos la categoría de ampliación de la estructura…

3. Activamos todo. En mi caso dio un error, que voy a ignorar ya que no encontré el motivo.

TABL WTYSC_WWB_NAVTREE_DATA inconsistente en versión activa

Verificar tabla WTYSC_WWB_NAVTREE_DATA (Q_EPURICELLI/22.08.14/17:1.

Categoría de ampliación actual Ampliable y numérico o de caracteres es falsa

Pueden seleccionarse siguientes categorías de ampliación:

Ampliable cualq.forma

4. Vamos a la transacción CMOD para crear una ampliación (en mi caso ya existía, así que puede faltar algún paso).

Vamos a componentes…

5. Sólo resta ingresar al EXIT que mejor nos convenga y allí crear el include. En mi caso usé el EXIT_SAPLMEREQ_005.

6. Dentro del include ZXM02U05, agregué el siguiente código:

* Obtengo la posición para poder modificarla
l_mereq_item = im_req_item->get_data( ).
CHECK l_mereq_item IS NOT INITIAL.
 
* Trae el comprador asociado a cotizaciones según el Centro Sum.-Grp.Art.Grupo de compras indicado
IF     im_data_new-reswk IS NOT INITIAL
  AND  im_data_new-matkl IS NOT INITIAL
  AND  im_data_new-ekgrp IS NOT INITIAL
  AND ( im_data_old-ekgrp NE im_data_new-ekgrp 
    OR  im_data_old-reswk NE im_data_new-reswk 
    OR  im_data_old-matkl NE im_data_new-matkl ).
 
  CLEAR l_mereq_item-zzcomprador.
  SELECT SINGLE bname 
	INTO l_mereq_item-zzcomprador "Campo Z donde dejo el comprador asociado.
    FROM zcot_001
    WHERE werks = im_data_new-reswk.
 
ENDIF.
 
CALL METHOD im_req_item->set_data( l_mereq_item ).

 

7. Finalmente el campo aparece en pantalla y calcula el comprador según el código al ingresar los datos por posición

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

POPUP_TO_DECIDE_LIST

Caso: se desea crear un popup para que el usuario seleccione una opción entre varias.

Solución: Usando la función POPUP_TO_DECIDE_LIST puedo hacerlo.

DATA: li_spopli TYPE STANDARD TABLE OF spopli,
wa_spopli TYPE spopli,
lv_result TYPE char1.

START-OF-SELECTION.
CLEAR: wa_spopli.
wa_spopli-varoption = ‘Opción 1′.
APPEND wa_spopli TO li_spopli.

CLEAR: wa_spopli.
wa_spopli-varoption = ‘Opción 2′.
APPEND wa_spopli TO li_spopli.

CLEAR: wa_spopli.
wa_spopli-varoption = ‘Opción 3′.
APPEND wa_spopli TO li_spopli.

CALL FUNCTION ‘POPUP_TO_DECIDE_LIST’
EXPORTING
titel = ‘POPUP – Radio Buttons’
textline1 = ‘Seleccione una opción’
IMPORTING
answer = lv_result
TABLES
t_spopli = li_spopli
EXCEPTIONS
not_enough_answers = 1
too_much_answers = 2
too_much_marks = 3
OTHERS = 4.

IF sy-subrc EQ 0.
IF lv_result NE ‘A’.
READ TABLE li_spopli INTO wa_spopli INDEX lv_result.
WRITE:/ ‘Se seleccionó: ‘, wa_spopli-varoption.
ELSE.
WRITE:/ ‘No ha realizado ninguna selección’.
ENDIF.
ENDIF.

Categorías:ABAP/4 Etiquetas: , ,

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: ,
Seguir

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