HOW TO GET DATA STANDARD REPORT

Alguna vez se te ha presentado el caso en que la data que muestra un reporte estándar SAP GUI podría ayudarte a satisfacer cierto requerimiento?

En esta oportunidad mostraremos como acceder a la data de cualquier reporte estándar SAP GUI ALV sin ampliación o enhancement

Caso ejemplo: Al ejecutar la transacción MB5T podemos visualizar el stock en tránsito de algún material desde un centro origen a un centro destino, por tanto se requiere obtener el detalle de la información para posteriores análisis y tratamiento de la data.
  1. La lógica de la obtención de la data del ALV lo encapsularemos dentro de una función;
  2. Dentro de un nuevo programa invocaremos a la función para luego tratar la data obtenida.


Datos de la transacción MB5T (programa: RM07MTRB)

Recuerda: Sólo puedes iniciar programas de tipo 1 con SUBMIT


En mi caso a modo de ejemplo crearé una función con el nombre: Z_BAPI_SD_STOCK_IN_TRANSIT

Visualizamos los parámetros que importará la función: material, centro receptor, centro de procedencia y indicador de stock.

Como el ALV que obtenemos de la ejecución de la tcode MB5T es un tipo de ALV HIERSEQ LIST trabajaremos con 2 tablas: T_HEADER_MB5T y T_DETAIL_MB5T para la cabecera y detalle respectivamente.

Para esto se ha creado 2 tipos de tabla: ZTT_HEADER_MB5T y ZTT_DETAIL_MB5T ambas tiene como tipo de línea a las estructuras: ZSSD_HEADER_MB5T  y ZSSD_DETAIL_MB5T respectivamente tanto para la cabecera y detalle.

Tipo de Tabla: ZTT_HEADER_MB5T

Estructura: ZSDD_HEADER_MB5T
Datos de cabecera del reporte MB5T
Aquí dentro de la definición de los componentes no es necesario poner todos los campos de la cabecera sólo los campos que cumplen con el propósito de nuestro requerimiento.

Material, Descripción de material, Centro receptor y Nombre del centro receptor

Tipo de Tabla: ZTT_DETAIL_MB5T

Estructura: ZSDD_DETAIL_MB5T
Datos del detalle del reporte MB5T
Aquí dentro de la definición de los componentes nos enfocamos sólo en los campos que cumplen con el propósito de nuestro requerimiento.

Pedido, Posición del pedido, Indicador de stock, Centro de procedencia, Importe y Moneda.

Código fuente de la función: Z_BAPI_SD_STOCK_IN_TRANSIT

Definimos las tablas internas:
<LT_DATA> y  <LT_DATA_LINE> para obtener la data de la cabecera y detalle del ALV estándar.
Observamos que lo hemos definido como un field-symbol de tipo 'any table' debido a que en inicio no se tiene definido el catálogo de campos que incorporará dicha tabla interna.

LT_SELSCREEN será la tabla interna que tendrá los datos ingresados en los parámetros de selección es por eso que tiene la misma estructura de RSPARAMS (ABAP: Estructura general para PARAMETERs y SELECT OPTIONs) 

Definimos las áreas de trabajo
<LS_DATA> de tipo ANY para los datos de la cabecera definido en la tabla interna <LT_DATA>

<LS_DATA_LINE> de tipo ANY para los datos del detalle definido en la tabla interna <LT_DATA_LINE>

<T_HEADER_MB5T> de tipo T_HEADER_MB5T definido en el parámetro 'TABLES' de la función (ver imágen anterior)

<T_DETAIL_MB5T> de tipo T_DETAIL_MB5T definido en el parámetro 'TABLES' de la función (ver imagen anterior)

LS_SELSCREEN para cada línea que representa un registro de datos a añadir a la tabla interna LT_SELSCREEN

Definimos las referencias a los Objetos 
LR_DATA_DESCR y LR_DATA_LINE_DESCR ambos hacen referencia a la clase CL_ABAP_DATADESCR (RTTS: Run Ttime type services) estos objetos serán utilizados para importar la data del ALV estándar.

LR_DATA y LR_DATA_LINE será para la creación de los objeto de datos para LR_DATA_DESCR y LR_DATA_LINE_DESCR respectivamente.

Paso 1: Uso del método set de la clase: CL_SALV_BS_RUNTIME
Este método inicializa las clases (limpia sus áreas de memoria), permite ajustar los 'flags' para poder tratar los posteriores objetos ALV

 Paso 2: Llenamos los datos que serán ingresados en los parámetros de selección
S: Select option
R: Radio button
P: Parameter

Observamos que los datos que importamos (material, centro receptor, centro de procedencia, indicador de stock) en la función Z_BAPI_SD_STOCK_IN_TRANSIT lo asignamos a  los parámetros de selección, de manera que la tabla interna LT_SELSCREEN contendrá la información de estos datos.

Paso 3: Realizamos un SUBMIT al programa donde indicamos los parámetros seleccionados 
SUBMIT al programa RM07MTRB donde le indicamos los parámetros de selección ingresados en LT_SELSCREEN

Paso 4: Ejecutamos el método GET_DATA_REF de la clase CL_SALV_BS_RUNTIME_INFO
GET_DATA_REF es uno de los métodos más flexibles, este método puede ser usado para acceder a una referencia de la tabla interna del ALV estándar; es útil cuando la estructura de datos de la tabla no es conocida, veamos:

Los datos que importaremos del método GET_DATA_REF lo almacenaremos en LR_DATA_DESCR y LR_DATA_LINE_DESCR

LR_DATA y LR_DATA_LINE crea los objeto de datos para LR_DATA_DESCR y LR_DATA_LINE_DESCR respectivamente.

Luego asignamos estos objetos dinámicos de datos LR_DATA y LR_DATA_LINE a las tablas internas LT_DATA y LT_DATA_LINE respectivamente

Paso 5: Ejecutamos el método GET_DATA de la clase CL_SALV_BS_RUNTIME_INFO
Este método se puede utilizar para acceder a los datos de la tabla cuando la estructura es conocida por el programa que lo envuelve.

Paso 6: Ejecutamos el método CLEAR_ALL de la clase CL_SALV_BS_RUNTIME
Este método limpia toda las áreas de memoria.

Paso 7: Llenamos los datos en las tablas de la función
Asignamos el objeto de datos de LR_DATA y LR_DATA_LINE a las áreas de trabajo <LS_DATA> y <LS_DATA_LINE> tanto para la cabecera y detalle respectivamente.

Por tanto, recorremos las tablas internas <LT_DATA> y <LT_DATA_LINE> y vamos llenando de data los campos que tenemos definido en las tablas T_HEADER_MB5T y T_DETAIL_MB5T.


En un nodo nuevo ejecutamos la tcode MB5T con los siguientes datos
Material: 30100-JS10A
Centro receptor: AQ04
Centro de procedencia: AQ03
Stock especial = E (Cartera de pedidos)

Resultado del reporte MB5T

Ahora sólo nos falta reflejar este resultado desde el programa y poner a prueba la lógica implementada en la función.

Por tanto crearemos un nuevo programa; en mi caso se llamará ZAQP002 la cual internamente invocará a la función Z_BAPI_SD_STOCK_IN_TRANSIT que tendrá como parámetros de exportación los mismos valores ingresado en los parámetros de selección de la tcode MB5T (ver imágenes anteriores)


Si ejecutamos el programa en modo Debug, observaremos que luego de haber invocado al módulo de función Z_BAPI_SD_STOCK_IN_TRANSIT tenemos data en las tablas internas LT_HEADER_MB5T y LT_DETAIL_MB5T que representa la data obtenida tanto de la cabecera y detalle respectivamente.


Observamos la data obtenida en la tabla interna LT_HEADER_MB5T (datos cabecera del ALV)


 Observamos los registros obtenidos en la tabla interna LT_DETAIL_MB5T (datos detalle del ALV)

Ambos datos de cabecera y detalle son un reflejo del ALV estándar como resultado de la ejecución desde la tcode MB5T

Ahora ya sabemos como acceder a la data de cualquier reporte estándar SAP GUI ALV

Aquí el código completo:

FUNCTION z_bapi_sd_stock_in_transit.
*&------------------------------------------------------------------------------------------------&*
*"*"Interfase local
*" IMPORTING
*" REFERENCE(IP_MATNR) TYPE MATNR
*" REFERENCE(IP_WERKS) TYPE WERKS_D
*" REFERENCE(IP_RESWK) TYPE RESWK
*" REFERENCE(IP_SOBKZ) TYPE SOBKZ
*" TABLES
*" T_HEADER_MB5T TYPE ZTT_HEADER_MB5T
*" T_DETAIL_MB5T TYPE ZTT_DETAIL_MB5T
*&------------------------------------------------------------------------------------------------&*

*&------------------------------------------------------------------------------------------------&*
*When an ALV report is executed, the ALV runtime information
*(the layout, field catalog, key fields, filters, etc. plus the data table)
*is stored away by methods of class CL_SALV_BS_RUNTIME_INFO for later use.
*(Incidentally, the class uses the same EXPORT TO MEMORY mechanism to store the runtime info
*however the class handles all this internally and provides API methods to access the information,
*meaning we don#t have to care how it is actually stored.)
*Now, with a submit statement and a few simple method calls,
*we can gain direct access to the data table of a report without making any changes to it.
*&------------------------------------------------------------------------------------------------&*

*Structure: RSPARAMS (ABAP: General Structure for PARAMETERS and SELECT-OPTIONS)

*Internal Tables
FIELD-SYMBOLS:   <lt_data> TYPE ANY TABLE,"Header's data
                                     <lt_data_line> TYPE ANY TABLE."Detail's data

DATA: lt_selscreen TYPE TABLE OF rsparams.


*Work Areas
FIELD-SYMBOLS:
 <ls_data>              TYPE ANY,"Work Area for <lt_data>
 <ls_data_line>      TYPE ANY,"Work Area for <lt_data_line>
 <t_header_mb5t>  LIKE LINE OF t_header_mb5t,
 <t_detail_mb5t>    LIKE LINE OF t_detail_mb5t.

DATA: ls_selscreen LIKE rsparams.

*Reference to Objects
DATA:   lr_data                   TYPE REF TO data,
                lr_data_line           TYPE REF TO data,
                lr_data_descr         TYPE REF TO cl_abap_datadescr,
                lr_data_line_descr TYPE REF TO cl_abap_datadescr.

*------------------------------------------------------------------------------------------------*
* Step 1:
*------------------------------------------------------------------------------------------------*
*cl_salv_bs_runtime_info=>set( )
*------------------------------------------------------------------------------------------------*

*this method initialises the class (clears its memory areas) and
*then allows the setting of flags to tell any subsequent ALV objects how to behave.
*It should be called in your wrapper program before submitting
*the wrapped ALV report program.
*------------------------------------------------------------------------------------------------*
cl_salv_bs_runtime_info=>set(
        EXPORTING 
                  display    = abap_false
                  metadata = abap_false
                  data         = abap_true
).

*------------------------------------------------------------------------------------------------*
* Step 2:
*------------------------------------------------------------------------------------------------*
* Populate the parameteres of selection in MB5T
*------------------------------------------------------------------------------------------------*

ls_selscreen-kind = 'S'."Type of selection: S(Select Option) | R(Radio Button) | P(Parameter)
ls_selscreen-sign = 'I'.
ls_selscreen-option = 'EQ'.

*Material
ls_selscreen-selname = 'MATNR'. ls_selscreen-low = ip_matnr.
APPEND ls_selscreen TO lt_selscreen.

*Receiving Plant
ls_selscreen-selname = 'WERKS'. ls_selscreen-low = ip_werks.
APPEND ls_selscreen TO lt_selscreen.

*Issuing Plant
ls_selscreen-selname = 'RESWK'. ls_selscreen-low = ip_reswk.
APPEND ls_selscreen TO lt_selscreen.

*Special Stock
ls_selscreen-selname = 'SOBKZ'. ls_selscreen-low = ip_sobkz.
APPEND ls_selscreen TO lt_selscreen.

*------------------------------------------------------------------------------------------------*
* Step 3:
*------------------------------------------------------------------------------------------------*
* SUBMIT program with parameters passed in table LT_SELSCREEN
* Programa: rm07mtrb
* Transacción: MB5T
*------------------------------------------------------------------------------------------------*
 

 SUBMIT rm07mtrb WITH SELECTION-TABLE lt_selscreen AND RETURN.


*------------------------------------------------------------------------------------------------*
* Step 4:
*------------------------------------------------------------------------------------------------*
*cl_salv_bs_runtime_info=>get_data_ref( )
*------------------------------------------------------------------------------------------------*

*By far the most flexible of the two GET_DATA* methods,
*this method can be used to access a reference to the data table variable.
*It is useful when the structure of the data table is not known,
*not of importance in the wrapper program or is dynamic.
*So a variable cannot be statically typed in the wrapper program.
*------------------------------------------------------------------------------------------------*
TRY.   
  cl_salv_bs_runtime_info=>get_data_ref(
            IMPORTING 
                        r_data_descr = lr_data_descr
                        r_data_line_descr = lr_data_line_descr
   ).

  CREATE DATA lr_data         TYPE HANDLE lr_data_descr.
  CREATE DATA lr_data_line TYPE HANDLE lr_data_line_descr.

  ASSIGN lr_data->*         TO <lt_data>.
  ASSIGN lr_data_line->* TO <lt_data_line>.

*------------------------------------------------------------------------------------------------*
* Step 5:
*------------------------------------------------------------------------------------------------*
*cl_salv_bs_runtime_info=>get_data( )
*------------------------------------------------------------------------------------------------*

*This method can be used to access the data table when the structure is known by the wrapper program.
*Note: If the wrapper program doesn't know the structure of the data table because it is dynamic
*or it just doesn't need to know the structure then use method GET_DATA_REF( ) instead.
  
  cl_salv_bs_runtime_info=>get_data(
              IMPORTING
                        t_data = <lt_data>
                        t_data_line = <lt_data_line>
   ).
CATCH cx_salv_bs_sc_runtime_info.
       MESSAGE `Unable to retrieve ALV data` TYPE 'E'.
ENDTRY.

*------------------------------------------------------------------------------------------------*
* Step 6:
*------------------------------------------------------------------------------------------------*
*cl_salv_bs_runtime_info=>clear_all( )
*------------------------------------------------------------------------------------------------*

*this method clears all memory areas
*thus resetting any of the flags that may have been set in the SET( ) method.
*Calling this method is especially important if you have set the DISPLAY flag to false but
*you want to display your own SAPGUI ALV report after submitting the wrapped one
*if the DISPLAY flag is not reset to its initial value of true before executing your own ALV,
*then your ALV will not be displayed either.


cl_salv_bs_runtime_info=>clear_all( ).


*------------------------------------------------------------------------------------------------*
* Step 7:
*------------------------------------------------------------------------------------------------*
*Populate data in T_HEADER_MB5T and T_DETAIL_MB5T
*------------------------------------------------------------------------------------------------*

*Populate data in T_HEADER_MB5T
ASSIGN lr_data->* TO <ls_data>.

 LOOP AT <lt_data> ASSIGNING <ls_data>.
     APPEND INITIAL LINE TO t_header_mb5t ASSIGNING <t_header_mb5t>.
     MOVE-CORRESPONDING <ls_data> TO <t_header_mb5t>.
 ENDLOOP.


*Populate data in T_DETAIL_MB5T
 ASSIGN lr_data_line->* TO <ls_data_line>.

 LOOP AT <lt_data_line> ASSIGNING <ls_data_line>.
     APPEND INITIAL LINE TO t_detail_mb5t ASSIGNING <t_detail_mb5t>.
     MOVE-CORRESPONDING <ls_data_line> TO <t_detail_mb5t>.
 ENDLOOP.
ENDFUNCTION.

Nos vemos en el siguiente Blog ;)
MAGALEX

Comentarios

  1. Hola, una pregunta como podría hacer para exportar 2 fieldsymbols a la vez, es decir 2 tablas co diferentes esctructuras de typo any(cada estrucutra es diferente)

    ResponderEliminar

Publicar un comentario

Entradas populares de este blog

Modificando Vista de Actualización SM30

User Exit para VA01 y VA02

Buttons and events in ALV GRID and ALV GRID OO