1、需求背景
当程序中有互为层级的字段,需要使用搜索帮助时,可以通过多次调用搜索帮助来实现。比如在程序中需要填写省市区三级地址
2、实现方式
2.1、平铺直叙
程序的搜索帮助,通常使用F4IF_INT_TABLE_VALUE_REQUEST来实现。多级的搜索帮助,可以简单的通过多次调用F4函数来实现。
点击省字段,弹出省搜索帮助,根据选择的省份,查询对应的市,弹出市搜索帮助,根据选择的市,查询对应的区县,弹出区县搜索帮助,选择后更新到ALV报表。
同理,点击市则弹出市和区的搜索帮助;点击区则只弹出区的搜索帮助
如图所示:
点击省字段代码示例,省需要写三遍F4:
"--------------------@斌将军-------------------- READ TABLE gt_cjso_alv ASSIGNING <fs_cjso_alv> INDEX pv_row_no-row_id. "获取对应数据集 CASE lv_fieldname1. WHEN 'ZZDEADREGION'."送货地址-省 SELECT land1, bland AS zzdeadregion, bezei FROM t005u INTO TABLE @DATA(lt_t005u) WHERE land1 EQ 'CN' AND spras EQ @sy-langu. ASSIGN lt_t005u TO <lt_f4table>. REFRESH gt_return. CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST' EXPORTING retfield = lv_fieldname1 dynpprog = sy-repid dynpnr = sy-dynnr dynprofield = lv_fieldname2 value_org = 'S' display = 'F' TABLES value_tab = <lt_f4table> return_tab = gt_return EXCEPTIONS parameter_error = 1 no_values_found = 2 OTHERS = 3. IF sy-subrc = 0. READ TABLE gt_return INTO gs_return INDEX 1. IF sy-subrc = 0. ASSIGN COMPONENT lv_fieldname1 OF STRUCTURE <fs_cjso_alv> TO <lv_field>. <lv_field> = gs_return-fieldval. SELECT country, region, city_code AS zzdeadcity, city_name FROM v_adrcity INTO TABLE @DATA(lt_v_adrcity) WHERE country EQ 'CN' AND langu EQ @sy-langu AND region EQ @<fs_cjso_alv>-zzdeadregion. ASSIGN lt_v_adrcity TO <lt_f4table>. lv_fieldname = 'ZZDEADCITY'. lv_dynprofld = 'ZZDEADCITY'. REFRESH gt_return. CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST' EXPORTING retfield = lv_fieldname dynpprog = sy-repid dynpnr = sy-dynnr dynprofield = lv_dynprofld value_org = 'S' display = 'F' TABLES value_tab = <lt_f4table> return_tab = gt_return EXCEPTIONS parameter_error = 1 no_values_found = 2 OTHERS = 3. IF sy-subrc = 0. READ TABLE gt_return INTO gs_return INDEX 1. IF sy-subrc = 0. ASSIGN COMPONENT 'ZZDEADCITY' OF STRUCTURE <fs_cjso_alv> TO <lv_field>. <lv_field> = gs_return-fieldval. lv_zzdeadcity = |{ <fs_cjso_alv>-zzdeadcity ALPHA = IN }|. SELECT country, city_code, city_name, strt_code AS zzdeadstreet, street FROM m_strta INTO TABLE @DATA(lt_m_strta) WHERE country EQ 'CN' AND langu EQ @sy-langu AND region EQ @<fs_cjso_alv>-zzdeadregion AND city_code EQ @lv_zzdeadcity. ASSIGN lt_m_strta TO <lt_f4table>. lv_fieldname = 'ZZDEADSTREET'. lv_dynprofld = 'ZZDEADSTREET'. REFRESH gt_return. CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST' EXPORTING retfield = lv_fieldname dynpprog = sy-repid dynpnr = sy-dynnr dynprofield = lv_dynprofld value_org = 'S' display = 'F' TABLES value_tab = <lt_f4table> return_tab = gt_return EXCEPTIONS parameter_error = 1 no_values_found = 2 OTHERS = 3. IF sy-subrc = 0. READ TABLE gt_return INTO gs_return INDEX 1. IF sy-subrc = 0. ASSIGN COMPONENT 'ZZDEADSTREET' OF STRUCTURE <fs_cjso_alv> TO <lv_field>. <lv_field> = gs_return-fieldval. ENDIF. ENDIF. ENDIF. ENDIF. ENDIF. ENDIF. WHEN 'ZZDEADCITY'."送货地址-市 …… WHEN 'ZZDEADSTREET'."送货地址-区县 …… WHEN OTHERS. ENDCASE. PERFORM frm_refresh_alv USING g_grid_9001. "--------------------@斌将军--------------------
2.2、简洁递归
上述方法,虽然能够实现,但是三级地址就需要写五遍重复性代码,如果遇到层级更多的搜索帮助,则需要写N(N+1)/2遍代码,所以我们可以使用递归函数,重复调用搜索帮助,使代码更简洁。
这里说明一点,什么是递归函数?
递归函数:在函数内部调用自身的函数被称为递归函数。递归函数可以将复杂问题转化为更简单的子问题来解决。一个经典的递归函数例子是阶乘函数,其中 n! 等于 n 乘以 (n-1)!。在函数内部通过调用自身来计算阶乘。
抽出通用代码,编写递归函数
"--------------------@斌将军-------------------- FORM frm_callback_f4 USING pv_level pv_fieldname CHANGING ps_alv TYPE ty_cjso_alv. * DATA:lv_zzdeadcity TYPE vbak-zzdeadcity. "送货地址-市 DATA:lt_return TYPE STANDARD TABLE OF ddshretval, ls_return TYPE ddshretval. DATA:lv_next_field TYPE dfies-fieldname, lv_next_level TYPE int4, lv_fieldname TYPE dfies-fieldname, lv_dynprofld TYPE help_info-dynprofld. FIELD-SYMBOLS:<lv_field>. lv_fieldname = pv_fieldname. lv_dynprofld = pv_fieldname. CONDENSE:lv_fieldname,lv_dynprofld NO-GAPS. lv_next_level = pv_level. "根据层级,查询当前层级的数据集,并赋值下一层的字段名 CASE lv_next_level. WHEN 1."第1层 省 SELECT land1, bland AS zzdeadregion, bezei FROM t005u INTO TABLE @DATA(lt_t005u) WHERE land1 EQ 'CN' AND spras EQ @sy-langu. UNASSIGN <gt_f4table>. ASSIGN lt_t005u TO <gt_f4table>. lv_next_field = 'ZZDEADCITY'. WHEN 2."第2层 市 SELECT country, region, city_code AS zzdeadcity, city_name FROM v_adrcity INTO TABLE @DATA(lt_v_adrcity) WHERE country EQ 'CN' AND langu EQ @sy-langu AND region EQ @ps_alv-zzdeadregion. UNASSIGN <gt_f4table>. ASSIGN lt_v_adrcity TO <gt_f4table>. lv_next_field = 'ZZDEADSTREET'. WHEN 3."第3层 区 DATA(lv_zzdeadcity) = |{ ps_alv-zzdeadcity ALPHA = IN }|. SELECT country, city_code, city_name, strt_code AS zzdeadstreet, street FROM m_strta INTO TABLE @DATA(lt_m_strta) WHERE country EQ 'CN' AND langu EQ @sy-langu AND region EQ @ps_alv-zzdeadregion AND city_code EQ @lv_zzdeadcity. UNASSIGN <gt_f4table>. ASSIGN lt_m_strta TO <gt_f4table>. WHEN OTHERS. ENDCASE. "调用搜索帮助函数 CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST' EXPORTING retfield = lv_fieldname dynpprog = sy-repid dynpnr = sy-dynnr dynprofield = lv_dynprofld value_org = 'S' display = 'F' TABLES value_tab = <gt_f4table> return_tab = lt_return EXCEPTIONS parameter_error = 1 no_values_found = 2 OTHERS = 3. IF sy-subrc = 0. READ TABLE lt_return INTO ls_return INDEX 1. IF sy-subrc = 0. ASSIGN COMPONENT lv_fieldname OF STRUCTURE ps_alv TO <lv_field>. <lv_field> = ls_return-fieldval. IF lv_next_level < 3."第三层查询完退出 lv_next_level = lv_next_level + 1. "调用函数本身,开始下次循环 PERFORM frm_callback_f4 USING lv_next_level lv_next_field CHANGING ps_alv. ENDIF. ENDIF. ENDIF. ENDFORM. "--------------------@斌将军--------------------
在点击字段时调用,通过赋值层级,就可以循环调用多级搜索帮助,且代码更加简洁,复用性更高
"--------------------@斌将军-------------------- FORM frm_alv_on_f4_9001 USING pv_fieldname pv_fieldvalue pv_row_no TYPE lvc_s_roid pv_event_data TYPE REF TO cl_alv_event_data pv_display. READ TABLE gt_cjso_alv ASSIGNING <fs_cjso_alv> INDEX pv_row_no-row_id. "获取对应数据集 CASE pv_fieldname. WHEN 'ZZDEADREGION'."送货地址-省 PERFORM frm_callback_f4 USING 1 'ZZDEADREGION' CHANGING <fs_cjso_alv>. WHEN 'ZZDEADCITY'."送货地址-市 PERFORM frm_callback_f4 USING 2 'ZZDEADCITY' CHANGING <fs_cjso_alv>. WHEN 'ZZDEADSTREET'."送货地址-区县 PERFORM frm_callback_f4 USING 3 'ZZDEADSTREET' CHANGING <fs_cjso_alv>. WHEN OTHERS. ENDCASE. PERFORM frm_refresh_alv USING g_grid_9001. ENDFORM. "--------------------@斌将军--------------------
定期更文,欢迎关注
TRANSLATE with x English TRANSLATE with COPY THE URL BELOW Back EMBED THE SNIPPET BELOW IN YOUR SITE Enable collaborative features and customize widget: Bing Webmaster Portal Back 此页面的语言为英语 翻译为中文(简体)
- 中文(简体)
- 中文(繁体)
- 丹麦语
- 乌克兰语
- 乌尔都语
- 亚美尼亚语
- 俄语
- 保加利亚语
- 克罗地亚语
- 冰岛语
- 加泰罗尼亚语
- 匈牙利语
- 卡纳达语
- 印地语
- 印尼语
- 古吉拉特语
- 哈萨克语
- 土耳其语
- 威尔士语
- 孟加拉语
- 尼泊尔语
- 布尔语(南非荷兰语)
- 希伯来语
- 希腊语
- 库尔德语
- 德语
- 意大利语
- 拉脱维亚语
- 挪威语
- 捷克语
- 斯洛伐克语
- 斯洛文尼亚语
- 旁遮普语
- 日语
- 普什图语
- 毛利语
- 法语
- 波兰语
- 波斯语
- 泰卢固语
- 泰米尔语
- 泰语
- 海地克里奥尔语
- 爱沙尼亚语
- 瑞典语
- 立陶宛语
- 缅甸语
- 罗马尼亚语
- 老挝语
- 芬兰语
- 英语
- 荷兰语
- 萨摩亚语
- 葡萄牙语
- 西班牙语
- 越南语
- 阿塞拜疆语
- 阿姆哈拉语
- 阿尔巴尼亚语
- 阿拉伯语
- 韩语
- 马尔加什语
- 马拉地语
- 马拉雅拉姆语
- 马来语
- 马耳他语
- 高棉语