文章目录
前言
本文记录个人学习笔记。因为ABAP 的开发水平高低不同,可能有些网友看不懂(需要再提升相关ABAP知识),有些网友感觉写的拖拉(高手自然一眼秒懂)。大家都是在ABAP的学习与成长道路中,能看得明白的,适合自己的,才是最好的文章 。还有一点,案例使用的表,是SAP 标准DEMO的航班数据表:SPFLI,去除模块间的数据表的理解差异,专心学会ABAP技术的要点。
本文是在学习了作者:“尤其是十月风” 原创文章 《ABAP ALV(LVC) 下拉框或者F4搜索帮助》 (此贴上链接)的基础上,总结自己的学习心得。所以对作者的原创分享表示感谢。
一、效果图
二、程序思路
对于FUNCTION_ALV 实现下拉,其实是就是F4搜索帮助的变种。
FUNCTION_ALV 实现在拉或F4 ,其实是要借助OOALV容器,然后执行OOALV的参照类: CL_GUI_ALV_GRID 中的方法SET_DROP_DOWN_TABLE ,去指定下拉列表(这里是GT_DROP)
在此之前,在FM_ALV(FUNCTION_ALV) 创建中,涉及FIELDCAT 的 drdn_field 字段设置,指定它。即指定目标字段为下拉,并且下拉框的分组字段是什么。(程序中: gs_fieldcat-drdn_field = ‘DD_HANDLE’.)
在运行FM_ALV 之前,要指定FM_ALV 运行过中的"CALLER_EXIT"事件,此事件,会将FM_ALV装载入到一个OOALV 容器中,然后通过类的方法:SET_DROP_DOWN_TABLE 将我们准备好的下拉框选项表,与字段绑定起来。
现在不明白,不要紧……。
如下三是主程序,直接CV到系统里,即可看到效果,第四部分,将分重点说明 ……
三、主程序
可以直接CTRL+C 复制到自己的系统,运行看效果,慢慢梳理自己的逻辑……,然后,再看四部分,重点解析……
*&---------------------------------------------------------------------*
*& Report ZRAY_LVC_F4_DROPDOWN
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT ZRAY_LVC_F4_DROPDOWN_F.
TYPE-POOLS:slis. "定义事件变量时,要用到这个函数组
TABLES: SPFLI.
TYPES: BEGIN OF ty_spfli,
carrid TYPE char3 , "航线代码
connid TYPE numc4 , "航班连接编号
countryfr TYPE char3 , "国家/地区代码
cityfrom TYPE char20 , "起飞城市
airpfrom TYPE char3 , "始发机场
countryto TYPE char3 , "国家/地区代码
cityto TYPE char20 , "到达城市
airpto TYPE char3 , "目标机场
grade_01 TYPE char10 , "国际航班评级
grade_02 TYPE char10 , "国内航班满意度
dd_handle TYPE INT4 , "评价分组国际国内
END OF ty_spfli.
DATA:
gt_spfli TYPE STANDARD TABLE OF ty_spfli,
gs_spfli TYPE ty_spfli.
DATA:
gt_fieldcat TYPE lvc_t_fcat, " ALV 字段目录“参数表
gs_fieldcat TYPE lvc_s_fcat, " ALV 字段目录“参数表-工作区
gs_layout TYPE lvc_s_layo. "ALV 样式布局 参数 结构
DATA:
GT_DROP TYPE LVC_T_DROP, "下拉菜单的值表:分组:HANDLE 和 值 VALUES
GS_DROP TYPE LVC_S_DROP.
DATA:
GT_EVENTS TYPE SLIS_T_EVENT, "ALV 事件表。
GS_EVENTS TYPE slis_alv_event. "ALV 事件工作区。
SELECT-OPTIONS: s_carr FOR spfli-carrid,
s_conn FOR spfli-connid.
**主程序部分
START-OF-SELECTION.
PERFORM FRM01_GET_DATA.
PERFORM FRM02_FIELDCAT_LAYOUT.
PERFORM FRM03_CREATE_DROPDOWN_VALUES.
PERFORM FRM04_CREATE_EVENTS.
PERFORM FRM05_CALL_ALV.
*&---------------------------------------------------------------------*
*& Form FRM01_GET_DATA
*&---------------------------------------------------------------------*
*& 获取数据
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm01_get_data .
SELECT
carrid "航线代码
connid "航班连接编号
countryfr "国家/地区代码
cityfrom "起飞城市
airpfrom "始发机场
countryto "国家/地区代码
cityto "到达城市
airpto "目标机场
INTO CORRESPONDING FIELDS OF TABLE gt_spfli
FROM spfli
WHERE carrid IN s_carr
AND connid IN s_conn.
IF sy-subrc EQ 0.
LOOP AT gt_spfli INTO gs_spfli.
IF gs_spfli-countryfr = gs_spfli-countryto.
gs_spfli-dd_handle = '1'.
ELSE.
gs_spfli-dd_handle = '2' .
ENDIF.
MODIFY gt_spfli FROM gs_spfli.
ENDLOOP.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM02_FIELDCAT_LAYOUT
*&---------------------------------------------------------------------*
*& 设置
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm02_fieldcat_layout .
DATA: lv_index TYPE sy-index VALUE 0.
gs_layout-zebra = 'X'. "斑马线
gs_layout-cwidth_opt = 'X'.
gs_layout-sel_mode = 'D' . "开启选择模式
DEFINE: fill_field.
lv_index = lv_index + 1.
CLEAR: gs_fieldcat.
gs_fieldcat-col_pos = lv_index.
gs_fieldcat-fieldname = &1.
gs_fieldcat-just = &2.
gs_fieldcat-ref_field = &3.
gs_fieldcat-ref_table = &4.
gs_fieldcat-coltexT = &5.
CASE &1.
WHEN 'GRADE_01' OR 'GRADE_02'.
gs_fieldcat-edit = 'X'.
gs_fieldcat-drdn_field = 'DD_HANDLE'.
* gs_fieldcat-drdn_hndl = '1'.
* WHEN .
* WHEN OTHERS.
ENDCASE.
APPEND gs_fieldcat TO gt_fieldcat.
END-OF-DEFINITION.
** &1 &2 &3 &4 &5
fill_field: 'CARRID' 'C' 'CARRID' 'SPFLI' '航线代码' .
fill_field: 'CONNID' 'C' 'CONNID' 'SPFLI' '航班连接编号' .
fill_field: 'COUNTRYFR' 'R' 'COUNTRYFR' 'SPFLI' '国家/地区代码' .
fill_field: 'CITYFROM' 'R' 'CITYFROM' 'SPFLI' '起飞城市' .
fill_field: 'AIRPFROM' 'R' 'AIRPFROM' 'SPFLI' '始发机场' .
fill_field: 'COUNTRYTO' 'R' 'COUNTRYTO' 'SPFLI' '国家/地区代码' .
fill_field: 'CITYTO' 'R' 'CITYTO' 'SPFLI' '到达城市' .
fill_field: 'AIRPTO' 'R' 'AIRPTO' 'SPFLI' '目标机场' .
fill_field: 'GRADE_01' 'C' '' '' '国际航班评级' .
fill_field: 'GRADE_02' 'C' '' '' '国内航班满意度' .
fill_field: 'DD_HANDLE' 'C' '' '' '评价分组国际国内' .
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM03_CREATE_DROPDOWN_VALUES
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm03_create_dropdown_values .
DEFINE: fill_drop.
CLEAR:gs_drop.
gs_drop-handle = &1.
gs_drop-value = &2.
APPEND gs_drop TO gt_drop.
END-OF-DEFINITION.
** &1 &2
FILL_DROP: '1' '非常满意' .
FILL_DROP: '1' '满意' .
FILL_DROP: '1' '一般' .
FILL_DROP: '1' '不满意' .
FILL_DROP: '2' 'A级' .
FILL_DROP: '2' 'B级' .
FILL_DROP: '2' 'C级' .
FILL_DROP: '2' 'D级' .
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM04_CREATE_EVENTS
*&---------------------------------------------------------------------*
*& 设置下拉框的事件
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm04_create_events .
GS_EVENTS-NAME = 'CALLER_EXIT'.
GS_EVENTS-FORM = 'USER_CALLER_EXIT'.
APPEND GS_EVENTS TO GT_EVENTS.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM05_CALL_ALV
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm05_call_alv .
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
EXPORTING
* I_INTERFACE_CHECK = ' '
* I_BYPASSING_BUFFER =
* I_BUFFER_ACTIVE =
i_callback_program = sy-repid
* I_CALLBACK_PF_STATUS_SET = ' '
* I_CALLBACK_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 =
is_layout_lvc = gs_layout
it_fieldcat_lvc = gt_fieldcat
* IT_EXCLUDING =
* IT_SPECIAL_GROUPS_LVC =
* IT_SORT_LVC =
* IT_FILTER_LVC =
* IT_HYPERLINK =
* IS_SEL_HIDE =
* I_DEFAULT = 'X'
* I_SAVE = ' '
* IS_VARIANT =
IT_EVENTS = GT_EVENTS
* IT_EVENT_EXIT =
* IS_PRINT_LVC =
* IS_REPREP_ID_LVC =
* I_SCREEN_START_COLUMN = 0
* I_SCREEN_START_LINE = 0
* I_SCREEN_END_COLUMN = 0
* I_SCREEN_END_LINE = 0
* I_HTML_HEIGHT_TOP =
* I_HTML_HEIGHT_END =
* IT_ALV_GRAPHICS =
* IT_EXCEPT_QINFO_LVC =
* IR_SALV_FULLSCREEN_ADAPTER =
* IMPORTING
* E_EXIT_CAUSED_BY_CALLER =
* ES_EXIT_CAUSED_BY_USER =
TABLES
t_outtab = gt_spfli
* EXCEPTIONS
* PROGRAM_ERROR = 1
* OTHERS = 2
.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form USER_CALLER_EXIT
*&---------------------------------------------------------------------*
*& 设置下拉列表,使用OOALV 的方法
*&---------------------------------------------------------------------*
*& --> LS_DATA
*& --> TYPE
*& --> SLIS_DATA_CALLER_EXIT
*&---------------------------------------------------------------------*
FORM user_caller_exit USING LS_DATA TYPE SLIS_DATA_CALLER_EXIT.
DATA LO_REF_ALV TYPE REF TO CL_GUI_ALV_GRID.
CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
* EXPORTING
* IR_SALV_FULLSCREEN_ADAPTER =
IMPORTING
* ET_EXCLUDING =
* E_REPID =
* E_CALLBACK_PROGRAM =
* E_CALLBACK_ROUTINE =
E_GRID = LO_REF_ALV.
CALL METHOD lo_ref_alv->set_drop_down_table
EXPORTING
it_drop_down = GT_DROP.
* it_drop_down_alias =
ENDFORM.
四、重点解析
4.1 FIELDCAT-drdn_field 字段
这个字段是用来控制下拉框的,它的意思是控制下拉的分组字段是谁。程序中我指定是的’DD_HANDLE’ 我设想是:国内航班一组评价体系,分组为“1”。国际航班为一组评价体系, 分组为“2”。如下代码可以看出一个下拉框值表里有两个分组。DD_HANDLE值 是在子例程:FORM frm01_get_data 计算得到的(即国内为1,国际为2),如下是下拉框列表值(利用宏写入的)
** &1 &2
FILL_DROP: '1' '非常满意' .
FILL_DROP: '1' '满意' .
FILL_DROP: '1' '一般' .
FILL_DROP: '1' '不满意' .
FILL_DROP: '2' 'A级' .
FILL_DROP: '2' 'B级' .
FILL_DROP: '2' 'C级' .
FILL_DROP: '2' 'D级' .
当然,也可直接设置此列采用那个分组,即 gs_fieldcat-drdn_hndl = ‘1’. (此字段已经注释掉了)所不同的是,不如上边设置灵活了,上边的设置一列字段可以采用多个分组的下拉,而利用drdn_hndl ,设置具体的分组值,一列就只可以用一种分组的下拉列表值。
4.2 下拉列表是怎么来的?
如二、所说思路,绑定下拉列表,我们其实是要通过类:CL_GUI_ALV_GRID 的方法:SET_DROP_DOWN_TABLE
SE24: CL_GUI_ALV_GRID 点参数如下
LVC_T_DROP 就是我们要提前准备好的下拉列表的表类型,其行类型LVC_S_DROP。
所以明白这些,在变量声明部分提前定义,变量定义如下:
DATA:
GT_DROP TYPE LVC_T_DROP, "下拉菜单的值表:分组:HANDLE 和 值 VALUES
GS_DROP TYPE LVC_S_DROP.
4.3 函数:GET_GLOBALS_FROM_SLVC_FULLSCR
这个函数,在中文网站少有全面的介绍。我大体看了一下英文的资料。大概意思是这个函数可以把当前全屏展示的ALV参数输出出来。
包括ALV .FIEDLCAT参数表 LAYOUT 参数结构等。如下是程序中的代码:
FORM user_caller_exit USING LS_DATA TYPE SLIS_DATA_CALLER_EXIT." 这个USING后的参数必须要带。为什么我不知道。
DATA LO_REF_ALV TYPE REF TO CL_GUI_ALV_GRID.
CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
* EXPORTING
* IR_SALV_FULLSCREEN_ADAPTER =
IMPORTING
* ET_EXCLUDING =
* E_REPID =
* E_CALLBACK_PROGRAM =
* E_CALLBACK_ROUTINE =
E_GRID = LO_REF_ALV. "将FM_ALV 装入新建的OOALV容器中
CALL METHOD lo_ref_alv->SET_DROP_DOWN_TABLE "绑定下拉框列表
EXPORTING
it_drop_down = GT_DROP.
* it_drop_down_alias =
ENDFORM.
4.4 FM_ALV 的事件设置
与OOALV 不同,FM_ALV一共有17个事件。(OOALV的事件非常多,可以SE24: CL_GUI_ALV_GRID 自己查看)
FM_ALV的标准事件,可以用函数: REUSE_ALV_EVENTS_GET SE37 直接执行,结果如下
这里我们用到的是‘CALLER_EXIT’ 事件,如下代码的意思是:将FM_ALV调用后,它所对应的事件CALLER_EXIT 触发后,执行USER_CALLER_EXIT 子例程(子例程的名称,可以自由命名的。如也可以起名成:FRM_CALLER_EXIT).
FORM frm04_create_events .
GS_EVENTS-NAME = 'CALLER_EXIT'. "这个事件的名称不能改,一定要如上图复制下来(大写)
GS_EVENTS-FORM = 'USER_CALLER_EXIT'.
APPEND GS_EVENTS TO GT_EVENTS.
ENDFORM.
4.5 最后求解问题……
在’CALLER_EXIT '对应的处理子例程’FORM user_caller_exit’中,需要加上USING LS_DATA TYPE SLIS_DATA_CALLER_EXIT. 入口参数。
这个参数在子例程中,没有用到, 但必须 必须得加上去,否则就会出错。很像 FM_ALV “USER_COMMAND” 和”PF_STATUS_SET" 一样。虽然没有用到参数,但参数必然要回。
期望能有高手,留言给予指点~~~感谢~