作者:​sap侠之大者​


CL_GUI_ALV_TREE 和CL_GUI_ALV_GRID的ON_DRAG、ON_DROP 事件来实现相应的拖拽功能。

ALV Grid的示例程序如下,此程序可以通过拖拽来改变ALV控件数据行的顺序:



1、创建一个600屏幕,只需一个屏幕元素OK_CODE即可



2、创建一个gui status,命名为STATUS,增加对退出按钮的相应



*&---------------------------------------------------------------------*
*& Report  YZ_TEST32
*&
*&---------------------------------------------------------------------*
*&copy from SAPTechnical.com
*&ALV report with drag and drop functionality on its rows
*&---------------------------------------------------------------------*

REPORT  YZ_TEST32 .

*Structure declaration for T016T
TYPES  :  BEGIN  OF TY_T016T ,
                  BRSCH  TYPE BRSCH ,
                  BRTXT  TYPE TEXT1_016T ,
                  SPRAS  TYPE SPRAS ,
                  END  OF TY_T016T .
*Work area and internal table for  T016T
DATA  : IT_T016T  TYPE  STANDARD  TABLE  OF TY_T016T ,
              WA_T016T  TYPE TY_T016T .
DATA OK_CODE  LIKE SY -UCOMM .
*class declaration
CLASS LCL_OBJDRAGDROPAPP  DEFINITION DEFERRED .
*data declarations for alv
DATA :   C_DRAGDROPAPP  TYPE  REF  TO LCL_OBJDRAGDROPAPP ,
                C_DOCKINGCONT  TYPE  REF  TO CL_GUI_DOCKING_CONTAINER ,
                C_ALV  TYPE  REF  TO CL_GUI_ALV_GRID ,
* reference variable to CL_DRAGDROP:
                C_DRAGDROPALV  TYPE  REF  TO CL_DRAGDROP ,
                IT_LAYOUT  TYPE LVC_S_LAYO ,
                IT_FCAT    TYPE LVC_T_FCAT .             "Field catalogue
*declarations for handle event
DATA :   EFFECT  TYPE  I ,
                HANDLE_ALV  TYPE  I .
*initialization event
INITIALIZATION .
*start of selection event
START-OF-SELECTION .
*select data
    PERFORM FETCH_DATA .
*ALV output
    PERFORM ALV_OUTPUT .
* Class definitions and method implementation for drag and drop
CLASS LCL_DRAGDROP  DEFINITION .
    PUBLIC  SECTION .
        DATA : WA  TYPE TY_T016T ,
                    INDEX  TYPE  I .    "Index of Line to be moved
ENDCLASS .                     "LCL_DRAGDROP DEFINITION
*Application class definition
CLASS LCL_OBJDRAGDROPAPP  DEFINITION .
    PUBLIC  SECTION .
        METHODS :
*Handling Event Drag
            HANDLE_ALV_DRAG
                FOR  EVENT ONDRAG
                OF CL_GUI_ALV_GRID
                IMPORTING E_ROW  E_COLUMN  E_DRAGDROPOBJ ,
*Handling event DROP
            HANDLE_ALV_DROP
                FOR  EVENT ONDROP
                OF CL_GUI_ALV_GRID
                IMPORTING E_ROW  E_COLUMN  E_DRAGDROPOBJ .
ENDCLASS .                     "LCL_objdragdropapp DEFINITION
*Application class implementation
CLASS LCL_OBJDRAGDROPAPP  IMPLEMENTATION .
*  OnDrag event is used to 'fetch' information from the drag source.
    METHOD HANDLE_ALV_DRAG .
        DATA : DATAOBJ  TYPE  REF  TO LCL_DRAGDROP ,
                    LINE  TYPE TY_T016T .
* Read dragged row
        READ  TABLE IT_T016T  INDEX E_ROW - INDEX  INTO  LINE .
* create and fill dataobject for events ONDROP
        CREATE OBJECT  DATAOBJ .
* Remembering row index to move a line
        MOVE E_ROW - INDEX  TO DATAOBJ -> INDEX .
* store the dragged line.
        READ  TABLE IT_T016T  INTO DATAOBJ ->WA  INDEX E_ROW - INDEX .
* Assigning data object to the refering event parameter
        E_DRAGDROPOBJ ->OBJECT  = DATAOBJ .
    ENDMETHOD .                     "HANDLE_ALV_DRAG
*Event handler for event 'OnDrop'. This event is used
*to use your dragged information in combination with your drop source.
    METHOD HANDLE_ALV_DROP .
        DATA : DATAOBJ  TYPE  REF  TO LCL_DRAGDROP ,
                    DROP_INDEX  TYPE  I ,
                    STABLE  TYPE LVC_S_STBL .
* Refresh Alv Grid Control without scrolling
        STABLE -ROW  =  'X' .
        STABLE -COL  =  'X' .
* Catch-Statement to ensure the drag&drop-Operation is aborted properly.
        CATCH  SYSTEM-EXCEPTIONS MOVE_CAST_ERROR  =  1 .
            DATAOBJ  ?=  E_DRAGDROPOBJ ->OBJECT .
            DELETE IT_T016T  INDEX DATAOBJ -> INDEX .
            INSERT DATAOBJ ->WA  INTO IT_T016T  INDEX E_ROW - INDEX .
*Refreshing the ALV
            CALL  METHOD C_ALV ->REFRESH_TABLE_DISPLAY
                EXPORTING
                    I_SOFT_REFRESH  =  'X'
                    IS_STABLE            = STABLE .
        ENDCATCH .
        IF SY -SUBRC  <>  0 .
* If anything went wrong aborting the drag and drop operation:
            CALL  METHOD E_DRAGDROPOBJ ->ABORT .
        ENDIF .
    ENDMETHOD .                     "HANDLE_ALV_DROP
ENDCLASS .                     "LCL_objdragdropapp IMPLEMENTATION
*&---------------------------------------------------------------------*
*&      Form  alv_output
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM ALV_OUTPUT  .
    CALL  SCREEN  600 .
ENDFORM .                     " alv_output
** Calling the ALV screen with custom container
*On this statement double click  it takes you to the screen painter SE51.
*Enter the attributes
*Create a Custom container and name it CC_CONT and OK code as OK_CODE.
*Save check and Activate the screen painter.
*Now a normal screen with number 600 is created which holds the ALV grid.
* PBO of the actual screen ,Here we can give a title and customized menus
*&---------------------------------------------------------------------*
*&      Module  STATUS_0600  OUTPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE STATUS_0600  OUTPUT .
    SET  PF-STATUS  'STATUS' .
*  SET TITLEBAR 'xxx'.
    IF C_ALV  IS  INITIAL .
        PERFORM ALV_CONTROLS .
    ENDIF .
ENDMODULE .                  " STATUS_0600  OUTPUT
*&---------------------------------------------------------------------*
*&      Form  alv_CONTROLS
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM ALV_CONTROLS .
* create docking container for alv control
    CREATE OBJECT  C_DOCKINGCONT
        EXPORTING
                DYNNR  =  '600'
                EXTENSION  =  300
                SIDE  = CL_GUI_DOCKING_CONTAINER =>DOCK_AT_TOP .
* create alv control
    CREATE OBJECT  C_ALV
          EXPORTING I_PARENT  = C_DOCKINGCONT .
* create the application object to handle the ABAP Objects Events
    CREATE OBJECT  C_DRAGDROPAPP .
* Events alv control
*For Dragging
    SET  HANDLER C_DRAGDROPAPP ->HANDLE_ALV_DRAG  FOR C_ALV .
*For Dropping
    SET  HANDLER C_DRAGDROPAPP ->HANDLE_ALV_DROP  FOR C_ALV .
* build tree nodes for drag&drop
    PERFORM BUILD_HANDLE .
* Fieldcatalogue for ALV
    PERFORM ALV_BUILD_FIELDCAT .
* ALV attributes FOR LAYOUT
    PERFORM ALV_REPORT_LAYOUT .
* Call ALV GRID
    CALL  METHOD C_ALV ->SET_TABLE_FOR_FIRST_DISPLAY
        EXPORTING
            IS_LAYOUT                                          = IT_LAYOUT
        CHANGING
            IT_OUTTAB                                          = IT_T016T
            IT_FIELDCATALOG                              = IT_FCAT
        EXCEPTIONS
            INVALID_PARAMETER_COMBINATION  =  1
            PROGRAM_ERROR                                  =  2
            TOO_MANY_LINES                                =  3
            OTHERS                         =  4 .
    IF SY -SUBRC  <>  0 .
        MESSAGE  ID SY -MSGID  TYPE SY -MSGTY  NUMBER SY -MSGNO
                              WITH SY -MSGV1  SY -MSGV2  SY -MSGV3  SY -MSGV4 .
    ENDIF .
ENDFORM .                                "ALV_CONTROLS
*&---------------------------------------------------------------------*
*&      Form  build_handle
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM BUILD_HANDLE .
* define a drag & Drop behaviour for the whole grid
    CREATE OBJECT  C_DRAGDROPALV .
    EFFECT  = CL_DRAGDROP => MOVE +  CL_DRAGDROP => COPY .
    CALL  METHOD C_DRAGDROPALV -> ADD
        EXPORTING
            FLAVOR          =  'Line'
            DRAGSRC        =  'X'
            DROPTARGET  =  'X'
            EFFECT          = EFFECT .
*getting the handle for drag and drop
    CALL  METHOD C_DRAGDROPALV ->GET_HANDLE
        IMPORTING
            HANDLE  = HANDLE_ALV .
ENDFORM .                                " build_handle
*&---------------------------------------------------------------------*
*&      Form  fetch_data
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM FETCH_DATA  .
* select and display data from t016
    SELECT BRTXT  BRSCH  SPRAS  FROM T016T  INTO CORRESPONDING  FIELDS  OF  TABLE IT_T016T
    WHERE SPRAS  =  'EN' .
ENDFORM .                     " fetch_data
*&---------------------------------------------------------------------*
*&      Form  alv_report_layout
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM ALV_REPORT_LAYOUT  .
    IT_LAYOUT -GRID_TITLE  =  'ALV Drag Drop' .
* provide handle to alv control to all rows for same drag & drop behaviour
    IT_LAYOUT -S_DRAGDROP -ROW_DDID  = HANDLE_ALV .
ENDFORM .                     " alv_report_layout
*&---------------------------------------------------------------------*
*&      Form  alv_build_fieldcat
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM ALV_BUILD_FIELDCAT  .
    DATA LV_FLDCAT  TYPE LVC_S_FCAT .
    CLEAR LV_FLDCAT .
    LV_FLDCAT -ROW_POS      =  '1' .
    LV_FLDCAT -COL_POS      =  '1' .
    LV_FLDCAT -FIELDNAME  =  'BRSCH' .
    LV_FLDCAT -TABNAME      =  'IT_T016T' .
    LV_FLDCAT -OUTPUTLEN  =  8 .
    LV_FLDCAT -SCRTEXT_M  =  'Industry' .
    APPEND LV_FLDCAT  TO IT_FCAT .
    CLEAR LV_FLDCAT .
    LV_FLDCAT -ROW_POS      =  '1' .
    LV_FLDCAT -COL_POS      =  '2' .
    LV_FLDCAT -FIELDNAME  =  'BRTXT' .
    LV_FLDCAT -TABNAME      =  'IT_T016T' .
    LV_FLDCAT -OUTPUTLEN  =  15 .
    LV_FLDCAT -SCRTEXT_M  =  'Description' .
    APPEND LV_FLDCAT  TO IT_FCAT .
    CLEAR LV_FLDCAT .
ENDFORM .                     " alv_build_fieldcat
* PAI module of the screen created. In case we use an interactive ALV or
*for additional functionalities we can create OK codes
*and based on the user command we can do the coding.
*&---------------------------------------------------------------------*
*&      Module  USER_COMMAND_0600  INPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE USER_COMMAND_0600  INPUT .
    OK_CODE  = SY -UCOMM .
    CASE OK_CODE .
        WHEN  'EXIT' .
            LEAVE  PROGRAM .
        WHEN  OTHERS .
    ENDCASE .
ENDMODULE .                  " USER_COMMAND_0600  INPUT





ALV Tree的示例程序:BCALV_GRID_DND_TREE,



可以将左侧ALV TREE的节点拖拽到右侧的ALV上。



实现ALV TREE的树结构拖拽,可以参考上述两个程序。