✒️ABAP Los cortes de control utilizando tablas internas
ABAP Los cortes de control utilizando tablas internas
LOS CORTES DE CONTROL UTILIZANDO TABLAS INTERNAS
1 | ¿Qué es un Corte de control?
Tal como vimos anteriormente una de las tareas que más vamos a realizar como programadores ABAP es la confección de reportes de salida por pantalla.
Para realizar estos reportes vamos a trabajar con tablas internas, ya que de esta forma podremos almacenar los registros que obtenemos de las tablas base de datos o cargar manualmente los registros de datos que surgen del procesamiento del programa y luego vamos a estructurar y formatear los datos que se mostrarán como salida del programa.
Cuando hablamos de estructurar y formatear nos referimos a: organizar la salida de los datos en la pantalla, dándoles un formato determinado, agrupando los campos de salida, ordenando el reporte por determinados campos, sumarizando campos, mostrando totales por distintos campos, entre otras cuestiones posibles.
Para realizar todo esto que mencionamos vamos a utilizar lo que se denominan Cortes de control.
***************************************************************************************
Corte de control
Es una forma de estructurar un reporte de salida por pantalla de modo de poder sumarizar datos y mostrar totales por distintos campos del reporte.
***************************************************************************************
Para entender de que se trata un corte de control pongamos un ejemplo:
Supongamos que tenemos que generar un reporte de clientes por región y distrito, en donde se muestre por cada región y distrito, los clientes existentes junto con sus importes.
También se desea mostrar el importe total por cliente, el importe total por distrito y el importe total por región.
A continuación, vamos a aprender a implementar los cortes de control en nuestros reportes ABAP.
2 | El paso a paso para implementar un corte de control
Los cortes de control en definitiva son una técnica y como toda técnica, se encuentra compuesta por una serie de pasos que debemos seguir para que funcione correctamente.
Vamos a analizar detalladamente todos los pasos que debemos seguir para implementar cortes de control.
Para ello vamos a tomar como ejemplo el Reporte de Clientes por Región y Distrito que mencionamos en el punto anterior.
Lo primero que vamos a necesitar para implementar el corte de control es declarar la tabla interna de salida del reporte. La particularidad que va a tener esta tabla es que va a estar compuesta por cada uno de los campos que se desean incluir en el reporte de salida y el orden en el que se declaran los campos en la tabla interna va a ser el mismo orden en el que se desea que esos campos se visualicen en pantalla.
Para nuestro reporte de clientes por región y distrito declaramos la tabla interna de salida TI_CLIENTES y la estructura o área de trabajo WA_CLIENTES de la siguiente forma:
* Tipo de datos
TYPES: BEGIN OF ty_clientes,
region(10) TYPE c,
distrito(10) TYPE c,
nrocliente(5) TYPE c,
importe TYPE i,
END OF ty_clientes.
* Tablas internas y estructuras
DATA: ti_clientes TYPE STANDARD TABLE OF ty_clientes,
wa_clientes LIKE LINE OF ti_clientes.
Por una particularidad de ABAP vamos a necesitar declarar siempre una estructura auxiliar, cuyo nombre será WA_CLIENTES_AUX, a parte de la que ya declaramos al momento de declarar la tabla interna.
DATA: wa_clientes_aux LIKE LINE OF ti_clientes.
Por último, vamos a declarar una variable de tipo I para cada uno de los importes que deseamos sumarizar. Es decir, vamos a declarar las variables V_IMPORTE_TOTAL_REGION, V_IMPORTE_TOTAL_DISTRITO y V_IMPORTE_TOTAL_CLIENTE.
DATA: v_importe_total_cliente TYPE i,
v_importe_total_distrito TYPE i,
v_importe_total_region TYPE i.
Ahora bien, luego de declarar todas las variables necesarias, vamos primeramente a borrar el contenido de la tabla interna TI_CLIENTES. Este paso previo es considerado una buena práctica de programación ya que, si bien todavía no llenamos con registros la tabla interna, podría suceder que esta quede con basura en memoria de ejecuciones anteriores, por lo que se producirían errores en la ejecución del reporte. Para prevenir estas situaciones erróneas ejecutamos el REFRESH de la tabla interna TI_CLIENTES.
****************************************************************************
REFRESH
Sentencia ABAP que se utiliza para inicializar el contenido de una tabla interna.
La sintaxis de la sentencia REFRESH es la siguiente:
REFRESH <tabla_interna>.
En ocasiones se suele confundir las sentencia CLEAR y REFRESH. Es importante tener en cuenta que utilizamos CLEAR para inicializar variables y estructuras, a diferencia de REFRESH el cual es exclusivo para tablas internas.
Es considerada una muy buena práctica de programación borrar el contenido de una tabla interna antes de utilizarla.
****************************************************************************
A continuación, vamos a proceder con el llenado del contenido de la tabla interna TI_CLIENTES. Para ello vamos a cargar cada uno de los registros de datos de la tabla interna completando los campos REGION, DISTRITO, NROCLIENTE e IMPORTE tal como vemos en la siguiente imagen:
CLEAR wa_clientes.
wa_clientes-region = 'CAPITAL'.
wa_clientes-distrito = 'Caballito'.
wa_clientes-nrocliente = '00001'.
wa_clientes-importe = 30.
APPEND wa_clientes TO ti_clientes.
CLEAR wa_clientes.
wa_clientes-region = 'CAPITAL'.
wa_clientes-distrito = 'Caballito'.
wa_clientes-nrocliente = '00700'.
wa_clientes-importe = 1000.
APPEND wa_clientes TO ti_clientes.
CLEAR wa_clientes.
wa_clientes-region = 'CAPITAL'.
wa_clientes-distrito = 'Caballito'.
wa_clientes-nrocliente = '00705'.
wa_clientes-importe = 10000.
APPEND wa_clientes TO ti_clientes.
CLEAR wa_clientes.
wa_clientes-region = 'CAPITAL'.
wa_clientes-distrito = 'Flores'.
wa_clientes-nrocliente = '00005'.
wa_clientes-importe = 90.
APPEND wa_clientes TO ti_clientes.
CLEAR wa_clientes.
wa_clientes-region = 'CAPITAL'.
wa_clientes-distrito = 'Flores'.
wa_clientes-nrocliente = '00122'.
wa_clientes-importe = 900.
APPEND wa_clientes TO ti_clientes.
CLEAR wa_clientes.
wa_clientes-region = 'CAPITAL'.
wa_clientes-distrito = 'Palermo'.
wa_clientes-nrocliente = '00011'.
wa_clientes-importe = 120.
APPEND wa_clientes TO ti_clientes.
CLEAR wa_clientes.
wa_clientes-region = 'CAPITAL'.
wa_clientes-distrito = 'Palermo'.
wa_clientes-nrocliente = '00111'.
wa_clientes-importe = 1200.
APPEND wa_clientes TO ti_clientes.
CLEAR wa_clientes.
wa_clientes-region = 'CAPITAL'.
wa_clientes-distrito = 'Belgrano'.
wa_clientes-nrocliente = '00012'.
wa_clientes-importe = 20.
APPEND wa_clientes TO ti_clientes.
CLEAR wa_clientes.
wa_clientes-region = 'CAPITAL'.
wa_clientes-distrito = 'Belgrano'.
wa_clientes-nrocliente = '05512'.
wa_clientes-importe = 2000.
APPEND wa_clientes TO ti_clientes.
CLEAR wa_clientes.
wa_clientes-region = 'CAPITAL'.
wa_clientes-distrito = 'Caballito'.
wa_clientes-nrocliente = '00001'.
wa_clientes-importe = 70.
APPEND wa_clientes TO ti_clientes.
CLEAR wa_clientes.
wa_clientes-region = 'AVELLANEDA'.
wa_clientes-distrito = 'Sur'.
wa_clientes-nrocliente = '00022'.
wa_clientes-importe = 30.
APPEND wa_clientes TO ti_clientes.
CLEAR wa_clientes.
wa_clientes-region = 'AVELLANEDA'.
wa_clientes-distrito = 'Sur'.
wa_clientes-nrocliente = '00100'.
wa_clientes-importe = 3000.
APPEND wa_clientes TO ti_clientes.
CLEAR wa_clientes.
wa_clientes-region = 'AVELLANEDA'.
wa_clientes-distrito = 'Sur'.
wa_clientes-nrocliente = '00099'.
wa_clientes-importe = 6000.
APPEND wa_clientes TO ti_clientes.
CLEAR wa_clientes.
wa_clientes-region = 'AVELLANEDA'.
wa_clientes-distrito = 'Norte'.
wa_clientes-nrocliente = '00029'.
wa_clientes-importe = 190.
APPEND wa_clientes TO ti_clientes.
CLEAR wa_clientes.
wa_clientes-region = 'AVELLANEDA'.
wa_clientes-distrito = 'Norte'.
wa_clientes-nrocliente = '00029'.
wa_clientes-importe = 190.
APPEND wa_clientes TO ti_clientes.
CLEAR wa_clientes.
wa_clientes-region = 'AVELLANEDA'.
wa_clientes-distrito = 'Norte'.
wa_clientes-nrocliente = '00301'.
wa_clientes-importe = 500.
APPEND wa_clientes TO ti_clientes.
CLEAR wa_clientes.
wa_clientes-region = 'QUILMES'.
wa_clientes-distrito = 'Centro'.
wa_clientes-nrocliente = '00084'.
wa_clientes-importe = 300.
APPEND wa_clientes TO ti_clientes.
CLEAR wa_clientes.
wa_clientes-region = 'QUILMES'.
wa_clientes-distrito = 'Ezpeleta'.
wa_clientes-nrocliente = '00172'.
wa_clientes-importe = 50.
APPEND wa_clientes TO ti_clientes.
********************************************
En el ámbito real de trabajo del día a día del programador ABAP, el contenido de la tabla interna de salida por pantalla va a ser el resultado de seleccionar registros de datos de diferentes tablas de la base de datos y luego realizar al procesamiento con ellos de modo de quedarnos con cierta información precisa, con la cuál se va a elaborar el reporte de salida por pantalla.
********************************************
Luego lo que vamos a necesitar es ordenar la tabla interna TI_CLIENTES por los campos por los cuales se va a realizar el corte de control. En este caso tenemos que ordenar por REGION, DISTRITO y NROCLIENTE. Recordemos que si en la ejecución de la sentencia SORT no especificamos el tipo de ordenamiento entonces el mismo por defecto se realizará en forma ascendente.
*----------------------------------------------------------------------*
* Ordenamos la tabla interna
*----------------------------------------------------------------------*
SORT ti_clientes BY region distrito nrocliente.
A continuación, vamos a recorrer la tabla interna TI_CLIENTES y es aquí dentro de este LOOP-ENDLOOP en donde se realiza el corazón de la técnica de corte de control.
Una vez dentro del LOOP lo primero que vamos a hacer y que es sumamente importante es pasar el contenido de la estructura o área de trabajo WA_CLIENTES a WA_CLIENTES_AUX.
*----------------------------------------------------------------------*
* Recorremos la tabla interna
*----------------------------------------------------------------------*
LOOP AT ti_clientes INTO wa_clientes.
* Copiamos el contenido del registro a una estructura auxiliar
CLEAR wa_clientes_aux.
wa_clientes_aux = wa_clientes.
Ahora viene la parte más importante de la técnica de corte de control, presta mucha atención.
Para realizar un corte de control, ABAP pone a nuestra disposición dos sentencias que nos facilitan el trabajo como programadores.
La sentencia AT NEW cuya sintaxis es la siguiente:
AT NEW campo.
...
ENDAT.
La sentencia AT NEW campo se ejecuta por cada valor nuevo que se encuentre almacenado en campo.
La sentencia AT NEW campo mira hacia atrás, es decir compara el contenido del campo del registro actual de la tabla interna que se está procesando contra el contenido del campo del registro anterior de la tabla interna que se procesó.
Si el resultado de esa comparación es que los contenidos de ambos campos son diferentes entonces se ejecuta la lógica ABAP que se encuentra dentro del AT NEW.
Si el resultado de esa comparación es que los contenidos de ambos campos son iguales entonces no se ejecuta la lógica ABAP que se encuentra dentro del AT NEW.
Si estamos procesando el primer registro de la tabla interna entonces compara el contenido del campo contra nada y el resultado de esa comparación es que son distintos por lo que se ejecuta la lógica ABAP que se encuentra dentro del AT NEW.
Y la sentencia AT END OF cuya sintaxis es la siguiente:
AT END OF campo.
...
ENDAT.
La sentencia AT END OF campo se ejecuta cuando se está procesando el último registro que tenga almacenado un valor determinado de campo.
La sentencia AT END OF campo mira hacia adelante, es decir compara el contenido del campo del registro actual de la tabla interna que se está procesando contra el contenido del campo del registro siguiente de la tabla interna que todavía no se procesó.
Si el resultado de esa comparación es que los contenidos de ambos campos son diferentes entonces se ejecuta la lógica ABAP que se encuentra dentro del AT END OF.
Si el resultado de esa comparación es que los contenidos de ambos campos son iguales entonces no se ejecuta la lógica ABAP que se encuentra dentro del AT END OF.
Si estamos procesando el último registro de la tabla interna entonces compara el contenido del campo contra nada y el resultado de esa comparación es que son distintos por lo que se ejecuta la lógica ABAP que se encuentra dentro del AT END OF.
Si volvemos a nuestro reporte de clientes por región y distrito entonces implementaríamos de la siguiente forma estas sentencias:
Por cada nueva región vamos a ejecutar un AT NEW REGION y aquí dentro vamos a hacer dos puntos fundamentales que son inicializar la variable V_IMPORTE_TOTAL_REGION que sumariza el importe por región e imprimir la región que estamos procesando.
*----------------------------------------------------------------------*
* Por cada nueva región
*----------------------------------------------------------------------*
AT NEW region.
CLEAR v_importe_total_region.
FORMAT COLOR 1.
WRITE:/ sy-uline(83).
WRITE:/ 'Región:', wa_clientes_aux-region.
WRITE:/ sy-uline(83).
ENDAT.
Por cada nuevo distrito vamos a ejecutar un AT NEW DISTRITO y aquí dentro vamos a hacer dos puntos fundamentales que son inicializar la variable V_IMPORTE_TOTAL_DISTRITO que sumariza el importe por distrito e imprimir el distrito que estamos procesando.
*----------------------------------------------------------------------*
* Por cada nuevo distrito
*----------------------------------------------------------------------*
AT NEW distrito.
CLEAR v_importe_total_distrito.
FORMAT COLOR 5.
WRITE:/10 'Distrito:', wa_clientes_aux-distrito.
ENDAT.
Por cada nuevo número de cliente vamos a ejecutar un AT NEW NROCLIENTE y aquí dentro vamos a inicializar la variable V_IMPORTE_TOTAL_CLIENTE que sumariza el importe por cliente.
*----------------------------------------------------------------------*
* Por cada nuevo cliente
*----------------------------------------------------------------------*
AT NEW nrocliente.
CLEAR v_importe_total_cliente.
ENDAT.
Una vez que se ejecutaron cada uno de los AT NEW entonces fuera de ellos será necesario sumarizar o acumular cada uno de los importes que mostraremos a continuación en el reporte.
* Acumulamos el importe
ADD wa_clientes_aux-importe TO v_importe_total_cliente.
ADD wa_clientes_aux-importe TO v_importe_total_distrito.
ADD wa_clientes_aux-importe TO v_importe_total_region.
Luego vamos a imprimir el total por cliente. Esto lo vamos a hacer cuando se ejecute el último registro correspondiente al número de cliente que estamos procesando.
Para ello vamos a ejecutar la sentencia AT END OF NROCLIENTE y en caso de ser el último número de cliente se ejecutará la lógica que se encuentra dentro del AT END OF, que consiste básicamente en imprimir en pantalla el número de cliente y el importe total acumulado por cliente tal como vemos a continuación:
*----------------------------------------------------------------------*
* Imprimimos total por cliente
*----------------------------------------------------------------------*
AT END OF nrocliente.
FORMAT COLOR 3.
WRITE:/30 'Cliente:', wa_clientes_aux-nrocliente,
50 'Importe Total Cliente', v_importe_total_cliente.
ENDAT.
Luego vamos a imprimir el total por distrito. Esto lo vamos a hacer cuando se ejecute el último registro correspondiente al distrito que estamos procesando.
Para ello vamos a ejecutar la sentencia AT END OF DISTRITO y en caso de ser el último distrito se ejecutará la lógica que se encuentra dentro del AT END OF, que consiste básicamente en imprimir en pantalla el importe total acumulado por distrito tal como vemos a continuación:
*----------------------------------------------------------------------*
* Imprimimos total por distrito
*----------------------------------------------------------------------*
AT END OF distrito.
FORMAT COLOR 5.
WRITE:/10 'Importe Total distrito', v_importe_total_distrito.
ENDAT.
Y por último vamos a imprimir el total por región. Esto lo vamos a hacer cuando se ejecute el último registro correspondiente a la región que estamos procesando.
Para ello vamos a ejecutar la sentencia AT END OF REGION y en caso de ser la última región se ejecutará la lógica que se encuentra dentro del AT END OF, que consiste básicamente en imprimir en pantalla el importe total acumulado por región tal como vemos a continuación:
*----------------------------------------------------------------------*
* Imprimimos total por región
*----------------------------------------------------------------------*
AT END OF region.
FORMAT COLOR 1.
WRITE:/ 'Importe Total región', v_importe_total_region.
ENDAT.
ENDLOOP.
***********************************************************************
Acabamos de explicar todos los pasos que debemos llevar a cabo para implementar la técnica de cortes de control en nuestros reportes.
***********************************************************************
 
 
 
Sobre el autor
Publicación académica de Nestor Adrian Lara, en su ámbito de estudios para la Carrera Consultor ABAP.
Nestor Adrian Lara
Profesión: Diseño Gráfico - Argentina - Legajo: BZ89W
✒️Autor de: 11 Publicaciones Académicas
🎓Egresado del módulo:
Certificación Académica de Nestor Lara