APAP INCLUDE

*&---------------------------------------------------------------------*
*& Report  YMWXBINCLUDE
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT  YMWXBINCLUDE.

INCLUDE YMWXBINCLUDE_TOP.

PERFORM GET_DATA_FORM.
PERFORM LAYOUT_FORM.
PERFORM FIELD_CAT_FORM.
PERFORM EVENT_WXB_FORM.
PERFORM DISPLAY_FORM.

* form 的声明 ,还是要放在后面, 否则,激活时候,就很容易出错,说变量没声明,或者无法访问等问题。
INCLUDE YMWXBINCLUDE_FORM.

*&---------------------------------------------------------------------*
*&  包含                YMWXBINCLUDE_TOP
*&---------------------------------------------------------------------*




*
*
*开发ALV的基本流程:
*第1步:声明变量 定义ALV所要用到的类型池:TYPE-POOLS: SLIS  针对ALV的控制信息数据(Layout & Fieldcat)

*第2步:定义内表 存放自定义数据文件的数据,以及在ALV中显示

*第3步:读取数据 读取数据存放至Internal TABLE
*第4步:ALV格式控制 建立ALV显示样式(layout)和显示字段清单(FIELD Catalogs)
*第5步:定义事件 建立事件清单(EVENT Catalogs)
*  事件一共分为  17 种 (比如:设置标题栏的显示和隐藏,用户操作的响应等)
*第6步:显示ALV 调用ALV FUNCTION MODULE
*  可以 到 se37  中  查看 REUSE_ALV_EVENTS_GET (这个和数据表一样,名称要记住了),
*  点击进去就可以看到所欲的事件声明了 ,如果要实现具体的 功能就需要写 子例程来实现
*第7步:用户事件 定义User按键处理事件
*   属于 第五步中的 事件的一种

* 例如到 VA03 中查看  输入订单编号   10000147 就可以查看 订单明细

* 在配置  ALV显示的时候,点击模式按钮
* 调用函数时候选择 :REUSE_ALV_GRID_DISPLAY 会自动生产函数的配置 ,配置上相应的选项之后,就可以金新股显示了。

* 第一步定义 ALV 相关变量

TYPE-POOLS:SLIS .

* 注意在下面的事件变量的定义中如果 不知道 参考什么 类型 ,
*双击 函数  REUSE_ALV_GRID_DISPLAY ,找到 入参 ,可然后找到要定义的类型 如: IT_EVENTS ,就可以看到 需要参考的类型了
* 直接定义为一样的就可以了 。
DATA:lt_fieldcat TYPE slis_t_fieldcat_alv ," 存储fieldcat的内表
      ls_fieldcat TYPE slis_fieldcat_alv,
      ls_layout TYPE slis_layout_alv " ALV 格式控制的结构体 :layout
      lt_event TYPE slis_t_event " 定义内表 ,参考声明了结构类型的types 类类型
      ls_event TYPE slis_alv_event " 定义工作区 直接参考了结构体
DATA lv_colpos TYPE int2 .
DATA lt_sort TYPE slis_t_sortinfo_alv.
DATA wa_sort TYPE slis_sortinfo_alv.
DATA ls_setting TYPE LVC_S_GLAY.

*第二部定义内表

TYPES:BEGIN OF ty_alvshow ,
  vbeln TYPE vbak-vbeln ,
  erdat TYPE vbak-erdat,
  ernam TYPE vbak-ernam,
  kunnr TYPE vbak-kunnr,

  posnr TYPE vbap-posnr,
  matnr TYPE vbap-matnr,
  matkl TYPE vbap-matkl,
  zmeng TYPE vbap-zmeng,
  zieme TYPE vbap-zieme,
  werks TYPE vbap-werks,
  lgort TYPE vbap-lgort,
END OF ty_alvshow.

DATA:lt_alvshow TYPE TABLE OF ty_alvshow," 定义内表哦
      wa_alvshow TYPE ty_alvshow ." 定义工作区

*&---------------------------------------------------------------------*
*&  包含                YMWXBINCLUDE_FORM
*&---------------------------------------------------------------------*

*******************form 定义 ****************************************

FORM WXB_FORM_USER_COMMAND USING R_UCOMM LIKE SY-UCOMM
      RS_SELFIELD TYPE SLIS_SELFIELD.
  DATA lt_vbap TYPE TABLE OF VBAP" 定义数据库内表
  DATA wa_vbap TYPE  VBAP." 定义 数据库工作区

  CASE  R_UCOMM.
  WHEN 'ZWXB'.
    MESSAGE '点击了自定义的按钮' TYPE 'I'.
  WHEN 'ZSAVE'.
    SELECT * FROM vbap INTO  TABLE lt_vbap FOR ALL ENTRIES IN lt_alvshow WHERE vbeln = lt_alvshow-vbeln  AND posnr = lt_alvshow-posnr .

    LOOP  AT lt_vbap INTO wa_vbap .
      " 要注意的是 vbeln 要放在 条件的第一个 位置, 等于 后面 追加 工作区里面的信息
      READ TABLE lt_alvshow INTO wa_alvshow WITH KEY vbeln = wa_vbap-vbeln  posnr = wa_vbap-posnr .
      IF sy-SUBRC .
        wa_vbap-ZMENG = wa_alvshow-ZMENG.
        MODIFY lt_vbap FROM wa_vbap .
      ENDIF.
      CLEAR wa_alvshow .
      CLEAR wa_vbap.
    ENDLOOP.

    UPDATE vbap FROM TABLE lt_vbap .
    IF  sy-SUBRC .
      COMMIT WORK .
      MESSAGE '更新成功' TYPE 'I'.
    ELSE.
      ROLLBACK WORK.
      MESSAGE '更新失败' TYPE 'I'.
    ENDIF.
    WHEN OTHERS.
  ENDCASE.
*IF R_UCOMM = 'ZWXB'.
*  MESSAGE '点击了自定义的按钮' TYPE 'I'.
*ELSEIF R_UCOMM = 'ZSAVE'.
*  MESSAGE '确定要保存吗?' TYPE 'I'.
*ENDIF.

ENDFORM.


FORM WXB_STATUS  USING RT_EXTAB TYPE SLIS_T_EXTAB.
*  set PF-STATUS 'WXB_STATUS'. " 这里是自定义的工具栏的名称,一个alv启动时候,就会直接调用自定义的工具栏
  SET PF-STATUS 'WXB_STATUS'.
ENDFORM .


* 下面是工具栏的自定义设置
FORM WXB_FORM_TOP_OF_PAGE.
  DATA LT_COMMENTARY TYPE SLIS_T_LISTHEADER.
  DATA WA_COMMENTARY TYPE slis_listheader .
  WA_COMMENTARY-typ 'H'.
  WA_COMMENTARY-info '销售凭证清单大号 '.
  APPEND WA_COMMENTARY TO LT_COMMENTARY .
  CLEAR WA_COMMENTARY.

  WA_COMMENTARY-typ 'S'.
  WA_COMMENTARY-info '销售凭证清单中号 '.
  APPEND WA_COMMENTARY TO LT_COMMENTARY .
  CLEAR WA_COMMENTARY.

  WA_COMMENTARY-typ 'A'.
  WA_COMMENTARY-info '销售凭证清单小号 '.
  APPEND WA_COMMENTARY TO LT_COMMENTARY .

  CALL FUNCTION 'REUSE_ALV_COMMENTARY_WRITE'
  EXPORTING
    IT_LIST_COMMENTARY = LT_COMMENTARY
*     I_LOGO             = 'WXBPIC'
*     I_END_OF_LIST_GRID =
*     I_ALV_FORM         =
    .
ENDFORM .
*&---------------------------------------------------------------------*
*&      Form  GET_DATA_FORM
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM GET_DATA_FORM .
*-----d读取数据 -----*

  SELECT  a~vbeln a~erdat a~ernam a~kunnr b~posnr b~matnr b~matkl b~zmeng b~zieme b~werks b~lgort
  FROM vbak AS a  INNER JOIN vbap AS b ON a~vbeln = b~vbeln INTO TABLE lt_alvshow UP TO 10 ROWS ." 暂时取出 100 行


ENDFORM.                    " GET_DATA_FORM
*&---------------------------------------------------------------------*
*&      Form  LAYOUT_FORM
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM LAYOUT_FORM .
*-------第四部:alv 格式控制 ---*

  ls_layout-zebra 'X'.
  ls_layout-detail_popup 'X'.
  ls_layout-f2code '&ETA'.
  ls_layout-detail_titlebar '详细信息'.
  ls_layout-colwidth_optimize 'X'.
ENDFORM.                    " LAYOUT_FORM
*&---------------------------------------------------------------------*
*&      Form  FIELD_CAT_FORM
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM FIELD_CAT_FORM .

  "field ,显示的字段清单

* 销售凭证
  lv_colpos .
  ls_fieldcat-fieldname 'VBELN'.
  ls_fieldcat-col_pos = lv_colpos.
  ls_fieldcat-KEY 'X'.
  ls_fieldcat-datatype 'CHAR'.
  ls_fieldcat-outputlen '10'.
  ls_fieldcat-seltext_m '销售凭证'.
  APPEND ls_fieldcat TO lt_fieldcat ." 将工作区中的数据追加到内表中



* 销售日期
  CLEAR ls_fieldcat.
  lv_colpos = lv_colpos + .
  ls_fieldcat-fieldname 'ERDAT'.
  ls_fieldcat-col_pos = lv_colpos.
  ls_fieldcat-datatype 'DATS'.
  ls_fieldcat-outputlen '8'.
  ls_fieldcat-seltext_m '销售日期'.
  APPEND ls_fieldcat TO lt_fieldcat ." 将工作区中的数据追加到内表中

* 创建人
  lv_colpos = lv_colpos + .
  CLEAR ls_fieldcat.
  ls_fieldcat-fieldname 'ERNAM'.
  ls_fieldcat-col_pos = lv_colpos.
  ls_fieldcat-datatype 'CHAR'.
  ls_fieldcat-outputlen '12'.
  ls_fieldcat-seltext_m '创建人'.
  APPEND ls_fieldcat TO lt_fieldcat ." 将工作区中的数据追加到内表中

* 售达方,客户
  lv_colpos = lv_colpos + .
  CLEAR ls_fieldcat.
  ls_fieldcat-fieldname 'KUNNR'.
  ls_fieldcat-col_pos = lv_colpos.
  ls_fieldcat-datatype 'CHAR'.
  ls_fieldcat-outputlen '10'.
  ls_fieldcat-seltext_m '售达方'.
  APPEND ls_fieldcat TO lt_fieldcat ." 将工作区中的数据追加到内表中

* 项目编码
  lv_colpos = lv_colpos + .
  CLEAR ls_fieldcat.
  ls_fieldcat-fieldname 'POSNR'.
  ls_fieldcat-col_pos = lv_colpos.
  ls_fieldcat-datatype 'NUMC'.
  ls_fieldcat-outputlen '6'.
  ls_fieldcat-seltext_m '项目编码'.
  APPEND ls_fieldcat TO lt_fieldcat ." 将工作区中的数据追加到内表中


* 物料
  CLEAR ls_fieldcat.
  lv_colpos = lv_colpos + .
  ls_fieldcat-fieldname 'MATNR'.
  ls_fieldcat-col_pos = lv_colpos.
  ls_fieldcat-datatype 'CHAR'.
  ls_fieldcat-outputlen '18'.
  ls_fieldcat-seltext_m '物料'.
  APPEND ls_fieldcat TO lt_fieldcat ." 将工作区中的数据追加到内表中



* 物料组
  CLEAR ls_fieldcat.
  lv_colpos = lv_colpos + .
  ls_fieldcat-fieldname 'MATKL'.
  ls_fieldcat-col_pos = lv_colpos.
  ls_fieldcat-datatype 'CHAR'.
  ls_fieldcat-outputlen '9'.
  ls_fieldcat-seltext_m '物料组'.
  APPEND ls_fieldcat TO lt_fieldcat ." 将工作区中的数据追加到内表中


* 数量
  CLEAR ls_fieldcat.
  lv_colpos = lv_colpos + .
  ls_fieldcat-fieldname 'ZMENG'.
  ls_fieldcat-col_pos = lv_colpos.
  ls_fieldcat-datatype 'QUAN'.
  ls_fieldcat-outputlen '13'.
  ls_fieldcat-seltext_m '数量'.
  ls_fieldcat-EDIT 'X'.   
" 把当前列 设置为 可编辑,还可以实现编辑之后,回车事件,动态改变当前行中其他值   
" 这时候,我们要指定小数点的位数   ls_fieldcat
-decimals_out 3.   
" 指定为 三位 ,如果是查看不需要设置,如果是可编辑,则要指定小数位长度

* 还有另外一种方法是可以不设置 小数位长度的,如下:
* ls_fieldcat-fieldname = 'ZMENG'.
*ls_fieldcat-ref_tabname = 'VBAP'.
* 就是设置参考的数据表和该表中的具体字段   ls_fieldcat

-do_sum 'X'" 求和 ,要对数字类型,对字符串字段没有效果   
APPEND ls_fieldcat TO lt_fieldcat ." 将工作区中的数据追加到内表中

* 单位   
CLEAR ls_fieldcat.   lv_colpos 
= lv_colpos + .   ls_fieldcat
-fieldname 'ZIEME'.   ls_fieldcat
-col_pos = lv_colpos.   ls_fieldcat
-datatype 'UNIT'.   ls_fieldcat
-outputlen '3'.   ls_fieldcat
-seltext_m '单位'.   
APPEND ls_fieldcat TO lt_fieldcat ." 将工作区中的数据追加到内表中


* 工厂   
CLEAR ls_fieldcat.   lv_colpos 
= lv_colpos + .   ls_fieldcat
-fieldname 'WERKS'.   ls_fieldcat
-col_pos = lv_colpos.   ls_fieldcat
-ref_tabname 'VBAP'.   
APPEND ls_fieldcat TO lt_fieldcat ." 将工作区中的数据追加到内表中

* 库存地点   
CLEAR ls_fieldcat.   lv_colpos 
= lv_colpos + .   ls_fieldcat
-fieldname 'LGORT'.   ls_fieldcat
-col_pos = lv_colpos.   ls_fieldcat
-ref_tabname 'VBAP'.   
APPEND ls_fieldcat TO lt_fieldcat ." 将工作区中的数据追加到内表中

ENDFORM.                    " FIELD_CAT_FORM
*&---------------------------------------------------------------------*
*&      Form  EVENT_WXB_FORM
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM EVENT_WXB_FORM .


*------ 第五步添加事件-----------*

* 开始 通过事件的内表逐条添加事件   ls_event

-name 'USER_COMMAND'" 用户响应事件   ls_event
-FORM 'WXB_FORM_USER_COMMAND'" 注意form名称的格式 ,这样比较清晰看到是一个子例程   
APPEND ls_event TO lt_event .   
CLEAR ls_event.
*   ls_event
-name 'PF_STATUS_SET'" 显示标题(大中小) 标题   ls_event
-FORM 'WXB_STATUS'" 设置 GUI-STATUS 状态栏   
APPEND ls_event TO lt_event .   
CLEAR ls_event.   ls_event

-name 'TOP_OF_PAGE'" 显示标题(大中小) 标题   ls_event
-FORM 'WXB_FORM_TOP_OF_PAGE'" 显示标题(大中小) 标题   
APPEND ls_event TO lt_event .




* 下面是开始排序   wa_sort

-fieldname 'ERDAT'.   wa_sort
-down 'X'.   
APPEND wa_sort TO  lt_sort .   

CLEAR wa_sort .   wa_sort


-fieldname 'POSNR'.   wa_sort
-UP 'X'.   
APPEND wa_sort TO  lt_sort .
ENDFORM.                    " EVENT_WXB_FORM
*&---------------------------------------------------------------------*
*&      Form  DISPLAY_FORM
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM DISPLAY_FORM .


*-----------------开始定义子例程(属于模块),必须在被调用才会被执行----------------------*

**************************************一切非执行语句都写在程序的最后面 ****************************************************************


*------ 第六步直接显示-----------*
* 下面使用到的参数,都要在使用之前传递 。   
" ALV 控制: 退出可编辑单元格时回调 ,返回编辑后的值
* 方便在  USER-COMMANE 中获取到 修改后的值  。
* 然后执行 sql 语句 将数据保存到数据库中。
* 还有一个问题 ,是当我们修改后数字后,
* 比如之前为  0.000 ,现在修改为 30.000 , 回车之后,返现数字变成了 0.030
*   ls_setting
-EDT_CLL_CB 'X'.   


DATA pgm TYPE sy-repid .   pgm 
= sy-repid .   
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'   
EXPORTING
*   I_INTERFACE_CHECK                 = ' '
*   I_BYPASSING_BUFFER                = ' '
*   I_BUFFER_ACTIVE                   = ' '     I_CALLBACK_PROGRAM                
=  pgm "sy-cprog  "  这个一定要添加 否则就会出不来效果

*   I_CALLBACK_PF_STATUS_SET          = 'WXB_TATUS'
*   I_CALLBACK_USER_COMMAND           = 'WXB_FORM_USER_COMMAND'
*   I_CALLBACK_TOP_OF_PAGE            = 'WXB_FORM_TOP_OF_PAGE'
*   I_CALLBACK_HTML_TOP_OF_PAGE       = ' '
*   I_CALLBACK_HTML_END_OF_LIST       = ' '
*   I_STRUCTURE_NAME                  =
*   I_BACKGROUND_ID                   = ' '
*   I_GRID_TITLE                      =     I_GRID_SETTINGS                   
= ls_setting     IS_LAYOUT                         
= ls_layout     IT_FIELDCAT                       
= lt_fieldcat
*   IT_EXCLUDING                      =
*   IT_SPECIAL_GROUPS                 =     IT_SORT                           
= lt_sort
*   IT_FILTER                         =
*   IS_SEL_HIDE                       =
*   I_DEFAULT                         = 'X'     I_SAVE                            
'A'
*   IS_VARIANT                        =     IT_EVENTS                         
= lt_event " 这里如果没有指定,就无法将内表中的时间绑定到函数中
*   IT_EVENT_EXIT                     =
*   IS_PRINT                          =
*   IS_REPREP_ID                      =
*   I_SCREEN_START_COLUMN             = 0
*   I_SCREEN_START_LINE               = 0
*   I_SCREEN_END_COLUMN               = 0
*   I_SCREEN_END_LINE                 = 0
*   I_HTML_HEIGHT_TOP                 = 0
*   I_HTML_HEIGHT_END                 = 0
*   IT_ALV_GRAPHICS                   =
*   IT_HYPERLINK                      =
*   IT_ADD_FIELDCAT                   =
*   IT_EXCEPT_QINFO                   =
*   IR_SALV_FULLSCREEN_ADAPTER        =
* IMPORTING
*   E_EXIT_CAUSED_BY_CALLER           =
*   ES_EXIT_CAUSED_BY_USER            =   
TABLES     T_OUTTAB                          
= lt_alvshow   
EXCEPTIONS     PROGRAM_ERROR                     
1     
OTHERS                            2     
.   
IF SY-SUBRC <> 0.
* Implement suitable error handling here   
ENDIF.

ENDFORM.                    " DISPLAY_FORM

生命的意义在于勇敢,错过,悔恨,真实之后的 风轻云淡。
原文地址:https://www.cnblogs.com/safely-pointer/p/7683220.html