ABAP ALV con CL_SALV_TABLE: Visualización moderna de tablas

Kategorie
ABAP-Statements
Veröffentlicht
Autor
Johannes

CL_SALV_TABLE es la API orientada a objetos moderna para ALV (ABAP List Viewer). Reemplaza los módulos de función antiguos (REUSE_ALV_*) y ofrece una interfaz limpia y tipada para visualización de tablas.

Estructura básica

DATA: lo_alv TYPE REF TO cl_salv_table.
TRY.
" Crear ALV
cl_salv_table=>factory(
IMPORTING r_salv_table = lo_alv
CHANGING t_table = lt_data
).
" Configuración...
" Mostrar
lo_alv->display( ).
CATCH cx_salv_msg INTO DATA(lx_error).
WRITE: / lx_error->get_text( ).
ENDTRY.

Ejemplos

1. Visualización ALV más simple

REPORT z_alv_simple.
TYPES: BEGIN OF ty_customer,
id TYPE i,
name TYPE string,
city TYPE string,
END OF ty_customer.
DATA: lt_customers TYPE TABLE OF ty_customer,
lo_alv TYPE REF TO cl_salv_table.
" Datos de prueba
lt_customers = VALUE #(
( id = 1 name = 'Empresa A' city = 'Madrid' )
( id = 2 name = 'Empresa B' city = 'Barcelona' )
( id = 3 name = 'Empresa C' city = 'Valencia' )
).
TRY.
cl_salv_table=>factory(
IMPORTING r_salv_table = lo_alv
CHANGING t_table = lt_customers
).
lo_alv->display( ).
CATCH cx_salv_msg.
ENDTRY.

2. Configurar columnas

DATA: lo_columns TYPE REF TO cl_salv_columns_table,
lo_column TYPE REF TO cl_salv_column.
TRY.
cl_salv_table=>factory(
IMPORTING r_salv_table = lo_alv
CHANGING t_table = lt_customers
).
" Obtener objeto de columnas
lo_columns = lo_alv->get_columns( ).
" Optimizar ancho de columnas
lo_columns->set_optimize( abap_true ).
" Configurar columna individual
lo_column = lo_columns->get_column( 'ID' ).
lo_column->set_short_text( 'ID' ).
lo_column->set_medium_text( 'ID Cliente' ).
lo_column->set_long_text( 'Número de cliente' ).
lo_column->set_output_length( 10 ).
lo_column = lo_columns->get_column( 'NAME' ).
lo_column->set_long_text( 'Nombre del cliente' ).
lo_column = lo_columns->get_column( 'CITY' ).
lo_column->set_long_text( 'Ciudad' ).
lo_alv->display( ).
CATCH cx_salv_not_found cx_salv_msg.
ENDTRY.

3. Ocultar columna

TRY.
lo_column = lo_columns->get_column( 'INTERNAL_FIELD' ).
lo_column->set_visible( abap_false ).
CATCH cx_salv_not_found.
ENDTRY.

4. Activar barra de herramientas

DATA: lo_functions TYPE REF TO cl_salv_functions_list.
" Activar todas las funciones estándar
lo_functions = lo_alv->get_functions( ).
lo_functions->set_all( abap_true ).
" O funciones individuales
lo_functions->set_export_xml( abap_true ).
lo_functions->set_export_spreadsheet( abap_true ).
lo_functions->set_print( abap_true ).
lo_functions->set_find( abap_true ).
lo_functions->set_aggregation( abap_true ).
lo_functions->set_filter( abap_true ).
lo_functions->set_sort_asc( abap_true ).
lo_functions->set_sort_desc( abap_true ).

5. Establecer ordenación

DATA: lo_sorts TYPE REF TO cl_salv_sorts.
lo_sorts = lo_alv->get_sorts( ).
TRY.
" Ordenar por ciudad (ascendente)
lo_sorts->add_sort(
columnname = 'CITY'
position = 1
sequence = if_salv_c_sort=>sort_up
).
" Segunda ordenación por nombre
lo_sorts->add_sort(
columnname = 'NAME'
position = 2
sequence = if_salv_c_sort=>sort_up
).
CATCH cx_salv_not_found cx_salv_existing cx_salv_data_error.
ENDTRY.

6. Establecer filtro

DATA: lo_filters TYPE REF TO cl_salv_filters.
lo_filters = lo_alv->get_filters( ).
TRY.
" Filtrar por ciudad
lo_filters->add_filter(
columnname = 'CITY'
sign = 'I'
option = 'EQ'
low = 'Madrid'
).
CATCH cx_salv_not_found cx_salv_existing cx_salv_data_error.
ENDTRY.

7. Agregación (sumas)

DATA: lo_aggregations TYPE REF TO cl_salv_aggregations.
lo_aggregations = lo_alv->get_aggregations( ).
TRY.
" Suma para columna de importe
lo_aggregations->add_aggregation(
columnname = 'AMOUNT'
aggregation = if_salv_c_aggregation=>total
).
" Promedio
lo_aggregations->add_aggregation(
columnname = 'QUANTITY'
aggregation = if_salv_c_aggregation=>average
).
CATCH cx_salv_not_found cx_salv_existing cx_salv_data_error.
ENDTRY.

8. Rayas cebra y layout

DATA: lo_display TYPE REF TO cl_salv_display_settings.
lo_display = lo_alv->get_display_settings( ).
" Patrón cebra (colores de fila alternados)
lo_display->set_striped_pattern( abap_true ).
" Establecer título
lo_display->set_list_header( 'Lista de clientes' ).
" Líneas horizontales
lo_display->set_horizontal_lines( abap_true ).
" Líneas verticales
lo_display->set_vertical_lines( abap_true ).

9. Manejar eventos (doble clic)

" Clase manejadora de eventos
CLASS lcl_event_handler DEFINITION.
PUBLIC SECTION.
METHODS: on_double_click
FOR EVENT double_click OF cl_salv_events_table
IMPORTING row column.
METHODS: on_link_click
FOR EVENT link_click OF cl_salv_events_table
IMPORTING row column.
ENDCLASS.
CLASS lcl_event_handler IMPLEMENTATION.
METHOD on_double_click.
" Leer datos
READ TABLE lt_customers INTO DATA(ls_cust) INDEX row.
IF sy-subrc = 0.
MESSAGE |Doble clic en { ls_cust-name }| TYPE 'I'.
ENDIF.
ENDMETHOD.
METHOD on_link_click.
MESSAGE |Clic en enlace: Fila { row }, Columna { column }| TYPE 'I'.
ENDMETHOD.
ENDCLASS.
" Programa principal
DATA: lo_events TYPE REF TO cl_salv_events_table,
lo_handler TYPE REF TO lcl_event_handler.
TRY.
cl_salv_table=>factory(
IMPORTING r_salv_table = lo_alv
CHANGING t_table = lt_customers
).
" Registrar manejador de eventos
lo_events = lo_alv->get_event( ).
lo_handler = NEW #( ).
SET HANDLER lo_handler->on_double_click FOR lo_events.
SET HANDLER lo_handler->on_link_click FOR lo_events.
lo_alv->display( ).
CATCH cx_salv_msg.
ENDTRY.

10. Hotspot (celdas clicables)

TRY.
lo_column = lo_columns->get_column( 'ID' ).
" Marcar columna como hotspot (enlace)
lo_column->set_cell_type( if_salv_c_cell_type=>hotspot ).
CATCH cx_salv_not_found.
ENDTRY.

11. Establecer colores

TYPES: BEGIN OF ty_colored_line,
id TYPE i,
name TYPE string,
status TYPE c LENGTH 1,
t_color TYPE lvc_t_scol, " Información de color
END OF ty_colored_line.
DATA: lt_data TYPE TABLE OF ty_colored_line,
ls_color TYPE lvc_s_scol.
" Llenar datos con colores
lt_data = VALUE #(
( id = 1 name = 'OK' status = 'G' )
( id = 2 name = 'Error' status = 'R' )
( id = 3 name = 'Aviso' status = 'Y' )
).
" Establecer colores
LOOP AT lt_data ASSIGNING FIELD-SYMBOL(<ls_line>).
CLEAR ls_color.
ls_color-fname = 'STATUS'.
CASE <ls_line>-status.
WHEN 'G'.
ls_color-color-col = col_positive. " Verde
WHEN 'R'.
ls_color-color-col = col_negative. " Rojo
WHEN 'Y'.
ls_color-color-col = col_total. " Amarillo
ENDCASE.
APPEND ls_color TO <ls_line>-t_color.
ENDLOOP.
" ALV con colores
TRY.
cl_salv_table=>factory(
IMPORTING r_salv_table = lo_alv
CHANGING t_table = lt_data
).
" Asignar columna de color
lo_columns = lo_alv->get_columns( ).
lo_columns->set_color_column( 'T_COLOR' ).
" Ocultar columna de color
lo_column = lo_columns->get_column( 'T_COLOR' ).
lo_column->set_visible( abap_false ).
lo_alv->display( ).
CATCH cx_salv_not_found cx_salv_msg.
ENDTRY.

12. Guardar/cargar layout

DATA: lo_layout TYPE REF TO cl_salv_layout,
ls_key TYPE salv_s_layout_key.
" Definir clave de layout
ls_key-report = sy-repid.
lo_layout = lo_alv->get_layout( ).
lo_layout->set_key( ls_key ).
" Usuario puede guardar layout
lo_layout->set_save_restriction( if_salv_c_layout=>restrict_none ).
" Layout por defecto
lo_layout->set_default( abap_true ).

13. Añadir botones propios

" ¡Solo posible en modo pantalla completa!
DATA: lo_functions TYPE REF TO cl_salv_functions.
" Establecer GUI status (para botones propios)
lo_alv->set_screen_status(
pfstatus = 'ZSTATUS'
report = sy-repid
set_functions = lo_alv->c_functions_all
).
" Manejador de eventos para comando de usuario
CLASS lcl_handler DEFINITION.
PUBLIC SECTION.
METHODS: on_user_command
FOR EVENT added_function OF cl_salv_events
IMPORTING e_salv_function.
ENDCLASS.
CLASS lcl_handler IMPLEMENTATION.
METHOD on_user_command.
CASE e_salv_function.
WHEN 'ZREFRESH'.
" Actualizar datos
refresh_data( ).
lo_alv->refresh( ).
WHEN 'ZEXPORT'.
" Exportación propia
export_data( ).
ENDCASE.
ENDMETHOD.
ENDCLASS.
" Registrar manejador
DATA: lo_events TYPE REF TO cl_salv_events.
lo_events = lo_alv->get_event( ).
SET HANDLER lo_handler->on_user_command FOR lo_events.

14. ALV en contenedor (Screen)

" Para programación de pantallas
DATA: lo_container TYPE REF TO cl_gui_custom_container.
" Crear contenedor (en pantalla: Custom Control 'CC_ALV')
lo_container = NEW #( container_name = 'CC_ALV' ).
TRY.
" ALV en contenedor
cl_salv_table=>factory(
EXPORTING r_container = lo_container
IMPORTING r_salv_table = lo_alv
CHANGING t_table = lt_data
).
" Configuración...
lo_alv->display( ).
CATCH cx_salv_msg.
ENDTRY.

15. Actualizar datos (Refresh)

" Los datos han cambiado
lt_customers = VALUE #(
( id = 1 name = 'Nuevo' city = 'Madrid' )
( id = 2 name = 'Actualizado' city = 'Barcelona' )
).
" Actualizar ALV
lo_alv->refresh( ).
" Con mantener posición de scroll
lo_alv->refresh(
s_stable = VALUE lvc_s_stbl( row = abap_true col = abap_true )
).

16. ALV editable

" ¡Por desgracia no es posible directamente con CL_SALV_TABLE!
" Para ALV editable: usar CL_GUI_ALV_GRID
" Workaround: Leer datos de la tabla después de Display
" (La tabla se pasó como CHANGING)

Clases importantes

ClaseDescripción
CL_SALV_TABLEClase ALV principal
CL_SALV_COLUMNS_TABLEColección de columnas
CL_SALV_COLUMNColumna individual
CL_SALV_FUNCTIONS_LISTFunciones de barra de herramientas
CL_SALV_DISPLAY_SETTINGSConfiguración de visualización
CL_SALV_SORTSOrdenaciones
CL_SALV_FILTERSFiltros
CL_SALV_AGGREGATIONSAgregaciones
CL_SALV_EVENTS_TABLEManejo de eventos
CL_SALV_LAYOUTGestión de layout

Notas importantes / Mejores prácticas

  • CL_SALV_TABLE es la API ALV moderna - prefierela sobre REUSE_ALV*.
  • factory() crea el objeto ALV - CHANGING para la tabla de datos.
  • Optimización de columnas con set_optimize( abap_true ) para anchos automáticos.
  • Barra de herramientas con get_functions( )->set_all( abap_true ) activar.
  • Eventos registrar mediante SET HANDLER.
  • Hotspots hacen las celdas clicables (set_cell_type).
  • Colores requieren una columna de color de tipo LVC_T_SCOL.
  • Editable solo posible con CL_GUI_ALV_GRID.
  • Contenedor usar para integración en pantallas.
  • Layout permite a los usuarios guardar su configuración.