Merge pull request #1 from darnoc312/darnoc312-autofilter

Autofilter solutions for excel writer
This commit is contained in:
darnoc312 2023-08-04 13:51:00 +02:00 committed by GitHub
commit e83cf832bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 122 additions and 108 deletions

View File

@ -387,59 +387,77 @@ CLASS zcl_excel_converter_alv IMPLEMENTATION.
METHOD get_filter. METHOD get_filter.
TYPES: BEGIN OF ts_field_range,
fieldname TYPE lvc_fname,
range_tab TYPE REF TO data,
END OF ts_field_range.
DATA: ls_filt TYPE lvc_s_filt, DATA: ls_filt TYPE lvc_s_filt,
l_line TYPE i, ls_filter TYPE zexcel_s_converter_fil,
ls_filter TYPE zexcel_s_converter_fil. lo_addit TYPE REF TO cl_abap_elemdescr,
DATA: lo_addit TYPE REF TO cl_abap_elemdescr,
lt_components_tab TYPE cl_abap_structdescr=>component_table, lt_components_tab TYPE cl_abap_structdescr=>component_table,
ls_components TYPE abap_componentdescr, ls_components TYPE abap_componentdescr,
lo_table TYPE REF TO cl_abap_tabledescr, lo_table TYPE REF TO cl_abap_tabledescr,
lo_struc TYPE REF TO cl_abap_structdescr, lo_struc TYPE REF TO cl_abap_structdescr,
lo_trange TYPE REF TO data, lt_field_range TYPE TABLE OF ts_field_range,
lo_srange TYPE REF TO data, ls_field_range LIKE LINE OF lt_field_range,
lo_ltabdata TYPE REF TO data. lv_fieldname TYPE lvc_fname.
FIELD-SYMBOLS: <fs_tab> TYPE STANDARD TABLE, FIELD-SYMBOLS: <fs_tab> TYPE STANDARD TABLE,
<fs_ltab> TYPE STANDARD TABLE,
<fs_stab> TYPE any, <fs_stab> TYPE any,
<fs> TYPE any, <fs> TYPE any,
<fs1> TYPE any,
<fs_srange> TYPE any, <fs_srange> TYPE any,
<fs_trange> TYPE STANDARD TABLE. <fs_trange> TYPE STANDARD TABLE,
<fs_field_range> LIKE LINE OF lt_field_range.
IF ws_option-filter = abap_false.
CLEAR et_filter. CLEAR et_filter.
IF wt_filt IS INITIAL OR
ws_option-filter = abap_false.
RETURN. RETURN.
ENDIF. ENDIF.
ASSIGN xo_table->* TO <fs_tab>. ASSIGN xo_table->* TO <fs_tab>.
READ TABLE <fs_tab> ASSIGNING <fs_stab> INDEX 1.
IF sy-subrc <> 0.
RETURN.
ENDIF.
CREATE DATA lo_ltabdata LIKE <fs_tab>. SORT wt_filt BY fieldname.
ASSIGN lo_ltabdata->* TO <fs_ltab>.
* 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 the combined ranges for each fieldname...
LOOP AT wt_filt INTO ls_filt. LOOP AT wt_filt INTO ls_filt.
LOOP AT <fs_tab> ASSIGNING <fs_stab>. IF ls_filt-fieldname <> lv_fieldname.
l_line = sy-tabix. lv_fieldname = ls_filt-fieldname.
UNASSIGN <fs_trange>.
ASSIGN COMPONENT ls_filt-fieldname OF STRUCTURE <fs_stab> TO <fs>. ASSIGN COMPONENT ls_filt-fieldname OF STRUCTURE <fs_stab> TO <fs>.
IF sy-subrc = 0. CHECK sy-subrc = 0.
IF l_line = 1.
CLEAR lt_components_tab. IF lt_components_tab IS INITIAL.
ls_components-name = 'SIGN'. ls_components-name = 'SIGN'.
lo_addit ?= cl_abap_typedescr=>describe_by_data( ls_filt-sign ). lo_addit ?= cl_abap_typedescr=>describe_by_data( ls_filt-sign ).
ls_components-type = lo_addit. ls_components-type = lo_addit.
INSERT ls_components INTO TABLE lt_components_tab. APPEND ls_components TO lt_components_tab.
ls_components-name = 'OPTION'. ls_components-name = 'OPTION'.
lo_addit ?= cl_abap_typedescr=>describe_by_data( ls_filt-option ). lo_addit ?= cl_abap_typedescr=>describe_by_data( ls_filt-option ).
ls_components-type = lo_addit. ls_components-type = lo_addit.
INSERT ls_components INTO TABLE lt_components_tab. APPEND ls_components TO lt_components_tab.
ELSE.
DELETE lt_components_tab FROM 3.
ENDIF.
lo_addit ?= cl_abap_typedescr=>describe_by_data( <fs> ).
ls_components-type = lo_addit.
ls_components-name = 'LOW'. ls_components-name = 'LOW'.
lo_addit ?= cl_abap_typedescr=>describe_by_data( <fs> ). APPEND ls_components TO lt_components_tab.
ls_components-type = lo_addit .
INSERT ls_components INTO TABLE lt_components_tab.
ls_components-name = 'HIGH'. ls_components-name = 'HIGH'.
lo_addit ?= cl_abap_typedescr=>describe_by_data( <fs> ). APPEND ls_components TO lt_components_tab.
ls_components-type = lo_addit .
INSERT ls_components INTO TABLE lt_components_tab.
"create new line type "create new line type
TRY. TRY.
lo_struc = cl_abap_structdescr=>create( p_components = lt_components_tab lo_struc = cl_abap_structdescr=>create( p_components = lt_components_tab
@ -449,37 +467,46 @@ CLASS zcl_excel_converter_alv IMPLEMENTATION.
ENDTRY. ENDTRY.
lo_table = cl_abap_tabledescr=>create( lo_struc ). lo_table = cl_abap_tabledescr=>create( lo_struc ).
CREATE DATA lo_trange TYPE HANDLE lo_table. ls_field_range-fieldname = ls_filt-fieldname.
CREATE DATA lo_srange TYPE HANDLE lo_struc. CREATE DATA ls_field_range-range_tab TYPE HANDLE lo_table.
APPEND ls_field_range TO lt_field_range.
ASSIGN lo_trange->* TO <fs_trange>. ASSIGN ls_field_range-range_tab->* TO <fs_trange>.
ASSIGN lo_srange->* TO <fs_srange>. ELSE.
CHECK <fs_trange> IS ASSIGNED.
ENDIF. ENDIF.
CLEAR <fs_trange>.
ASSIGN COMPONENT 'SIGN' OF STRUCTURE <fs_srange> TO <fs1>. APPEND INITIAL LINE TO <fs_trange> ASSIGNING <fs_srange>.
<fs1> = ls_filt-sign. ASSIGN COMPONENT 'SIGN' OF STRUCTURE <fs_srange> TO <fs>.
ASSIGN COMPONENT 'OPTION' OF STRUCTURE <fs_srange> TO <fs1>. <fs> = ls_filt-sign.
<fs1> = ls_filt-option. ASSIGN COMPONENT 'OPTION' OF STRUCTURE <fs_srange> TO <fs>.
ASSIGN COMPONENT 'LOW' OF STRUCTURE <fs_srange> TO <fs1>. <fs> = ls_filt-option.
<fs1> = ls_filt-low. ASSIGN COMPONENT 'LOW' OF STRUCTURE <fs_srange> TO <fs>.
ASSIGN COMPONENT 'HIGH' OF STRUCTURE <fs_srange> TO <fs1>. <fs> = ls_filt-low.
<fs1> = ls_filt-high. ASSIGN COMPONENT 'HIGH' OF STRUCTURE <fs_srange> TO <fs>.
INSERT <fs_srange> INTO TABLE <fs_trange>. <fs> = ls_filt-high.
ENDLOOP.
IF lt_field_range IS INITIAL.
RETURN.
ENDIF.
* 2. Step: Now apply the fieldname ranges afterwards...
LOOP AT <fs_tab> ASSIGNING <fs_stab>.
ls_filter-rownumber = sy-tabix.
LOOP AT lt_field_range ASSIGNING <fs_field_range>.
ASSIGN COMPONENT <fs_field_range>-fieldname OF STRUCTURE <fs_stab> TO <fs>.
ASSIGN <fs_field_range>-range_tab->* TO <fs_trange>.
IF <fs> IN <fs_trange>. IF <fs> IN <fs_trange>.
IF ws_option-filter = abap_true. IF ws_option-filter = abap_true.
ls_filter-rownumber = l_line. ls_filter-columnname = <fs_field_range>-fieldname.
ls_filter-columnname = ls_filt-fieldname.
INSERT ls_filter INTO TABLE et_filter. INSERT ls_filter INTO TABLE et_filter.
ELSE.
INSERT <fs_stab> INTO TABLE <fs_ltab>.
ENDIF.
ENDIF. ENDIF.
ELSEIF ws_option-filter = abap_undefined.
DELETE <fs_tab>.
EXIT. "--> next xo_table line
ENDIF. ENDIF.
ENDLOOP. ENDLOOP.
IF ws_option-filter = abap_undefined.
<fs_tab> = <fs_ltab>.
CLEAR <fs_ltab>.
ENDIF.
ENDLOOP. ENDLOOP.
ENDMETHOD. ENDMETHOD.

View File

@ -4212,10 +4212,11 @@ CLASS zcl_excel_writer_2007 IMPLEMENTATION.
DATA: col_count TYPE int4, DATA: col_count TYPE int4,
lo_autofilters TYPE REF TO zcl_excel_autofilters, lo_autofilters TYPE REF TO zcl_excel_autofilters,
lo_autofilter TYPE REF TO zcl_excel_autofilter, lo_autofilter TYPE REF TO zcl_excel_autofilter,
l_autofilter_hidden TYPE flag,
lt_values TYPE zexcel_t_autofilter_values, lt_values TYPE zexcel_t_autofilter_values,
ls_values TYPE zexcel_s_autofilter_values, ls_values TYPE zexcel_s_autofilter_values,
ls_area TYPE zexcel_s_autofilter_area, ls_area TYPE zexcel_s_autofilter_area,
lt_filter_cols TYPE SORTED TABLE OF zexcel_cell_column WITH UNIQUE KEY table_line,
lt_cols2match LIKE lt_filter_cols,
lo_iterator TYPE REF TO zcl_excel_collection_iterator, lo_iterator TYPE REF TO zcl_excel_collection_iterator,
lo_table TYPE REF TO zcl_excel_table, lo_table TYPE REF TO zcl_excel_table,
@ -4263,7 +4264,9 @@ CLASS zcl_excel_writer_2007 IMPLEMENTATION.
IF lo_autofilter IS BOUND. IF lo_autofilter IS BOUND.
lt_values = lo_autofilter->get_values( ) . lt_values = lo_autofilter->get_values( ) .
ls_area = lo_autofilter->get_filter_area( ) . ls_area = lo_autofilter->get_filter_area( ) .
l_autofilter_hidden = abap_true. " First defautl is not showing LOOP AT lt_values INTO ls_values.
INSERT ls_values-column INTO TABLE lt_filter_cols.
ENDLOOP.
ENDIF. ENDIF.
*--------------------------------------------------------------------* *--------------------------------------------------------------------*
*issue #220 - If cell in tables-area don't use default from row or column or sheet - Coding 1 - start *issue #220 - If cell in tables-area don't use default from row or column or sheet - Coding 1 - start
@ -4324,16 +4327,8 @@ CLASS zcl_excel_writer_2007 IMPLEMENTATION.
INSERT ls_sheet_content_empty INTO TABLE io_worksheet->sheet_content. INSERT ls_sheet_content_empty INTO TABLE io_worksheet->sheet_content.
ENDIF. ENDIF.
CLEAR ls_sheet_content. CLEAR: ls_sheet_content, ls_sheet_content_empty.
LOOP AT io_worksheet->sheet_content INTO ls_sheet_content. LOOP AT io_worksheet->sheet_content INTO ls_sheet_content.
IF lt_values IS INITIAL. " no values attached to autofilter " issue #368 autofilter filtering too much
CLEAR l_autofilter_hidden.
ELSE.
READ TABLE lt_values INTO ls_values WITH KEY column = ls_last_row-cell_column.
IF sy-subrc = 0 AND ls_values-value = ls_last_row-cell_value.
CLEAR l_autofilter_hidden.
ENDIF.
ENDIF.
CLEAR ls_style_mapping. CLEAR ls_style_mapping.
*Create row element *Create row element
*issues #346,#154, #195 - problems when we have information in row_dimension but no cell content in that row *issues #346,#154, #195 - problems when we have information in row_dimension but no cell content in that row
@ -4364,18 +4359,10 @@ CLASS zcl_excel_writer_2007 IMPLEMENTATION.
ENDIF. ENDIF.
IF ls_last_row-cell_row NE <ls_sheet_content>-cell_row. IF ls_last_row-cell_row NE <ls_sheet_content>-cell_row.
IF lo_autofilter IS BOUND.
IF ls_area-row_start >= ls_last_row-cell_row OR " One less for header
ls_area-row_end < ls_last_row-cell_row .
CLEAR l_autofilter_hidden.
ENDIF.
ELSE.
CLEAR l_autofilter_hidden.
ENDIF.
IF ls_last_row-cell_row IS NOT INITIAL. IF ls_last_row-cell_row IS NOT INITIAL.
" Row visibility of previos row. " Row visibility of previos row.
IF lo_row->get_visible( io_worksheet ) = abap_false OR IF lo_row->get_visible( io_worksheet ) = abap_false OR
l_autofilter_hidden = abap_true. lt_cols2match IS NOT INITIAL.
lo_element_2->set_attribute_ns( name = 'hidden' value = 'true' ). lo_element_2->set_attribute_ns( name = 'hidden' value = 'true' ).
ENDIF. ENDIF.
rv_ixml_sheet_data_root->append_child( new_child = lo_element_2 ). " row node rv_ixml_sheet_data_root->append_child( new_child = lo_element_2 ). " row node
@ -4423,16 +4410,29 @@ CLASS zcl_excel_writer_2007 IMPLEMENTATION.
lo_element_2->set_attribute_ns( name = 's' value = lv_value ). lo_element_2->set_attribute_ns( name = 's' value = lv_value ).
lo_element_2->set_attribute_ns( name = 'customFormat' value = '1' ). lo_element_2->set_attribute_ns( name = 'customFormat' value = '1' ).
ENDIF. ENDIF.
IF lt_values IS INITIAL. " no values attached to autofilter " issue #368 autofilter filtering too much IF lo_autofilter IS BOUND.
CLEAR l_autofilter_hidden. IF ls_area-row_start < <ls_sheet_content>-cell_row AND "One less for header
ls_area-row_end >= <ls_sheet_content>-cell_row.
" First default is not showing
lt_cols2match = lt_filter_cols.
ELSE. ELSE.
l_autofilter_hidden = abap_true. " First default is not showing CLEAR lt_cols2match.
ENDIF.
ENDIF. ENDIF.
ELSE. ELSE.
ENDIF. ENDIF.
ls_last_row = <ls_sheet_content>.
ENDWHILE. ENDWHILE.
READ TABLE lt_values TRANSPORTING NO FIELDS
WITH KEY column = <ls_sheet_content>-cell_column
value = <ls_sheet_content>-cell_value
BINARY SEARCH.
IF sy-subrc = 0.
DELETE TABLE lt_cols2match WITH TABLE KEY table_line = <ls_sheet_content>-cell_column.
ENDIF.
lo_element_3 = io_document->create_simple_element( name = lc_xml_node_c lo_element_3 = io_document->create_simple_element( name = lc_xml_node_c
parent = io_document ). parent = io_document ).
@ -4537,24 +4537,11 @@ CLASS zcl_excel_writer_2007 IMPLEMENTATION.
ENDIF. ENDIF.
lo_element_2->append_child( new_child = lo_element_3 ). " column node lo_element_2->append_child( new_child = lo_element_3 ). " column node
ls_last_row = <ls_sheet_content>.
ENDLOOP. ENDLOOP.
IF sy-subrc = 0. IF sy-subrc = 0.
READ TABLE lt_values INTO ls_values WITH KEY column = ls_last_row-cell_column.
IF sy-subrc = 0 AND ls_values-value = ls_last_row-cell_value.
CLEAR l_autofilter_hidden.
ENDIF.
IF lo_autofilter IS BOUND.
IF ls_area-row_start >= ls_last_row-cell_row OR " One less for header
ls_area-row_end < ls_last_row-cell_row .
CLEAR l_autofilter_hidden.
ENDIF.
ELSE.
CLEAR l_autofilter_hidden.
ENDIF.
" Row visibility of previos row. " Row visibility of previos row.
IF lo_row->get_visible( ) = abap_false OR IF lo_row->get_visible( ) = abap_false OR
l_autofilter_hidden = abap_true. lt_cols2match IS NOT INITIAL.
lo_element_2->set_attribute_ns( name = 'hidden' value = 'true' ). lo_element_2->set_attribute_ns( name = 'hidden' value = 'true' ).
ENDIF. ENDIF.
rv_ixml_sheet_data_root->append_child( new_child = lo_element_2 ). " row node rv_ixml_sheet_data_root->append_child( new_child = lo_element_2 ). " row node