一、ALV相关概念

ALV――ABAP LIST VIEWER,这里我们姑且称之为ABAP表单浏览器,用它可以标准化,简单化R/3系统中的表单,它可以提供给用户一个统一的表单格式以及用户接口。

二、程序的编写

 1.写一个ALV程序的基本流程:

   第一步:定义将要用到的表,即TALBES定义部分,然后定义TYPE-POOLS: SLIS.

   第二步:定义第一步中提到的这些数据类型或者内表的实体对象 ,内表结构    

   第三步:定义一些需要用到的变量

   第四步: 定义自己的选择屏幕

   第五步: start-of-selection部分

            1用一个子函数完成自己所需要数据的抓取,也可以直接取数

            2用一个子函数完成要显示列表的列名行(第一行)的相关赋值(i_fieldcat_alv)以及设置

            3用一个子函数完成输出格式的设置(i_layout),比如双击一条记录是否弹出对话框啊?是用哪个功能键触发等等

            4用一个子函数FORM DISPLAY_DATA来显示上面我们已经分别封装好的数据,需要调用两个常用的FUNCTION MODULE:

               FUNCTION 'REUSE_ALV_GRID_DISPLAY'    “用来显示表单数据

               FUNCTION 'REUSE_ALV_COMMENTARY_WRITE'  “用来显示表单标题

            5定义某些事件

            6定义排序

            7定义ALV报表可编辑及更新数据库表

2.在我们写ALV程序的时候,有一个类型组是肯定要用到的:

   TYPE-POOLS:SLIS。

   在这个类型组中有很多ALV的自定义数据类型以及结构化数据类型(通过TYPE来定义的),我们在写ALV表单的时候需要调用的。我们常用的几个有(蓝色部分):

3. 两个重要的数据结构

(1)catalogt属性 (每列对应一个这样的结构slis_fieldcat_alv,所有的列信息存储到内表中slis_t_fieldcat_alv)

(2)Layout 属性(slis_layout_alv 仅是个扁平的结构,存储控制ALV样式的信息)

 下面直接上代码

*&---------------------------------------------------------------------*
*& Report YPMRP010_ALV01
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT YPMRP010_ALV01.
*-----设定变量-------*
TYPE-POOLS:SLIS.
TABLES:VBAP.
*定义ALV结构
DATA:LT_FIELDCAT TYPE  SLIS_T_FIELDCAT_ALV."FIELDCAT内表
DATA:LS_FIELDCAT TYPE SLIS_FIELDCAT_ALV."FIELDCAT工作区
DATA:LS_LAYOUT TYPE SLIS_LAYOUT_ALV."ALV控制结构体:layout
DATA:LT_EVENT TYPE SLIS_T_EVENT."事件内表
DATA:LS_EVENT TYPE SLIS_ALV_EVENT."事件工作区
DATA:LT_SORT TYPE SLIS_T_SORTINFO_ALV. "用于排序的内表
DATA:LS_SORT TYPE SLIS_SORTINFO_ALV."用于排序的工作区
DATA:LS_SETTING TYPE LVC_S_GLAY."ALV 控制: 退出可编辑单元格时回调
*定义内表结构
TYPES:BEGIN OF TY_ALVSHOW,
        VBELN LIKE VBAK-VBELN,
        ERDAT LIKE VBAK-ERDAT,
        ERNAM LIKE VBAK-ERNAM,
        KUNNR LIKE  VBAK-KUNNR,
        POSNR LIKE VBAP-POSNR,
        MATNR LIKE VBAP-MATNR,
        MATKL LIKE VBAP-MATKL,
        ZMENG LIKE VBAP-ZMENG,
        ZIEME LIKE VBAP-ZIEME,
        WERKS LIKE VBAP-WERKS,
        LGORT LIKE VBAP-LGORT,
      END OF TY_ALVSHOW.
*定义内表及工作区
DATA:IT_ALVSHOW TYPE STANDARD TABLE OF TY_ALVSHOW.
DATA:WA_ALVSHOW TYPE TY_ALVSHOW.
DATA:IT_ALVSHOW1 TYPE STANDARD TABLE OF TY_ALVSHOW.
DATA:WA_ALVSHOW1 TYPE TY_ALVSHOW.
DATA:COL_POS TYPE I.
SELECT-OPTIONS:S_VBELN FOR VBAP-VBELN.
*取数据
SELECT
  VBAK~VBELN  VBAK~ERDAT  VBAK~ERNAM  VBAK~KUNNR  VBAP~POSNR  VBAP~MATNR  VBAP~MATKL
  VBAP~ZMENG  VBAP~ZIEME  VBAP~WERKS  VBAP~LGORT  FROM VBAK
  INNER JOIN VBAP ON VBAK~VBELN = VBAP~VBELN
*  INTO CORRESPONDING FIELDS OF TABLE IT_ALVSHOW WHERE VBAK~VBELN IN S_VBELN.
  INTO CORRESPONDING FIELDS OF TABLE IT_ALVSHOW UP TO 5 ROWS.
IT_ALVSHOW1 = IT_ALVSHOW.
*ALV格式控制layout
LS_LAYOUT-ZEBRA = 'X'.
LS_LAYOUT-DETAIL_POPUP = 'X'.
LS_LAYOUT-DETAIL_TITLEBAR = '详细信息'.
LS_LAYOUT-F2CODE = '&ETA'.
LS_LAYOUT-COLWIDTH_OPTIMIZE = 'X'.
*  fieldcat
COL_POS = 0.
*销售凭证列
COL_POS = COL_POS + 1.
LS_FIELDCAT-FIELDNAME = 'VBELN'.
LS_FIELDCAT-COL_POS = COL_POS.
LS_FIELDCAT-KEY = 'X'.
LS_FIELDCAT-SELTEXT_M = '销售凭证'.
APPEND LS_FIELDCAT TO LT_FIELDCAT.
CLEAR:LS_FIELDCAT.
*创建日期
COL_POS = COL_POS + 1.
LS_FIELDCAT-FIELDNAME = 'ERDAT'.
LS_FIELDCAT-COL_POS = COL_POS.
LS_FIELDCAT-REF_TABNAME  = 'VBAK'.
APPEND LS_FIELDCAT TO LT_FIELDCAT.
CLEAR:LS_FIELDCAT.
*创建者
COL_POS = COL_POS + 1.
LS_FIELDCAT-FIELDNAME = 'ERNAM'.
LS_FIELDCAT-COL_POS = COL_POS.
LS_FIELDCAT-SELTEXT_M = '创建人'.
APPEND LS_FIELDCAT TO LT_FIELDCAT.
CLEAR:LS_FIELDCAT.
*售达方 自己起字段描述
COL_POS = COL_POS + 1.
LS_FIELDCAT-FIELDNAME = 'KUNNR'.
LS_FIELDCAT-COL_POS = COL_POS.
LS_FIELDCAT-SELTEXT_M = '客户'.
APPEND LS_FIELDCAT TO LT_FIELDCAT.
CLEAR:LS_FIELDCAT.
*售达方1  参考数据字典表名
COL_POS = COL_POS + 1.
LS_FIELDCAT-FIELDNAME = 'KUNNR'.
LS_FIELDCAT-COL_POS = COL_POS.
LS_FIELDCAT-REF_TABNAME = 'VBAK'.
APPEND LS_FIELDCAT TO LT_FIELDCAT.
CLEAR:LS_FIELDCAT.
*行号
COL_POS = COL_POS + 1.
LS_FIELDCAT-FIELDNAME = 'POSNR'.
LS_FIELDCAT-COL_POS = COL_POS.
LS_FIELDCAT-REF_TABNAME = 'VBAP'.
APPEND LS_FIELDCAT TO LT_FIELDCAT.
CLEAR:LS_FIELDCAT.
*物料
COL_POS = COL_POS + 1.
LS_FIELDCAT-FIELDNAME = 'MATNR'.
LS_FIELDCAT-COL_POS = COL_POS.
LS_FIELDCAT-SELTEXT_M = '物料编码'.
APPEND LS_FIELDCAT TO LT_FIELDCAT.
CLEAR:LS_FIELDCAT.
*物料组
COL_POS = COL_POS + 1.
LS_FIELDCAT-FIELDNAME = 'MATKL'.
LS_FIELDCAT-COL_POS = COL_POS.
LS_FIELDCAT-SELTEXT_M = '物料组'.
APPEND LS_FIELDCAT TO LT_FIELDCAT.
CLEAR:LS_FIELDCAT.
*数量
COL_POS = COL_POS + 1.
LS_FIELDCAT-FIELDNAME = 'ZMENG'.
LS_FIELDCAT-COL_POS = COL_POS.
LS_FIELDCAT-SELTEXT_M = '数量'.
LS_FIELDCAT-DO_SUM = 'X'. "总计
LS_FIELDCAT-EDIT = 'X'. "总计
LS_FIELDCAT-DECIMALS_OUT = 3. "因为当编辑数量的时候,如果是小数,要指定小数位,否则输入数据之后回车会自动缩小,如果使用ref则不需要设置

APPEND LS_FIELDCAT TO LT_FIELDCAT.
CLEAR:LS_FIELDCAT.
*单位
COL_POS = COL_POS + 1.
LS_FIELDCAT-FIELDNAME = 'ZIEME'.
LS_FIELDCAT-COL_POS = COL_POS.
LS_FIELDCAT-SELTEXT_M = '单位'.
APPEND LS_FIELDCAT TO LT_FIELDCAT.
CLEAR:LS_FIELDCAT.
*工厂
COL_POS = COL_POS + 1.
LS_FIELDCAT-FIELDNAME = 'WERKS'.
LS_FIELDCAT-COL_POS = COL_POS.
LS_FIELDCAT-REF_TABNAME = 'VBAP'.
APPEND LS_FIELDCAT TO LT_FIELDCAT.
CLEAR:LS_FIELDCAT.
*库位
COL_POS = COL_POS + 1.
LS_FIELDCAT-FIELDNAME = 'LGORT'.
LS_FIELDCAT-COL_POS = COL_POS.
LS_FIELDCAT-SELTEXT_M = '库位'.
APPEND LS_FIELDCAT TO LT_FIELDCAT.
CLEAR:LS_FIELDCAT.
*定义事件
LS_EVENT-NAME = 'USER_COMMAND'."用户响应事件
LS_EVENT-FORM = 'FORM_USER_COMMAND'."子例程
APPEND LS_EVENT TO LT_EVENT."加入到事件内表
CLEAR:LS_EVENT.
LS_EVENT-NAME = 'TOP_OF_PAGE'."显示标题
LS_EVENT-FORM = 'FORM_TOP_OF_PAGE'."子例程
APPEND LS_EVENT TO LT_EVENT.
CLEAR:LS_EVENT.
LS_EVENT-NAME = 'PF_STATUS_SET'."设置gui状态栏
LS_EVENT-FORM = 'FORM_PF_STATUS_SET'."子例程
APPEND LS_EVENT TO LT_EVENT.
CLEAR:LS_EVENT.
*排序
LS_SORT-FIELDNAME = 'ERDAT'.
LS_SORT-DOWN = 'X'.
APPEND LS_SORT TO LT_SORT.
LS_SORT-FIELDNAME = 'KUNNR'.
LS_SORT-UP = 'X'.
APPEND LS_SORT TO LT_SORT.
CLEAR:LS_SORT.
*ALV 控制: 退出可编辑单元格时回调
LS_SETTING-EDT_CLL_CB = 'X'.

*显示
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
  EXPORTING
*   I_INTERFACE_CHECK        = ' '
*   I_BYPASSING_BUFFER       = ' '
*   I_BUFFER_ACTIVE          = ' '
    I_CALLBACK_PROGRAM       = SY-REPID
    I_CALLBACK_PF_STATUS_SET = 'SET PF-STATUS '
    I_CALLBACK_USER_COMMAND  = ' USER_COMMAND'
*   I_CALLBACK_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                   = ' '
*   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                 = IT_ALVSHOW
  EXCEPTIONS
    PROGRAM_ERROR            = 1
    OTHERS                   = 2.
IF SY-SUBRC <> 0.
* Implement suitable error handling here
ENDIF.
"FORM define
FORM FORM_USER_COMMAND USING R_UCOMM LIKE SY-UCOMM
   RS_SELFIELD TYPE SLIS_SELFIELD.
*  DATA:IT_VBAP TYPE TABLE OF VBAP."更新源内表,要和数据库表结构一致  7.5以前可以定义内表
*  DATA:WA_VBAP TYPE VBAP.

*  CASE .
*  	WHEN .
*  	WHEN .
*  	WHEN OTHERS.
*  ENDCASE. 也可以用case

  IF R_UCOMM = '&ADD'.
    MESSAGE '您触发了按钮TEST' TYPE 'I'.
  ENDIF.
  IF R_UCOMM = 'ZSAVE'.
*    SELECT * FROM VBAP INTO TABLE @DATA(LT_VBAP) FOR ALL ENTRIES IN @IT_ALVSHOW"7.5以后可以直接@data内表名
*        WHERE VBELN = @IT_ALVSHOW-VBELN AND POSNR = @IT_ALVSHOW-POSNR.
*    LOOP AT LT_VBAP INTO DATA(WA_VBAP).
*      READ TABLE IT_ALVSHOW INTO WA_ALVSHOW WITH  KEY VBELN = WA_VBAP-VBELN POSNR =  WA_VBAP-POSNR.
*      IF SY-SUBRC = 0.
*        WA_VBAP-ZMENG = WA_ALVSHOW-ZMENG.
*        MODIFY LT_VBAP FROM WA_VBAP.
*        CLEAR:WA_VBAP,WA_ALVSHOW.
*        UPDATE VBAP FROM TABLE LT_VBAP.
*      ENDIF.
*    ENDLOOP.
    DATA:TABLE_DEL TYPE TABLE OF  TY_ALVSHOW.
    DATA:TABLE_ADD TYPE TABLE OF  TY_ALVSHOW.
    DATA:TABLE_MOD TYPE TABLE OF  TY_ALVSHOW.
    DATA:WA_TABLE_MOD TYPE TY_ALVSHOW.
    DATA:NO_CHANGES(1) TYPE C.
    CALL FUNCTION 'CTVB_COMPARE_TABLES' "用于比较更改前后内表的变化,比上面的全部循环更新更有效率
      EXPORTING
        TABLE_OLD  = IT_ALVSHOW1
        TABLE_NEW  = IT_ALVSHOW
        KEY_LENGTH = '2'
*       IF_SORTED  =
      IMPORTING
        TABLE_DEL  = TABLE_DEL
        TABLE_ADD  = TABLE_ADD
        TABLE_MOD  = TABLE_MOD
        NO_CHANGES = NO_CHANGES.
    SELECT * FROM VBAP INTO TABLE @DATA(LT_VBAP) FOR ALL ENTRIES IN @TABLE_MOD"7.5以后可以直接@data内表名
        WHERE VBELN = @TABLE_MOD-VBELN AND POSNR = @TABLE_MOD-POSNR.
    LOOP AT LT_VBAP INTO DATA(WA_VBAP).
      READ TABLE TABLE_MOD INTO WA_TABLE_MOD WITH  KEY VBELN = WA_VBAP-VBELN POSNR =  WA_VBAP-POSNR.
      IF SY-SUBRC = 0.
        WA_VBAP-ZMENG = WA_TABLE_MOD-ZMENG.
        MODIFY LT_VBAP FROM WA_VBAP.
        CLEAR:WA_VBAP,WA_TABLE_MOD.
        UPDATE VBAP FROM TABLE LT_VBAP.
      ENDIF.
    ENDLOOP.

    IF SY-SUBRC = 0.
      COMMIT WORK.  "用于提交数据
      MESSAGE '更新成功' TYPE 'I'.
    ELSE.
      ROLLBACK WORK.
      MESSAGE '更新失败' TYPE 'I'.
    ENDIF.
  ENDIF.
ENDFORM.
FORM   FORM_TOP_OF_PAGE.

  DATA:LT_COMMENTARY TYPE SLIS_T_LISTHEADER,
       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.
  CLEAR:WA_COMMENTARY.
  CALL FUNCTION 'REUSE_ALV_COMMENTARY_WRITE' "用于ALV标题的显示
    EXPORTING
      IT_LIST_COMMENTARY = LT_COMMENTARY
      I_LOGO             = 'ZTEST1'.
*     I_END_OF_LIST_GRID =
*     I_ALV_FORM         =
ENDFORM.
FORM FORM_PF_STATUS_SET USING RT_EXTAB TYPE SLIS_T_EXTAB.
  SET PF-STATUS'STANDARD'.
ENDFORM.
08-08 17:03