Reports with class
In
MVC (model view controller) framework for ABAP part 1 you can find the "starter kit" for a framework you can use to create applications that are using dynpros and CFW controls that the framework is able to control. In this second part I will introduce only one further class that can be used for report programming. In my daily work, I am using this report very frequently as a template for new ones.
The demo application
Just like the demo application in the first part, the application contains the framework class that you can extract to a public class for reusing the code.
Application screen You can upload the screen 0001 from the file attached. Other than in the first part, we do not need a subscreen here. All we need is an empty screen that is able to carry the docking container in which we will place an ALV with the result list.
Selection screen controller The selection screen is controlled by the new class ZCL_MVCFW_CON_SELSCR. The controller derives from the class ZCL_MVCFW_CON_DYNPRO and extends it only with two methods
How it works
In order to get everything to work, a few steps are necessary. Let's go through it step by step.
Selection screen interface To simplify the passing of selection screen parameters between the classes, I use always a local interface that contains a structured type with all input elements from the selection screen
You can see that I use the same names for the components as for the selection screen elements:
Global data Some global variables are indispensible:
INITIALIZATION Here the main controller is instantiated. After that, the
get_con_dynpro method is called to create a controller for the actual dynpro, which is the selection screen.
PAI The PAI event of a selection screen is
at selection-screen, so we call the PAI of the screen controller, which is a framework method that does the following:
- Ask the main controller to fetch the screen data.
- Therefore, the method get_screen_data of the main controller must be redefined:

As you see, the data is stored in an attribute of the main controller. This can be useful, if you want to react to user inputs during PBO, i.e. switching on/of field attributes and so on.
- Invoke the PAI of the super class, which will compare all component values from the screen with the stored ones in the memory of the framework class ZCL_MVCFW_DYNPRO and call PAI_FIELD_CHANGE on change of values.
START-OF-SELECTION The method
run of the selection-screen controller is called.
RUN The control is passed to the main controller (
run_program), where the main logic of the report begins to work.
Batch/Online processing As you can see in
run_program, there are two branches, one for background processing and one for online. The online branch is similar to the demo in part 1. For the batch processing, a list has to be created instead of calling a screen. Therefore, a list controller has been added to the program, which we derive from the generic CFW controller.
Of course we do not have any CFW control here. But the framework class can be used even without container. In method
refresh the output is coded. In this case, I use CL_SALV_TABLE to produce an output list.
Some notes
I some of my use cases, I use more than one model class because of complexity of the application. In this case, it comes handy to declare common used data types in the interface
lif_report.
All the best
Jörg
*&---------------------------------------------------------------------*
*& Report ZP_MVCFW_REPORT_DEMO
*&
*&---------------------------------------------------------------------*
report zp_mvcfw_report_demo.
interface lif_report.
types:
begin of gty_s_selscreen,
s_carrid type range of sflight-carrid,
s_connid type range of sflight-connid,
s_fldate type range of sflight-fldate,
p_batch type abap_bool,
end of gty_s_selscreen.
endinterface.
class lcl_model definition.
public section.
methods:
read_db
importing is_selection type lif_report=>gty_s_selscreen,
get_out_tab
exporting et_out type standard table.
private section.
data: mt_main_output type table of sflight,
ms_selection type lif_report=>gty_s_selscreen.
endclass. "lcl_model DEFINITION
class lcl_con_selscr_1000 definition deferred.
class lcl_con_main definition inheriting from zcl_mvcfw_con_main.
public section.
constants:
cv_con_alv_out type char32 value 'LCL_CON_ALV_OUT',
cv_con_selscreen_1000 type char32 value 'LCL_CON_SELSCR_1000',
cv_con_list type char32 value 'LCL_CON_LIST'.
methods:
constructor
importing iv_program type syrepid,
pai_main
importing
iv_ucomm type syucomm,
pbo_main redefinition,
run_program,
get_selections redefinition.
protected section.
methods:
create_con_dynpro redefinition,
create_one_controller redefinition.
private section.
data: mo_model type ref to lcl_model,
ms_selscreen type lif_report=>gty_s_selscreen.
endclass. "lcl_con_main DEFINITION
class lcl_con_selscr_1000 definition inheriting from zcl_mvcfw_con_selscr.
public section.
methods:
constructor
importing io_model type ref to lcl_model
io_con_main type ref to lcl_con_main
is_selections type lif_report=>gty_s_selscreen,
run redefinition.
protected section.
methods:
pai_field_change redefinition.
private section.
data: mo_model type ref to lcl_model,
mo_main type ref to lcl_con_main,
" only for background run:
mt_out type table of sflight.
endclass. "lcl_con_selscr_1000 DEFINITION
class lcl_con_alv_out definition inheriting from zcl_mvcfw_con_alv.
public section.
methods:
refresh redefinition,
constructor
importing
io_container type ref to cl_gui_container
io_model type ref to lcl_model
io_main type ref to lcl_con_main
raising zcx_mvcfw_error.
protected section.
methods:
prepare_layout redefinition,
on_double_click redefinition,
on_toolbar redefinition,
on_ucomm redefinition,
prepare_exclude redefinition.
private section.
data: mo_model type ref to lcl_model,
mo_main type ref to lcl_con_main.
endclass. "lcl_con_alv_out DEFINITION
class lcl_con_list definition inheriting from zcl_mvcfw_con_cfw.
public section.
methods:
constructor
importing
io_model type ref to lcl_model
io_main type ref to lcl_con_main,
refresh redefinition.
protected section.
private section.
data: mo_model type ref to lcl_model,
mo_main type ref to lcl_con_main,
mt_out type table of sflight.
endclass.
tables sflight.
select-options: s_carrid for sflight-carrid,
s_connid for sflight-connid,
s_fldate for sflight-fldate.
parameters p_batch as checkbox.
data: gv_okcode type syucomm,
go_sel_screen type ref to lcl_con_selscr_1000,
go_main type ref to lcl_con_main.
*--------------------------------------------------------------------*
* report events
*--------------------------------------------------------------------*
initialization.
" start point: create main and sel.screen controllers
go_main ?= lcl_con_main=>get_instance( ).
go_sel_screen ?= go_main->get_con_dynpro( ).
at selection-screen.
" call pai of sel.screen controller
go_sel_screen->pai( ).
start-of-selection.
" call run routine of sel.screen controller
go_sel_screen->run( ).
class lcl_model implementation.
method read_db.
ms_selection = is_selection.
select * from sflight into table mt_main_output
where carrid in ms_selection-s_carrid and
connid in ms_selection-s_connid and
fldate in ms_selection-s_fldate.
endmethod. "read_db
method get_out_tab.
et_out = mt_main_output.
endmethod. "get_out_tab
endclass. "lcl_model IMPLEMENTATION
class lcl_con_main implementation.
method constructor.
" the report name is needed in the framework
super->constructor( |{ sy-repid }| ).
try.
create object mo_model.
" set parameters of the controller for the GUI interface
set_gui_interface(
exporting
iv_gui_status = 'MAIN' " IV_GUI_STATUS
iv_titlebar = 'MAIN'
).
catch cx_static_check.
leave program.
endtry.
endmethod. "constructor
method pbo_main.
" pbo_main is for screen 0001, NOT for the selection screen
try.
get_con( cv_con_alv_out )->refresh( ).
rv_res = super->pbo_main( ).
catch cx_static_check.
" error handling here
endtry.
endmethod.
method pai_main.
case iv_ucomm.
when 'EXIT' or 'BACK' or 'CANC'.
set screen 0.
leave screen.
endcase.
endmethod. "pai_main
method create_con_dynpro.
case sy-dynnr.
when '1000'.
create object ro_res
type lcl_con_selscr_1000
exporting
io_model = mo_model
io_con_main = me
is_selections = ms_selscreen. " propagate the selection structure
" store the controller object
endcase.
endmethod. "get_con_dynpro
method create_one_controller.
" create each output controller on request
case iv_type.
when cv_con_alv_out.
create object ro_res
type (iv_type)
exporting
io_container = new cl_gui_docking_container(
extension = 9999
)
io_main = me
io_model = mo_model.
when cv_con_list.
" special case list: no container needed
create object ro_res
type (iv_type)
exporting
io_main = me
io_model = mo_model.
endcase.
endmethod. "create_one_controller
method get_selections.
" the only access to the global fields in the selection screen
ms_selscreen-s_carrid = s_carrid[].
ms_selscreen-s_connid = s_connid[].
ms_selscreen-s_fldate = s_fldate[].
ms_selscreen-p_batch = p_batch.
if es_data is supplied.
es_data = ms_selscreen.
endif.
endmethod.
method run_program.
try.
mo_model->read_db( ms_selscreen ).
" decide how to present the data
if sy-batch = abap_true or
ms_selscreen-p_batch = abap_true.
" a list is used
get_con( cv_con_list )->refresh( ).
else.
" an interactive grid is used
call screen 1.
endif.
catch cx_static_check.
" error handling here
endtry.
endmethod.
endclass.
class lcl_con_selscr_1000 implementation.
method constructor.
data: lt_fname type lvc_t_fnam.
" 1. call the general constructor with the structure name
" 2. set the model object
super->constructor( is_selections = is_selections
io_con_main = io_con_main ).
mo_model = io_model.
" concrete main controller from generic via casting
mo_main ?= mo_con_main.
endmethod. "constructor
method pai_field_change.
* try.
* mo_model->perform_field_check( iv_fieldname = iv_fieldname
* iv_source = iv_source ).
* catch zcx_mvcfw_error into data(lo_err).
* message lo_err type 'S' display like 'E'.
* endtry.
endmethod. "pai_field_change
method run.
" pass the control to the main controller
mo_main->run_program( ).
endmethod. "pbo
endclass. "create_con_dynpro
class lcl_con_alv_out implementation.
method constructor.
super->constructor(
io_container = io_container
iv_structure_name = 'sflight' ).
mo_model = io_model.
mo_main = io_main..
endmethod. "constructor
*
method prepare_exclude.
* Example
* append:
* cl_gui_alv_grid=>mc_fc_graph to et_tab.
endmethod. "prepare_exclude
method prepare_layout.
rs_res-cwidth_opt = abap_true.
rs_res-grid_title = 'Flights table'.
endmethod. "prepare_layout
method on_double_click.
field-symbols: <ls_list> type sflight,
<lt_tab> type standard table.
try.
assign mr_table->* to <lt_tab>.
read table <lt_tab> assigning <ls_list> index es_row_no-row_id.
if sy-subrc = 0 .
" include double click functions
endif.
catch zcx_mvcfw_error into data(lo_err).
message lo_err type 'S' display like 'E'.
endtry.
endmethod. "on_double_click
method refresh.
field-symbols: <lt_table> type standard table.
data: ls_layout type lvc_s_layo.
assign mr_table->* to <lt_table>.
mo_model->get_out_tab( importing et_out = <lt_table> ).
refresh_table( ).
endmethod. "refresh
*
method on_toolbar.
data: ls_toolbar type stb_button.
" create user buttons
ls_toolbar-function = 'CLOSE'.
ls_toolbar-icon = icon_close.
append ls_toolbar to e_object->mt_toolbar.
endmethod. "on_toolbar
method on_ucomm.
data: lv_line_index type i.
try.
case e_ucomm.
when 'CLOSE'.
hide( ).
endcase.
catch zcx_mvcfw_error into data(lo_err).
message lo_err type 'S' display like 'E'.
endtry.
endmethod. "on_ucomm_equi
endclass. "lcl_con_alv_out IMPLEMENTATION
class lcl_con_list implementation.
method constructor.
super->constructor( ).
mo_model = io_model.
mo_main = io_main.
endmethod.
*--------------------------------------------------------------------*
* Redefinition: create a abap list (used for batch run)
*--------------------------------------------------------------------*
method refresh.
data lo_salv type ref to cl_salv_table.
mo_model->get_out_tab( importing et_out = mt_out ).
cl_salv_table=>factory(
exporting
list_display = if_salv_c_bool_sap=>true " ALV Displayed in List Mode
importing
r_salv_table = lo_salv " Basis Class Simple ALV Tables
changing
t_table = mt_out
).
lo_salv->get_columns( )->set_optimize( ).
lo_salv->display( ).
endmethod.
endclass.
module pbo_0001 output.
go_main->pbo_main( ).
endmodule.
module pai_0001 input.
go_main->pai_main( iv_ucomm = gv_okcode ).
endmodule.