Introduction
Oftentimes, access to SE16 or SE16n is not granted to SAP end-users. This program would allow an analyst to configure their own reports by pointing to existing CDS Views, Views or SAP Tables without writing code. They configure their selection screens by importing an Excel spreadsheet. Lastly, create an SAP Transaction code which points to the report and assign certain users’ authorization to the new transaction. This program is suitable for those SAP installs with HANA.
In my previous blog, here…
http://sapabapcentral.blogspot.com/2018/10/dynamic-selection-screen-with-alv-ida.html
…we combined an Excel upload, Dynamic Select Option generation, displayed on a Popup Screen and showed the results in ALV IDA created for HANA. To fully understand this Blog, it is recommended that you read the above Blog, first. However, if you want to skip the details, just go to the “Program Walkthrough” section below, see how it works, then get the code.
In this blog, we will enhance this program from the above blog, to make it re-runnable without re-importing the Excel file each time. We will also add a new column, where you may specify a Transaction Code, to allow the program to dynamically generate the report based on the Transaction Code entered and store many reports in your configuration table.
Software Versions:
◈ S/4HANA (SAP_BASIS 752, SAP_ABA 75C)
◈ SAPGUI Version 750
◈ Eclipse Version: Oxygen.3a Release (4.7.3a)
◈ Microsoft Excel (.xlsx capable)
Program Overview
Original Program Flow Diagram
New Program Flow Diagram
Excel File Format
The Excel file will contain either a Table, View or CDS View with the fields that you’d like to appear as Select-Options on your popup window. As an enhancement to the previous program, we will add a new row for a Transaction Code. This will allow us to execute the report via transaction code, without re-loading an Excel spreadsheet each time. In addition, we can store the configuration settings for many reports and their corresponding transaction codes.
Example Excel file with 3 reports:
Column A will contain 3 labels for each report:
◈ Transaction Code
◈ Table, View or CDS View Name
◈ Selection Fields
Column B contains the actual Transaction Code, Table/View/CDS View name and a list of the fields you want to be included as Select Options on the Popup window.
For example, the first report:
◈ B1 = The Custom SAP Transaction Code
◈ B2 = Table, View or CDS View Name
◈ B3+ = List of fields to be included as Select Options
For the CDS View “S_BOOKINGS”, include the fields CARRIERID, FLIGHTDATE, CUSTOMERID, LOCALCURRENCYAMOUNT on the popup window as Select-Options whenever we execute the custom SAP Transaction code ZBOOKINGS.
The popup window for the above, would look like the following:
New Enhancements
New Z Table
First, to support these new features, let’s create a new Z Table, which will hold the configuration for the reports. For a single report, our Excel input has the following format:
Let’s flatten out the structure, to create a schema, like the following:
You could go to SE11 and create the table in the classical manner. In the spirit of utilizing the latest tools, let’s use the Eclipse IDE with the ABAP Development Tools (ADT):
From your project explorer, right-click on the “Dictionary” node and the menu path “New > Database Table”
Enter the following and click “Finish”:
Note, you may choose a different table name, other than ZREPORT. If so, you can simply update this table name, wherever it is referenced in the code.
We now get a general template for a new table:
Overwrite the above with the following data definition:
@EndUserText.label : 'Instant Report Configuration'
@AbapCatalog.enhancementCategory : #EXTENSIBLE_CHARACTER_NUMERIC
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #LIMITED
define table zreport {
key mandt : mandt not null;
key tcode : sytcode not null;
key view_or_table : ddlname not null;
key selection_field : fieldname not null;
}
Save and Activate
You can now go to SE11, and view the above table we just created:
To view the data in our table, we could go to our Eclipse Project Explorer, right-click on the table name and the menu path “Open with > Data Preview”:
Of course, our table is currently empty, but later we can view our imported records here:
In addition to the above, create a table type named ZTTY_REPORT that contains the above as line type ZREPORT:
We will use this table type ZTTY_REPORT in our method parameters, for better readability.
New Methods and Code
Next, let’s add the additional code required for our program.
First, we’ll need some new select options on the screen to support our new functionality. Our new selection screen will be:
The options will perform the following:
Run the Report Only: The report will run by reading the existing configuration table entries in ZREPORT for the Transaction Code entered. If selected, we will hide the “Excel SelOpt File” and “Refresh Table (all entries)” parameters.
Update the Table Only: The Excel File will be read, and the table ZREPORT will be updated. If selected, we will hide the “Transaction Code” selection parameter.
Update Table and Run Report: Execute both of the above options – Update the table and run the report for whatever transaction code is entered.
Refresh Table (all entries):
◈ Checked: If the checkbox is enabled, all entries in the ZREPORT table will first be deleted. Next, all entries in the Excel File will be inserted. That is, a complete refresh from the Excel file.
◈ Unchecked: If the checkbox is disabled – If entries in the Excel file don’t yet exist in the ZREPORT table, they will be inserted (i.e. add a new report). If the entries already exist, they will be updated (overwritten) with the corresponding entry.
The New Selection Screen Code is:
REPORT z_instant_report.
TABLES: zreport.
SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME TITLE mn_lbl.
PARAMETERS: rb_run RADIOBUTTON GROUP gr1 DEFAULT 'X' USER-COMMAND cmd,
rb_load RADIOBUTTON GROUP gr1,
rb_both RADIOBUTTON GROUP gr1.
SELECT-OPTIONS: s_tcode FOR zreport-tcode MODIF ID cfg NO INTERVALS NO-EXTENSION.
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE fil_lbl.
PARAMETERS: p_refr AS CHECKBOX MODIF ID lod,
p_ifile TYPE localfile MODIF ID lod DEFAULT 'c:\1\SeloptFile_ZREPORT.xlsx'.
SELECTION-SCREEN END OF BLOCK b1.
SELECTION-SCREEN END OF BLOCK b2.
In the INITIALIZATION section, add the labels for the new selection screen elements:
INITIALIZATION.
%_p_ifile_%_app_%-text = 'Excel SelOpt File'.
fil_lbl = 'Excel Input File'.
mn_lbl = 'Program Options'.
%_rb_run_%_app_%-text = 'Run the Report Only'.
%_rb_load_%_app_%-text = 'Update the Table Only'.
%_rb_both_%_app_%-text = 'Update Table and Run Report'.
%_p_refr_%_app_%-text = 'Refresh Table (all entries)'.
%_s_tcode_%_app_%-text = 'Transaction Code'.
Depending on which radio button we select, let’s hide the selections that are not relevant. After the INITIALIZATION event, add the new event “AT SELECTION-SCREEN OUTPUT” to the program and add the following code:
AT SELECTION-SCREEN OUTPUT.
IF rb_run = abap_true. "Report Only
LOOP AT SCREEN.
IF screen-group1 = 'LOD'.
screen-active = '0'. "Hide
MODIFY SCREEN.
ENDIF.
IF screen-group1 = 'CFG'.
screen-active = '1'. "Show
MODIFY SCREEN.
ENDIF.
ENDLOOP.
ELSEIF rb_load = abap_true. "Update Table only
LOOP AT SCREEN.
IF screen-group1 = 'LOD'.
screen-active = '1'. "Show
MODIFY SCREEN.
ENDIF.
IF screen-group1 = 'CFG'.
screen-active = '0'. "Hide
MODIFY SCREEN.
ENDIF.
ENDLOOP.
ELSEIF rb_both = abap_true. "Update Table and Run Report
LOOP AT SCREEN.
IF screen-group1 = 'LOD'.
screen-active = '1'. "Show
MODIFY SCREEN.
ENDIF.
IF screen-group1 = 'CFG'.
screen-active = '1'. "Show
MODIFY SCREEN.
ENDIF.
ENDLOOP.
ENDIF.
In our original program, we simply passed the Excel file and the report was run with the following call:
NEW lcl_dynamic_sel( )->execute( CONV string( p_ifile ) ).
To support our new options, let’s add a new structure that may be passed to the execute method. In the public section of the class, add the following code:
CLASS lcl_dynamic_sel DEFINITION CREATE PUBLIC FINAL.
PUBLIC SECTION.
CONSTANTS: c_excel TYPE string VALUE 'Excel files(*.xlsx)|*.xlsx'.
TYPES: BEGIN OF lty_selopts,
filename TYPE string,
tcode TYPE sytcode,
refresh TYPE boolean,
run_only TYPE boolean,
load_only TYPE boolean,
run_and_load TYPE boolean,
END OF lty_selopts.
Rename the import parameter for the execute method and use this type:
METHODS:
execute
IMPORTING im_selopts type lty_selopts.
Adjust the call to the following for the execute method:
START-OF-SELECTION.
NEW lcl_dynamic_sel( )->execute( value #(
filename = CONV string( p_ifile )
tcode = s_tcode-low
refresh = p_refr
run_only = rb_run
load_only = rb_load
run_and_load = rb_both ) ).
We will have 2 entry points for this class, the EXECUTE method and the EXECUTE_REPORT method.
New EXECUTE Method:
Here is the code for our new execute method:
METHOD execute. "Called from the Selection Screen...
IF im_selopts-run_only = abap_true.
run_report( get_config_table( im_selopts-tcode ) ).
ELSEIF im_selopts-load_only = abap_true.
update_config_data( it_config = get_excel_data( im_selopts-filename )
im_refresh = im_selopts-refresh ).
ELSEIF im_selopts-run_and_load = abap_true.
update_config_data( it_config = get_excel_data( im_selopts-filename )
im_refresh = im_selopts-refresh ).
run_report( get_config_table( im_selopts-tcode ) ).
ENDIF.
ENDMETHOD. "execute
This method is called when running the program from the regular selection screen (i.e. SE38).
New EXECUTE_REPORT Method:
This method is called whenever a Transaction code is entered by the user. It will then auto-launch the report by reading the config table for that TCode. The code for this method is:
METHOD execute_report. "Called from a TCode...
NEW lcl_dynamic_sel( )->execute( VALUE #( tcode = sy-tcode
run_only = abap_true ) ).
ENDMETHOD. "execute_report
We simply instantiate the report, but with only the TCode and run_only options.
See the complete program for all other changes, including the following methods:
BUILD_SELECT_OPTIONS: Adjust this method to handle a table, rather than the Excel spreadsheet.
GET_CONFIG_TABLE : A new method to fetch the contents of the configuration table (ZREPORT), to be passed to the updated BUILD_SELECT_OPTIONS method.
EXECUTE_REPORT: A new public class method, which will allow the program to be executed from a Transaction Code. We will walkthrough this setup later.
UPDATE_CONFIG_DATA: A new method to update the ZREPORT configuration table, after reading the Excel input file.
RUN_REPORT: Our original EXECUTE method is renamed to this method. Our new EXECUTE method will evaluate the select options, and execute the various methods, see below.
Program Walkthrough
Initial Setup
The program will give you the ability to setup a transaction code, in order to launch a report that you’ve stored in your ZREPORT configuration table. This enables you to also setup authorizations for that transaction code, assign to certain users, etc. First, let’s setup a new transaction code for each of our 3 reports, as follows. We can create a transaction code, which executes a method within a local class of a program (doesn’t have to be a global class!). Here are the steps:
Execute the transaction SE93 and enter the Transaction ZBOOKINGS and click “Create”:
Enter a description for your report and select the option “Method of a class (OO transaction)” and click Continue:
Uncheck the “OO transaction model”, and a new field will appear, which will allow you to specify a local method in our program. Enter the following:
Notice that since we are simply pointing to our method, we can easily copy the above TCode twice and name them ZMARA and ZFINANCE.
From SE93, enter the ZBOOKINGS Transaction Code and click the copy button:
Repeat the above for ZFINANCE. That’s it! Nothing to change in these copied TCodes, because the EXECUTE_REPORT method looks at sy-tcode to see which report to run:
METHOD execute_report. "Called from a TCode...
NEW lcl_dynamic_sel( )->execute( VALUE #( tcode = sy-tcode
run_only = abap_true ) ).
ENDMETHOD. "execute_report
As you may have guessed, if you always run the program from the standard selection screen (i.e. via SE38), you could execute various reports without ever creating an actual TCode in SE93.
Running the Report
Let’s walk through the program and see how it works…
The first screen has the following select options:
As mentioned earlier, some of the above options will be hidden, depending on which radio button you select. The default will look like the following:
Run the Report Only (Option 1):
The default selection screen will look like the following:
Enter one of our transaction codes from earlier, for example ZBOOKINGS:
Execute the program (F8), and you will get the following pop-up selections:
These are the 4 select options we specified in the ZREPORT table earlier:
Execute the selection pop-up and see the results of the CDS view:
The above method of executing the program, enters via the EXECUTE method.
Now, let’s enter the SAP Transaction ZBOOKINGS directly from the TCode box (enter /NZBOOKINGS and hit enter):
You will now get the same pop-up and results as above:
This method of executing the program checks our setup for the TCode in SE93, and calls the EXECUTE_REPORT method in our program:
Try out the ZMARA and ZFINANCE TCodes to see the reports we have setup:
ZMARA:
Selection Screen:
ZFINANCE:
Selection Screen:
Update the Table Only (Option 2):
When selecting the second radio button, you will get the following screen:
This screen will enable you to read an Excel file (format discussed earlier), and update the ZREPORT table. The checkbox “Refresh Table (all entries):”, will delete all entries in the ZREPORT table, and replace them will those entries in the Excel spreadsheet. If you leave this unchecked, only entries in the Excel Spreadsheet will be updated (for records that already exist) or inserted (for new records).
When executing with our Excel file from early, you will get the following pop-up message telling you that the 14 entries have been updated in the ZREPORT table:
If you also selected the “Refresh…” option, an additional pop-up message will tell you the table was completely refreshed.
Update Table and Run Report (Option 3):
When selecting the 3rd radio button, you will get the following screen:
Just as it says, it will execute both options, first updating the ZREPORT table, then executing the specified Transaction Code (i.e. ZBOOKINGS).
Complete Program
REPORT z_instant_report.
TABLES: zreport.
SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME TITLE mn_lbl.
PARAMETERS: rb_run RADIOBUTTON GROUP gr1 DEFAULT 'X' USER-COMMAND cmd,
rb_load RADIOBUTTON GROUP gr1,
rb_both RADIOBUTTON GROUP gr1.
SELECT-OPTIONS: s_tcode FOR zreport-tcode MODIF ID cfg NO INTERVALS NO-EXTENSION.
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE fil_lbl.
PARAMETERS: p_refr AS CHECKBOX MODIF ID lod,
p_ifile TYPE localfile MODIF ID lod DEFAULT 'c:\1\SeloptFile_ZREPORT.xlsx'.
SELECTION-SCREEN END OF BLOCK b1.
SELECTION-SCREEN END OF BLOCK b2.
CLASS lcl_dynamic_sel DEFINITION CREATE PUBLIC FINAL.
PUBLIC SECTION.
CONSTANTS: c_excel TYPE string VALUE 'Excel files(*.xlsx)|*.xlsx'.
TYPES: BEGIN OF lty_selopts,
filename TYPE string,
tcode TYPE sytcode,
refresh TYPE boolean,
run_only TYPE boolean,
load_only TYPE boolean,
run_and_load TYPE boolean,
END OF lty_selopts,
BEGIN OF lty_flabel,
name TYPE fieldname,
text TYPE rstxtmd,
END OF lty_flabel,
ltty_flabel_tab TYPE SORTED TABLE OF lty_flabel WITH UNIQUE KEY name,
BEGIN OF lty_selopt,
name TYPE string,
text TYPE rstxtmd,
select_option TYPE sci_refdat,
END OF lty_selopt,
ltty_selopt TYPE STANDARD TABLE OF lty_selopt.
CLASS-METHODS:
select_file
IMPORTING i_filename TYPE string
i_type TYPE string
RETURNING VALUE(re_file) TYPE localfile,
execute_report.
METHODS:
execute
IMPORTING im_selopts TYPE lty_selopts.
PRIVATE SECTION.
METHODS:
get_excel_data
IMPORTING im_file TYPE string
RETURNING VALUE(rt_table) TYPE ztty_report,
get_field_labels
IMPORTING im_tabview TYPE string
EXPORTING et_field_labels TYPE ltty_flabel_tab
e_cds_view TYPE boolean,
build_select_options
IMPORTING it_config TYPE ztty_report
EXPORTING e_cds_view_name TYPE ddlname
et_selopts TYPE ltty_selopt
e_cds_view TYPE boolean,
update_config_data
IMPORTING it_config TYPE ztty_report
im_refresh TYPE boolean,
get_config_table
IMPORTING im_tcode TYPE sytcode
RETURNING VALUE(rt_table) TYPE ztty_report,
run_report
IMPORTING it_config TYPE ztty_report.
ENDCLASS. "lcl_dynamic_sel
CLASS lcl_dynamic_sel IMPLEMENTATION.
METHOD execute_report. "Called from a TCode...
NEW lcl_dynamic_sel( )->execute( VALUE #( tcode = sy-tcode
run_only = abap_true ) ).
ENDMETHOD. "execute_report
METHOD execute. "Called from the Selection Screen...
IF im_selopts-run_only = abap_true.
run_report( get_config_table( im_selopts-tcode ) ).
ELSEIF im_selopts-load_only = abap_true.
update_config_data( it_config = get_excel_data( im_selopts-filename )
im_refresh = im_selopts-refresh ).
ELSEIF im_selopts-run_and_load = abap_true.
update_config_data( it_config = get_excel_data( im_selopts-filename )
im_refresh = im_selopts-refresh ).
run_report( get_config_table( im_selopts-tcode ) ).
ENDIF.
ENDMETHOD. "execute
METHOD get_config_table.
IF im_tcode IS INITIAL. RETURN. ENDIF.
SELECT * INTO TABLE rt_table FROM zreport WHERE tcode = im_tcode.
IF rt_table[] IS INITIAL.
MESSAGE |No entries found in ZREPORT table for TCode { im_tcode }.| TYPE 'I'.
ENDIF.
ENDMETHOD. "get_config_table
METHOD update_config_data.
IF im_refresh = abap_true.
SELECT * INTO TABLE @DATA(lt_delete) FROM zreport.
DELETE zreport FROM TABLE lt_delete.
COMMIT WORK AND WAIT.
MESSAGE |ZREPORT config table was refreshed (all entries deleted).| TYPE 'I'.
ELSE.
DELETE zreport FROM TABLE it_config.
COMMIT WORK AND WAIT.
ENDIF.
INSERT zreport FROM TABLE it_config.
COMMIT WORK AND WAIT.
SELECT COUNT( * ) INTO @DATA(lv_count) FROM zreport.
MESSAGE |{ lv_count } Records loaded to the ZREPORT config table.| TYPE 'I'.
ENDMETHOD. "update_config_table
METHOD run_report.
DATA: lt_popup_selections TYPE sci_atttab.
IF it_config[] IS INITIAL. RETURN. ENDIF.
build_select_options( EXPORTING it_config = it_config
IMPORTING e_cds_view_name = DATA(lv_cds_view_name)
et_selopts = DATA(lt_select_options)
e_cds_view = DATA(lv_is_cds_view) ).
IF lv_cds_view_name IS INITIAL. RETURN. ENDIF.
IF lt_select_options[] IS INITIAL.
MESSAGE |No selection fields specified for '{ lv_cds_view_name }'.| TYPE 'I'.
RETURN.
ENDIF.
LOOP AT lt_select_options ASSIGNING FIELD-SYMBOL().
APPEND VALUE #( ref = -select_option
kind = 'S'
text = -text )
TO lt_popup_selections.
ENDLOOP.
DATA(lv_result) = cl_ci_query_attributes=>generic(
EXPORTING
p_name = CONV #( sy-repid )
p_title = 'Enter Field Selections'
p_attributes = lt_popup_selections
p_display = abap_false " General Flag
).
IF lv_result = 'X'. RETURN. ENDIF.
IF lv_is_cds_view = abap_true.
DATA(lo_alv_cds) = cl_salv_gui_table_ida=>create_for_cds_view( iv_cds_view_name = CONV dbtabl( lv_cds_view_name ) ).
ELSE.
DATA(lo_alv) = cl_salv_gui_table_ida=>create( iv_table_name = CONV dbtabl( lv_cds_view_name ) ).
ENDIF.
DATA(lo_collector) = NEW cl_salv_range_tab_collector( ).
LOOP AT lt_select_options INTO DATA(lw_sel).
ASSIGN lw_sel-select_option->* TO FIELD-SYMBOL().
IF IS NOT INITIAL.
lo_collector->add_ranges_for_name( iv_name = lw_sel-name it_ranges = ).
ENDIF.
UNASSIGN .
ENDLOOP.
lo_collector->get_collected_ranges( IMPORTING et_named_ranges = DATA(lt_name_range_pairs) ).
IF lv_is_cds_view = abap_true.
lo_alv_cds->set_select_options( it_ranges = lt_name_range_pairs ) .
lo_alv_cds->fullscreen( )->display( ) .
ELSE.
lo_alv->set_select_options( it_ranges = lt_name_range_pairs ) .
lo_alv->fullscreen( )->display( ) .
ENDIF.
ENDMETHOD. "run_report
METHOD select_file.
re_file = cl_openxml_helper=>browse_local_file_open(
iv_title = 'Select File'
iv_filename = i_filename
iv_extpattern = i_type ).
ENDMETHOD. "select_file
METHOD get_excel_data.
DATA: lt_xtab TYPE cpt_x255,
lv_size TYPE i,
lw_record TYPE zreport.
FIELD-SYMBOLS: TYPE table.
CALL METHOD cl_gui_frontend_services=>gui_upload
EXPORTING
filename = im_file
filetype = 'BIN'
IMPORTING
filelength = lv_size
CHANGING
data_tab = lt_xtab
EXCEPTIONS
OTHERS = 1.
IF sy-subrc NE 0.
MESSAGE |Invalid File { im_file }| TYPE 'I'.
RETURN.
ENDIF.
cl_scp_change_db=>xtab_to_xstr( EXPORTING im_xtab = lt_xtab
im_size = lv_size
IMPORTING ex_xstring = DATA(lv_xstring) ).
DATA(lo_excel) = NEW cl_fdt_xl_spreadsheet( document_name = im_file
xdocument = lv_xstring ).
lo_excel->if_fdt_doc_spreadsheet~get_worksheet_names(
IMPORTING worksheet_names = DATA(lt_worksheets) ).
DATA(lo_table) = lo_excel->if_fdt_doc_spreadsheet~get_itab_from_worksheet( lt_worksheets[ 1 ] ).
ASSIGN lo_table->* TO .
LOOP AT ASSIGNING FIELD-SYMBOL().
ASSIGN COMPONENT 1 OF STRUCTURE TO FIELD-SYMBOL().
ASSIGN COMPONENT 2 OF STRUCTURE TO FIELD-SYMBOL().
IF IS INITIAL. EXIT. ENDIF.
CASE .
WHEN 'Transaction Code:'.
CLEAR lw_record.
lw_record-tcode = .
WHEN 'CDS View/View/Table Name:'.
lw_record-view_or_table = .
WHEN 'Selection Fields:' OR ''.
lw_record-selection_field = .
APPEND lw_record TO rt_table.
ENDCASE.
ENDLOOP.
ENDMETHOD. "get_excel_data
METHOD get_field_labels.
DATA: lw_dtel TYPE rsddtel.
SELECT l~fieldname, l~rollname INTO TABLE @DATA(lt_elements) FROM dd03l AS l
JOIN ddldependency AS d ON l~tabname = d~objectname
WHERE d~ddlname = @im_tabview AND d~state = 'A' AND d~objecttype = 'VIEW'.
IF sy-subrc <> 0.
SELECT fieldname rollname INTO TABLE lt_elements FROM dd03l
WHERE tabname = im_tabview.
ELSE.
e_cds_view = abap_true.
ENDIF.
LOOP AT lt_elements INTO DATA(lw_elem).
CLEAR lw_dtel.
CALL FUNCTION 'RSD_DTEL_GET'
EXPORTING
i_dtelnm = lw_elem-rollname
IMPORTING
e_s_dtel = lw_dtel
EXCEPTIONS
dtel_not_found = 1
doma_not_found = 2
illegal_input = 3
OTHERS = 4.
IF sy-subrc <> 0. CONTINUE. ENDIF.
INSERT VALUE lty_flabel( name = lw_elem-fieldname
text = lw_dtel-txtmd ) INTO TABLE et_field_labels.
ENDLOOP.
ENDMETHOD. "get_field_labels
METHOD build_select_options.
DATA: lo_cds_data TYPE REF TO data,
lr_structdescr TYPE REF TO cl_abap_structdescr,
lr_tabledescr TYPE REF TO cl_abap_tabledescr,
lr_datadescr TYPE REF TO cl_abap_datadescr,
lr_typedescr TYPE REF TO cl_abap_typedescr,
lt_selopts TYPE abap_component_tab,
lw_component TYPE abap_componentdescr,
lo_wa TYPE REF TO data,
lo_tab TYPE REF TO data.
FIELD-SYMBOLS: TYPE any.
IF it_config[] IS INITIAL. RETURN. ENDIF.
DATA(lv_cds_view) = it_config[ 1 ]-view_or_table.
get_field_labels( EXPORTING im_tabview = CONV #( lv_cds_view )
IMPORTING et_field_labels = DATA(lt_fdesc)
e_cds_view = e_cds_view ).
IF lt_fdesc[] IS INITIAL.
MESSAGE |Invalid CDS View, Table or View Name '{ lv_cds_view }'.| TYPE 'I'.
RETURN.
ENDIF.
CREATE DATA lo_cds_data TYPE (lv_cds_view).
ASSIGN lo_cds_data->* TO .
DATA(lt_components) = CAST cl_abap_structdescr( cl_abap_typedescr=>describe_by_name( lv_cds_view ) )->components.
LOOP AT it_config ASSIGNING FIELD-SYMBOL().
ASSIGN COMPONENT 'SELECTION_FIELD' OF STRUCTURE TO FIELD-SYMBOL().
IF line_exists( lt_components[ name = ] ).
CLEAR: lr_structdescr, lr_tabledescr, lr_datadescr, lr_typedescr,
lt_selopts[], lw_component, lo_wa, lo_tab.
lw_component-name = 'SIGN'.
lw_component-type ?= cl_abap_elemdescr=>get_c( p_length = 1 ).
INSERT lw_component INTO TABLE lt_selopts.
CLEAR lw_component.
lw_component-name = 'OPTION'.
lw_component-type ?= cl_abap_elemdescr=>get_c( p_length = 2 ).
INSERT lw_component INTO TABLE lt_selopts.
CLEAR lw_component.
lw_component-name = 'LOW'.
lw_component-type ?= cl_abap_elemdescr=>describe_by_name( |{ lv_cds_view }-{ }| ).
INSERT lw_component INTO TABLE lt_selopts.
CLEAR lw_component-name.
lw_component-name = 'HIGH'.
lw_component-type ?= cl_abap_elemdescr=>describe_by_name( |{ lv_cds_view }-{ }| ).
INSERT lw_component INTO TABLE lt_selopts.
lr_structdescr ?= cl_abap_structdescr=>create( lt_selopts ).
CREATE DATA lo_wa TYPE HANDLE lr_structdescr.
ASSIGN lo_wa->* TO FIELD-SYMBOL().
lr_datadescr ?= lr_structdescr.
lr_tabledescr ?= cl_abap_tabledescr=>create( lr_datadescr ).
CREATE DATA lo_tab TYPE HANDLE lr_tabledescr.
ASSIGN lo_tab->* TO FIELD-SYMBOL().
APPEND VALUE #( name =
text = lt_fdesc[ name = ]-text
select_option = REF #( ) )
TO et_selopts.
ELSE.
MESSAGE |Invalid field { }| TYPE 'I'.
ENDIF.
UNASSIGN: , , .
ENDLOOP.
e_cds_view_name = lv_cds_view.
ENDMETHOD. "build_select_options
ENDCLASS. "lcl_dynamic_sel
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_ifile.
p_ifile = lcl_dynamic_sel=>select_file( i_filename = CONV string( p_ifile )
i_type = lcl_dynamic_sel=>c_excel ).
INITIALIZATION.
%_p_ifile_%_app_%-text = 'Excel SelOpt File'.
fil_lbl = 'Excel Input File'.
mn_lbl = 'Program Options'.
%_rb_run_%_app_%-text = 'Run the Report Only'.
%_rb_load_%_app_%-text = 'Update the Table Only'.
%_rb_both_%_app_%-text = 'Update Table and Run Report'.
%_p_refr_%_app_%-text = 'Refresh Table (all entries)'.
%_s_tcode_%_app_%-text = 'Transaction Code'.
AT SELECTION-SCREEN OUTPUT.
IF rb_run = abap_true. "Report Only
LOOP AT SCREEN.
IF screen-group1 = 'LOD'.
screen-active = '0'. "Hide
MODIFY SCREEN.
ENDIF.
IF screen-group1 = 'CFG'.
screen-active = '1'. "Show
MODIFY SCREEN.
ENDIF.
ENDLOOP.
ELSEIF rb_load = abap_true. "Update Table only
LOOP AT SCREEN.
IF screen-group1 = 'LOD'.
screen-active = '1'. "Show
MODIFY SCREEN.
ENDIF.
IF screen-group1 = 'CFG'.
screen-active = '0'. "Hide
MODIFY SCREEN.
ENDIF.
ENDLOOP.
ELSEIF rb_both = abap_true. "Update Table and Run Report
LOOP AT SCREEN.
IF screen-group1 = 'LOD'.
screen-active = '1'. "Show
MODIFY SCREEN.
ENDIF.
IF screen-group1 = 'CFG'.
screen-active = '1'. "Show
MODIFY SCREEN.
ENDIF.
ENDLOOP.
ENDIF.
START-OF-SELECTION.
NEW lcl_dynamic_sel( )->execute( VALUE #(
filename = CONV string( p_ifile )
tcode = s_tcode-low
refresh = p_refr
run_only = rb_run
load_only = rb_load
run_and_load = rb_both ) ).
No comments:
Post a Comment