1, 用到的函数,类方法
下面介绍一个能根据所选表字段自动创建动态select-options的例子代码,代码中用到了以下函数和类方法:
1, FREE_SELECTIONS_INIT:初始化动态选择画面
2, FREE_SELECTIONS_DIALOG:弹出生成动态select-options的字段选择窗口
3, FREE_SELECTIONS_WHERE_2_EX:转换数据格式,RSDS_TWHERE ==> RSDS_TEXPR
4, cl_alv_table_create=>create_dynamic_table :创建动态内表
2, 例子代码
完整代码如下:感兴趣可以自己debug看看。
REPORT ztest_dynamic_selection. *---------------------------------------------------------------------- *Tables * *---------------------------------------------------------------------- TABLES : sscrfields, "Fields on selection screens dd03l. "Table Fields *---------------------------------------------------------------------- *Type Pools * *---------------------------------------------------------------------- TYPE-POOLS:rsds. *---------------------------------------------------------------------- *Selection Screen * *---------------------------------------------------------------------- SELECTION-SCREEN : BEGIN OF BLOCK b1 WITH FRAME TITLE text-001, SKIP, BEGIN OF LINE, COMMENT 1(5) text-002. PARAMETERS : p_tab LIKE dd03l-tabname OBLIGATORY. "Table name SELECTION-SCREEN : PUSHBUTTON 45(8) p_btn USER-COMMAND clk, "Select-options END OF LINE, END OF BLOCK b1. *---------------------------------------------------------------------- *Types * *---------------------------------------------------------------------- TYPES: BEGIN OF t_dd03l, tabname LIKE dd03l-tabname, "Table Name fieldname LIKE dd03l-fieldname, "Field Name keyflag LIKE dd03l-keyflag, "Key Flag rollname LIKE dd03l-rollname, "Roll Name position LIKE dd03l-position, "Position ddtext(30), "Description END OF t_dd03l, BEGIN OF t_fields. INCLUDE STRUCTURE dd03l. TYPES: END OF t_fields. TYPES : BEGIN OF t_tabs. "To hold the table names INCLUDE STRUCTURE rsdstabs. TYPES : END OF t_tabs. TYPES : BEGIN OF t_flds. "To hold the field names INCLUDE STRUCTURE rsdsfields. TYPES : END OF t_flds. TYPES : BEGIN OF t_fname, "To hold the field names fld LIKE dd03l-fieldname, END OF t_fname. *---------------------------------------------------------------------- *Internal Tables * *---------------------------------------------------------------------- DATA : it_dd03l TYPE TABLE OF t_dd03l, "To hold the field names it_tabs TYPE TABLE OF t_tabs, "To hold the table names it_flds TYPE TABLE OF t_flds, "To hold the field names it_temp TYPE TABLE OF t_flds, "Temp. table to hold field names it_fields TYPE TABLE OF t_fields, "To hold the field names it_cat TYPE TABLE OF lvc_s_fcat, "To hold Field Catalog it_fname TYPE TABLE OF t_fname. *---------------------------------------------------------------------- *Work areas * *---------------------------------------------------------------------- DATA: d_ref TYPE REF TO data , "Data reference wa_dd03l LIKE LINE OF it_dd03l, "Workarea for IT_DD03L wa_tabs LIKE LINE OF it_tabs, "Workarea for IT_TABS wa_flds LIKE LINE OF it_flds, "Workarea for IT_FLDS wa_temp LIKE LINE OF it_temp, "Workarea for IT_TEMP wa_fields LIKE LINE OF it_fields, "Workarea for IT_FIELDS wa_cat LIKE LINE OF it_cat , "Workarea for IT_CAT wa_fname LIKE LINE OF it_fname. "Workarea for IT_FNAME *---------------------------------------------------------------------- *Field Symbols * *---------------------------------------------------------------------- FIELD-SYMBOLS : <f_fs> TYPE table. "FieldSymbol for holding fields *---------------------------------------------------------------------- *Variables * *---------------------------------------------------------------------- DATA: gx_texpr TYPE rsds_texpr, "Variable to hold Expression gx_twhere TYPE rsds_twhere, "Variable to hold Where Clause gv_selid LIKE rsdynsel-selid, "Variable to hold Selid gv_actnum LIKE sy-tfill, "Variable to hold no of fields gv_title LIKE sy-title, "Variable to hold Title gv_where_cl(100) TYPE c, "Variable to hold Where clause gv_tbname LIKE dd03l-tabname, gv_temp. SELECT-OPTIONS: s_fld FOR dd03l-fieldname NO-DISPLAY, "To hold fields selected s_selop FOR dd03l-fieldname NO-DISPLAY, "To hold fields for creating dyn. select-options s_where FOR gv_where_cl NO-DISPLAY. "To hold where condition PARAMETERS: gv_t_old LIKE dd03l-tabname NO-DISPLAY. "Earlier Table name DATA : gt_grid TYPE REF TO cl_gui_alv_grid, gt_cust TYPE REF TO cl_gui_custom_container, "Custom Container cust TYPE scrfname VALUE 'CC_OUTPUT'. "Custom controller *---------------------------------------------------------------------- *Constants * *---------------------------------------------------------------------- CONSTANTS: gc_i TYPE c VALUE 'I', gc_eq(2) TYPE c VALUE 'EQ'. *---------------------------------------------------------------------- *Initialization * *---------------------------------------------------------------------- INITIALIZATION. **--Initialize values PERFORM initialize. *---------------------------------------------------------------------- *At Selection Screen * *---------------------------------------------------------------------- AT SELECTION-SCREEN. *--Select the fields of the input table PERFORM select_flds. *---------------------------------------------------------------------- *Start Of Selection * *---------------------------------------------------------------------- START-OF-SELECTION. *--Fetch data to display output PERFORM fetch_data. *---------------------------------------------------------------------- *End Of Selection * *---------------------------------------------------------------------- END-OF-SELECTION. CALL SCREEN '0300'. *---------------------------------------------------------------------- *At User Command * *---------------------------------------------------------------------- AT USER-COMMAND. CASE sy-ucomm. WHEN 'OK'. REFRESH it_temp. CLEAR it_temp. MOVE 'S' TO wa_temp-type. MOVE gv_tbname TO wa_temp-tablename. DO. READ LINE sy-index FIELD VALUE gv_temp INTO gv_temp. IF sy-subrc NE 0. EXIT. ENDIF. IF gv_temp EQ 'X'. sy-index = sy-index - 1. READ TABLE it_dd03l INTO wa_dd03l INDEX sy-index. IF sy-subrc = 0. MOVE wa_dd03l-fieldname TO wa_temp-fieldname. APPEND wa_temp TO it_temp. CLEAR gv_temp. ENDIF. ENDIF. ENDDO. DESCRIBE TABLE it_temp. IF sy-tfill GT 70. **--More than 70 fields can not be selected MESSAGE 'Cannot select more than 70 Parameters' TYPE 'I'. REFRESH it_temp[]. CLEAR it_temp. ELSE. LEAVE LIST-PROCESSING. ENDIF. WHEN 'CANCEL'. LEAVE LIST-PROCESSING. WHEN 'SELALL'. **--Select all fields CLEAR wa_dd03l-fieldname. DO. READ LINE sy-index. IF sy-subrc EQ 0 AND wa_dd03l-fieldname NE space. gv_temp = 'X'. MODIFY LINE sy-index INDEX 0 FIELD VALUE gv_temp. HIDE gv_temp. CLEAR wa_dd03l-fieldname. ELSEIF sy-subrc NE 0. EXIT. ENDIF. ENDDO. WHEN 'DSELALL'. **--Deselect all fields CLEAR gv_temp. DO. READ LINE sy-index. IF sy-subrc EQ 0. CLEAR gv_temp. MODIFY LINE sy-index INDEX 0 FIELD VALUE gv_temp FROM gv_temp. HIDE gv_temp. ELSEIF sy-subrc NE 0. EXIT. ENDIF. ENDDO. ENDCASE. sy-lsind = 0. *&--------------------------------------------------------------------- *& Form INITIALIZE *&--------------------------------------------------------------------- * Initialize values on selection-screen *---------------------------------------------------------------------- FORM initialize . p_btn = 'Options'(003). ENDFORM. " INITIALIZE *&--------------------------------------------------------------------- *& Form SELECT_FLDS *&--------------------------------------------------------------------- * Select fields from the table *---------------------------------------------------------------------- FORM select_flds . CASE sscrfields-ucomm. WHEN 'CLK'. **--Display Screen with the list of fields PERFORM genr_scr. ENDCASE. ENDFORM. " SELECT_FLDS *&--------------------------------------------------------------------- *& Form genr_scr *&--------------------------------------------------------------------- * Display a screen with list of fields *---------------------------------------------------------------------- FORM genr_scr. **--If table in the parameter is not the same as the old table and **--old table is not blank, then initialise all the variables associated IF p_tab NE gv_t_old AND gv_t_old IS NOT INITIAL. REFRESH: it_tabs, it_flds, gx_texpr, gx_twhere, s_where, s_selop. CLEAR: gv_selid. **--Pass current table parameter value to Old table parameter gv_t_old = p_tab. ENDIF. **--Pass the current table name to old table variable IF gv_t_old EQ space. gv_t_old = p_tab. ENDIF. **--Check if table name is given before clicking the button IF p_tab IS INITIAL. MESSAGE 'Enter the Table name' TYPE 'E'. ENDIF. **--Get the list of fields of a given table PERFORM get_selections. **--If none of the fields, provide the list of fields for selecting IF it_flds[] IS INITIAL. CLEAR gv_selid. PERFORM select_fieldlist. ENDIF. **--Show message if none of the fields are selected IF it_flds[] IS INITIAL. MESSAGE 'No parameters selected' TYPE 'S'. EXIT. ENDIF. **--Generate dynamic select-options REFRESH it_tabs. CLEAR : it_tabs, wa_tabs. wa_tabs-prim_tab = p_tab. APPEND wa_tabs TO it_tabs. PERFORM set_values. **--Generate Expression from Where clause CALL FUNCTION 'FREE_SELECTIONS_WHERE_2_EX' EXPORTING where_clauses = gx_twhere IMPORTING expressions = gx_texpr EXCEPTIONS incorrect_expression = 1 OTHERS = 2. IF sy-subrc NE 0. MESSAGE 'Error in Dynamic screen generation' TYPE 'I'. EXIT. ENDIF. IF gx_texpr IS NOT INITIAL. **--Populate values to select-options from expression PERFORM set_values. ENDIF. **--Display screen with the fields listed IF gv_selid IS NOT INITIAL. PERFORM call_screen. ENDIF. ENDFORM. " genr_scr *&--------------------------------------------------------------------- *& Form GET_SELECTIONS *&--------------------------------------------------------------------- * Fetch the fields in the table given *---------------------------------------------------------------------- FORM get_selections. DATA : wa_where LIKE LINE OF gx_twhere. REFRESH: it_flds, gx_twhere. CLEAR : wa_flds. wa_flds-tablename = p_tab. wa_flds-type = 'S'. LOOP AT s_selop. **--Populate all the fields selected that are previously selected wa_flds-fieldname = s_selop-low. APPEND wa_flds TO it_flds. ENDLOOP. IF s_where[] IS NOT INITIAL. **--Populate values to where condition if any data is previously given **--to the dynamic select-options wa_where-tablename = p_tab. LOOP AT s_where. APPEND s_where-low TO wa_where-where_tab. ENDLOOP. APPEND wa_where TO gx_twhere. ENDIF. ENDFORM. " GET_SELECTIONS *&--------------------------------------------------------------------- *& Form SELECT_FIELDLIST *&--------------------------------------------------------------------- * Display the list of fields *---------------------------------------------------------------------- FORM select_fieldlist. CLEAR: it_dd03l[], it_dd03l, gv_tbname. **--Get field names for given table SELECT tabname fieldname keyflag rollname position FROM dd03l INTO TABLE it_dd03l WHERE tabname EQ p_tab AND fieldname NE 'MANDT'. IF sy-subrc = 0. SORT it_dd03l BY position. DELETE it_dd03l WHERE fieldname CP '.INCLU*'. ENDIF. **--Get the description of the fields LOOP AT it_dd03l INTO wa_dd03l. IF NOT wa_dd03l-rollname IS INITIAL. SELECT SINGLE ddtext FROM dd04t INTO wa_dd03l-ddtext WHERE rollname EQ wa_dd03l-rollname AND ddlanguage = sy-langu AND as4local = 'A'. MODIFY it_dd03l FROM wa_dd03l. ELSE. SELECT SINGLE ddtext FROM dd03t INTO wa_dd03l-ddtext WHERE tabname EQ wa_dd03l-tabname AND ddlanguage = sy-langu AND as4local = 'A' AND fieldname = wa_dd03l-fieldname. MODIFY it_dd03l FROM wa_dd03l. ENDIF. ENDLOOP. gv_tbname = p_tab. **--Display screen with the fields listed for the given table CALL SCREEN 200 STARTING AT 10 2 ENDING AT 70 22. **--Clear all the fields selected CLEAR : it_flds, it_flds[], gv_tbname. **--Populate the newly selected fields it_flds[] = it_temp[]. **--Clear temporary table with the fields selected CLEAR : it_temp, it_temp[]. ENDFORM. " SELECT_FIELDLIST *&--------------------------------------------------------------------- *& Form INITIALIZE_SCREEN *&--------------------------------------------------------------------- FORM initialize_screen. CALL FUNCTION 'FREE_SELECTIONS_INIT' EXPORTING kind = 'T' expressions = gx_texpr IMPORTING selection_id = gv_selid number_of_active_fields = gv_actnum TABLES tables_tab = it_tabs fields_tab = it_flds EXCEPTIONS fields_incomplete = 01 fields_no_join = 02 field_not_found = 03 no_tables = 04 table_not_found = 05 expression_not_supported = 06 incorrect_expression = 07 illegal_kind = 08 area_not_found = 09 inconsistent_area = 10 kind_f_no_fields_left = 11 kind_f_no_fields = 12 too_many_fields = 13. ENDFORM. " INITIALIZE_SCREEN *&--------------------------------------------------------------------- *& Form SET_VALUES *&--------------------------------------------------------------------- * Set the values to the select-options *---------------------------------------------------------------------- FORM set_values. CALL FUNCTION 'FREE_SELECTIONS_INIT' EXPORTING kind = 'T' expressions = gx_texpr IMPORTING selection_id = gv_selid number_of_active_fields = gv_actnum TABLES tables_tab = it_tabs fields_tab = it_flds EXCEPTIONS fields_incomplete = 01 fields_no_join = 02 field_not_found = 03 no_tables = 04 table_not_found = 05 expression_not_supported = 06 incorrect_expression = 07 illegal_kind = 08 area_not_found = 09 inconsistent_area = 10 kind_f_no_fields_left = 11 kind_f_no_fields = 12 too_many_fields = 13. ENDFORM. " SET_VALUES *&--------------------------------------------------------------------- *& Form CALL_SCREEN *&--------------------------------------------------------------------- * Call the screen to display the fields *---------------------------------------------------------------------- FORM call_screen. DATA : wa_where LIKE LINE OF gx_twhere, lv_txt TYPE string. lv_txt = 'Dynamic Selections Parameters for'(007). CONCATENATE lv_txt p_tab INTO gv_title SEPARATED BY space. CALL FUNCTION 'FREE_SELECTIONS_DIALOG' EXPORTING selection_id = gv_selid title = gv_title tree_visible = ' ' IMPORTING where_clauses = gx_twhere expressions = gx_texpr number_of_active_fields = gv_actnum TABLES fields_tab = it_flds EXCEPTIONS internal_error = 01 no_action = 02 no_fields_selected = 03 no_tables_selected = 04 selid_not_found = 05. IF sy-subrc EQ 0. REFRESH: s_where, s_selop. **--Populate the Where clause with selected values s_where-sign = gc_i. s_where-option = gc_eq. CLEAR wa_where. READ TABLE gx_twhere INDEX 1 INTO wa_where. LOOP AT wa_where-where_tab INTO s_where-low. APPEND s_where. ENDLOOP. **--Populate all the fields s_selop-sign = gc_i. s_selop-option = gc_eq. CLEAR : wa_flds. LOOP AT it_flds INTO wa_flds. s_selop-low = wa_flds-fieldname. APPEND s_selop. ENDLOOP. ENDIF. ENDFORM. " CALL_SCREEN *&--------------------------------------------------------------------- *& Module STATUS_0200 OUTPUT *&--------------------------------------------------------------------- * Display screen with select-options *---------------------------------------------------------------------- MODULE status_0200 OUTPUT. DATA: lv_txt TYPE string. lv_txt = 'Selection Paramters List'(008). SET PF-STATUS 'DIALOG'. LEAVE TO LIST-PROCESSING AND RETURN TO SCREEN 0. SUPPRESS DIALOG. MOVE lv_txt TO sy-title. **--display list of fields that can be selected for creating dynamic select-options LOOP AT it_dd03l INTO wa_dd03l. AT FIRST. WRITE: (60) sy-uline. ENDAT. READ TABLE it_flds INTO wa_flds WITH KEY fieldname = wa_dd03l-fieldname. IF sy-subrc NE 0. CLEAR gv_temp. ELSE. gv_temp = 'X'. ENDIF. WRITE:/ '|' ,gv_temp AS CHECKBOX. WRITE: (20) wa_dd03l-fieldname,'|', wa_dd03l-ddtext, AT 60 '|'. HIDE: gv_temp, wa_dd03l-fieldname, wa_dd03l-keyflag. AT LAST. WRITE: (60) sy-uline. ENDAT. ENDLOOP. ENDMODULE. " STATUS_0200 OUTPUT *&--------------------------------------------------------------------- *& Form FETCH_DATA *&--------------------------------------------------------------------- * Fetch data from table *---------------------------------------------------------------------- FORM fetch_data . DATA: lv_where TYPE string, lv_cnt TYPE i. **--Check for the existance of the table SELECT * FROM dd03l INTO TABLE it_fields WHERE tabname = p_tab. SORT it_fields BY position. **--Delete the fields starting with .INCLU DELETE it_fields WHERE fieldname CP '.INCLU*'. **--Display the first 150 fields of the table LOOP AT it_fields INTO wa_fields TO 150. lv_cnt = lv_cnt + 1. wa_cat-tabname = p_tab. wa_cat-fieldname = wa_fields-fieldname. wa_cat-col_pos = lv_cnt. wa_cat-inttype = wa_fields-inttype. wa_cat-datatype = wa_fields-datatype. wa_cat-intlen = wa_fields-intlen. wa_cat-seltext = wa_fields-fieldname. wa_cat-decimals = wa_fields-decimals. wa_cat-ref_field = wa_fields-fieldname. wa_cat-ref_table = p_tab. APPEND wa_cat TO it_cat. CLEAR wa_cat. wa_fname-fld = wa_fields-fieldname. APPEND wa_fname TO it_fname. CLEAR wa_fname. ENDLOOP. **--Create a dynamic internal table with the 150 fields CALL METHOD cl_alv_table_create=>create_dynamic_table EXPORTING it_fieldcatalog = it_cat IMPORTING ep_table = d_ref. ASSIGN d_ref->* TO <f_fs>. **--Populate the Where clause as a string LOOP AT s_where. CONCATENATE lv_where s_where-low INTO lv_where SEPARATED BY space. ENDLOOP. **--Select the data from the table given as input and populate **--it into the dynamic internal table created based on the where condition SELECT (it_fname) FROM (p_tab) INTO CORRESPONDING FIELDS OF TABLE <f_fs> WHERE (lv_where). **--If no entries are found that satisfies the selection criteria IF sy-subrc <> 0. MESSAGE 'No data found' TYPE 'I'. ENDIF. ENDFORM. " FETCH_DATA *&--------------------------------------------------------------------- *& Form DISPLAY_DATA *&--------------------------------------------------------------------- * Display data in the grid control *---------------------------------------------------------------------- FORM display_data . IF gt_cust IS INITIAL. CREATE OBJECT gt_cust EXPORTING container_name = cust. CREATE OBJECT gt_grid EXPORTING i_parent = gt_cust. **--Display the data in the grid control CALL METHOD gt_grid->set_table_for_first_display EXPORTING i_buffer_active = 'X' i_bypassing_buffer = ' ' CHANGING it_outtab = <f_fs> it_fieldcatalog = it_cat EXCEPTIONS invalid_parameter_combination = 1 program_error = 2 too_many_lines = 3 OTHERS = 4. IF sy-subrc <> 0. ENDIF. ENDIF. ENDFORM. " DISPLAY_DATA *&--------------------------------------------------------------------- *& Module DISPLAY_DATA OUTPUT *&--------------------------------------------------------------------- * Dispaly data in the output *---------------------------------------------------------------------- MODULE display_data OUTPUT. PERFORM display_data. ENDMODULE. " DISPLAY_DATA OUTPUT *&--------------------------------------------------------------------- *& Module STATUS_0300 OUTPUT *&--------------------------------------------------------------------- * Pf-status for the screen *---------------------------------------------------------------------- MODULE status_0300 OUTPUT. SET PF-STATUS '13317'. ENDMODULE. " STATUS_0300 OUTPUT *&--------------------------------------------------------------------- *& Module USER_COMMAND_0300 INPUT *&--------------------------------------------------------------------- * Handling the button clicks *---------------------------------------------------------------------- MODULE user_command_0300 INPUT. CASE sy-ucomm. **--Go to the previous screen WHEN 'BACK'. LEAVE TO SCREEN 0. **--Come out of the program WHEN 'EXIT'. LEAVE PROGRAM. ENDCASE. ENDMODULE. " USER_COMMAND_0300 INPUT
代码中用到了两个status:
1,DIALOG
2,13317
另外还要创建两个屏幕,200和300,
1,screen 0200
代码:
PROCESS BEFORE OUTPUT. **--Set PF-STATUS MODULE STATUS_0200. PROCESS AFTER INPUT.
2,Screen 0300
代码:
PROCESS BEFORE OUTPUT. **--Set PF-STATUS MODULE STATUS_0300. **--Display data using custom controller MODULE DISPLAY_DATA. PROCESS AFTER INPUT. **--Handle button clicks MODULE USER_COMMAND_0300.
3, 运行方法
运行如下:
输入表名后,点击options按钮选择动态select-options用到的字段,
然后进入下一屏,可以填入select-options的条件,也可以点击上面New field selection按钮添加或删除select-opions的字段。
最后,返回到初始选择画面,运行出结果,
以上。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/19259.html