diff --git a/src/demos/zdemo_excel32.prog.abap b/src/demos/zdemo_excel32.prog.abap index 0a16bca..c97e4c9 100644 --- a/src/demos/zdemo_excel32.prog.abap +++ b/src/demos/zdemo_excel32.prog.abap @@ -38,6 +38,8 @@ DATA: lo_excel TYPE REF TO zcl_excel, lo_salv TYPE REF TO cl_salv_table, gr_events TYPE REF TO lcl_handle_events, lr_events TYPE REF TO cl_salv_events_table, + lo_layout TYPE REF TO cl_salv_layout, + ls_layoutkey TYPE salv_s_layout_key, gt_sbook TYPE TABLE OF sbook. DATA: l_path TYPE string, " local dir @@ -88,6 +90,12 @@ START-OF-SELECTION. CREATE OBJECT gr_events. SET HANDLER gr_events->on_user_command FOR lr_events. + lo_layout = lo_salv->get_layout( ). + ls_layoutkey-report = sy-repid. + lo_layout->set_key( ls_layoutkey ). + lo_layout->set_save_restriction( cl_salv_layout=>restrict_none ). + lo_layout->set_default( cl_salv_layout=>true ). + lo_salv->display( ). diff --git a/src/not_cloud/zcl_excel_converter_alv.clas.abap b/src/not_cloud/zcl_excel_converter_alv.clas.abap index c44a423..ec92f33 100644 --- a/src/not_cloud/zcl_excel_converter_alv.clas.abap +++ b/src/not_cloud/zcl_excel_converter_alv.clas.abap @@ -1,18 +1,18 @@ -CLASS zcl_excel_converter_alv DEFINITION - PUBLIC - ABSTRACT - CREATE PUBLIC . +class ZCL_EXCEL_CONVERTER_ALV definition + public + abstract + create public . *"* public components of class ZCL_EXCEL_CONVERTER_ALV *"* do not include other source files here!!! - PUBLIC SECTION. - - INTERFACES zif_excel_converter - ALL METHODS ABSTRACT . - - CLASS-METHODS class_constructor . *"* protected components of class ZCL_EXCEL_CONVERTER_ALV *"* do not include other source files here!!! +public section. + + interfaces ZIF_EXCEL_CONVERTER + all methods abstract . + + class-methods CLASS_CONSTRUCTOR . PROTECTED SECTION. DATA wt_sort TYPE lvc_t_sort . @@ -49,7 +49,7 @@ ENDCLASS. -CLASS zcl_excel_converter_alv IMPLEMENTATION. +CLASS ZCL_EXCEL_CONVERTER_ALV IMPLEMENTATION. METHOD apply_sort. @@ -407,22 +407,118 @@ CLASS zcl_excel_converter_alv IMPLEMENTATION. TYPE any, TYPE STANDARD TABLE. - IF ws_option-filter = abap_false. - CLEAR et_filter. - RETURN. - ENDIF. + CASE 2. - ASSIGN xo_table->* TO . + WHEN 1. - CREATE DATA lo_ltabdata LIKE . - ASSIGN lo_ltabdata->* TO . + IF ws_option-filter = abap_false. + CLEAR et_filter. + RETURN. + ENDIF. - LOOP AT wt_filt INTO ls_filt. - LOOP AT ASSIGNING . - l_line = sy-tabix. - ASSIGN COMPONENT ls_filt-fieldname OF STRUCTURE TO . - IF sy-subrc = 0. - IF l_line = 1. + ASSIGN xo_table->* TO . + + CREATE DATA lo_ltabdata LIKE . + ASSIGN lo_ltabdata->* TO . + + LOOP AT wt_filt INTO ls_filt. + LOOP AT ASSIGNING . + l_line = sy-tabix. + ASSIGN COMPONENT ls_filt-fieldname OF STRUCTURE TO . + IF sy-subrc = 0. + IF l_line = 1. + CLEAR lt_components_tab. + ls_components-name = 'SIGN'. + lo_addit ?= cl_abap_typedescr=>describe_by_data( ls_filt-sign ). + ls_components-type = lo_addit . + INSERT ls_components INTO TABLE lt_components_tab. + ls_components-name = 'OPTION'. + lo_addit ?= cl_abap_typedescr=>describe_by_data( ls_filt-option ). + ls_components-type = lo_addit . + INSERT ls_components INTO TABLE lt_components_tab. + ls_components-name = 'LOW'. + lo_addit ?= cl_abap_typedescr=>describe_by_data( ). + ls_components-type = lo_addit . + INSERT ls_components INTO TABLE lt_components_tab. + ls_components-name = 'HIGH'. + lo_addit ?= cl_abap_typedescr=>describe_by_data( ). + ls_components-type = lo_addit . + INSERT ls_components INTO TABLE lt_components_tab. + "create new line type + TRY. + lo_struc = cl_abap_structdescr=>create( p_components = lt_components_tab + p_strict = abap_false ). + CATCH cx_sy_struct_creation. + CONTINUE. + ENDTRY. + lo_table = cl_abap_tabledescr=>create( lo_struc ). + + CREATE DATA lo_trange TYPE HANDLE lo_table. + CREATE DATA lo_srange TYPE HANDLE lo_struc. + + ASSIGN lo_trange->* TO . + ASSIGN lo_srange->* TO . + ENDIF. + CLEAR . + ASSIGN COMPONENT 'SIGN' OF STRUCTURE TO . + = ls_filt-sign. + ASSIGN COMPONENT 'OPTION' OF STRUCTURE TO . + = ls_filt-option. + ASSIGN COMPONENT 'LOW' OF STRUCTURE TO . + = ls_filt-low. + ASSIGN COMPONENT 'HIGH' OF STRUCTURE TO . + = ls_filt-high. + INSERT INTO TABLE . + IF IN . + IF ws_option-filter = abap_true. + ls_filter-rownumber = l_line. + ls_filter-columnname = ls_filt-fieldname. + INSERT ls_filter INTO TABLE et_filter. + ELSE. + INSERT INTO TABLE . + ENDIF. + ENDIF. + ENDIF. + ENDLOOP. + IF ws_option-filter = abap_undefined. + = . + CLEAR . + ENDIF. + ENDLOOP. + + + WHEN 2. + + TYPES: BEGIN OF ty_field_range, + fieldname TYPE lvc_fname, + range_tab TYPE REF TO data, + range_wa TYPE REF TO data, + END OF ty_field_range. + DATA: lt_field_range TYPE HASHED TABLE OF ty_field_range WITH UNIQUE KEY fieldname, + ls_field_range LIKE LINE OF lt_field_range. + FIELD-SYMBOLS: LIKE LINE OF lt_field_range. + + IF ws_option-filter = abap_false. + CLEAR et_filter. + RETURN. + ENDIF. + + ASSIGN xo_table->* TO . + + CREATE DATA lo_ltabdata LIKE . + ASSIGN lo_ltabdata->* TO . + +* Range creation and range comparison must be done in two steps: +* This is due to the fact, that range values might be applied +* all together at once not value after value for a specific fieldname +* --> Having multiple excluding values is a problem that would otherwise +* occur... + +* 1. Step: Create a the combined ranges for each fieldname... + LOOP AT wt_filt INTO ls_filt. + + READ TABLE lt_field_range WITH TABLE KEY fieldname = ls_filt-fieldname ASSIGNING . + IF sy-subrc <> 0. CLEAR lt_components_tab. ls_components-name = 'SIGN'. lo_addit ?= cl_abap_typedescr=>describe_by_data( ls_filt-sign ). @@ -432,14 +528,23 @@ CLASS zcl_excel_converter_alv IMPLEMENTATION. lo_addit ?= cl_abap_typedescr=>describe_by_data( ls_filt-option ). ls_components-type = lo_addit . INSERT ls_components INTO TABLE lt_components_tab. + + lo_table ?= cl_abap_tabledescr=>describe_by_data( ). + TRY. + lo_struc ?= lo_table->get_table_line_type( ). + ls_components-type = lo_struc->get_component_type( p_name = ls_filt-fieldname ). + CATCH cx_sy_move_cast_error. +* Unstructured table. Might never occur... + ls_components-type = lo_table->get_table_line_type( ). + ENDTRY. + + CHECK ls_components-type IS NOT INITIAL. + ls_components-name = 'LOW'. - lo_addit ?= cl_abap_typedescr=>describe_by_data( ). - ls_components-type = lo_addit . INSERT ls_components INTO TABLE lt_components_tab. ls_components-name = 'HIGH'. - lo_addit ?= cl_abap_typedescr=>describe_by_data( ). - ls_components-type = lo_addit . INSERT ls_components INTO TABLE lt_components_tab. + "create new line type TRY. lo_struc = cl_abap_structdescr=>create( p_components = lt_components_tab @@ -449,13 +554,16 @@ CLASS zcl_excel_converter_alv IMPLEMENTATION. ENDTRY. lo_table = cl_abap_tabledescr=>create( lo_struc ). - CREATE DATA lo_trange TYPE HANDLE lo_table. - CREATE DATA lo_srange TYPE HANDLE lo_struc. + ls_field_range-fieldname = ls_filt-fieldname. + CREATE DATA ls_field_range-range_tab TYPE HANDLE lo_table. + CREATE DATA ls_field_range-range_wa TYPE HANDLE lo_struc. + INSERT ls_field_range INTO TABLE lt_field_range ASSIGNING . - ASSIGN lo_trange->* TO . - ASSIGN lo_srange->* TO . ENDIF. - CLEAR . + + ASSIGN -range_tab->* TO . + ASSIGN -range_wa->* TO . + ASSIGN COMPONENT 'SIGN' OF STRUCTURE TO . = ls_filt-sign. ASSIGN COMPONENT 'OPTION' OF STRUCTURE TO . @@ -465,22 +573,37 @@ CLASS zcl_excel_converter_alv IMPLEMENTATION. ASSIGN COMPONENT 'HIGH' OF STRUCTURE TO . = ls_filt-high. INSERT INTO TABLE . - IF IN . - IF ws_option-filter = abap_true. - ls_filter-rownumber = l_line. - ls_filter-columnname = ls_filt-fieldname. - INSERT ls_filter INTO TABLE et_filter. + + ENDLOOP. + +* 2. Step: Now apply the fieldname ranges afterwards... + LOOP AT ASSIGNING . + ls_filter-rownumber = sy-tabix. + DATA selected TYPE abap_bool. + selected = abap_true. + LOOP AT lt_field_range ASSIGNING . + ASSIGN COMPONENT ls_filt-fieldname OF STRUCTURE TO . + ASSIGN -range_tab->* TO . + IF IN . + IF ws_option-filter = abap_true. + ls_filter-columnname = -fieldname. + INSERT ls_filter INTO TABLE et_filter. + ENDIF. ELSE. - INSERT INTO TABLE . + selected = abap_false. ENDIF. + ENDLOOP. + IF selected = abap_true AND ws_option-filter = abap_undefined. + INSERT INTO TABLE . ENDIF. + ENDLOOP. + + IF wt_filt IS NOT INITIAL AND ws_option-filter = abap_undefined. + = . + CLEAR . ENDIF. - ENDLOOP. - IF ws_option-filter = abap_undefined. - = . - CLEAR . - ENDIF. - ENDLOOP. + + ENDCASE. ENDMETHOD. diff --git a/src/not_cloud/zcl_excel_converter_alv.clas.testclasses.abap b/src/not_cloud/zcl_excel_converter_alv.clas.testclasses.abap new file mode 100644 index 0000000..d8c7f50 --- /dev/null +++ b/src/not_cloud/zcl_excel_converter_alv.clas.testclasses.abap @@ -0,0 +1,238 @@ +*CLASS ltc_get_filter DEFINITION DEFERRED. +*CLASS zcl_excel_converter_alv DEFINITION LOCAL FRIENDS +* ltc_get_filter. + +CLASS ltc_converter_alv DEFINITION FOR TESTING INHERITING FROM zcl_excel_converter_alv. + + PUBLIC SECTION. + + TYPES: BEGIN OF ty_alv_line, + field_1 TYPE string, + field_2 TYPE string, + END OF ty_alv_line, + ty_alv_table TYPE STANDARD TABLE OF ty_alv_line WITH DEFAULT KEY. + + METHODS: + zif_excel_converter~can_convert_object REDEFINITION, + zif_excel_converter~create_fieldcatalog REDEFINITION, + zif_excel_converter~get_supported_class REDEFINITION. + + METHODS set_alv_table + IMPORTING + alv_table TYPE ty_alv_table. + + METHODS set_alv_filter_table + IMPORTING + alv_filter_table TYPE lvc_t_filt. + + METHODS wrapper_of_get_filter + EXPORTING + et_filter TYPE zexcel_t_converter_fil + et_filtered_alv_table TYPE ty_alv_table. + + PRIVATE SECTION. + + DATA: alv_table TYPE ty_alv_table. + +ENDCLASS. + + +CLASS ltc_converter_alv IMPLEMENTATION. + + METHOD zif_excel_converter~can_convert_object. + + ENDMETHOD. + + METHOD zif_excel_converter~create_fieldcatalog. + + ENDMETHOD. + + METHOD zif_excel_converter~get_supported_class. + + ENDMETHOD. + + METHOD wrapper_of_get_filter. + DATA: ref_alv_table TYPE REF TO data. + + et_filtered_alv_table = alv_table. + GET REFERENCE OF et_filtered_alv_table INTO ref_alv_table. + + " Get ET_FILTER + ws_option-filter = abap_true. + get_filter( + IMPORTING + et_filter = et_filter + CHANGING + xo_table = ref_alv_table ). + + " Get filtered table + ws_option-filter = abap_undefined. + get_filter( + CHANGING + xo_table = ref_alv_table ). + + ENDMETHOD. + + METHOD set_alv_table. + + me->alv_table = alv_table. + + ENDMETHOD. + + METHOD set_alv_filter_table. + + wt_filt = alv_filter_table. + + ENDMETHOD. + +ENDCLASS. + +CLASS ltc_get_filter DEFINITION FOR TESTING + RISK LEVEL HARMLESS + DURATION SHORT. + + PRIVATE SECTION. + + TYPES: BEGIN OF ty_output, + filter_table TYPE zexcel_t_converter_fil, + filtered_alv_table TYPE ltc_converter_alv=>ty_alv_table, + END OF ty_output. + DATA: + f_cut TYPE REF TO ltc_converter_alv, "class under test + alv_line TYPE ltc_converter_alv=>ty_alv_line, + alv_table TYPE ltc_converter_alv=>ty_alv_table, + alv_filter_line TYPE lvc_s_filt, + alv_filter_table TYPE lvc_t_filt, + filter_line TYPE zexcel_s_converter_fil, + filter_table TYPE zexcel_t_converter_fil, + filtered_alv_line TYPE ltc_converter_alv=>ty_alv_line, + filtered_alv_table TYPE ltc_converter_alv=>ty_alv_table, + act TYPE ty_output, + exp TYPE ty_output. + + METHODS: + none FOR TESTING RAISING cx_static_check, + one_field_eq_or_eq FOR TESTING RAISING cx_static_check, + simple FOR TESTING RAISING cx_static_check, + two_fields_eq FOR TESTING RAISING cx_static_check. + + METHODS: setup. + +ENDCLASS. + + +CLASS ltc_get_filter IMPLEMENTATION. + + + METHOD none. + + f_cut->wrapper_of_get_filter( + IMPORTING + et_filter = act-filter_table + et_filtered_alv_table = act-filtered_alv_table ). + + exp-filtered_alv_table = alv_table. + + cl_abap_unit_assert=>assert_equals( act = act-filter_table exp = exp-filter_table ). + cl_abap_unit_assert=>assert_equals( act = act-filtered_alv_table exp = exp-filtered_alv_table ). + + ENDMETHOD. + + + METHOD one_field_eq_or_eq. + + alv_filter_line-fieldname = 'FIELD_1'. + alv_filter_line-sign = 'I'. + alv_filter_line-option = 'EQ'. + alv_filter_line-low = 'A'. + APPEND alv_filter_line TO alv_filter_table. + alv_filter_line-low = 'B'. + APPEND alv_filter_line TO alv_filter_table. + f_cut->set_alv_filter_table( alv_filter_table ). + + f_cut->wrapper_of_get_filter( + IMPORTING + et_filter = act-filter_table + et_filtered_alv_table = act-filtered_alv_table ). + + filter_line-rownumber = 1. + filter_line-columnname = 'FIELD_1'. + INSERT filter_line INTO TABLE exp-filter_table. + filter_line-rownumber = 2. + filter_line-columnname = 'FIELD_1'. + INSERT filter_line INTO TABLE exp-filter_table. + + exp-filtered_alv_table = alv_table. + + cl_abap_unit_assert=>assert_equals( act = act-filter_table exp = exp-filter_table ). + cl_abap_unit_assert=>assert_equals( act = act-filtered_alv_table exp = exp-filtered_alv_table ). + + ENDMETHOD. + + + METHOD setup. + + CREATE OBJECT f_cut. + alv_line-field_1 = 'A'. + alv_line-field_2 = 'C'. + APPEND alv_line TO alv_table. + alv_line-field_1 = 'B'. + alv_line-field_2 = 'D'. + APPEND alv_line TO alv_table. + f_cut->set_alv_table( alv_table ). + + ENDMETHOD. + + + METHOD simple. + + alv_filter_line-fieldname = 'FIELD_1'. + alv_filter_line-sign = 'I'. + alv_filter_line-option = 'EQ'. + alv_filter_line-low = 'A'. + alv_filter_line-high = ''. + APPEND alv_filter_line TO alv_filter_table. + f_cut->set_alv_filter_table( alv_filter_table ). + + f_cut->wrapper_of_get_filter( + IMPORTING + et_filter = act-filter_table + et_filtered_alv_table = act-filtered_alv_table ). + + filter_line-rownumber = 1. + filter_line-columnname = 'FIELD_1'. + INSERT filter_line INTO TABLE exp-filter_table. + + exp-filtered_alv_table = alv_table. + DELETE exp-filtered_alv_table WHERE field_1 <> 'A'. + + cl_abap_unit_assert=>assert_equals( act = act-filter_table exp = exp-filter_table ). + cl_abap_unit_assert=>assert_equals( act = act-filtered_alv_table exp = exp-filtered_alv_table ). + + ENDMETHOD. + + + METHOD two_fields_eq. + + alv_filter_line-fieldname = 'FIELD_1'. + alv_filter_line-sign = 'I'. + alv_filter_line-option = 'EQ'. + alv_filter_line-low = 'A'. + APPEND alv_filter_line TO alv_filter_table. + alv_filter_line-fieldname = 'FIELD_2'. + alv_filter_line-low = 'D'. + APPEND alv_filter_line TO alv_filter_table. + f_cut->set_alv_filter_table( alv_filter_table ). + + f_cut->wrapper_of_get_filter( + IMPORTING + et_filter = act-filter_table + et_filtered_alv_table = act-filtered_alv_table ). + + cl_abap_unit_assert=>assert_equals( act = act-filter_table exp = exp-filter_table ). + cl_abap_unit_assert=>assert_equals( act = act-filtered_alv_table exp = exp-filtered_alv_table ). + + ENDMETHOD. + + +ENDCLASS. diff --git a/src/not_cloud/zcl_excel_converter_alv.clas.xml b/src/not_cloud/zcl_excel_converter_alv.clas.xml index 73ee89a..69ac195 100644 --- a/src/not_cloud/zcl_excel_converter_alv.clas.xml +++ b/src/not_cloud/zcl_excel_converter_alv.clas.xml @@ -10,6 +10,7 @@ X X X + X