Está en la página 1de 9

Programa tipo reporte usando POO

Introducción
Este es el inicio de un grupo de documentos enfocados a mostrar como se genera un reporte ABAP
usando programación orientada a objetos. En el primer documento “Programa tipo reporte usando
POO Parte 1” se describe el problema planteado y el análisis del mismo. En el segundo documento
“Programa tipo reporte usando POO Parte 2” se muestra el diseño del programa, mostrando las clases
que van a ser usadas, describiendo los métodos y atributos usados de manera general. En el tercer
documento “Programa tipo reporte usando POO Parte 3” se muestra la implementación realizada y se
coloca el código fuente del programa terminado.

Con respecto a los programas de tipo reporte conocidos en la clasificación FRICE como Report (R),
permiten la visualización de datos de un sistema SAP, los programas de tipo reporte son informes que
se presenta como listados que son usados para desplegar información relevante en forma de grilla; esto
quiere decir que la información es mostrada en columnas y filas. Generalmente estos reportes se usan
para extraer información de la base de datos, tomando como filtro unos parámetros ingresados por el
usuario y mostrando en un listado información relevante para que sea usada para cubrir necesidades
específicas.

El objetivo del grupo de documentos mencionados en el primer párrafo es explicar el desarrollo de un


programa de tipo reporte usando clases para su desarrollo y usando como lenguaje de modelado UML
para explicar los diferentes artefactos que se crearon para desarrollar el programa; básicamente lo que
se quiere es dar a entender una forma de generar reportes en SAP, sin dejar de lado que este tipo de
reporte se puede modificar de tal forma que pueda fácilmente migrarse a una interface; esto para el
caso que queramos que nuestro programa de tipo reporte permita interactuar con un sistema legado,
de tal forma que si en el sistema legado se solicita información de SAP esta pueda ser obtenida usando
la misma lógica que se tiene en el programa, lo cual haría que nuestro programa de tipo reporte se
comporte como una interface, esto es de utilidad cuando queremos que el sistema SAP interactúe con
otros sistemas.

Adicionalmente, el código descrito se puede usar como plantilla a la hora de crear nuevos programas de
tipo reporte, la idea de hacerlo con clases es para que sea de fácil entendimiento e implementación en
reportes de tipo ALV, clásicos o en un archivo plano.

Para llevar a cabo un orden voy a mencionar un escenario ficticio, esto con el fin de permitir llevar la
explicación del desarrollo de tal forma que represente una solución sobre un escenario real y permita
entender los conceptos que se van a exponer.
Programa tipo reporte usando POO Parte 1
En este documento se plantea el problema y se va a hacer el análisis del mismo usando casos de uso.

Problema planteado
Se desea crear un reporte que permita mostrar la información del maestro de materiales, el reporte se
genera tomando como filtros el código del material y/o su nombre y/o el grupo de artículos, la
información a mostrar en el reporte son los datos generales del material. La información va a ser
visualizada en un reporte de tipo ALV.

Análisis del problema


El programa de reporte a desarrollar se va a enfocar en el maestro de materiales, ahora bien, en lo
referente al programa de tipo reporte se observa en el siguiente diagrama de casos de uso cómo el
usuario interactúa con el sistema:

Caso de uso Generar Reporte


1. El usuario ingresa a la transacción.
2. Ingresa los filtros en la pantalla de selección.
3. Da clic en el botón ejecutar.
3.1. Llama al caso de uso obtener datos
4. Aparece un reporte ALV con la información.

Caso de uso Obtener datos


1. El usuario inicialmente dio clic en ejecutar.
2. Se extraen los datos generales del maestro de materiales.
3. Los datos obtenidos se pasan al reporte ALV

Programa tipo reporte usando POO Parte 2


En el documento Programa tipo reporte usando POO Parte 1 se llevó a cabo el planteamiento y análisis
del problema, en este documento se va a llevar a cabo el diseño del programa.

Diseño del programa de tipo reporte


Con base a los casos de uso ahora podemos construir un diseño desde el punto de vista ABAP, para lo
cual identificamos las clases con las que vamos a modelar el programa.
Diagrama de clases

La clase GCL_PROGRAM es una clase local en la que todos sus métodos y atributos son estáticos y
públicos. El objetivo de esta clase es contener todos los atributos globales del programa, así como el
llamado de los eventos necesarios en un programa de tipo reporte en ABAP, adicionalmente, esta clase
es la encargada de generar el reporte ALV. La clase GCL_PROGRAM tiene un atributo
GO_ZCL_YEJEMPLO1 que va a ser una instancia de la clase ZCL_YEJEMPLO1, la cual se va a encargar de
obtener la información de la base de datos, esta clase tiene otro atributo llamado GO_ALV_TABLE el
cual es una instancia de la clase CL_SALV_TABLE y va a ser el encargado de generar el reporte en ALV.

La clase ZCL_YEJEMPLO1 es una clase global de instancia, la idea de esta clase es servir de interface para
extraer los datos necesarios de la base de datos y comunicarlos a la clase GCL_PROGRAM, esta clase va
a contener un constructor el cual se va a encargar de mapear los filtros de entrada en los atributos de la
clase, es decir, por cada parámetro de entrada en la pantalla inicial se va a tener un atributo de esta
clase y un parámetro en el método constructor, en el constructor se van a iniciar los parámetros que van
a servir para llevar a cabo la consulta de la información. El método público SET_DATA va a ser el
encargado de buscar la información en el sistema y almacenarlo en el atributo global GIT_DATA, este
atributo va a contener la información que va a ser pasada al reporte ALV. El método GET_DATA va a ser
el encargado de obtener la información, retornando una referencia a los datos que se encuentra en el
atributo GIT_DATA.

Diseño de pantallas
Las siguientes pantallas muestran el funcionamiento general del programa de tipo reporte:
Pantalla principal

Pantalla ALV con la información final

Programa tipo reporte usando POO Parte 3


Después de tener el diseño el cual se expuso en el documento Programa tipo reporte usando POO
Parte 2, usándolo como base vamos a llevar a cabo la implementación, la cual se describe en este
documento.

Implementación
Con base en el diseño de clases creado en el documento Programa tipo reporte usando POO Parte 2 se
llevó a cabo la implementación de la solución, la codificación de la solución se muestra agrupando los
objetos de desarrollo de manera jerárquica, desde el programa principal, pasando por cada uno de sus
INCLUDE y llegando a cada una de las clases creadas.

INCLUDE YEJEMPLO1
*&---------------------------------------------------------------------*
*& Report YEJEMPLO1
*& Programa de tipo report usando POO, el cual muestra el listado
*& de materiales usando el código de material, texto breve del material
*& y grupo de artículos como filtros de entrada
*&---------------------------------------------------------------------*
*& Autor: Fernando Muñoz Beltrán
*& Email: fmunozb@gmail.com
*&---------------------------------------------------------------------*

INCLUDE yejemplo1_top . " Datos globales y definición de clases


INCLUDE yejemplo1_cla . " Implementación de clases
INCLUDE yejemplo1_eve . " Eventos del reporte

INCLUDE YEJEMPLO1_TOP
REPORT yejemplo1.
*----------------------------------------------------------------------*
* CLASS gcl_program DEFINITION
*----------------------------------------------------------------------*
* Clase encargada de contener el llamado de eventos de un programa de
* tipo reporte en ABAP y de generar el ALV
*----------------------------------------------------------------------*
CLASS gcl_program DEFINITION.
PUBLIC SECTION.
"Atributos
CLASS-DATA: go_zcl_yejemplo1 TYPE REF TO zcl_yejemplo1, "Clase de control
go_data TYPE REF TO data, "Referencia a los datos
gv_matnr TYPE mara-matnr, "Tipo para parámetro de entrada
gv_maktx TYPE makt-maktx, "Tipo para parámetro de entrada
gv_matkl TYPE mara-matkl, "Tipo para parámetro de entrada
go_alv_table TYPE REF TO cl_salv_table. "Instancia de CL_SALV_TABLE

"Métodos
CLASS-METHODS: start_of_selection, "Ejecución de la lógica inicial del programa
end_of_selection, "Ejecución de la lógica final del programa
display_report. "Muestra el resultado del reporte
ENDCLASS. "gcl_program DEFINITION

* Dynpro con los parámetros selección


SELECTION-SCREEN BEGIN OF BLOCK b_1 WITH FRAME TITLE text-001.
SELECT-OPTIONS: s_matnr FOR gcl_program=>gv_matnr, "Código de material
s_maktx FOR gcl_program=>gv_maktx, "Nombre del material
s_matkl FOR gcl_program=>gv_matkl. "Grupo de artículos
SELECTION-SCREEN END OF BLOCK b_1.

INCLUDE YEJEMPLO1_CLA
*----------------------------------------------------------------------*
* CLASS gcl_program IMPLEMENTATION
*----------------------------------------------------------------------*
* Clase usada para la modularizadión en POO
*----------------------------------------------------------------------*
CLASS gcl_program IMPLEMENTATION.

METHOD start_of_selection.
"Inicializa el objeto controlador de la clase con los parámetros de selección
CREATE OBJECT go_zcl_yejemplo1
EXPORTING
it_matnr = s_matnr[]
it_maktx = s_matkl[]
it_matkl = s_maktx[].
"Si extrae la información de la base de datos
IF go_zcl_yejemplo1->set_data( ) = abap_true.
"Obtiene la referencia a los datos extraidos
go_data = go_zcl_yejemplo1->get_data( ).
ELSE.
MESSAGE 'No se encontraron datos con los filtros seleccionados' TYPE 'I'.
ENDIF.
ENDMETHOD. "start_of_selection

METHOD end_of_selection.
"Muestra el reporte
display_report( ).
ENDMETHOD. "end_of_selection

METHOD display_report.
"Muestra el reporte en un ALV
DATA: lo_root TYPE REF TO cx_root, "Manejo de excepciones
lv_mes TYPE string. "Mensaje
FIELD-SYMBOLS: <fs_git_data> TYPE ANY TABLE. "Tabla con los datos

"Asigna el área de memoria de los datos al field symbol


ASSIGN go_data->* TO <fs_git_data>.
IF sy-subrc = 0.
"Si la asignación fue correcta imprime el ALV
TRY.
CALL METHOD cl_salv_table=>factory
IMPORTING
r_salv_table = go_alv_table
CHANGING
t_table = <fs_git_data>.
"Imprime el reporte
go_alv_table->display( ).
CATCH cx_salv_msg INTO lo_root.
"Si genera error
lv_mes = lo_root->get_text( ).
MESSAGE lv_mes TYPE 'E'.
ENDTRY.
ENDIF.
ENDMETHOD. "display_report
ENDCLASS. "gcl_program IMPLEMENTATION

INCLUDE YEJEMPLO1_EVE
* Evento ejecutado después de ingresar los parámetros de entrada
START-OF-SELECTION.
"Coloca los datos desde la base de datos en el atributo GIT_DATA
gcl_program=>start_of_selection( ).

* Evento ejecutado despues de seleccionar los datos de la base de datos


END-OF-SELECTION.
"Ejecuta la lógica de impresión
gcl_program=>end_of_selection( ).
CLASS ZCL_YEJEMPLO1
*----------------------------------------------------------------------*
* CLASS ZCL_YEJEMPLO1 DEFINITION
*----------------------------------------------------------------------*
* Clase generada desde la SE24
*----------------------------------------------------------------------*
CLASS zcl_yejemplo1 DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .

PUBLIC SECTION.
*"* public components of class ZCL_YEJEMPLO1
*"* do not include other source files here!!!

METHODS constructor
IMPORTING
!it_matnr TYPE ANY TABLE
!it_maktx TYPE ANY TABLE
!it_matkl TYPE ANY TABLE .
METHODS set_data
RETURNING
value(rp_ok) TYPE boolean .
METHODS get_data
RETURNING
value(rt_data) TYPE REF TO data .
PROTECTED SECTION.
*"* protected components of class ZCL_YEJEMPLO1
*"* do not include other source files here!!!
PRIVATE SECTION.
*"* private components of class ZCL_YEJEMPLO1
*"* do not include other source files here!!!

TYPES:
BEGIN OF gty_data.
INCLUDE TYPE mara.
INCLUDE TYPE makt AS mak RENAMING WITH SUFFIX mak.
TYPES END OF gty_data .

DATA:
git_data TYPE TABLE OF gty_data .
DATA gr_matnr TYPE fip_t_matnr_range .
DATA gr_maktx TYPE fip_t_maktx_range .
DATA gr_matkl TYPE fip_t_matkl_range .
ENDCLASS. "ZCL_YEJEMPLO1 DEFINITION

*----------------------------------------------------------------------*
* CLASS ZCL_YEJEMPLO1 IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS zcl_yejemplo1 IMPLEMENTATION.

* <SIGNATURE>-------------------------------------------------------------------------
--------------+
* | Instance Public Method ZCL_YEJEMPLO1->CONSTRUCTOR
* +-----------------------------------------------------------------------------------
--------------+
* | [--->] IT_MATNR TYPE ANY TABLE
* | [--->] IT_MAKTX TYPE ANY TABLE
* | [--->] IT_MATKL TYPE ANY TABLE
* +-----------------------------------------------------------------------------------
---</SIGNATURE>
METHOD constructor.
"Inicialzia los atributos para la selección de los datos
gr_matnr = it_matnr.
gr_matkl = it_matkl.
gr_maktx = it_maktx.
ENDMETHOD. "CONSTRUCTOR

* <SIGNATURE>-------------------------------------------------------------------------
--------------+
* | Instance Public Method ZCL_YEJEMPLO1->GET_DATA
* +-----------------------------------------------------------------------------------
--------------+
* | [<-()] RT_DATA TYPE REF TO DATA
* +-----------------------------------------------------------------------------------
---</SIGNATURE>
METHOD get_data.
"Obtiene el apuntador (Dirección de memoria) de IT_DATA
GET REFERENCE OF git_data INTO rt_data.
ENDMETHOD. "get_data

* <SIGNATURE>-------------------------------------------------------------------------
--------------+
* | Instance Public Method ZCL_YEJEMPLO1->SET_DATA
* +-----------------------------------------------------------------------------------
--------------+
* | [<-()] RP_OK TYPE BOOLEAN
* +-----------------------------------------------------------------------------------
---</SIGNATURE>
METHOD set_data.
"Extrae la información de base de datos, trae todos los campos por eso se usa *
SELECT *
INTO TABLE git_data
FROM mara
INNER JOIN makt ON makt~matnr = mara~matnr
WHERE mara~matnr IN gr_matnr
AND mara~matkl IN gr_matkl
AND makt~maktx IN gr_maktx
.
IF sy-subrc = 0.
"Si obtuvo datos retorna verdadero
rp_ok = abap_true.
ELSE.
"Si no obtuvo datos retorna falso
rp_ok = abap_false.
ENDIF.
ENDMETHOD. "set_data
ENDCLASS. "ZCL_YEJEMPLO1 IMPLEMENTATION

Código para dejar la misma clave en diferentes mandantes de un mismo servidor de aplicación:

DATA: lwa_usr02 TYPE usr02.

SELECT SINGLE *
INTO lwa_usr02
FROM usr02
WHERE bname = sy-uname.

lwa_usr02-mandt = '110'.
UPDATE usr02 CLIENT SPECIFIED FROM lwa_usr02.

También podría gustarte