1. Demand background
When there are mutually hierarchical fields in the program and you need to use search help, you can do so by calling search help multiple times. For example, in the program, you need to fill in the third-level address of the province, city, and city
2. Implementation method
2.1. Straight talk
Program search help is usually implemented using F4IF_INT_TABLE_VALUE_REQUEST. Multi-level search help can be achieved simply by calling the F4 function multiple times.
Click the province field to pop up the province search help. According to the selected province, query the corresponding city, and the city search help pops up. According to the selected city, query the corresponding district and county, and the district and county search help pops up. After selection, update to the ALV report.
In the same way, if you click on the city, the search help for the city and district will pop up; if you click on the district, only the search help for the district will pop up.
as the picture shows:
Click on the provincial field code example. You need to write F4 three times:
"--------------------@General Bin-------------------- READ TABLE gt_cjso_alv ASSIGNING <fs_cjso_alv> INDEX pv_row_no-row_id. "Get the corresponding data set CASE lv_fieldname1. WHEN 'ZZDEADREGION'."Shipping Address-Province 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'."Shipping address - City … WHEN 'ZZDEADSTREET'."Shipping address-district and county … WHEN OTHERS. ENDCASE. PERFORM frm_refresh_alv USING g_grid_9001. "--------------------@General Bin--------------------
2.2. Simple recursion
Although the above method can be implemented, the third-level address requires writing repetitive code five times. If you encounter search help with more levels, you need to write N(N + 1)/2 times of code, so we can use a recursive function. , repeatedly calling the search help to make the code more concise.
Here is a little explanation, what is a recursive function?
Recursive function: A function that calls itself inside a function is called a recursive function. Recursive functions can transform complex problems into simpler sub-problems to solve. A classic example of a recursive function is the factorial function, where n! is equal to n times (n-1)!. The factorial is calculated inside the function by calling itself.
Extract common code and write recursive functions
"--------------------@General Bin-------------------- FORM frm_callback_f4 USING pv_level pv_fieldname CHANGING ps_alv TYPE ty_cjso_alv. * DATA:lv_zzdeadcity TYPE vbak-zzdeadcity. "Shipping address-city 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. "According to the level, query the data set of the current level and assign the field name of the next level. CASE lv_next_level. WHEN 1."Level 1 Province 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."Layer 2 City 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."Third layer area 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. "Calling the search help function 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."Exit after third level query lv_next_level = lv_next_level + 1. "Call the function itself and start the next cycle PERFORM frm_callback_f4 USING lv_next_level lv_next_field CHANGING ps_alv. ENDIF. ENDIF. ENDIF. ENDFORM. "--------------------@General Bin--------------------
Called when a field is clicked, through the assignment level, multi-level search help can be called cyclically, and the code is simpler and more reusable.
"--------------------@General Bin-------------------- 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. "Get the corresponding data set CASE pv_fieldname. WHEN 'ZZDEADREGION'."Shipping Address-Province PERFORM frm_callback_f4 USING 1 'ZZDEADREGION' CHANGING <fs_cjso_alv>. WHEN 'ZZDEADCITY'."Shipping address - City PERFORM frm_callback_f4 USING 2 'ZZDEADCITY' CHANGING <fs_cjso_alv>. WHEN 'ZZDEADSTREET'."Shipping address-district and county PERFORM frm_callback_f4 USING 3 'ZZDEADSTREET' CHANGING <fs_cjso_alv>. WHEN OTHERS. ENDCASE. PERFORM frm_refresh_alv USING g_grid_9001. ENDFORM. "--------------------@General Bin--------------------
Regular updates, welcome to follow