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: 

cl_gui_alv_grid standard toolbar sort buttons does not work well

k_sood
Active Participant
0 Kudos

Hi All,

I have an created an ALV Program and have shown the standard alv toolbar which includes also the sorting asc and Des buttons, these however does not work well.

Issues for ex :

1. One column is sorted in asc oder - Fine. Now click the descending button on the same column , It opens a dialog box , where I need to select the sort order and the radio buttons are there for sort asc and sort des . I select the desc button , still it does not sort in des order.

2. Now I select multiple columns and click the button sort in asc order , it again shows the dialog box to select the columns and ask to select the corresponding radio buttons, for asc, or desc. Selected Asc for all the columns, no sorting happens .

I had assumed, These are standard sort buttons and should work fine but does not look like. Am I missing anything ? Do I need to set the sorting in the field catalog ?

Best Regards

KS

1 ACCEPTED SOLUTION

k_sood
Active Participant

With the help of Michael , I was able to resolve the issue. Instead of the standard Refresh Event , I created a custom refresh button and did the data retrieval and other tasks on the click of that button .

12 REPLIES 12

michael_piesche
Active Contributor
  1. Sorting Demo
    Please have a look at the SAP demo report "BCALV_GRID_DEMO" (or any other "BCALV_GRID_*" report), execute it and play around with selecting column headers and then sorting asc/desc as well as selecting column fields and then 'sorting asc/desc'. Does it behave as expected compared to your problem?
  2. Apply Sorting on Column Header
    When you left-click on a column header and right afterwards one of the symbols for Sorting Ascending or Descending, it sorts the rows based on that column right away (you shouldnt have to go through the "Define Sort Order" Dialog Box). If you have clicked anywhere else before, then yes, you get the "Define Sort Order" Dialog Box.
  3. Define Sort Order Dialog Box
    In case you opened the "Define Sort Order" Dialog Box, you need to first move all desired and available columns from the column set on the left to the sort criteria on the right. Second, you need to set set the order of the sort criteria using the up and down buttons. Third, you need to set whether a sort criteria on a column should be ascending or descending. Lastly, you need to click the green check mark button to apply this sort order
  4. Still Other problems
    If your problems are not related to the above steps, please be more specific on your issue, providing screenshots of the described problem, as well as providing coding that is related to creating and setting up the ALV_GRID with table data for display

k_sood
Active Participant

1. Sorting works fine in this Demo Program . Also in the code there is nothing implemented specifically for the sorting. Its a Standard toolbar button and it should work correctly .

2. Same behaviour with the Right click also. First Time fine, Second time the dialog box opens.

3. First of all this dialog box should not be coming , secondly if I am doing sorting on one column , why do I need to move all the columns to the sort criteria .

4. Clicked the asc sorting on the info record column, that worked fine. Then clicked on the descending button by selecting the same column , dialog box opened, selected descending there, it completely destroyed the sorting neither ascending nor descending . See Screenshot. sorting 1 . You can see the descending sign is shown on the column but the sorting is not correct.

Coding as follows:

METHOD create_cont_grid.
IF me->custom_container IS INITIAL. "This check ensures that the Container is created only if the screen PBO is Processed for the first time.
* create container
CREATE OBJECT me->custom_container
EXPORTING
container_name = 'MYCONTAINER'
EXCEPTIONS
cntl_error = 1
cntl_system_error = 2
create_error = 3
lifetime_error = 4
lifetime_dynpro_dynpro_link = 5.
IF sy-subrc <> 0.
* Error in creation of cointainer

ENDIF.
* create alv grid using the container as parent.
CREATE OBJECT me->gr_grid
EXPORTING
i_parent = me->custom_container
EXCEPTIONS
error_cntl_create = 1
error_cntl_init = 2
error_cntl_link = 3
error_dp_create = 4
OTHERS = 5.
IF sy-subrc <> 0.
* Error in creation of grid

ENDIF.
* Trigger first display
me->first_display( ).
ELSE.
* Simply Refresh the Grid.
me->refresh_grid( ).
ENDIF.
ENDMETHOD.

METHOD first_display.
DATA : ls_layout TYPE lvc_s_layo,
ls_variant TYPE disvariant,
lv_repid TYPE repid.

DATA ls_exclude TYPE ui_func.
DATA lt_toolbar_excluding TYPE ui_functions.

*Excluding Unnecessary Standard Toolbar Buttons
ls_exclude = cl_gui_alv_grid=>mc_fc_loc_append_row.
APPEND ls_exclude TO lt_toolbar_excluding.
ls_exclude = cl_gui_alv_grid=>mc_fc_loc_delete_row.
APPEND ls_exclude TO lt_toolbar_excluding.
ls_exclude = cl_gui_alv_grid=>mc_fc_loc_insert_row.
APPEND ls_exclude TO lt_toolbar_excluding.
ls_exclude = cl_gui_alv_grid=>mc_fc_check.
APPEND ls_exclude TO lt_toolbar_excluding.
ls_exclude = cl_gui_alv_grid=>mc_fc_loc_copy_row.
APPEND ls_exclude TO lt_toolbar_excluding.
* ls_exclude = cl_gui_alv_grid=>mc_fc_refresh.
* APPEND ls_exclude TO lt_toolbar_excluding.
ls_exclude = cl_gui_alv_grid=>mc_fc_loc_cut.
APPEND ls_exclude TO lt_toolbar_excluding.
ls_exclude = cl_gui_alv_grid=>mc_fc_loc_copy.
APPEND ls_exclude TO lt_toolbar_excluding.
ls_exclude = cl_gui_alv_grid=>mc_fc_loc_undo.
APPEND ls_exclude TO lt_toolbar_excluding.
* Following Two are to Exclude the Insert with Overwrite Combi Button
ls_exclude = cl_gui_alv_grid=>mc_fc_loc_paste_new_row .
APPEND ls_exclude TO lt_toolbar_excluding.
ls_exclude = cl_gui_alv_grid=>mc_fc_loc_paste .
APPEND ls_exclude TO lt_toolbar_excluding.
ls_exclude = cl_gui_alv_grid=>mc_fc_info.
APPEND ls_exclude TO lt_toolbar_excluding.
ls_exclude = cl_gui_alv_grid=>mc_fc_views.
APPEND ls_exclude TO lt_toolbar_excluding.


lv_repid = sy-repid .
ls_variant-report = lv_repid.

ls_layout-zebra = 'X' .
ls_layout-smalltitle = 'X'.

*First Display of ALV .
CALL METHOD gr_grid->set_table_for_first_display
EXPORTING
is_variant = ls_variant
is_layout = ls_layout
i_default = 'X' "with X users can save default Layouts. If its space , users can not save default layouts. If a default Layout Exists, it will be loaded automatically.
i_save = 'A' "Space: layouts cannot be saved . U: only user Defined Layouts. X: Only Global Layouts. A: Both User defined and Global layouts.
it_toolbar_excluding = lt_toolbar_excluding
CHANGING
it_fieldcatalog = ot_fieldcat[]
it_outtab = ot_data
EXCEPTIONS
invalid_parameter_combination = 1
program_error = 2
too_many_lines = 3
OTHERS = 4.
IF sy-subrc NE 0.
* Error in Display of grid
ENDIF.

*Assign Class to Event Handler.
* CREATE OBJECT gr_event_handler .
SET HANDLER me->handle_hotspot_click FOR gr_grid.
SET HANDLER me->on_data_changed FOR gr_grid.
SET HANDLER me->refresh FOR gr_grid .
ENDMETHOD.

Thanks .

[A] Review of Your Coding:

My best guess right now is, that the problem either lies in a) your method refresh_grid( ), or b) in how create_cont_grid() and the table ot_data is changed or c) in what events the event handler have been subscribed to and what coding they perform.

But in order to fully analyse your coding you have to give more information:

1. Declaration and Implementation of methods/event handlers:

  • refresh_grid()
  • handle_hotspot_click()
  • on_data_changed()
  • refresh()

2. Declaration of variables:

  • gr_grid TYPE REF TO cl_gui_alv_grid,
  • custom_container TYPE REF TO cl_gui_custom_container,
  • ot_fieldcat TYPE lvc_t_fcat
  • ot_data TYPE STANDARD TABLE OF ???

3. How are your public methods called?

  • eg. create_cont_grid()

4. How are your class/method attributes filled?

  • ot_fieldcat
  • ot_data

[B] Remarks to your 'Comment':

>>1. Sorting works fine in this Demo Program . Also in the code there is nothing implemented specifically for the sorting. Its a Standard toolbar button and it should work correctly .

So you have to ask yourself, if the Demo Program works fine, why does your program not work fine. Is the problem in the ALV_GRID or in your coding?

>>2. Same behaviour with the Right click also. First Time fine, Second time the dialog box opens.

The "second time" remark lets me believe, that there is some custom coding in between that throws stuff off. Cant put my finger on it yet though.

>> 3. First of all this dialog box should not be coming , secondly if I am doing sorting on one column , why do I need to move all the columns to the sort criteria .

I see where the confusion comes from. I simply meant it as "you need to first move all desired columns from the column set on the left to the sort criteria on the right" (if those desired columns are also available of course). Because you can set more than one sorting criteria, if desired.

4. Clicked the asc sorting on the info record column, that worked fine. Then clicked on the descending button by selecting the same column , dialog box opened, selected descending there, it completely destroyed the sorting neither ascending nor descending .

So a second right click on a column header as well as a second click on the asc/desc button while a column header is selected/marked, always leads to the "destruction of the sorting". Still seems to me, that there is some costum coding happening after the first interaction with the Grid. Please give more details as mentioned in [1].

[C] Community-Guidelines:

a) Please use comment function to comment someones answer, dont post it as answer, when you are clearly just give more information about your problem.

b) Answers will popup in the Inbox of the author of the question, Comments will popup in the Inbox of the author or the answer if it is a comment to an answer (or for the author of the question if it is a comment to the question), adding the user name link of a community user to a question/answer/comment will also popup in the Inbox of that user, just like this would k_sood. Anything else will not popup in the Inbox and you can simply hope, that the person you tried to address, stops by again on accident or purposly in the near future.

c) Please use the "Insert Code" button to format ABAP coding.

k_sood
Active Participant
0 Kudos

Thanks For writing. Enclosed more details. Please let me know , if you miss anything else.

1. Declaration and Implementation of Methods as follows: , did not use the handle_hotspot_click. so its deleted now.
CLASS lcl_purchasing DEFINITION.
  PUBLIC SECTION.
*Grid Objects
    DATA : custom_container TYPE REF TO cl_gui_custom_container,
           mycontainer      TYPE scrfname VALUE 'ALV_CONTAINER',
           gr_grid          TYPE REF TO cl_gui_alv_grid.
*Object Tables
    DATA: ot_fieldcat     TYPE lvc_t_fcat,
          ot_data         TYPE TABLE OF custom_Structure , "Data for ALV
          ot_changed_data TYPE TABLE OF custom_Structure.  "Changed Data for ALV

    DATA: ov_menge_assort TYPE char17,
          ov_menge_actual TYPE char17.

*Event Handling Methods
    METHODS:
      refresh
        FOR EVENT after_refresh   OF cl_gui_alv_grid ,
      on_data_changed
        FOR EVENT data_changed OF cl_gui_alv_grid
        IMPORTING er_data_changed sender .
*Application Instance Methods
    METHODS:
      get_data ,
      prepare_catalog,
      process_pbo,
      calc_title_menge,
      set_titlebar,
      create_cont_grid,
      first_display,
      refresh_grid,
      process_pai,
      save_create_pr,
      create_po,
      get_stock,
      get_range ,
      get_assort_menge IMPORTING iv_lifnr TYPE lifnr
                                 iv_matkl TYPE matkl
                       EXPORTING ev_menge TYPE menge
                       .
ENDCLASS.

CLASS lcl_purchasing IMPLEMENTATION.
  METHOD refresh.
    me->refresh_grid( ).
  ENDMETHOD.

  METHOD on_data_changed.
*This Method is putting the changed rows into the Class Object Table named ot_changed_data.
    FIELD-SYMBOLS: <ls_changed_data> TYPE custom_Structure,
                   <ls_data>         TYPE custom_Structure.
    CHECK er_data_changed->mp_mod_rows IS NOT INITIAL.
    " Execute Further code, only if there are changed rows . 
    LOOP AT er_data_changed->mt_good_cells ASSIGNING FIELD-SYMBOL(<cell>).
      READ TABLE ot_data ASSIGNING <ls_data> INDEX <cell>-row_id.
      IF sy-subrc EQ 0.
        READ TABLE ot_changed_data ASSIGNING <ls_changed_data> INDEX <cell>-row_id.
        IF sy-subrc NE 0.
          APPEND INITIAL LINE TO ot_changed_data ASSIGNING <ls_changed_data>.
          MOVE-CORRESPONDING <ls_data> TO <ls_changed_data>.   "Copying the Original row from Alv Output Table .
          <ls_changed_data>-menge = <cell>-value .             "Putting New Menge Value into the Menge field.
        ELSE.
          MOVE-CORRESPONDING <ls_data> TO <ls_changed_data>.   "Copying the Original row from Alv Output Table .
          <ls_changed_data>-menge = <cell>-value .             "Putting New Menge Value into the Menge field.
        ENDIF.
      ENDIF.
    ENDLOOP.
    " refresh not required at this point.
  ENDMETHOD. "handle_data_changed
  METHOD refresh_grid.
    DATA: ls_stable TYPE lvc_s_stbl.
    REFRESH: ot_data[] . "Output Table is Refreshed to load the data again. 
    me->get_data( ).  "To consider the changed data, read data again from database.
    me->calc_title_menge( ).
    me->set_titlebar( ).
    ls_stable-row = 'X'.
    ls_stable-col = 'X'.
    CALL METHOD gr_grid->refresh_table_display
      EXPORTING
        is_stable      = ls_stable
        i_soft_refresh = 'X'.
  ENDMETHOD.

method get_data.
	"data fetch logic from cds , FuMo etc.
endmethod.

method calc_title_menge.
"Quantity is calculated to be shown in the title.
enemethod.

method set_titlebar.
"Quantity obtained in the previous method is set in the title .
endmethod.
endclass.


2. All the declarations are in the code above .

3. Public method call as follows , All the calls are mostly made from one method to the other of the same class .

   METHOD process_pbo.
    me->create_cont_grid( ).
    CLEAR : ov_menge_actual, ov_menge_assort.
    me->calc_title_menge( ).
    SET PF-STATUS 'STATUS_100'.
    me->set_titlebar( ).
  ENDMETHOD.

  METHOD create_cont_grid.
    IF me->custom_container IS INITIAL.   * create container
      CREATE OBJECT me->custom_container
        EXPORTING
          container_name              = 'MYCONTAINER'
        EXCEPTIONS
          cntl_error                  = 1
          cntl_system_error           = 2
          create_error                = 3
          lifetime_error              = 4
          lifetime_dynpro_dynpro_link = 5.
      IF sy-subrc <> 0.
* Error in creation of cointainer
        MESSAGE e001(messageclass).
      ENDIF.
* create alv grid using the container as parent.
      CREATE OBJECT me->gr_grid
        EXPORTING
          i_parent          = me->custom_container
        EXCEPTIONS
          error_cntl_create = 1
          error_cntl_init   = 2
          error_cntl_link   = 3
          error_dp_create   = 4
          OTHERS            = 5.
      IF sy-subrc <> 0.
* Error in creation of grid
        MESSAGE e002(messageclass).
      ENDIF.
* Trigger first display
      me->first_display( ).
    ELSE.
* Simply Refresh the Grid.
      me->refresh_grid( ).
    ENDIF.
  ENDMETHOD.

METHOD first_display.
*    Displaying the Alv for the First Time .
    DATA : ls_layout  TYPE lvc_s_layo,
           ls_variant TYPE disvariant,
           lv_repid   TYPE repid.
    DATA ls_exclude TYPE ui_func.
    DATA lt_toolbar_excluding TYPE ui_functions.
*Excluding Unnecessary Standard Toolbar Buttons
    ls_exclude = cl_gui_alv_grid=>mc_fc_loc_append_row.
    APPEND ls_exclude TO lt_toolbar_excluding.
    ls_exclude = cl_gui_alv_grid=>mc_fc_loc_delete_row.
    APPEND ls_exclude TO lt_toolbar_excluding.
    ls_exclude = cl_gui_alv_grid=>mc_fc_loc_insert_row.
    APPEND ls_exclude TO lt_toolbar_excluding.
    ls_exclude = cl_gui_alv_grid=>mc_fc_check.
    APPEND ls_exclude TO lt_toolbar_excluding.
    ls_exclude = cl_gui_alv_grid=>mc_fc_loc_copy_row.
    APPEND ls_exclude TO lt_toolbar_excluding.
    ls_exclude = cl_gui_alv_grid=>mc_fc_loc_cut.
    APPEND ls_exclude TO lt_toolbar_excluding.
    ls_exclude = cl_gui_alv_grid=>mc_fc_loc_copy.
    APPEND ls_exclude TO lt_toolbar_excluding.
    ls_exclude = cl_gui_alv_grid=>mc_fc_loc_undo.
    APPEND ls_exclude TO lt_toolbar_excluding.
    ls_exclude = cl_gui_alv_grid=>mc_fc_info.
    APPEND ls_exclude TO lt_toolbar_excluding.
    ls_exclude = cl_gui_alv_grid=>mc_fc_views.
    APPEND ls_exclude TO lt_toolbar_excluding.
*    Following Two are to Exclude the Insert with Overwrite Combi Button
    ls_exclude = cl_gui_alv_grid=>mc_fc_loc_paste_new_row .
    APPEND ls_exclude TO lt_toolbar_excluding.
    ls_exclude = cl_gui_alv_grid=>mc_fc_loc_paste .
    APPEND ls_exclude TO lt_toolbar_excluding.

    lv_repid = sy-repid .
    ls_variant-report = lv_repid.
    ls_layout-zebra = 'X' .
    ls_layout-smalltitle = 'X'.

*First Display of ALV .
    CALL METHOD gr_grid->set_table_for_first_display
      EXPORTING
        is_variant                    = ls_variant
        is_layout                     = ls_layout
        i_default                     = 'X'   "with X users can save default Layouts. If its space , users can not save default layouts.  If a default Layout Exists, it will be loaded automatically.
        i_save                        = 'A'   "Space: layouts cannot be saved . U: only user Defined Layouts. X: Only Global Layouts. A: Both User defined and Global layouts.
        it_toolbar_excluding          = lt_toolbar_excluding
      CHANGING
        it_fieldcatalog               = ot_fieldcat[]
        it_outtab                     = ot_data
      EXCEPTIONS
        invalid_parameter_combination = 1
        program_error                 = 2
        too_many_lines                = 3
        OTHERS                        = 4.
    IF sy-subrc NE 0.
* Error in Display of grid
      MESSAGE e005(messageclass).
    ENDIF.
*Assign Class to Event Handler.
    SET HANDLER me->on_data_changed FOR gr_grid.
    SET HANDLER me->refresh FOR gr_grid .


  ENDMETHOD.


4. Fieldcatalog is filled in the following method , Ot_data is filled in the method get_data , which fetches the data from a cds view and some FuModules.

  METHOD prepare_catalog.
* Field Catalog to display the fields is prepared here.
    CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'
      EXPORTING
        i_structure_name       = 'custom_structure'
      CHANGING
        ct_fieldcat            = ot_fieldcat
      EXCEPTIONS
        inconsistent_interface = 1
        program_error          = 2
        OTHERS                 = 3.
    IF sy-subrc <> 0.
* error handling
      MESSAGE e005(messageclass).
    ENDIF.
    LOOP AT ot_fieldcat ASSIGNING FIELD-SYMBOL(<ls_fcat>).
      <ls_fcat>-col_opt = 'X'.
      CASE <ls_fcat>-fieldname.
        WHEN 'MENGE'.
          <ls_fcat>-edit = 'X'.
          <ls_fcat>-do_sum = 'X' .
        WHEN 'LABST'.
          <ls_fcat>-do_sum = 'X' .
        WHEN 'MENGE_PO'.
          <ls_fcat>-do_sum = 'X' .
        WHEN 'RES' .
          <ls_fcat>-do_sum = 'X' .
        WHEN 'VERBR_THIS' .
          <ls_fcat>-do_sum = 'X' .
        WHEN 'VERBR_LAST'.
          <ls_fcat>-do_sum = 'X' .
        WHEN 'FORECAST'.
          <ls_fcat>-do_sum = 'X' .
        WHEN 'INFNR'.
*Fields not to display .
        WHEN 'VERBR_YTD' .
          <ls_fcat>-no_out = 'X' .
          <ls_fcat>-tech = 'X' .
      ENDCASE.
    ENDLOOP.
  ENDMETHOD.


k_sood
Active Participant
0 Kudos

I commented out the following call and Sorting is working fine. You were Right , problem was with the Refresh. Thanks a lot .

I have the Standard Refresh button in the toolbar Visible and The data has to be refreshed in the alv on the click of this button. Is the call to the method refresh_table_display not correct ? or the event is not correct ?

METHOD refresh.
*  me->refresh_grid( ).
  ENDMETHOD.

k_sood
Active Participant
0 Kudos

Thanks Michael, I am able to resolve the issue. I was using the Event after_refresh to refresh my alv , that was probably not the righ thing. So now created a custom button event and did the refresh of my data on that button click.

*Declaration of two new methods
      handle_toolbar
        FOR EVENT toolbar OF cl_gui_alv_grid
        IMPORTING e_object e_interactive ,
      handle_user_command
        FOR EVENT user_command OF cl_gui_alv_grid
        IMPORTING e_ucomm.
 Implementation.

  METHOD handle_toolbar.
    DATA: ls_toolbar  TYPE stb_button.

* append a separator to normal toolbar
    CLEAR ls_toolbar.
    MOVE 3 TO ls_toolbar-butn_type.
    APPEND ls_toolbar TO e_object->mt_toolbar.

    CLEAR ls_toolbar.
    MOVE 'REFR' TO ls_toolbar-function.
    MOVE icon_refresh  TO ls_toolbar-icon.
    MOVE 'REFRESH' TO ls_toolbar-quickinfo.
    MOVE 'REFRESH' TO ls_toolbar-text.
    MOVE ' ' TO ls_toolbar-disabled.
    APPEND ls_toolbar TO e_object->mt_toolbar.
  ENDMETHOD.
  METHOD handle_user_command.
    CASE e_ucomm.
      WHEN 'REFR'.
        me->refresh_grid( ).
    ENDCASE.
  ENDMETHOD.

k_sood
Active Participant
0 Kudos

Refered program

BCALV_GRID_05

to add the custom Button.

k_sood
Active Participant
0 Kudos
Any further Idea ?

Br,

KS

Sandra_Rossi
Active Contributor
0 Kudos

Please use the COMMENT button for comments, questions, adding details, etc., ANSWER is only to propose a solution, dixit SAP text at the right of the answer area.

Sandra_Rossi
Active Contributor
0 Kudos

Did you look for a patch in the SAP notes?

Sandra_Rossi
Active Contributor
0 Kudos

As you say that BCALV_GRID_DEMO program is fine, there's probably no bug so no patch.

So, the simplest thing you have to do is to compare your program and BCALV_GRID_DEMO, and simplify your code until your program works, and you'll locate the issue.

k_sood
Active Participant

With the help of Michael , I was able to resolve the issue. Instead of the standard Refresh Event , I created a custom refresh button and did the data retrieval and other tasks on the click of that button .