当程序中有互为层级的字段,需要使用搜索帮助时,可以通过多次调用搜索帮助来实现。比如在程序中需要填写省市区三级地址
程序的搜索帮助,通常使用F4IF_INT_TABLE_VALUE_REQUEST来实现。多级的搜索帮助,可以简单的通过多次调用F4函数来实现。
点击省字段,弹出省搜索帮助,根据选择的省份,查询对应的市,弹出市搜索帮助,根据选择的市,查询对应的区县,弹出区县搜索帮助,选择后更新到ALV报表。
同理,点击市则弹出市和区的搜索帮助;点击区则只弹出区的搜索帮助
如图所示:
点击省字段代码示例,省需要写三遍F4:
"--------------------@斌将军--------------------
READ TABLE gt_cjso_alv ASSIGNING 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 .
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 =
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 TO .
= 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 @-zzdeadregion.
ASSIGN lt_v_adrcity TO .
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 =
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 TO .
= gs_return-fieldval.
lv_zzdeadcity = |{ -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 @-zzdeadregion
AND city_code EQ @lv_zzdeadcity.
ASSIGN lt_m_strta TO .
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 =
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 TO .
= gs_return-fieldval.
ENDIF.
ENDIF.
ENDIF.
ENDIF.
ENDIF.
ENDIF.
WHEN 'ZZDEADCITY'."送货地址-市
……
WHEN 'ZZDEADSTREET'."送货地址-区县
……
WHEN OTHERS.
ENDCASE.
PERFORM frm_refresh_alv USING g_grid_9001.
"--------------------@斌将军--------------------
上述方法,虽然能够实现,但是三级地址就需要写五遍重复性代码,如果遇到层级更多的搜索帮助,则需要写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_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 .
ASSIGN lt_t005u TO .
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 .
ASSIGN lt_v_adrcity TO .
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 .
ASSIGN lt_m_strta TO .
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 =
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 .
= 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 INDEX pv_row_no-row_id.
"获取对应数据集
CASE pv_fieldname.
WHEN 'ZZDEADREGION'."送货地址-省
PERFORM frm_callback_f4 USING 1 'ZZDEADREGION' CHANGING .
WHEN 'ZZDEADCITY'."送货地址-市
PERFORM frm_callback_f4 USING 2 'ZZDEADCITY' CHANGING .
WHEN 'ZZDEADSTREET'."送货地址-区县
PERFORM frm_callback_f4 USING 3 'ZZDEADSTREET' CHANGING .
WHEN OTHERS.
ENDCASE.
PERFORM frm_refresh_alv USING g_grid_9001.
ENDFORM.
"--------------------@斌将军--------------------
定期更文,欢迎关注