Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

ALV Grid cell merge behavior changed if 2+ sorted columns (approx 7.40 -> 7.57)

Sandra_Rossi
Active Contributor
864

Hi experts,

In a 7.52 SP 04 version (also verified on 7.40 SP 23), I'd like to know if it's possible to obtain a feature which is available in a more recent version 7.57:

My concern is about the cell merge when there are two or more sorted columns: if one value is the same BUT a value in previous sort columns has changed, this value should be displayed.

To be clear, below is an example with SALV_TEST_TABLE program, I sort on columns CARRID then LOCCURKEY (currency), in versions 7.40 and 7.57. For information, SAP GUI is the same (7.70 PL 3). I think that the 7.57 behavior is better, so I'd like to "backport" this behavior to 7.40.

Do you know if there's a SAP note (I already searched, I found none), or any other solution to do it in 7.40?

Thanks a lot!

Sandra

In 7.40 (ECC EHP 6), "USD" doesn't appear because cell merge works on just one column (Currency), ignoring the other sorted columns (Airline Carrier):

It happens with:

  • ABAP trial version 7.52 SP 04
  • Kernel: 753 PL 400

It also happens with an older version, based on ECC:

  • SAP_BASIS: 740 SP 23
  • SAP_APPL: 617 SP 20
  • Kernel: 753 PL 1200

In 7.57 (S/4HANA), "USD" appears because there is a change of carrier value (column 1) :

  • SAP_BASIS: 757 SP 0
  • S4CORE: 107 SP 0
  • Kernel: 789 PL 52
1 ACCEPTED SOLUTION

Sandra_Rossi
Active Contributor
717

Part 1: answer (TL;DR: 7.40 SP 23 and 7.52 SP 04 don't implement stop merge for sorted columns, 7.57 does; feature was added in a version between the two, no related SAP note found)

Part 2: fix of one standard bug in 7.57 SP 0 (bug after scrolling/paging)

Part 3: fix for 7.40 SP 23 (may work in other versions)

Part 4: little bug with Integrated Excel feature (short dump)

=============================================

PART 1

In 7.57, the logic happens at the method STOP_MERGE_CELLS_BY_SORT_LEVEL of the class CL_SALV_GUI_TABLE_WRITER_IDA.

Internally, in the Grid View control, the cell merge is done via the field "MERGE" of the property "InfoTable" (see details below), but "stopped" by setting an internal style (constant ALV_STYLE4_STOP_MERGE in the include <CL_ALV_CONTROL>, value 2 in STYLE4).

The method STOP_MERGE_CELLS_BY_SORT_LEVEL doesn't exist in 7.40.

In 7.40, most of the formatting of styles happen in the function module LVC_FILL_DATA_TABLE, but STYLE4 is left to 0 and still the cell merge occurs in a sorted column.

Going further, we can see that the method SOFT_REFRESH_TABLE_DISPLAY of CL_GUI_ALV_GRID calls the function module LVC_GET_INFO_DATA_TABLE to fill the attribute MT_INFO (of type LVC_T_INFO) whose component MERGE is 'X' for sorted columns. The method SET_INFO_TABLE of CL_GUI_ALV_GRID_BASE then sends MT_INFO directly to the property "InfoTable" of the Grid View control.

Conclusion concerning the Grid View control: the property "InfoTable" is used to do a cell merge by column (MERGE = 'X'), and the property "DataTable" has STYLE4 = 2 to disable the cell merge in one cell (force the value to be shown).

If I run SALV_IDA_DISPLAY_DATA in 7.40 (which runs cl_salv_gui_table_ida=>create), I can see the same behavior as in 7.57. Switching from classic ALV to IDA may not be transparent, as it's taking the data directly from the database, the developer may need to do important adaptations. It has also some drawback like having the layout button displayed on the far right of the screen (I'd prefer to have all the buttons at the same place).

Conclusion: I guess that SAP did some huge refactoring between the two versions to remove code redundancy between classic SALV and IDA.

In 7.40, the only solution is to use IDA instead of classic SALV. Unless someone can find a fix.

=============================================

PART 2

In 7.57 SP 0, stop merge for sorted columns works in the first rows but fails when rows are scrolled.

Fix in method adapt_lvc_data of CL_SALV_GUI_GRID_FACADE:

*      lt_appl_data_index_range = VALUE #( ( ls_sort_fieldname_info-s_source_index_range ) ). " STANDARD
      lt_appl_data_index_range = VALUE #( ( ls_sort_fieldname_info-s_row_pos_range ) ). " FIX

Fix in method set_stop_merge_style of CL_SALV_GUI_TABLE_WRITER_IDA:

*          IF <s_lvc_data>-row_pos BETWEEN ls_sort_fieldname_info-s_source_index_range-from " STANDARD
*                                  AND ls_sort_fieldname_info-s_source_index_range-to.      " STANDARD
          IF <s_lvc_data>-row_pos BETWEEN ls_sort_fieldname_info-s_row_pos_range-from      " FIXED
                                  AND ls_sort_fieldname_info-s_row_pos_range-to.           " FIXED

=============================================

PART 3

In 7.40 SP 23, create this class ZCL_GUI_ALV_GRID_SORT_MERGE from this gist link, and the below code is for demonstration (data: ALV with 94 rows from table SFLIGHT, initialize them via program SAPBC_DATA_GENERATOR).

EDIT: excluding the Excel inplace button as explained in PART 4 (it_toolbar_excluding = VALUE #( ( lo_alv->mc_fc_view_excel ) )).

REPORT zdemo.
DATA go_alv TYPE REF TO zcl_gui_alv_grid_sort_merge.
DATA gt_sflight TYPE TABLE OF sflight.
PARAMETERS dummy.

AT SELECTION-SCREEN OUTPUT.
  IF go_alv IS INITIAL.
    CREATE OBJECT go_alv
      EXPORTING
        i_parent = cl_gui_container=>screen0.
    SELECT * FROM sflight INTO TABLE gt_sflight.
    DATA(lt_fcat) = VALUE lvc_t_fcat( ).
    PERFORM get_fcat CHANGING gt_sflight lt_fcat.
    lt_fcat[ fieldname = 'MANDT' ] = VALUE #(
      BASE lt_fcat[ fieldname = 'MANDT' ]
      rollname = 'S_CARR_ID' datatype  = 'CHAR' domname  = 'S_CARR_ID' ref_field = 'CARRID' ).
    lt_fcat[ fieldname = 'MANDT' ]-col_pos = 3.
    DATA(lt_sort) = VALUE lvc_t_sort( ( spos = 1 fieldname = 'CARRID' )
                                      ( spos = 2 fieldname = 'MANDT' ) ).
    go_alv->set_table_for_first_display(
        EXPORTING i_structure_name     = 'SFLIGHT'
                  it_toolbar_excluding = VALUE #( ( go_alv->mc_fc_view_excel ) )
        CHANGING  it_outtab            = gt_sflight
                  it_fieldcatalog      = lt_fcat
                  it_sort              = lt_sort ).
  ENDIF.

AT SELECTION-SCREEN ON EXIT-COMMAND.
  go_alv->free( ).
  FREE go_alv.

FORM get_fcat CHANGING it_std TYPE STANDARD TABLE et_fcat TYPE lvc_t_fcat.
  DATA lo_table TYPE REF TO cl_salv_table.
  DATA lo_columns TYPE REF TO cl_salv_columns_list.
  DATA lo_agg TYPE REF TO cl_salv_aggregations.
  REFRESH et_fcat.
  CALL METHOD cl_salv_table=>factory
    IMPORTING
      r_salv_table = lo_table
    CHANGING
      t_table      = it_std[].
  lo_columns = lo_table->get_columns( ).
  lo_agg = lo_table->get_aggregations( ).
  et_fcat = cl_salv_controller_metadata=>get_lvc_fieldcatalog( r_columns = lo_columns r_aggregations = lo_agg ).
ENDFORM.

The values are nicely shown as I expect:

=============================================

PART 4

There's a "little" bug with the Excel inplace feature, a short dump happens if there are sorted columns and the button Excel inplace is clicked.

I didn't spend time on understanding why there's a difference between 7.40 and 7.57, I just disabled this function code (mc_fc_view_excel) because it's an old feature I don't like --and requires additional sap_sm.xls template files--, I prefer the export to XLSX format, which works well:

    go_alv->set_table_for_first_display(
        EXPORTING is_layout       = VALUE #( ... )
                  it_toolbar_excluding = VALUE #( ( go_alv->mc_fc_view_excel ) )
        CHANGING  it_outtab       = ...
                  it_fieldcatalog = ...
                  it_sort         = ... ).
1 REPLY 1

Sandra_Rossi
Active Contributor
718

Part 1: answer (TL;DR: 7.40 SP 23 and 7.52 SP 04 don't implement stop merge for sorted columns, 7.57 does; feature was added in a version between the two, no related SAP note found)

Part 2: fix of one standard bug in 7.57 SP 0 (bug after scrolling/paging)

Part 3: fix for 7.40 SP 23 (may work in other versions)

Part 4: little bug with Integrated Excel feature (short dump)

=============================================

PART 1

In 7.57, the logic happens at the method STOP_MERGE_CELLS_BY_SORT_LEVEL of the class CL_SALV_GUI_TABLE_WRITER_IDA.

Internally, in the Grid View control, the cell merge is done via the field "MERGE" of the property "InfoTable" (see details below), but "stopped" by setting an internal style (constant ALV_STYLE4_STOP_MERGE in the include <CL_ALV_CONTROL>, value 2 in STYLE4).

The method STOP_MERGE_CELLS_BY_SORT_LEVEL doesn't exist in 7.40.

In 7.40, most of the formatting of styles happen in the function module LVC_FILL_DATA_TABLE, but STYLE4 is left to 0 and still the cell merge occurs in a sorted column.

Going further, we can see that the method SOFT_REFRESH_TABLE_DISPLAY of CL_GUI_ALV_GRID calls the function module LVC_GET_INFO_DATA_TABLE to fill the attribute MT_INFO (of type LVC_T_INFO) whose component MERGE is 'X' for sorted columns. The method SET_INFO_TABLE of CL_GUI_ALV_GRID_BASE then sends MT_INFO directly to the property "InfoTable" of the Grid View control.

Conclusion concerning the Grid View control: the property "InfoTable" is used to do a cell merge by column (MERGE = 'X'), and the property "DataTable" has STYLE4 = 2 to disable the cell merge in one cell (force the value to be shown).

If I run SALV_IDA_DISPLAY_DATA in 7.40 (which runs cl_salv_gui_table_ida=>create), I can see the same behavior as in 7.57. Switching from classic ALV to IDA may not be transparent, as it's taking the data directly from the database, the developer may need to do important adaptations. It has also some drawback like having the layout button displayed on the far right of the screen (I'd prefer to have all the buttons at the same place).

Conclusion: I guess that SAP did some huge refactoring between the two versions to remove code redundancy between classic SALV and IDA.

In 7.40, the only solution is to use IDA instead of classic SALV. Unless someone can find a fix.

=============================================

PART 2

In 7.57 SP 0, stop merge for sorted columns works in the first rows but fails when rows are scrolled.

Fix in method adapt_lvc_data of CL_SALV_GUI_GRID_FACADE:

*      lt_appl_data_index_range = VALUE #( ( ls_sort_fieldname_info-s_source_index_range ) ). " STANDARD
      lt_appl_data_index_range = VALUE #( ( ls_sort_fieldname_info-s_row_pos_range ) ). " FIX

Fix in method set_stop_merge_style of CL_SALV_GUI_TABLE_WRITER_IDA:

*          IF <s_lvc_data>-row_pos BETWEEN ls_sort_fieldname_info-s_source_index_range-from " STANDARD
*                                  AND ls_sort_fieldname_info-s_source_index_range-to.      " STANDARD
          IF <s_lvc_data>-row_pos BETWEEN ls_sort_fieldname_info-s_row_pos_range-from      " FIXED
                                  AND ls_sort_fieldname_info-s_row_pos_range-to.           " FIXED

=============================================

PART 3

In 7.40 SP 23, create this class ZCL_GUI_ALV_GRID_SORT_MERGE from this gist link, and the below code is for demonstration (data: ALV with 94 rows from table SFLIGHT, initialize them via program SAPBC_DATA_GENERATOR).

EDIT: excluding the Excel inplace button as explained in PART 4 (it_toolbar_excluding = VALUE #( ( lo_alv->mc_fc_view_excel ) )).

REPORT zdemo.
DATA go_alv TYPE REF TO zcl_gui_alv_grid_sort_merge.
DATA gt_sflight TYPE TABLE OF sflight.
PARAMETERS dummy.

AT SELECTION-SCREEN OUTPUT.
  IF go_alv IS INITIAL.
    CREATE OBJECT go_alv
      EXPORTING
        i_parent = cl_gui_container=>screen0.
    SELECT * FROM sflight INTO TABLE gt_sflight.
    DATA(lt_fcat) = VALUE lvc_t_fcat( ).
    PERFORM get_fcat CHANGING gt_sflight lt_fcat.
    lt_fcat[ fieldname = 'MANDT' ] = VALUE #(
      BASE lt_fcat[ fieldname = 'MANDT' ]
      rollname = 'S_CARR_ID' datatype  = 'CHAR' domname  = 'S_CARR_ID' ref_field = 'CARRID' ).
    lt_fcat[ fieldname = 'MANDT' ]-col_pos = 3.
    DATA(lt_sort) = VALUE lvc_t_sort( ( spos = 1 fieldname = 'CARRID' )
                                      ( spos = 2 fieldname = 'MANDT' ) ).
    go_alv->set_table_for_first_display(
        EXPORTING i_structure_name     = 'SFLIGHT'
                  it_toolbar_excluding = VALUE #( ( go_alv->mc_fc_view_excel ) )
        CHANGING  it_outtab            = gt_sflight
                  it_fieldcatalog      = lt_fcat
                  it_sort              = lt_sort ).
  ENDIF.

AT SELECTION-SCREEN ON EXIT-COMMAND.
  go_alv->free( ).
  FREE go_alv.

FORM get_fcat CHANGING it_std TYPE STANDARD TABLE et_fcat TYPE lvc_t_fcat.
  DATA lo_table TYPE REF TO cl_salv_table.
  DATA lo_columns TYPE REF TO cl_salv_columns_list.
  DATA lo_agg TYPE REF TO cl_salv_aggregations.
  REFRESH et_fcat.
  CALL METHOD cl_salv_table=>factory
    IMPORTING
      r_salv_table = lo_table
    CHANGING
      t_table      = it_std[].
  lo_columns = lo_table->get_columns( ).
  lo_agg = lo_table->get_aggregations( ).
  et_fcat = cl_salv_controller_metadata=>get_lvc_fieldcatalog( r_columns = lo_columns r_aggregations = lo_agg ).
ENDFORM.

The values are nicely shown as I expect:

=============================================

PART 4

There's a "little" bug with the Excel inplace feature, a short dump happens if there are sorted columns and the button Excel inplace is clicked.

I didn't spend time on understanding why there's a difference between 7.40 and 7.57, I just disabled this function code (mc_fc_view_excel) because it's an old feature I don't like --and requires additional sap_sm.xls template files--, I prefer the export to XLSX format, which works well:

    go_alv->set_table_for_first_display(
        EXPORTING is_layout       = VALUE #( ... )
                  it_toolbar_excluding = VALUE #( ( go_alv->mc_fc_view_excel ) )
        CHANGING  it_outtab       = ...
                  it_fieldcatalog = ...
                  it_sort         = ... ).