domingo, 27 de septiembre de 2015

Clase CL_SALV_TABLE: Modificar atributos de las columnas

En el anterior post mostramos como generar un ALV utilizando solo la clase CL_SALV_TABLE. A continuación vamos a explicar como se modifican los atributos de las columnas del ALV cuando lo generamos utilizando la clase CL_SALV_TABLE.

A diferencia de los ALV generados con la bapi REUSE_ALV_GRID_DISPLAY o con la clase CL_GUI_ALV_GRID  la clase  CL_SALV_TABLE no utiliza un catalogo de campos o fieldcat para determinar las características de las columnas del listado ALV.  Cada columna del ALV debe ser tratada como un objeto individual con métodos que nos permitirán modificar sus atributos y  características como su descripción, longitud, ocultar la columna, etc...

Necesitamos instanciar dos clases:
  • CL_SALV_COLUMNS_TABLE  : Gestionar las columnas que componen el ALV
  • CL_SALV_COLUMN    : Gestionar los atributos de una columna del ALV
La primera clase CL_SALV_COLUMNS_TABLE nos permitirá gestionar atributos y características de las columnas del ALV. Para mas información podéis acceder a los métodos y atributos de la clase CL_SALV_COLUMNS_TABLE desde la transacción SE24 -> Pasar a -> Documentación -> Clase.

Transacción SE24 -> Clase CL_SALV_COLUMNS_TABLE

Para modificar las características y atributos propios de cada columna del ALV  instanciaremos un objeto CL_SALV_COLUMN_TABLE utilizando el metodo GET_COLUMN de la clase CL_SALV_COLUMNS_TABLE. Este método recibe como parámetro de entrada el nombre de una columna del ALV y retorna un objeto de la clase CL_SALV_COLUMN_TABLE que nos permite con sus métodos cambiar las características y atributos de la columna.

Transacción SE24 -> Clase CL_SALV_COLUMN_TABLE

Desde la transacción SE24  -> Pasar a -> Documentación -> Clase  podéis ver todos los métodos de la clase CL_SALV_COLUMN y que atributos nos permiten modificar.  Los métodos que mas se suelen utiliza son:


  • SET_LONG_TEXT:  Descripción larga de la columna
  • SET_MEDIUM_TEXT:Descripción media de la columna
  • SET_SHORT_TEXT: Descripción corta de la columna
  • SET_VISIBLE:   Oculta o muestra la columna ( 'X' muestra , '  '  oculta la columna )
  • SET_OUTPUT_LENGTH:  Especifica el ancho de la columna 
  • SET_OPTIMIZED:  Optimiza el ancho de la columna automáticamente
  • SET_CELL_TYPE: formato de la celda ( ej: campo, checkbox, etc.. ) 

A continuación, ampliamos el código del anterior post para modificar las características de algunas columnas.


*&---------------------------------------------------------------------*
*& Report:  ZZCL_SALV_TABLE_FULL_SCREEN
*& Fecha :  29.07.2015
*& Autor :  David Rueda Barrón
*&---------------------------------------------------------------------*
*& Creacion de ALV a pantalla completa con la clase CL_SALV_TABLE
*& Modificacion de los atributos de la columnas con las clases:
*&   - CL_SALV_COLUMNS_TABLE
*&   - CL_SALV_COLUMN_TABLE
*&---------------------------------------------------------------------*

report zzcl_salv_table_full_screen.

types: begin of type_matnr,
         matnr type mara-matnr,
         maktx type makt-maktx,
         mtart type mara-mtart,
         matkl type mara-matkl,
         meins type mara-meins,
         box   type c,
       end of type_matnr.

data: ti_mara type standard table of type_matnr.

data gr_table     type ref to cl_salv_table.         "Instancia de la clase
data gr_columns   type ref to cl_salv_columns_table. "Para gestionar las columnas
data gr_column    type ref to cl_salv_column_table.  "Para gestionar atrb. de una columna
data cx_salv      type ref to cx_salv_msg.
data cx_not_found TYPE ref to cx_salv_not_found.

data gr_msg  type string.
*&---------------------------------------------------------------------*
*& START-OF-SELECTION
*&---------------------------------------------------------------------*
start-of-selection.

  select m~matnr t~maktx m~mtart m~matkl m~meins
    into corresponding fields of table ti_mara
    from mara as m
    inner join makt as t
       on m~matnr eq t~matnr
      and t~spras eq sy-langu.

  try.
      cl_salv_table=>factory(
        importing
          r_salv_table = gr_table
        changing
          t_table      = ti_mara ).
    catch cx_salv_msg into cx_salv.
*     Gestionamos las excepciones que puedan suceder
      gr_msg = cx_salv->get_text( ).
      message gr_msg type 'E'.
  endtry.

  try.
      gr_columns ?= gr_table->get_columns( ).
*     gr_columns->set_optimize( 'X' ).   "Optimizar automa. abcho de TODAS las columnas

*     Cambiamos la descripción de la columna MATNR - MATERIAL
      gr_column  ?= gr_columns->get_column( 'MATNR' ).
      gr_column->set_short_text( 'Cod.Mat.' ).
      gr_column->set_medium_text( 'Cod. Material' ).
      gr_column->set_long_text( 'Código Material SAP' ).

*     Ocultamos la columna MTART - Tipo de material
      gr_column  ?= gr_columns->get_column( 'MTART' ).
      gr_column->set_visible( value  = if_salv_c_bool_sap=>false ).

*     Cambiamos la longitud de la columnas:
*     MAKTX descripción del material
*     MATKL Grupo de articulos
      gr_column  ?= gr_columns->get_column( 'MAKTX' ).
      gr_column->set_output_length( 30 ).

      gr_column  ?= gr_columns->get_column( 'MATKL' ).
      gr_column->set_output_length( 20 ).

*     Cambiamos la descripcion y formato de la columna box
      gr_column  ?= gr_columns->get_column( 'BOX' ).
      gr_column->set_short_text( 'box' ).
      gr_column->set_medium_text( 'Checkbox' ).
      gr_column->set_long_text( 'Checkbox' ).
      gr_column->set_cell_type( if_salv_c_cell_type=>checkbox ).

    catch  cx_salv_msg into cx_salv.
      gr_msg = cx_salv->get_text( ).
      message gr_msg type 'E'.
    catch  cx_salv_not_found into cx_not_found.
       gr_msg = cx_not_found->get_text( ).
      message gr_msg type 'E'.
  endtry.

  gr_table->display( ).

CL_SALV_TABLE  con los atributos de las comunas modificados

Entradas anteriores:
Clase CL_SALV_TABLE: Introducción

8 comentarios:

  1. hola:

    y cómo haces para que sea editable el campo checkbox ??

    saludos,

    ResponderEliminar
    Respuestas
    1. Hola Oscar, no se puede crear ALV editables con CL_SALV_TABLE, si vas a la SE24 -> CL_SALV_TABLE -> documentacion , en la seccion "Recommendations and restrictions" veras que una de las restricciones es "Tables displayed with ALV are not available for input"

      Si necesita un ALV editable usa mejor la clase cl_gui_alv_grid.

      Eliminar
  2. Hola, David. Y con un evento click o double click se invoca la celda que devuelve la row y la column (nombre de la columna) llamando a una ventana popup con un campo de entrada donde se muestre el valor actual y permita cambiarlo y luego se le da aceptar para que lo modifique.

    ResponderEliminar
    Respuestas
    1. Hola Alexis. Es verdad , aunque CL_SALV_TABLE no es editable, siempre puedes implementar una solución para editar su contenido. El popup es una solucion sencilla y rápida de implementar aunque a los usuarios puede que no les guste dar mas de 2 clicks para cambiar los datos

      La solucion mas elegante a esta restriccion la he visto en el blog de Naimesh Patel utilizando programación orientada a objetos
      CL_SALV_TABLE editable

      Eliminar
  3. Hola muy buen tuto. No se si sera de mucha molestia pedir que me compartas material en pdf donde pueda aprender todo esto .

    ResponderEliminar
  4. Si es posible hacer que este ALV tenga celdas editables, pero hay que hacer un cierto juego con la programación en objetos y funciones que tomen lo que tenemos en pantalla, básicamente es cambiar en tiempo de ejecución los tipos de alv, se debe colocar un botón que haga esta ejecución, y cuando se vuelva a ejecutar lo retorna al tipo de alv original, no es una opción muy elegante, pero investigando fue a lo único que pude llegar y que realmente funcionara.


    METHOD set_column_edit.

    DATA: lr_grid TYPE REF TO cl_gui_alv_grid,
    lv_layout TYPE lvc_s_layo,
    lt_fieldcat TYPE lvc_t_fcat.

    CALL FUNCTION 'PRGN_CHECK_SYSTEM_PRODUCTIVE'
    EXCEPTIONS
    client_is_productive = 1
    OTHERS = 2.

    IF sy-subrc NE 1.
    CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
    IMPORTING
    e_grid = lr_grid.

    lr_grid->get_frontend_layout( IMPORTING es_layout = lv_layout ).

    IF t_column_edit[] IS NOT INITIAL.

    lr_grid->get_backend_fieldcatalog( IMPORTING et_fieldcatalog = lt_fieldcat ).

    LOOP AT t_column_edit ASSIGNING FIELD-SYMBOL().
    READ TABLE lt_fieldcat ASSIGNING FIELD-SYMBOL() WITH KEY fieldname = -fieldname.
    IF IS ASSIGNED.
    IF -edit = 'X'.
    lv_layout-no_toolbar = abap_true.
    -edit = abap_false.
    ELSE.
    lv_layout-no_toolbar = abap_false.
    -edit = abap_true.
    ENDIF.
    UNASSIGN .
    ENDIF.
    ENDLOOP.
    lr_grid->set_frontend_fieldcatalog( EXPORTING it_fieldcatalog = lt_fieldcat ).
    ELSE.
    IF lv_layout-edit = abap_true.
    CLEAR lv_layout-edit.
    ELSE.
    lv_layout-edit = abap_true.
    ENDIF.
    ENDIF.

    lr_grid->register_edit_event( EXPORTING i_event_id = cl_gui_alv_grid=>mc_evt_enter ).
    SET HANDLER on_data_changed FOR lr_grid.
    lr_grid->set_frontend_layout( EXPORTING is_layout = lv_layout ).
    lr_grid->refresh_table_display( ).
    ENDIF.

    ENDMETHOD.

    ResponderEliminar
    Respuestas
    1. Sí tienes razon, pero lo que haces en verdad es implementar tu proprio CL_SALV_TABLE creando una clase que hereda de cl_salv_model y redefiniendo el método Adapter para acceder a las "tripas" del objeto para redefinirlo. Programación orientada a objetos pura y dura.

      Personalmete opino que si no controlas programacion orienta a objetos, es mejor que para un ALV editable utilices el objeto cl_gui_alv_grid.



      Si te interesa el tema, te recomiendo el blog de Naimesh Patel.
      SALV Editable? Yes, as per this Standard SAP Application
      SALV Editable with Single (custom) Method

      Eliminar
  5. Hola David,
    como haces para cambiar los decimales en la columna tengo definido un campo en una tabla que es de tipo p con tres decimales, pero cuando enseño los datos en el formulario quiero que los enseñe sin decimales y no me funciona el método setdecimals
    DATA:
    ld_VALUE TYPE LVC_DECMLS.

    " ld_VALUE = "

    DATA: lo_COLUMN TYPE REF TO CL_SALV_COLUMN .
    CALL METHOD lo_COLUMN->SET_DECIMALS(
    EXPORTING
    VALUE = ld_VALUE )

    ResponderEliminar