Application Development and Automation 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: 
Read only

Sorting Issue for ALV Splitter

Former Member
0 Likes
9,478

My ALV report, once double click on header, the line item will show.

When i tried to sort by header, once double clicked (on header), it is not showing correct line item (image).

Form SORT.     

DATA: NO TYPE I VALUE 1.

  IF G_GRID_LEFT IS NOT INITIAL.   <<<< value for SPOS FIELDNAME was showing

    CLEAR gt_sort.

    GS_SORT-SPOS = NO.

    GS_SORT-FIELDNAME = 'EBELN'.

    GS_SORT-DOWN = 'X'.

    APPEND GS_SORT TO GT_SORT.


  ELSEIF g_grid_right IS NOT INITIAL.   <<< during debug it skips this part, as ebeln is key field

    CLEAR gt_sort.

    GS_SORT-SPOS = NO.

    GS_SORT-FIELDNAME = 'EBELN'.

    GS_SORT-DOWN = 'X'.

    APPEND GS_SORT TO GT_SORT.

  ENDIF.


ENDFORM.

The purchasing doc number (between header and line item) are sharing the same key, when double clicked by right line item should show relevant purchasing document item details (as shown before perform SORT was added into the program)

Program: https://www.mediafire.com/file/v0tlqnarkogm1ov/ALV_Program.docx/file

My ALV report, once double click on header, the line item will show.

When i tried to sort by header, once double clicked (on header), it is not showing correct line item (image).

Form SORT.     

DATA: NO TYPE I VALUE 1.

  IF G_GRID_LEFT IS NOT INITIAL.   <<<< value for SPOS FIELDNAME was showing

    CLEAR gt_sort.

    GS_SORT-SPOS = NO.

    GS_SORT-FIELDNAME = 'EBELN'.

    GS_SORT-DOWN = 'X'.

    APPEND GS_SORT TO GT_SORT.


  ELSEIF g_grid_right IS NOT INITIAL.   <<< during debug it skips this part, as ebeln is key field

    CLEAR gt_sort.

    GS_SORT-SPOS = NO.

    GS_SORT-FIELDNAME = 'EBELN'.

    GS_SORT-DOWN = 'X'.

    APPEND GS_SORT TO GT_SORT.

  ENDIF.


ENDFORM.

The purchasing doc number (between header and line item) are sharing the same key, when double clicked by right line item should show relevant purchasing document item details (as shown before perform SORT was added into the program)

Program: https://www.mediafire.com/file/v0tlqnarkogm1ov/ALV_Program.docx/file

20 REPLIES 20
Read only

Sandra_Rossi
Active Contributor
0 Likes
9,370

Please attach file inside SAP forum, otherwise it may disappear in the future.

Read only

Former Member
9,370

Source code attached


Read only

Former Member
0 Likes
9,370

Create method

value( IT_ZHEADER )	TYPE ZEKKO03_TT	PO Header Table Type - importing
value( IT_ZITEMS )	TYPE ZEKPO03_TT	PO Item Table Type - importing
value( ES_BAPIRET2 )	TYPE BAPIRET2	Return Parameter - exporting


METHOD CREATE_PURCHASE_ORDERS.
    DATA: ls_zheader LIKE LINE OF it_zheader,
          ls_zitems LIKE LINE OF it_zitems.

      append ls_zheader TO IT_ZHEADER.

      modify zekko03 FROM TABLE it_zheader .
        IF SY-SUBRC = 0.
          COMMIT WORK.
          ES_BAPIRET2-TYPE = 'S'.
          ES_BAPIRET2-MESSAGE = 'Successfully updated for table ZEKKO03'.

        ELSE.
          ROLLBACK WORK.
          ES_BAPIRET2-TYPE = 'E'.
          ES_BAPIRET2-MESSAGE = 'Error updating table ZEKKO03'.
        ENDIF.


       append ls_zitems TO IT_ZITEMS.


       modify zekpo03 FROM TABLE it_zitems.
        IF SY-SUBRC = 0.
          COMMIT WORK.
          ES_BAPIRET2-TYPE = 'S'.
          ES_BAPIRET2-MESSAGE = 'Successfully updated for table ZEKKO03'.


        ELSE.
          ROLLBACK WORK.
          ES_BAPIRET2-TYPE = 'E'.
          ES_BAPIRET2-MESSAGE = 'Error updating table ZEKKO03'.
        ENDIF.
  ENDMETHOD.

delete method

value( IV_IS_DELETE_ALL )	TYPE BOOLEAN OPTIONAL	Purchasing Document Number - impoting
value( IT_ZHEADER )	TYPE ZEKKO03_TT	PO Header Table Type - importing
value( IT_ZITEMS )	TYPE ZEKPO03_TT	PO Item Table Type - importing
value( ES_BAPIRET2 )	TYPE BAPIRET2	Return Parameter - exporting

METHOD DELETE_PURCHASE_ORDERS.


    DATA: LS_ZHEADER     TYPE ZEKKO03,
          LS_ZITEMS      TYPE ZEKPO03,
          LV_COUNT_HDR   TYPE I,
          LV_COUNT_ITEMS TYPE I.


    IF IV_IS_DELETE_ALL = 'X' OR IV_IS_DELETE_ALL = 'x' .
      DELETE FROM ZEKKO03.
      DELETE FROM ZEKPO03.


      IF SY-SUBRC = 0.
        ES_BAPIRET2-TYPE = 'S'.
        ES_BAPIRET2-MESSAGE = 'All records deleted'.


      ENDIF.


    ELSE.
      LOOP AT IT_ZHEADER INTO LS_ZHEADER.
        SELECT COUNT(*) INTO LV_COUNT_HDR FROM ZEKPO03
          WHERE EBELN = LS_ZHEADER-EBELN.
      ENDLOOP.


            IF LV_COUNT_HDR = 1.


        DELETE FROM ZEKPO03 WHERE EBELN EQ LS_ZHEADER-EBELN.
        DELETE FROM ZEKKO03 WHERE EBELN EQ LS_ZHEADER-EBELN.


        IF SY-SUBRC = 0.
          ES_BAPIRET2-TYPE = 'S'.
          ES_BAPIRET2-MESSAGE = 'Record successfully deleted'.


        ELSE.
          ES_BAPIRET2-TYPE = 'E'.
          ES_BAPIRET2-MESSAGE = 'Error deleting record'.
        ENDIF.
      ENDIF.
    ENDIF.
  ENDMETHOD.

select method

value( IV_KEY )	TYPE ZEBELN_EMNT OPTIONAL	Purchasing Document Number - importing
value( IV_MAX_ROWS )	TYPE I  DEFAULT 0	0 - means load ALL - importing
value( IT_ZHEADER )	TYPE ZEKKO03_TT	PO Header - exporting
value( IT_ZITEMS )	TYPE ZEKPO03_TT	PO Line Item - exporting
value( ES_BAPIRET2 )	TYPE BAPIRET2	Return Parameter - exporting

    DATA: LS_ZHEADER TYPE ZEKKO03.


    IF IV_KEY IS INITIAL .


      SELECT MANDT EBELN BEDAT BSART LIFNR WAERS KNUMV
        INTO TABLE IT_ZHEADER
        FROM ZEKKO03
        WHERE EBELN EQ IV_KEY.


      IF SY-SUBRC = 0.


        IF IV_MAX_ROWS GT 0.


          SELECT MANDT EBELN BEDAT BSART LIFNR WAERS KNUMV
            FROM ZEKKO03 INTO TABLE IT_ZHEADER
            UP TO IV_MAX_ROWS ROWS.


          SELECT MANDT EBELN EBELP BUKRS WERKS MATNR MENGE MEINS NETPR
            FROM ZEKPO03 INTO TABLE IT_ZITEMS UP TO IV_MAX_ROWS ROWS
            WHERE EBELN EQ IV_KEY.


          ES_BAPIRET2-TYPE = 'S'.
          ES_BAPIRET2-MESSAGE = 'Record with input rows found'.


        ELSEIF IV_MAX_ROWS EQ 0.


          SELECT MANDT EBELN EBELP BUKRS WERKS MATNR MENGE MEINS NETPR
            FROM ZEKPO03 INTO TABLE IT_ZITEMS
            WHERE EBELN EQ IV_KEY.


          ES_BAPIRET2-TYPE = 'S'.
          ES_BAPIRET2-MESSAGE = 'All records found'.


        ELSE .
          ES_BAPIRET2-TYPE = 'E'.
          ES_BAPIRET2-MESSAGE = 'No record found'.
        ENDIF.


      ELSE.     "this statement belongs to sy-subrc (all above are fulfilled)


        SELECT MANDT EBELN BEDAT BSART LIFNR WAERS KNUMV
          FROM ZEKKO03 INTO TABLE IT_ZHEADER
          UP TO IV_MAX_ROWS ROWS.


        LOOP AT IT_ZHEADER INTO LS_ZHEADER.   ""join line item to header
          SELECT MANDT EBELN EBELP BUKRS WERKS MATNR MENGE MEINS NETPR
            FROM ZEKPO03 APPENDING TABLE IT_ZITEMS
            WHERE EBELN EQ LS_ZHEADER-EBELN.
        ENDLOOP.
      ENDIF.
    ELSE.
      SELECT MANDT EBELN EBELP BUKRS WERKS MATNR MENGE MEINS NETPR      """added for ALV program
        INTO TABLE IT_ZITEMS
        FROM ZEKPO03
        WHERE EBELN EQ IV_KEY.
      SELECT MANDT EBELN BEDAT BSART LIFNR WAERS KNUMV                  """" added for ALV program
        INTO TABLE IT_ZHEADER
        FROM ZEKKO03
        WHERE EBELN EQ IV_KEY.
    ENDIF.

reload method

  METHOD RELOAD_PURCHASE_ORDERS.


    DATA: IT_EKKO TYPE TABLE OF ZEKKO03,
          IT_EKPO TYPE TABLE OF ZEKPO03.




      SELECT MANDT EBELN BEDAT BSART LIFNR WAERS KNUMV
      FROM EKKO INTO CORRESPONDING FIELDS OF TABLE IT_EKKO.
      INSERT ZEKKO03 FROM TABLE IT_EKKO ACCEPTING DUPLICATE KEYS.


      IF SY-SUBRC = 0.
        ES_BAPIRET2-TYPE = 'S'.
        ES_BAPIRET2-ID = 'HDRSuccess'.
        ES_BAPIRET2-MESSAGE = 'Data with specified row reloaded into tables'.
      ENDIF.




      SELECT MANDT EBELN EBELP BUKRS WERKS MATNR MENGE MEINS NETPR
   FROM EKPO INTO CORRESPONDING FIELDS OF TABLE IT_EKPO.
      INSERT ZEKPO03 FROM TABLE IT_EKPO ACCEPTING DUPLICATE KEYS.


      IF SY-SUBRC = 0.
        ES_BAPIRET2-TYPE = 'S'.
        ES_BAPIRET2-ID = 'LINESucces'.
        ES_BAPIRET2-MESSAGE = 'Data with specified row reloaded into tables'.
      ENDIF.

  ENDMETHOD.



Read only

Sandra_Rossi
Active Contributor
0 Likes
9,370

In fact, I don't understand what symptom you have, how to reproduce, and what you expect.

Let me rephrase:

  • 1) You: My ALV report, once double click on header, the line item will show.
  • I: You mean, you have on screen with two ALV, the left one contains the headers, and once you double click on one line of ALV headers, the right ALV displays the details of the selected line.
  • 2) You: When i tried to sort by header, once double clicked (on header), it is not showing correct line item (image).
  • I: You mean, your program sorts automatically the ALV of headers by the column EBELN. You say "It is not showing" in the ALV of details, then could you explain what it's showing? How is it related to the "sorting issue"?
  • 3) You: The purchasing doc number (between header and line item) are sharing the same key, when double clicked by right line item should show relevant purchasing document item details (as shown before perform SORT was added into the program)
  • I: I don't understand what means "double clicked by right line item" because your program handles only the double click of your left ALV of headers.

Note that I don't understand your double click handler method, why do you use the method GET_SELECTED_ROWS instead of using the parameter E_ROW which contains the number of the double-clicked line? Why do you call the method select_purchase_orders 5 times? Why do you need to refresh the left ALV of headers? (only the right ALV of details needs to be refreshed - keep things simple)

Read only

Former Member
0 Likes
9,370

1. Yes

2. Attached image, it is showing the wrong line item (wrong-line-item.png)

3. once performed double click on header, it should show relevant line item

why do you use the method GET_SELECTED_ROWS

im get_selected_rows has ET_ROW_NO with allows to read row_id, read by index is not applicable for double click in pmy program previously

didnt manage to find a good sample for double click that is applicable to my program

Why do you call the method select_purchase_orders 5 times?

Here is the debug result for delete method - debug 1 through 4 images

Refresh left ALV is needed for the delete record to reflect at runtime. If removed the refresh, it will not reflect at runtime but only removed the record in database table zekko03

Read only

Former Member
0 Likes
9,370

Rest of screenshots.

Read only

Former Member
0 Likes
9,370

Sorry i uploaded several images due to limited space

Read only

Sandra_Rossi
Active Contributor
0 Likes
9,370

So it's not a sorting issue. It's just that you don't select the right line. Why don't you use the parameter E_ROW instead of GET_SELECTED_ROWS? (NB: in debug, you should find out the reason why the wrong line is retrieved, we can't do that for you)

Don't refresh left ALV of headers if one of its lines is double clicked. Refresh left ALV only if a line from database table ZEKKO03 is actually deleted. I advise to not reload the whole internal table, just delete the corresponding line of the internal table.

Read only

Former Member
0 Likes
9,370

Yes im not refreshing the left grid (for double click) and I made changes to E_ROW as well, still the same result as previous one (with get_selected_row) where it retrieved the wrong line

  METHOD  HANDLE_DOUBLE_CLICK.

*   define local data
    DATA:
      LT_ZHEADER TYPE TABLE OF ZEKKO03,
      LT_ZITEMS2 TYPE TABLE OF ZEKPO03,
      LS_ZHEADER TYPE ZEKKO03,
      LS_ZITEMS2 LIKE LINE OF LT_ZITEMS2.       """ like line of applicable to structure for ztables

    IF e_row-index gt 0.

          CALL METHOD ZCL_03_DATA_MODEL=>SELECT_PURCHASE_ORDERS     """ PO selection to get total number of record on header in the db table
            EXPORTING
*             IV_KEY      =
              IV_MAX_ROWS = IV_MAX_ROWS
            IMPORTING
              IT_ZHEADER  = LT_ZHEADER   .

          READ TABLE LT_ZHEADER INDEX e_row-index INTO LS_ZHEADER.

          CALL METHOD ZCL_03_DATA_MODEL=>SELECT_PURCHASE_ORDERS           """""select line items based on header
            EXPORTING
              IV_KEY    = LS_Zheader-EBELN
*             IV_MAX_ROWS =
            IMPORTING
*             IT_ZHEADER  =
              IT_ZITEMS = LT_ZITEMS2
*             ES_BAPIRET2 =
            .
     ENDIF.

        GT_ZITEMS = LT_ZITEMS2.
        G_GRID_RIGHT->REFRESH_TABLE_DISPLAY( ).    <br>

I already have a key LS_Zheader-EBELN

    CLASS-METHODS:
      HANDLE_DOUBLE_CLICK FOR EVENT DOUBLE_CLICK OF CL_GUI_ALV_GRID
        IMPORTING
          E_ROW
          E_COLUMN.<br>

With e_row and e_column defined, what else have i missed?

Read only

Former Member
0 Likes
9,370

The debug result shown as retrieved the wrong line (deb1.png to deb3.png3)

Read only

Sandra_Rossi
Active Contributor
9,370

With E_ROW-INDEX, why do you access another internal table than the one of the left ALV? It's then normal that the line which is read doesn't correspond to the one in the left ALV.

READ TABLE GT_ZHEADER INDEX e_row-index INTO LS_ZHEADER.
Read only

MateuszAdamus
Active Contributor
0 Likes
9,370

Hi arnold92

The issue is that you're reading data from DB again into the LT_ZHEADER internal table. When you do that, you're losing the sorting that was done in ALV, thus reading record with index gives you an incorrect results.

Make an instance variable in your class called for example AT_ZHEADER (a for attribute) and read the PO data into the table only once, when you're loading your program.

Do the same for items.

This way your program will work faster (no multiple DB reads) and you won't have to refresh the data in every method.

When you remove the DB refresh you should also have a proper result of your HANDLE_DOUBLE_CLICK method.

Hope this helps.

regards,

Mateusz

Read only

0 Likes
9,370

Hi Mateusz,

Sorry im still new to this and worth learning, do you mean doing it in this way? Meaning i have to change all method to instance method? im using static method

CLASS LCL_EVENTHANDLER DEFINITION." class definition

  PUBLIC SECTION.

    CLASS-METHODS:
      HANDLE_DOUBLE_CLICK FOR EVENT DOUBLE_CLICK OF CL_GUI_ALV_GRID
        IMPORTING
          E_ROW
          E_COLUMN
          ES_ROW_NO
          SENDER.
    
    DATA: AT_ZHEADER TYPE ZEKKO03.


ENDCLASS.         <br>
CLASS LCL_EVENTHANDLER IMPLEMENTATION." implementation
  METHOD  HANDLE_DOUBLE_CLICK.

*   define local data
    DATA:
      LT_ZHEADER TYPE TABLE OF ZEKKO03,
      LT_ZITEMS2 TYPE TABLE OF ZEKPO03,
      LS_ZHEADER TYPE ZEKKO03,
      LS_ZITEMS2 LIKE LINE OF LT_ZITEMS2.       """ like line of applicable to structure for ztables

    IF e_row-index gt 0.


           READ TABLE AT_ZHEADER INDEX e_row-index INTO LS_ZHEADER.   """use ALV internal table to perform read data

          CALL METHOD ZCL_03_DATA_MODEL=>SELECT_PURCHASE_ORDERS           """""select line items based on header
            EXPORTING
              IV_KEY    = LS_Zheader-EBELN
*             IV_MAX_ROWS =
            IMPORTING
*             IT_ZHEADER  =
              IT_ZITEMS = LT_ZITEMS2
*             ES_BAPIRET2 =
            .
     ENDIF.<br>

Read only

0 Likes
9,370

Hi arnold92

No worries. 🙂 We've all been there some time ago.

Sure, you can make it an instance attribute and change the methods to instance. You can also make the attributes static and keep on using the static methods.

It really depends on the requirements and logic of the report you're working on. As this is a test report, as far as I understand, then keep everything static, just to save time and not change everything.

regards,

Mateusz

Read only

0 Likes
9,370

Ive been using static method since the beginning for this test report, so what you are suggesting "instance variable " only applicable to instance method and not static?

Read only

0 Likes
9,370

Yes, you need to have an instance to be able to use an instance variable. Since you only have static methods, then I don't think you have an instance of your object.
In this case just make the attributes static, for the purpose of this learning exercise it will be just fine.

regards,

Mateusz

Read only

9,370

arnold92 Refactoring the code so that it's coded according to best practice is maybe not the priority for you, because you should first make the program work.

But of course, in the end, Mateusz is right. If you write object-oriented code, you should also write the whole "view" part inside a class. Currently you only defined a "model" class to work with the database. But be careful to not mix information from the view and from the model. AT_ZHEADER is part of the "view". Note that LCL_EVENTHANDLER should be merged into the view class.

In the Model-View-Control design, you also have the controller class to control what view is to be displayed and so on.

Finally, your report should just have one line of code to invoke the controller class.

Read only

0 Likes
9,370

Sorry to ask again, if im using static method, then im not able to do what you are saying as below?

" Make an instance variable in your class called for example AT_ZHEADER (a for attribute) and read the PO data into the table only once, when you're loading your program.

Do the same for items.

This way your program will work faster (no multiple DB reads) and you won't have to refresh the data in every method."

Read only

9,370

Hi arnold92

Yes, you're not able to do it, because an instance variable requires an object instance to exits. If you don't have an instance of an object, then instance variable defined for this object (in the class) won't exist either.

However, in your case, you can define the AT_ZHEADER and AT_ZITEMS attributes as static and it will be fine.

I urge to read about instance and static attributes/methods, for example this article: https://help.sap.com/doc/abapdocu_752_index_htm/7.52/en-us/abenclass_attributes.htm

regards,

Mateusz

Read only

Former Member
0 Likes
9,370

Thank you for rectifying, it is working now.