在SAP报表开发中,经常使用设计页眉。也就是我们提到的top of page,以及类似页脚的 end of list。
那这两部分如何实现的呢,有两种方法,一种是html方式,另一种也是我们本文要讲的使用事件和调用函数的方法。
简单来说,主要用到两个函数:REUSE_ALV_EVENTS_GET 和REUSE_ALV_COMMENTART_WRITE.
而涉及到的内表也是两个:
TYPE-POOLS:SLIS.
DATA:GT_EVENT TYPE SLIS_T_EVENT,
GW_EVENT LIKE LINE OF GT_EVENT.
DATA:GT_LISTHEADER TYPE SLIS_T_LISTHEADER,
GW_LISTHEADER LIKE LINE OF GT_LISTHEADER.
这里GT_EVENT作用相当于创建页眉或页脚,而GT_LISTHEADER内表的作用则是存放展示在页眉页脚的内容。
简单来说:一个call function的ALV报表,我们在全局定义了上述的内表和工作区后,只需要额外添加几个FORM即可实现页眉页脚,而对原来的报表没有任何额外的影响。
如下:
首先给GT_EVENT赋值,其实这个内表只有两个字段,一个是NAME,一个是FORM。通过调用函数 REUSE_ALV_EVENTS_GET,系统会给GT_EVENT赋值多行name,其中name字段值为 top_of_page 和 end_of_list 的行就是我们需要的。然后我们给这两行的form字段分别赋值。
PERFORM BUILD_EVENTS.
FORM BUILD_EVENTS.
CALL FUNCTION 'REUSE_ALV_EVENTS_GET'
EXPORTING
I_LIST_TYPE = 0
IMPORTING
ET_EVENTS = GT_EVENT
EXCEPTIONS
LIST_TYPE_WRONG = 1
OTHERS = 2
.
IF SY-SUBRC <> 0.
* Implement suitable error handling here
ENDIF.
READ TABLE GT_EVENT WITH KEY NAME = 'TOP_OF_PAGE' INTO GW_EVENT.
IF SY-SUBRC = 0.
MOVE 'FRM_TOP_OF_PAGE' TO GW_EVENT-FORM.
MODIFY GT_EVENT FROM GW_EVENT INDEX SY-TABIX.
ENDIF.
READ TABLE GT_EVENT WITH KEY NAME = 'END_OF_LIST' INTO GW_EVENT.
IF SY-SUBRC = 0.
GW_EVENT-FORM = 'FRM_END_OF_LIST'.
MODIFY GT_EVENT FROM GW_EVENT INDEX SY-TABIX.
ENDIF.
ENDFORM.
完成EVENT的相关赋值后,就是listheader的赋值了,上面提到的gt_event内表中两个name行分别赋值form字段。这就是下面要写的form。
首先是top_of_page, 对应的form是 frm_top_of_page.
基本上就是给 listheader内表写值,typ 代表标题(H,字体变大)或内容(S),key 为关键内容(加黑),info为普通行。赋值完毕后,最后的函数调用才是关键,也是文章最开头我们提到的那个function:REUSE_ALV_COMMENTARY_WRITE .作用是将内容展现在页眉。
FORM FRM_TOP_OF_PAGE.
DATA:STR1 TYPE STRING.
CLEAR:GT_LISTHEADER,GW_LISTHEADER.
GW_LISTHEADER-TYP = 'H'.
GW_LISTHEADER-KEY = ''.
GW_LISTHEADER-INFO = '测试报表抬头'.
APPEND GW_LISTHEADER TO GT_LISTHEADER.
CLEAR:GW_LISTHEADER.
DESCRIBE TABLE GT_TEST LINES STR1.
CONDENSE STR1 NO-GAPS.
CONCATENATE '报表条目数共计: ' STR1 INTO STR1.
GW_LISTHEADER-TYP = 'S'.
GW_LISTHEADER-KEY = '页眉:'.
GW_LISTHEADER-INFO = STR1.
APPEND GW_LISTHEADER TO GT_LISTHEADER.
CLEAR:GW_LISTHEADER.
CALL FUNCTION 'REUSE_ALV_COMMENTARY_WRITE'
EXPORTING
IT_LIST_COMMENTARY = GT_LISTHEADER
* I_LOGO = ''
* I_END_OF_LIST_GRID =
* I_ALV_FORM =
.
ENDFORM.
同理,页脚展示如下:
FORM FRM_END_OF_LIST.
DATA:STR2 TYPE STRING.
CONCATENATE '创建者:' SY-UNAME INTO STR2.
CLEAR:GT_LISTHEADER,GW_LISTHEADER.
GW_LISTHEADER-TYP = 'S'.
GW_LISTHEADER-KEY = '页尾:'.
GW_LISTHEADER-INFO = STR2.
APPEND GW_LISTHEADER TO GT_LISTHEADER.
CLEAR:GW_LISTHEADER,STR2.
CONCATENATE '时间:' SY-DATUM(4) '-' SY-DATUM+4(2) '-' SY-DATUM+6(2) INTO STR2.
GW_LISTHEADER-TYP = 'S'.
* GW_LISTHEADER-KEY = 'X'.
GW_LISTHEADER-INFO = STR2.
APPEND GW_LISTHEADER TO GT_LISTHEADER.
CALL FUNCTION 'REUSE_ALV_COMMENTARY_WRITE'
EXPORTING
IT_LIST_COMMENTARY = GT_LISTHEADER
* I_LOGO =
* I_END_OF_LIST_GRID =
* I_ALV_FORM =
.
ENDFORM.
总结:上述完毕,最后要想展现出页眉和页脚,在展示报表的函数中,一定不能忘记给参数赋值:IT_EVENTS = GT_EVENT.这里我们调用的REUSE_ALV_GRID_DISPLAY函数。
此外,REUSE_ALV_COMMENTARY_WRITE .这个函数我们这里提一下,我们只用到了exporting的第一行,也就是listheader内表导入。其中i_logo参数也可以使用,会展示图片。比如我们 i_logo = ‘ENJOYSAP_LOGO’ 会展现系统自带的图片。
贴出一个简单的报表小例子:
这里我们没有使用数据结构,但是GUI状态需要建立,例子中使用的名字是9000.
*&---------------------------------------------------------------------*
*& Report ZTEST
*&
*&---------------------------------------------------------------------*
REPORT ZTEST.
TYPE-POOLS:SLIS.
TABLES:MARA,MARC.
DATA: GT_FIELDCAT TYPE SLIS_T_FIELDCAT_ALV,
GS_LAYOUT TYPE SLIS_LAYOUT_ALV,
GS_GRID TYPE REF TO CL_GUI_ALV_GRID.
DATA:GT_EVENT TYPE SLIS_T_EVENT,
GW_EVENT LIKE LINE OF GT_EVENT.
DATA:GT_LISTHEADER TYPE SLIS_T_LISTHEADER,
GW_LISTHEADER LIKE LINE OF GT_LISTHEADER.
DATA:L_REPID LIKE SY-REPID."当前程序名"
L_REPID = SY-REPID.
TYPES:BEGIN OF TY_TEST,
MATNR TYPE MAKT-MATNR,
WERKS TYPE MARC-WERKS,
DISPO TYPE MARC-DISPO,
MAKTX TYPE MAKT-MAKTX,
END OF TY_TEST.
DATA:GT_TEST TYPE TABLE OF TY_TEST,
GW_TEST TYPE TY_TEST.
SELECTION-SCREEN BEGIN OF BLOCK B1 WITH FRAME TITLE TEXT-001.
SELECT-OPTIONS : S_MATNR FOR MARA-MATNR,
S_WERKS FOR MARC-WERKS.
SELECTION-SCREEN END OF BLOCK B1.
START-OF-SELECTION.
PERFORM SET_LAYOUT.
PERFORM SET_FIELDCAT.
PERFORM GET_DATA.
PERFORM BUILD_EVENTS.
PERFORM SHOW_ALV.
FORM SET_LAYOUT.
GS_LAYOUT-ZEBRA = 'X'.
GS_LAYOUT-COLWIDTH_OPTIMIZE = 'X'."设置最优宽度"
ENDFORM.
FORM SET_FIELDCAT.
DATA:GW_FIELDCAT TYPE SLIS_FIELDCAT_ALV.
DATA: COLNUM TYPE I VALUE 1.
GW_FIELDCAT-COL_POS = COLNUM.
GW_FIELDCAT-FIELDNAME = 'MATNR'.
GW_FIELDCAT-SELTEXT_S = '物料号'.
GW_FIELDCAT-LZERO = 'X'.
GW_FIELDCAT-KEY = 'X'.
GW_FIELDCAT-HOTSPOT = 'X'.
APPEND GW_FIELDCAT TO GT_FIELDCAT.
CLEAR:GW_FIELDCAT.
COLNUM = COLNUM + 1.
GW_FIELDCAT-COL_POS = COLNUM.
GW_FIELDCAT-FIELDNAME = 'WERKS'.
GW_FIELDCAT-SELTEXT_S = '工厂'.
APPEND GW_FIELDCAT TO GT_FIELDCAT.
CLEAR:GW_FIELDCAT.
COLNUM = COLNUM + 1.
GW_FIELDCAT-COL_POS = COLNUM.
GW_FIELDCAT-FIELDNAME = 'DISPO'.
GW_FIELDCAT-SELTEXT_S = 'MRP控制'.
APPEND GW_FIELDCAT TO GT_FIELDCAT.
CLEAR:GW_FIELDCAT.
COLNUM = COLNUM + 1.
GW_FIELDCAT-COL_POS = COLNUM.
GW_FIELDCAT-FIELDNAME = 'MAKTX'.
GW_FIELDCAT-SELTEXT_S = '物料描述'.
APPEND GW_FIELDCAT TO GT_FIELDCAT.
CLEAR:GW_FIELDCAT.
ENDFORM.
FORM GET_DATA.
SELECT
MARA~MATNR
WERKS
DISPO
MAKTX
INTO TABLE GT_TEST
FROM MARA INNER JOIN MARC ON MARA~MATNR = MARC~MATNR
INNER JOIN MAKT ON MARA~MATNR = MAKT~MATNR
WHERE MARA~MATNR IN S_MATNR
AND WERKS IN S_WERKS.
ENDFORM.
FORM SHOW_ALV.
DATA:IS_VARIANT TYPE DISVARIANT."变式格式"
IS_VARIANT-REPORT = SY-REPID.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
I_CALLBACK_PROGRAM = L_REPID
I_CALLBACK_PF_STATUS_SET = 'FRM_STATUS '
I_CALLBACK_USER_COMMAND = 'FRM_COMMAND '
* I_CALLBACK_TOP_OF_PAGE = ' '
IS_LAYOUT = GS_LAYOUT
IT_FIELDCAT = GT_FIELDCAT
I_SAVE = 'A'
IS_VARIANT = IS_VARIANT
IT_EVENTS = GT_EVENT
TABLES
T_OUTTAB = GT_TEST
EXCEPTIONS
PROGRAM_ERROR = 1
OTHERS = 2
.
IF SY-SUBRC <> 0.
* Implement suitable error handling here
ENDIF.
ENDFORM.
FORM FRM_STATUS USING RT_EXTAB TYPE SLIS_T_EXTAB.
set PF-STATUS '9000'.
ENDFORM.
FORM FRM_COMMAND USING L_UCOMM LIKE SY-UCOMM
W_SELFIELD TYPE SLIS_SELFIELD.
CASE L_UCOMM.
WHEN '&IC1'."单击事件"
WHEN OTHERS.
ENDCASE .
ENDFORM.
FORM BUILD_EVENTS.
CALL FUNCTION 'REUSE_ALV_EVENTS_GET'
EXPORTING
I_LIST_TYPE = 0
IMPORTING
ET_EVENTS = GT_EVENT
EXCEPTIONS
LIST_TYPE_WRONG = 1
OTHERS = 2
.
IF SY-SUBRC <> 0.
* Implement suitable error handling here
ENDIF.
READ TABLE GT_EVENT WITH KEY NAME = 'TOP_OF_PAGE' INTO GW_EVENT.
IF SY-SUBRC = 0.
MOVE 'FRM_TOP_OF_PAGE' TO GW_EVENT-FORM.
MODIFY GT_EVENT FROM GW_EVENT INDEX SY-TABIX.
ENDIF.
READ TABLE GT_EVENT WITH KEY NAME = 'END_OF_LIST' INTO GW_EVENT.
IF SY-SUBRC = 0.
GW_EVENT-FORM = 'FRM_END_OF_LIST'.
MODIFY GT_EVENT FROM GW_EVENT INDEX SY-TABIX.
ENDIF.
ENDFORM.
FORM FRM_TOP_OF_PAGE.
DATA:STR1 TYPE STRING.
CLEAR:GT_LISTHEADER,GW_LISTHEADER.
GW_LISTHEADER-TYP = 'H'.
GW_LISTHEADER-KEY = ''.
GW_LISTHEADER-INFO = '测试报表抬头'.
APPEND GW_LISTHEADER TO GT_LISTHEADER.
CLEAR:GW_LISTHEADER.
DESCRIBE TABLE GT_TEST LINES STR1.
CONDENSE STR1 NO-GAPS.
CONCATENATE '报表条目数共计: ' STR1 INTO STR1.
GW_LISTHEADER-TYP = 'S'.
GW_LISTHEADER-KEY = '页眉:'.
GW_LISTHEADER-INFO = STR1.
APPEND GW_LISTHEADER TO GT_LISTHEADER.
CLEAR:GW_LISTHEADER.
CALL FUNCTION 'REUSE_ALV_COMMENTARY_WRITE'
EXPORTING
IT_LIST_COMMENTARY = GT_LISTHEADER
* I_LOGO = ''
* I_END_OF_LIST_GRID =
* I_ALV_FORM =
.
ENDFORM.
FORM FRM_END_OF_LIST.
DATA:STR2 TYPE STRING.
CONCATENATE '创建者:' SY-UNAME INTO STR2.
CLEAR:GT_LISTHEADER,GW_LISTHEADER.
GW_LISTHEADER-TYP = 'S'.
GW_LISTHEADER-KEY = '页尾:'.
GW_LISTHEADER-INFO = STR2.
APPEND GW_LISTHEADER TO GT_LISTHEADER.
CLEAR:GW_LISTHEADER,STR2.
CONCATENATE '时间:' SY-DATUM(4) '-' SY-DATUM+4(2) '-' SY-DATUM+6(2) INTO STR2.
GW_LISTHEADER-TYP = 'S'.
* GW_LISTHEADER-KEY = 'X'.
GW_LISTHEADER-INFO = STR2.
APPEND GW_LISTHEADER TO GT_LISTHEADER.
CALL FUNCTION 'REUSE_ALV_COMMENTARY_WRITE'
EXPORTING
IT_LIST_COMMENTARY = GT_LISTHEADER
I_LOGO = 'ENJOYSAP_LOGO'
* I_END_OF_LIST_GRID =
* I_ALV_FORM =
.
ENDFORM.