如有转载请注明出处:http://blog.csdn.net/donkey2004112103/archive/2009/05/17/4193870.aspx
小总结一下函数方法调用alv的过程。其实用函数调用alv非常简单,只需要一个REUSE_ALV_GRID_DISPLAY函数即可(或者list的方式),但是如果要做的复杂的话也可以非常复杂,如我之前的加上异常,单选框,或者加上双击命令,加上各种事件。过于复杂的不讲了,以一个平常项目中够用的例子讲解,还有其他需求直接可以再pack:slis中找到,或者se38中直接输入*demo*就可以看到一堆例子。下面是使用alv的一些必备信息。
1. 类型池(Type-pools)
如果使用函数调用ALV必须要用TYPE-POOLS: SLIS.这个类行池里包含了alv所有要用到的类型,当有哪些字段名称忘记的时候可以到这个pool里查找相应的字段。
2. 字段信息(SLIS_T_FIELDCAT_ALV)
如果我们自己写一个ALV的函数让别人调用,有哪些参数必不可缺了?字段信息肯定必不可全,字段信息决定了ALV到底输出哪些信息。通常有两种方式一是手动,而是自动。
2.1 手动生成
lt_fieldcat TYPE slis_t_fieldcat_alv. “定义字段表
WA_FIELDCAT-TABNAME = 'IT_EKKO'.
WA_FIELDCAT-FIELDNAME = 'EBELN'.
WA_FIELDCAT-SELTEXT_M = 'PO NO.'.
APPEND WA_FIELDCAT TO I_FIELDCAT.
CLEAR WA_FIELDCAT.
这样就完成了一个字段的定义,不过通常都会用一个宏来完成相应的功能。如下:
DEFINE init_key.
clear &1 .
&1-fieldname = &2 .
&1-coltext = &4.
&1-outputlen = &5.
&1-no_zero = 'X' .
&1-key = 'X' . "冻结窗口
append &1 to &3 .
end-OF-DEFINITION.
这样定义多个字段就会比较方便。
2.2 自动生成
自动生成字段信息必须要调用这个函数:
CALL FUNCTION 'REUSE_ALV_FIELDCATALOG_MERGE'
* EXPORTING
* I_PROGRAM_NAME =
* I_INTERNAL_TABNAME =
* I_STRUCTURE_NAME =
* I_CLIENT_NEVER_DISPLAY = 'X'
* I_INCLNAME =
* I_BYPASSING_BUFFER =
* I_BUFFER_ACTIVE =
CHANGING
ct_fieldcat =
* EXCEPTIONS
* INCONSISTENT_INTERFACE = 1
* PROGRAM_ERROR = 2
* OTHERS = 3
通常只需要两个参数,一是changing参数,即输出的字段信息。二是红色标记的部分,如果是一个内表的话就用第一个,有自建表或者系统表的话就用第二个。二者只能填一个,注意使用内表作为参数的话,类型定义只能用like而不能用type。
如果还需要增加或删除一些字段的话只需要修改这个内表就可以了。下面是实例:
*//增加选择项
MOVE 'SELECTED' TO ls_fieldcat-fieldname.
MOVE 'X' TO ls_fieldcat-edit.
MOVE 'X' TO ls_fieldcat-checkbox.
INSERT ls_fieldcat INTO ct_fieldcat INDEX 1.
*//删除不必要显示的项
DELETE ct_fieldcat WHERE fieldname EQ 'INFO_TYPE_CODE'
OR fieldname EQ 'INFO_NUMBER'
OR fieldname EQ 'STATUS'
OR fieldname EQ 'GOODS_LIST_FLAG'
OR fieldname EQ 'COMPANY'
OR fieldname EQ 'COMPANY_NAME'
OR fieldname EQ 'SALES_ORG'
OR fieldname EQ 'SALES_ORG_DESC'
OR fieldname EQ 'MESSAGE'.
*//隐藏一些字段
LOOP AT ct_fieldcat INTO ls_fieldcat WHERE fieldname EQ 'NOTICE_NUMBER'
OR fieldname EQ 'REVERSE_CODE'
OR fieldname EQ 'REVERSE_NUMBER'.
MOVE 'X' TO ls_fieldcat-no_out.
MODIFY ct_fieldcat FROM ls_fieldcat INDEX sy-tabix.
ENDLOOP.
3. 布局设置(SLIS_LAYOUT_ALV)
布局设置参数之多绝对不是一般人能记住,只需要在使用的时候查查,平常使用的参数也比较少。估计colwidth_optimize这个用的多一些。下面一个简单的事例完成了设置布局。
DATA: ls_layout TYPE slis_layout_alv,
PERFORM frm_build_layout CHANGING ls_layout.
FORM frm_build_layout CHANGING cs_layout TYPE slis_layout_alv.
CLEAR cs_layout.
MOVE 'X' TO cs_layout-detail_popup.
MOVE 'X' TO cs_layout-colwidth_optimize.
ENDFORM. "FRM_BUILD_LAYOUT
这样就完成了布局设置。
4. 事件处理(SLIS_T_EVENT)
ALV事件处理有点蹊跷,SAP有一些默认的函数名作为事件函数,我们也可以修改这些函数名。不过为什么不把这些事件函数直接写到调用函数作为参数了,SAP还有一个类型专门保存这个事件名称,还有一些常量,暂时还不明白。在SLIS中这些常量都是事件的名称,如下:
* Events
slis_ev_item_data_expand type slis_formname value 'ITEM_DATA_EXPAND',
slis_ev_reprep_sel_modify type slis_formname value 'REPREP_SEL_MODIFY',
slis_ev_caller_exit_at_start type slis_formname value 'CALLER_EXIT',
slis_ev_user_command type slis_formname value 'USER_COMMAND',
slis_ev_top_of_page type slis_formname value 'TOP_OF_PAGE',
slis_ev_data_changed type slis_formname value 'DATA_CHANGED',
slis_ev_top_of_coverpage type slis_formname value 'TOP_OF_COVERPAGE',
slis_ev_end_of_coverpage type slis_formname value 'END_OF_COVERPAGE',
slis_ev_foreign_top_of_page type slis_formname
value 'FOREIGN_TOP_OF_PAGE',
slis_ev_foreign_end_of_page type slis_formname
value 'FOREIGN_END_OF_PAGE',
slis_ev_pf_status_set type slis_formname value 'PF_STATUS_SET',
slis_ev_list_modify type slis_formname value 'LIST_MODIFY',
slis_ev_top_of_list type slis_formname value 'TOP_OF_LIST',
slis_ev_end_of_page type slis_formname value 'END_OF_PAGE',
slis_ev_end_of_list type slis_formname value 'END_OF_LIST',
slis_ev_after_line_output type slis_formname value 'AFTER_LINE_OUTPUT',
slis_ev_before_line_output type slis_formname value
'BEFORE_LINE_OUTPUT',
slis_ev_subtotal_text type slis_formname value 'SUBTOTAL_TEXT',
slis_ev_grouplevel_change type slis_formname value 'GROUPLEVEL_CHANGE',
slis_ev_context_menu type slis_formname value 'CONTEXT_MENU'.
要让SAP调用自己写的事件分为两部,一是注册这些事件,二是调用ALV函数的时候将保存事件的内表作为参数写入调用ALV函数的参数。
4.1.注册事件
下面的代码注册了一个TOP_OF_PAGE,和一个
GT_EVENTS TYPE SLIS_T_EVENT,
PERFORM EVENTTAB_BUILD USING GT_EVENTS[].
FORM EVENTTAB_BUILD USING RT_EVENTS TYPE SLIS_T_EVENT.
*"Registration of events to happen during list display
DATA: LS_EVENT TYPE SLIS_ALV_EVENT.
*
CALL FUNCTION 'REUSE_ALV_EVENTS_GET'
EXPORTING
I_LIST_TYPE = 0
IMPORTING
ET_EVENTS = RT_EVENTS.
READ TABLE RT_EVENTS WITH KEY NAME = SLIS_EV_TOP_OF_PAGE
INTO LS_EVENT.
IF SY-SUBRC = 0.
MOVE ‘TOP_OF_PAGE’ TO LS_EVENT-FORM.
APPEND LS_EVENT TO RT_EVENTS.
ENDIF.
READ TABLE V_EVENTS INTO WA_EVENT WITH KEY NAME = 'USER_COMMAND'.
IF SY-SUBRC EQ 0.
WA_EVENT-FORM = 'USER_COMMAND'.
MODIFY V_EVENTS FROM WA_EVENT TRANSPORTING FORM WHERE NAME =
WA_EVENT-NAME.
ENDFORM.
接着我们只需要写这两个函数就好了,名字命名和上面注册代码部分一样即可。
4.2.处理事件
处理事件根据上面的例子有两个事件,这两个事件需要两个相应的form,名字就是TOP_OF_PAGE和USER_COMMAND。
FORM TOP_OF_PAGE.
CALL FUNCTION 'REUSE_ALV_COMMENTARY_WRITE'
EXPORTING
IT_LIST_COMMENTARY = IT_LISTHEADER
* i_logo =
* I_END_OF_LIST_GRID =
.
ENDFORM. "TOP_OF_PAGE
FORM BUILD_LISTHEADER USING I_LISTHEADER TYPE SLIS_T_LISTHEADER.
DATA HLINE TYPE SLIS_LISTHEADER.
HLINE-INFO = '黄立 header'.
HLINE-TYP = 'H'.
APPEND HLINE TO I_LISTHEADER.
ENDFORM. "build_listheader
上面的函数完成了在alv中显示页头,效果如下:
抬头字体可以设置类型,有H,S,A其效果各有不同。方便设计出内容丰富的抬头。
用户命令事件,用的非常多,尤其以用户双击事件居多。下面的代码是双击事件的例子。
FORM USER_COMMAND USING R_UCOMM LIKE SY-UCOMM
RS_SELFIELD TYPE SLIS_SELFIELD.
CASE R_UCOMM.
WHEN '&IC1'.
READ TABLE IT_EKKO INTO WA_EKKO INDEX RS_SELFIELD-TABINDEX.
PERFORM BUILD_FIELDCATLOG_EKPO.
PERFORM EVENT_CALL_EKPO.
PERFORM POPULATE_EVENT_EKPO.
PERFORM DATA_RETRIEVAL_EKPO.
PERFORM BUILD_LISTHEADER_EKPO USING IT_LISTHEADER.
PERFORM DISPLAY_ALV_EKPO.
ENDCASE.
ENDFORM. "user_command
其中&IC1代表用户双击,很奇怪的一个字符串。双击事件我们可以再做一个报表的明细数据用ALV显示。上面的例子就是这样的,当然也可以做成用户需要的任何形式。
5. 调用函数
一切完成之后就是最后一步调用function,把刚才的参数全部写进一个函数的参数中。代码如下:
FORM DISPLAY_ALV_REPORT.
V_REPID = SY-REPID.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
I_CALLBACK_PROGRAM = V_REPID
* I_CALLBACK_PF_STATUS_SET = ' '
I_CALLBACK_USER_COMMAND = 'USER_COMMAND'
I_CALLBACK_TOP_OF_PAGE = 'TOP_OF_PAGE'
I_GRID_TITLE = I_TITLE_EKKO
* I_GRID_SETTINGS =
IS_LAYOUT = ALV_LAYOUT
IT_FIELDCAT = I_FIELDCAT[]
I_SAVE = 'A'
* is_variant = i_variant
IT_EVENTS = V_EVENTS
TABLES
T_OUTTAB = IT_EKKO
* EXCEPTIONS
* PROGRAM_ERROR = 1
* OTHERS = 2
.
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. "display_alv_report
所有的刚才设置的参数全部会用在这个函数中,调用完这个函数之后就大功告成,显示出ALV了。如图: