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 how to merge duplicate rows when i hide a column

Former Member
0 Kudos
2,988

Hi experts, I'm looking for an answer to this question for three days, i haven't found any post that can help me... Then i created my post. Thank you for your help.

First : I have this display using an ALV grid:


First picture :

Article | Prod.bio | TyAr | Fr.geh. | Allergene | Hier.pdt. | L/B
100     |          | ZPFD |         |           |  86       |
600     |          | ZPFD |         |           |  86       |
1000    |          | ZPFD |         |           |  86       |
1300    |          | ZPFD |         |           |  86       |
3000    |          | ZROH |         |           |  8790     |
3005    |          | ZROH |         |           |  8790     | 004
3010    |          | ZROH |         |           |  8790     | 005
3013    |          | ZROH |         |           |  8790     |    

We can see that the values are not duplicated by the primary key "article ".

When I hide the primary key using 'right click > hide' or the specific ALV button, I have this display:

Second picture :

Prod.bio | TyAr | Fr.geh | Allergene | Hier.pdt. | L/B
         | ZPFD |        |           |  86       |
         | ZPFD |        |           |  86       |
         | ZPFD |        |           |  86       |
         | ZPFD |        |           |  86       |
         | ZROH |        |           |  8790     |
         | ZROH |        |           |  8790     | 004
         | ZROH |        |           |  8790     | 005
         | ZROH |        |           |  8790     | 

There is no need to keep all these values after have hide "article " So how do I write my code to dynamically merge the lines. I don't want to make two check boxes for my different screens.

I post the attended result :


Third picture :

Prod.bio | TyAr | Fr.geh | Allergene | Hier.pdt. | L/B
         | ZPFD |        |           |  86       | 
         | ZROH |        |           |  8790     |
         | ZROH |        |           |  8790     | 004
         | ZROH |        |           |  8790     | 005

And my code, an alv grid display:

REPORT ZTESTALEX01 NO STANDARD PAGE HEADING.
**********************************************************************
*TEST ALV DYNAMIQUE
**********************************************************************

TABLES: MARA.TYPE-pools: slis.

"ALV Declarations

DATA: 
 it_fieldcat TYPE slis_t_fieldcat_alv WITHHEADERLINE,
 wa_fieldcat TYPE slis_t_fieldcat_alv,
 l_layout TYPE slis_layout_alv,
 it_sort TYPE slis_t_sortinfo_alv WITHHEADERLINE,
 wa_sort TYPE slis_t_sortinfo_alv.

DATA: BEGIN OF TB_MARA OCCURS 0,
 MATNR LIKE MARA-MATNR,"Article
 ZZBIOJFA LIKE MARA-ZZBIOJFA,"Article bio
 MTART LIKE MARA-MTART,"
 ZZFRUIT LIKE MARA-ZZFRUIT,"
 ZZALLERGENE LIKE MARA-ZZALLERGENE,"
 PRDHA LIKE MARA-PRDHA,"
 LABOR LIKE MARA-LABOR,"lab./bureau d'étude
END OF TB_MARA.

DATA: BEGIN OF TB_COPY OCCURS 0,
 MATNR LIKE MARA-MATNR,"Article
 ZZBIOJFA LIKE MARA-ZZBIOJFA,"Article bio
 MTART LIKE MARA-MTART,"
 ZZFRUIT LIKE MARA-ZZFRUIT,"
 ZZALLERGENE LIKE MARA-ZZALLERGENE,"
 PRDHA LIKE MARA-PRDHA,"
 LABOR LIKE MARA-LABOR,"lab./bureau d'étude
END OF TB_COPY.

START-OF-SELECTION.
SELECT*FROM MARA into CORRESPONDING FIELDS OF TABLE TB_MARA.
it_fieldcat-fieldname ='MATNR'.
it_fieldcat-tabname ='TB_MARA'.
it_fieldcat-ref_tabname ='MARA'.APPEND it_fieldcat TO wa_fieldcat.clear it_fieldcat.
it_fieldcat-fieldname ='ZZBIOJFA'.
it_fieldcat-tabname ='TB_MARA'.
it_fieldcat-ref_tabname ='MARA'.APPEND it_fieldcat TO wa_fieldcat.clear it_fieldcat.
it_fieldcat-fieldname ='MTART'.
it_fieldcat-tabname ='TB_MARA'.
it_fieldcat-ref_tabname ='MARA'.APPEND it_fieldcat TO wa_fieldcat.clear it_fieldcat.
it_fieldcat-fieldname ='ZZFRUIT'.
it_fieldcat-tabname ='TB_MARA'.
it_fieldcat-ref_tabname ='MARA'.APPEND it_fieldcat TO wa_fieldcat.clear it_fieldcat.
it_fieldcat-fieldname ='ZZALLERGENE'.
it_fieldcat-tabname ='TB_MARA'.
it_fieldcat-ref_tabname ='MARA'.APPEND it_fieldcat TO wa_fieldcat.clear it_fieldcat.
it_fieldcat-fieldname ='PRDHA'.
it_fieldcat-tabname ='TB_MARA'.
it_fieldcat-ref_tabname ='MARA'.APPEND it_fieldcat TO wa_fieldcat.clear it_fieldcat.
it_fieldcat-fieldname ='LABOR'.
it_fieldcat-tabname ='TB_MARA'.
it_fieldcat-ref_tabname ='MARA'.APPEND it_fieldcat TO wa_fieldcat.clear it_fieldcat.
l_layout-window_titlebar ='Table MARA'.CLEAR it_sort.
 it_sort-FIELDNAME ='MATNR'.
 it_sort-UP ='X'.APPEND it_sort TO wa_sort.CLEAR it_sort.

DELETEADJACENT DUPLICATES FROM TB_MARA COMPARING ALL FIELDS.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
 i_callback_program =sy-repid
 is_layout = l_layout
 it_fieldcat = wa_fieldcat[]
 it_sort = wa_sort[]
 i_callback_top_of_page ='TOP'
 I_HTML_HEIGHT_TOP =1
TABLES
 t_outtab = TB_MARA
EXCEPTIONS
 program_error =1
 others=2.
IF sy-subrc <> 0.
ENDIF.
***------------------------------------------------------------------*
*** Top-of-page ***
***------------------------------------------------------------------*
FORM TOP.
CALL FUNCTION'Z_EGF_TOP_OF_PAGE'
EXPORTING
 P_BOTTOM_LINE =''."Pour enlever la ligne vide de l'en-tete dans l'apercu avant impression
ENDFORM.

Thanks for yours answers.

1 ACCEPTED SOLUTION

raymond_giuseppi
Active Contributor
694

You could handle event after_refresh (convert first your old fashioned FM report to OO) in the handling method, read the current field catalog (get_frontend_fieldcatalog) and if and only if required, update the displayed internal table (from a saved internal table with data read from database or reload from database, don't forget that user can display again a previously hidden field) and execute refresh_table_display.

19 REPLIES 19

Sandra_Rossi
Active Contributor
0 Kudos
694

Could you please post the images again, they are not shown.

Former Member
694

Done, i have upload my pictures again. But can't you access it through the links at the bottom of the page?

Sandra_Rossi
Active Contributor
694

ALV does not have the feature to merge identical lines, nor lines with the same visible content.

So, condense the lines of the internal table before displaying the ALV (SORT ... BY ... + DELETE ADJACENT DUPLICATES ... COMPARING ... both followed by the list of fields you want i.e. all fields except "article").

0 Kudos
694

Yeah sure but if the user hide the column 'L/B', i'll have duplicates fields again ...
The field 'article' was a sample. He is a part of a program who contains 24 fields and when i hide a column, i have some duplicates lines. There must be a solution, the guy who created ALV has probably thought about that. He cannot make this mistake. What is the insterest to display ten times one row ?

694

It's just your opinion how the ALV grid should work. It's 20 years it works like that and nobody complained. A most important feature of ALV is to work with slow network, the data is not fully transferred to the frontend. The ALV Grid control doesn't change the internal table (except sorting), so it's up to you to change it.

694

As Sandra said, this is by design. Think of it like an Excel spreadsheet: when you hide a column the data is still there and formulas pointing to it still show the values. It’s just the display that’s affected,

694

I'm curious - how do you expect ALV to figure out what is a duplicate and what isn't? In this particular case you happened to have empty values. But what if they were not empty? Let's say we have this data:

ZPFD 5
ZPFD 5
ZROH 10

If "5" here is some kind of identifier then a human would look at this and say: hm, I don't really need to see 3 rows here as the first two are clearly duplicates. But what is "5" is quantity or net value and the first two lines belong to two different documents (with the document # hidden)? Then it's not a duplicate at all! How do you expect ALV to know the difference?

raymond_giuseppi
Active Contributor
695

You could handle event after_refresh (convert first your old fashioned FM report to OO) in the handling method, read the current field catalog (get_frontend_fieldcatalog) and if and only if required, update the displayed internal table (from a saved internal table with data read from database or reload from database, don't forget that user can display again a previously hidden field) and execute refresh_table_display.

0 Kudos
694

Thanks, I'll try what you say. If it works, I will not forget to accept your answer.

694

Check carefully the 'if and only if required' of my answer as the refresh_table_display will trigger a new after_refresh so you must prevent an infinite loop.

0 Kudos
694

Ok, now i use OO ALV, i call the after_refresh event and i have fixed the infinite loop but one probleme left :

I have 24 different fields and my data provide from 10 differents tables. So, i put all my data in an internal table who regroup all fields. So I think that the best issue is to do a sort and a delete duplicate... on the unnecessary fields. When i hide a column, the only field who change is named 'no_out'. So thanks this field, i can get (looping on the new fieldcatalog and filtring by no_out check) all field's name i need and put them into a local variable. But the sort and the delete duplicate only accept fields as parameter, so all field's name i have get are useless 😕

0 Kudos
694

The SORT statement allows a by (otab) option, the DELETE ADJACENT DUPLICATES alas no.

So better clear the no_out and tech fields values in the internal table (or rebuild it from save/db) then sort by table_line and delete adjacent duplicates.

0 Kudos
694

SORT by (otab) don't accept multiple field's value... Any suggestion please ?

0 Kudos
694

ABAP_SORTORDER_TAB is a table type, nevertheless you could use my second solution (clearing not displayed fields in itab and apply a standard sort)

0 Kudos
694
FORM d0100_event_after_refresh.
 CLEAR TEST. "Pour éviter le redondance de l'événement after refresh
CLEAR wa_mara. "La table de work area CLEAR it_aff. "La table devant etre affichée CLEAR it_fieldcat. "Les champs à afficher
CALL METHOD g_grid->get_frontend_fieldcatalog IMPORTING et_fieldcatalog = it_fieldcat. LOOP AT it_fieldcat INTO wa_fieldcat. "On parcours les champs à afficher CLEAR NOOUT1. CLEAR NOOUT2.
IF wa_fieldcat-no_out = ''. "Si le champ doit etre afficher CONCATENATE 'it_aff-' wa_fieldcat-fieldname INTO NOOUT1. "Le nom complet du champ à afficher
CONCATENATE 'it_mara-' wa_fieldcat-fieldname INTO NOOUT2. "Le nom complet du champ dont provient les données
LOOP AT it_mara INTO wa_mara. "On parcours la table des données
MOVE wa_mara-(wa_fieldcat-fieldname) TO it_aff-(wa_fieldcat-fieldname). "On ne stock que les données qui nous intéressent j'aimerai utiliser les variables ci dessus si possible ENDLOOP.
ENDIF.
ENDLOOP.
SORT it_aff ASCENDING. "On trie toutes les données DELETE ADJACENT DUPLICATES FROM it_aff COMPARING ALL FIELDS. "On supprime les duplicatas
CALL METHOD g_grid->refresh_table_display. "Reaffichage
TEST = 'X'.
ENDFORM.

0 Kudos
694

So, i try to get field name dynamicly but this never works... I have tried with field-symbol, (var) but abap never recognize the syntax (for fields who don't exist)

0 Kudos
694

Try some assignments of fields like

LOOP AT it_mara assigning <mara>.
  APPEND INITIAL LINE TO it_aff ASSIGNING <aff>.
  LOOP AT it_fieldcat ASSIGNING <field> WHERE no_out IS INITIAL and tech IS INITIAL.
    ASSIGN COMPONENT <field>-fieldname OF STRUCTURE <mara> to <from>.
    CHECK <from> IS ASSIGNED.
    ASSIGN COMPONENT <field>-fieldname OF STRUCTURE <aff> to <to>.
    CHECK <to> IS ASSIGNED.
    <to> = <from>.
  ENDLOOP.
ENDLOOP.

0 Kudos
694

Thanks a lot, i have past 5 days on this without found the solution and you did it on 10 mins,and this match perfectly with my expected purpose. Really, thank you.

Former Member
0 Kudos
694

It is not 100%, what you want (you get a subtotals line for free), but best what you can do with the sum function in ALV.