I work as ABAP developer in one of the domestic companies implementing SAP.
The other day, a specification came from the consultant with the task of making a special summarizing line (ALV GRID), in which there would be all sorts of sums, values, names, etc., which, according to the standard, should not be there. You also need to implement the ability for the user to change the data in this line manually.
For those who are in the tank: the cumulative lines are yellow, and sub-lists are displayed in them, in this case by the customer.
')

Thinking over my brain and asking around for my colleagues,
I decided to send a consultant far away with such inquiries I received 2 solution options:
- Make your own summary line, which will be in the inner label. Customize for her output with color, amounts, etc.
- Try to substitute the necessary values ​​in the standard line of summarization.
The first option immediately threw. Just recently, the development of rules with such a line, hemorrhoids do not get enough - you can not sort the filter data in the ALV, the line can move somewhere, etc. etc. In addition, in the standard line there is a bunch of cool and useful buns of the type of line collapsing into one or a hierarchy of piles. The only drawback is that no matter how you go around, it’s impossible to open a standard pondering line for editing (well, or overwork).
The second option - is it possible in general? Having received approval from the authorities to investigate the issue, it was useful to google, and on the very first link a kind Hindu explains that this is completely legitimate and realistic. In the CL_GUI_ALV_GRID class, there is a GET_SUBTOTALS method that returns references to tables with sums of all levels that you can safely change in your program. It looks like this:

Cheers, comrades! The task is clear, and even a plan of action has emerged. Left values ​​need to be inserted only in the sub-lines for debtors. Those. we pass to the SET_TABLE_FOR_FIRST_DISPLAY method the IT_SORT parameter, in which we specify the first sort level - sort by customer. We take out the table of the amounts of the 1st level (these will be the amounts for the debtors) and substitute the necessary values ​​there:
Schematically looks like this:
FORM fill_sort CHANGING ct_sort TYPE lvc_t_sort. APPEND INITIAL LINE TO ct_sort ASSIGNING FIELD-SYMBOL(<lfs_sort>). <lfs_sort>-spos = '1'. <lfs_sort>-fieldname = 'KUNNR'. " !!!! <lfs_sort>-subtot = 'X'. <lfs_sort>-up = 'X'. ENDFORM. go_alv_grid->set_table_for_first_display( ... ). PERFORM set_subtotals. ... FORM set_subtotals . DATA: lr_collect01 TYPE REF TO data . FIELD-SYMBOLS: <lfs_tab> TYPE ANY TABLE , <lfs_line> TYPE ty_data . go_alv_grid->get_subtotals( IMPORTING ep_collect01 = lr_collect01 ). ASSIGN lr_collect01->* TO <lfs_tab>. IF <lfs_tab> IS ASSIGNED. LOOP AT <lfs_tab> ASSIGNING <lfs_line>. " ENDLOOP. ENDIF. ENDFORM.
“Will it really work ?!”, I thought, and with shaking hands I launched a report. It worked!!! But not quite right. Values ​​were derived only in sabtotaly, turned out to be "under" the screen. Those. those that need to scroll down. The solution was found quite quickly on the Internet: to cause a soft update of the ALV after changing the sub sizes:
go_alv_grid->refresh_table_display( i_soft_refresh = 'X' ).
If you do not specify the i_soft_refresh parameter, the update will recalculate all the subtotal and overwrite our data.
Everything?! Can I give to the test? Well, it wasn’t that good ... so, stand ... and if the user changes the sort? Or filter the data? Or even do anything with our table!? It will be updated and all our values ​​will disappear! Heck…
But as it turned out, the CL_GUI_ALV_GRID class has a magical and very useful event: AFTER_REFRESH, which runs every time the ALV is updated. This time the plan of action is as follows:
1. We catch the event AFTER_REFRESH;
2. Get the criteria for sorting the current state of the ALV (which will now be displayed on the screen): go_alv_grid-> get_sort_criteria;
3. Checking: at the first sorting level, the debtor must be (<lfs_sort> -spos = 1 AND <lfs_sort> -fieldname = 'KUNNR') and sub-counting must be enabled (<lfs_sort> -subtot = 'X');
3.a. If everything is ok, we launch a subroutine that substitutes the necessary data into the summarization lines: PERFORM set_subtotals .;
3.b. Otherwise, we change the sorting criteria in such a way that the debtor is at the first level and the sub-numbering is enabled for it;
3.b.I. If there is no customer at all in the sorting criterion, then we extend the 9th level sorting (if there is one), increase all other levels by +1, and insert the first level sorting by customer;
3.b.II. If the sorting by customer is in the table, but not at the first level, then we increase all the sorting levels lower than the customer level by +1, and change the customer sorting level by 1;
4. Set the correct sorting criteria: go_alv_grid-> set_sort_criteria (lt_sort);
5. Next, we run the ALV update with the recalculation of the amounts (here we must be careful not to run the infinite recursion, because the AFTER_REFRESH event will work again);
6. The event will work for the 2nd time, but the sorting criteria will be correct, and the filling of the sabtotal lines will start (by the way, the problem here is that you need to check if the correct amounts are set so that the program does not freeze due to endless recursion, because after changing the amounts we need to run a soft update ALV).
Profit! We get praise from the authorities and consultant! No matter how the user tormented the ALV, there will always be a debtor at the first sorting level, for him there will always be a sub-line with the necessary values.
Only one problem remains - the user still cannot change the data manually. And he wants. But, having communicated with the consultant, we decided to catch a double-click on such a line and throw out a window with input fields that the user will fill in, press Enter and they will get into the required fields in the table. The question arises, how to distinguish the line from the usual one? The answer is: yes, of course! What are all the silly questions? The DOUBLE_CLICK event has an excellent parameter: is_row-rowtype. It is empty in regular lines, and is filled in service. It is usually filled with a line of this type:
S 0101 0000000001
Experimentally, it turned out that S is a summing line (there is also the value T - the total line of sums), 0101 is the sorting level (at least the last 2 digits). The second field of the is_row (index) structure contains the row number of the table of sums of the required level. All information is there! We act:
1. Check that the user clicked on the sabtotal;
2. We receive the table of the sums of the first level: go_alv_grid-> get_subtotals;
3. Read the required string sub_total_tab [is_row-index];
4. Show the user a window with input fields (insert the current values ​​of the string into them);
5. Get user data;
6. Insert user data in our line;
7. Softly update ALV.
Well, almost everything! Everyone is happy, everything works! Well, at least for me, while the consultant is on vacation and has not yet checked.