ALV报表在SAP系统里面几乎随处可见,只要跟报表有关的系统都会制作成ALV的形式。像SE11里面查看表格的内容,系统就以ALV的形式体现,在报表里面可以对任何的栏位进行排序,还可以对任何的列进行筛选,也可以导出成Excel文档,也能对数值列进行汇总。可以说ALV的报表在实际报表的开发中占有非常重要的地位。学会它是每个ABAPer必须要经过的一关。
目前实现ALV的形式报表主要有2种:调用函数REUSE_ALV_GRID_DISPLAY和用面向对象的方法实现。前一种比较普遍,不过性能好像不太高,如果查询语句写得不太精妙,很容易出现卡的情况。后者是采用面向对象的形式,事先在画面上画出一个控制区域,然后用代码的形式填充ALV进去。
现在着重介绍第二种方法。
1、首先在SE38里面新建一个程序:
2、保存退出,在SE51里面新建屏幕100:
3、打开格式,准备在上面画出一个控制区域:
4、然后在代码页里将状态,事件添加进去,同时在PBO里面添加一个MODULE,用于载入ALV报表:
5、回到SE38里面打开新建的程序,添加一个INCLUDE ZALV_OO 程序,将与ALV有关的代码放进去封装起来,这样以后所有的程序都可以调用:
INCLUDE ZALV_OO.
相关代码如下:
*ALV变量设定
DATA GR_ALVGRID TYPE REF TO CL_GUI_ALV_GRID .DATA GC_CUSTOM_CONTROL_NAME TYPE SCRFNAME VALUE 'CC_ALV'. "对应我们画的控制区的名称DATA GR_CCONTAINER TYPE REF TO CL_GUI_CUSTOM_CONTAINER .*---栏位DATA GT_FIELDCAT TYPE LVC_T_FCAT .*---布局DATA GS_LAYOUT TYPE LVC_S_LAYO . *个人定义的变量DATA: SET_COLOR TYPE I, DECI_COUNT TYPE P, CHR_COUNT(8) TYPE C, TITLE(50) TYPE C, ALL_FIELD TYPE I, ALL_FIELD1 TYPE I, LV_INDEX TYPE I, TABIX LIKE SY-TABIX, TMP_TITLE TYPE STRING.*&---------------------------------------------------------------------**& Form display_alv*&---------------------------------------------------------------------** 显示ALV报表*----------------------------------------------------------------------*FORM DISPLAY_ALV USING IT_TABLE TYPE TABLE. IF GR_ALVGRID IS INITIAL .*----新建容器,填充到我们画的控制区域 CREATE OBJECT GR_CCONTAINER EXPORTING CONTAINER_NAME = GC_CUSTOM_CONTROL_NAME "这个地方前面已经赋值了 EXCEPTIONS CNTL_ERROR = 1 CNTL_SYSTEM_ERROR = 2 CREATE_ERROR = 3 LIFETIME_ERROR = 4 LIFETIME_DYNPRO_DYNPRO_LINK = 5 OTHERS = 6. IF SY-SUBRC EQ 0.*----容器新建成功,然后在此容器里面新建ALV的实例 CREATE OBJECT GR_ALVGRID EXPORTING I_PARENT = GR_CCONTAINER EXCEPTIONS ERROR_CNTL_CREATE = 1 ERROR_CNTL_INIT = 2 ERROR_CNTL_LINK = 3 ERROR_DP_CREATE = 4 OTHERS = 5. IF SY-SUBRC <> 0. ENDIF.*----准备获取栏位列表 PERFORM SETFIELDS."*-----设置布局 PERFORM PREPARE_LAYOUT CHANGING GS_LAYOUT .
*准备完毕,显示ALV CALL METHOD GR_ALVGRID->SET_TABLE_FOR_FIRST_DISPLAY EXPORTING* I_BUFFER_ACTIVE =* I_CONSISTENCY_CHECK =* I_STRUCTURE_NAME =* IS_VARIANT =* I_SAVE =* I_DEFAULT = 'X' IS_LAYOUT = GS_LAYOUT* IS_PRINT =* IT_SPECIAL_GROUPS =* IT_TOOLBAR_EXCLUDING =* IT_HYPERLINK = CHANGING IT_OUTTAB = IT_TABLE[] "设置成自己的内表 IT_FIELDCATALOG = GT_FIELDCAT* IT_SORT =* IT_FILTER = EXCEPTIONS INVALID_PARAMETER_COMBINATION = 1 PROGRAM_ERROR = 2 TOO_MANY_LINES = 3 OTHERS = 4 . IF SY-SUBRC <> 0. ENDIF.*刷新ALV CALL METHOD GR_ALVGRID->REFRESH_TABLE_DISPLAY* EXPORTING* IS_STABLE =* I_SOFT_REFRESH = EXCEPTIONS FINISHED = 1 OTHERS = 2 . IF SY-SUBRC <> 0.*--Exception handling ENDIF. ENDIF . ENDIF.
*状态栏里面显示本报表名称和记录等信息 CHR_COUNT = DECI_COUNT. CONDENSE CHR_COUNT. CONCATENATE TMP_TITLE ',共' CHR_COUNT '笔记录' INTO TITLE. MESSAGE TITLE TYPE 'S'.
ENDFORM . "display_alv*&---------------------------------------------------------------------**& Form prepare_layout*&---------------------------------------------------------------------** ALV属性,具体属性意义请参考LVC_S_LAYO*----------------------------------------------------------------------** -->PS_LAYOUT text*----------------------------------------------------------------------*FORM PREPARE_LAYOUT CHANGING PS_LAYOUT TYPE LVC_S_LAYO. PS_LAYOUT-ZEBRA = 'X' . PS_LAYOUT-GRID_TITLE = TITLE . PS_LAYOUT-SMALLTITLE = 'X' . PS_LAYOUT-SEL_MODE = 'A'. PS_LAYOUT-INFO_FNAME = 'COLOR'. PS_LAYOUT-CWIDTH_OPT = 'X'. PS_LAYOUT-DETAILINIT = 'X'.ENDFORM. " prepare_layout *设置ALV表栏位的宏DEFINE DSETFIELDS. DATA LS_FCAT TYPE LVC_S_FCAT . LS_FCAT-FIELDNAME = &1. LS_FCAT-INTTYPE = 'C' . LS_FCAT-OUTPUTLEN = &3. LS_FCAT-COLTEXT = &2. LS_FCAT-SELTEXT = &2. APPEND LS_FCAT TO GT_FIELDCAT .END-OF-DEFINITION.*&---------------------------------------------------------------------**& FORM SETFIELDS*&---------------------------------------------------------------------** 调用宏设置栏位*----------------------------------------------------------------------*FORM SETFIELD USING TMP_FIELD TYPE C TMP_NAME TYPE C TMP_LENGTH TYPE I. DSETFIELDS TMP_FIELD TMP_NAME TMP_LENGTH.ENDFORM. "SETFIELDS
6、设定完INCLUDE之后,在主程序里面新建一个内表:
TABLES:SFLIGHT. DATA:BEGIN OF IT_SFLIGHT OCCURS 0, CARRID LIKE SFLIGHT-CARRID, CONNID LIKE SFLIGHT-CONNID, FLDATE LIKE SFLIGHT-FLDATE, PRICE LIKE SFLIGHT-PRICE, COLOR(4) TYPE C, END OF IT_SFLIGHT.
START-OF-SELECTION. PERFORM GETDATA. "读取数据 CALL SCREEN 100. "呼叫屏幕
*&---------------------------------------------------------------------**& Form SETFIELDS*&---------------------------------------------------------------------** 设置栏位*----------------------------------------------------------------------* FORM SETFIELDS. PERFORM SETFIELD USING 'CARRID' '航线承运人ID' 3. PERFORM SETFIELD USING 'CONNID' '航班连接 Id' 4. PERFORM SETFIELD USING 'FLDATE' '航班日期' 8. PERFORM SETFIELD USING 'PRICE' '航空运费' 15. ENDFORM. "SETFIELDS
*&---------------------------------------------------------------------**& Module DISPLAY_ALV OUTPUT*&---------------------------------------------------------------------** 在PBO里面传入内表内容以ALV展现*----------------------------------------------------------------------* MODULE DISPLAY_ALV OUTPUT. PERFORM DISPLAY_ALV USING IT_SFLIGHT[]. ENDMODULE. " DISPLAY_ALV OUTPUT
*&---------------------------------------------------------------------**& Form GETDATA*&---------------------------------------------------------------------** 读取数据*----------------------------------------------------------------------** --> p1 text* <-- p2 text*----------------------------------------------------------------------* FORM GETDATA . DATA:SET_COLOR TYPE I. SELECT * INTO CORRESPONDING FIELDS OF TABLE IT_SFLIGHT FROM SFLIGHT WHERE CARRID IN S_CARRID AND CONNID IN S_CONNID AND FLDATE IN S_FLDATE AND PRICE IN S_PRICE. DESCRIBE TABLE IT_SFLIGHT LINES DECI_COUNT. "获取记录数 LOOP AT IT_SFLIGHT. SET_COLOR = SY-TABIX MOD 2. IF SET_COLOR = 0. IT_SFLIGHT-COLOR = 'C500'. "设置颜色 ELSE. CLEAR IT_SFLIGHT-COLOR. ENDIF. MODIFY IT_SFLIGHT. ENDLOOP. TMP_TITLE = 'ALV面向对象测试'. "报表名称 ENDFORM. " GETDATA
7、OK,一切完毕之后激活,运行:
如此,ALV就实现了。接下来我们来分析一下它的性能:
8、输入SE30:
点击Execute,系统会跑一次报表,退出之后,点击下面的Evaluate:
很直观可以看出该报表之行的情况。如果跟调用function:REUSE_ALV_GRID_DISPLAY 对比起来就会发现用OO的形式来做性能会更好的。