abap2xlsx icon indicating copy to clipboard operation
abap2xlsx copied to clipboard

Autofilter with more values does not work

Open miskohut opened this issue 9 years ago • 6 comments

Hi,

I have defined autofilter for 13th row. And I want to set more values to first column. I do it by:


lv_cell_value = 'Sum'.

  lo_autofilter->set_value(
    exporting
      i_column = 1    " Cell Column
      i_value  = lv_cell_value
  ).

  lv_cell_value = 'ProjectA'.

  lo_autofilter->set_value(
    exporting
      i_column = 1    " Cell Column
      i_value  = lv_cell_value
  ).

  lv_cell_value = 'ProjectB'.

  lo_autofilter->set_value(
    exporting
      i_column = 1    " Cell Column
      i_value  = lv_cell_value    " Cell Column
  ).

  lv_cell_value = 'ProjectC'.

  lo_autofilter->set_value(
    exporting
      i_column = 1    " Cell Column
      i_value  = lv_cell_value   " Cell Column
  ).

When excel is generated, the values in filter are selected, but they are not displayed. I have to open the filter, the values are checked but I have to press 'OK' in order to 'apply' the filter.

I'm doing this because I want all values to be selected when excel is generated. But when I just set filter without setting values then nothing is selected in the filter.

I have added one value to report ZDEMO_EXCEL33 and the result is the same. All values defined in code are checked in the filter but you must press 'OK' to apply the filter. Could you please help me with that? Thank you in advance.

miskohut avatar Jun 08 '16 10:06 miskohut

Any chance that you fork the project, create a fix and then provide a pull request?

gregorwolf avatar Jun 10 '16 08:06 gregorwolf

I'm not sure if I understood the question. Are you asking me if I fixed the problem myself? If you do then no, I was trying to debug the writer class but with no success.

miskohut avatar Jun 13 '16 06:06 miskohut

Maybe we should merge this issue #440 with issues #368 and #421 into one large issue "Multiple errors with autofilters"?

StefanSchmoecker avatar Jun 13 '16 07:06 StefanSchmoecker

Hi guys,

the problem can be solved in Method GET_FILTER of class ZCL_EXCEL_CONVERTER_ALV. The following coding should resolve all problems related to incorrect filtering due to multiple excluding values:

 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: ls_filt   TYPE lvc_s_filt,
        ls_filter TYPE zexcel_s_converter_fil.
  DATA: lo_addit          TYPE REF TO cl_abap_elemdescr,
        lt_components_tab TYPE cl_abap_structdescr=>component_table,
        ls_components     TYPE abap_componentdescr,
        lo_table          TYPE REF TO cl_abap_tabledescr,
        lo_struc          TYPE REF TO cl_abap_structdescr,
        lo_tdata          TYPE REF TO data,
        lo_sdata          TYPE REF TO 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: <fs_tab>         TYPE STANDARD TABLE,
                 <fs_stab>        TYPE any,
                 <fs>             TYPE any,
                 <fs1>            TYPE any,
                 <fs_srange>      TYPE any,
                 <fs_trange>      TYPE STANDARD TABLE,
                 <fs_field_range> LIKE LINE OF lt_field_range.

  ASSIGN io_table->* TO <fs_tab>.

* 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 <fs_field_range>.
    IF sy-subrc <> 0.
      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.

      lo_table ?= cl_abap_tabledescr=>describe_by_data( <fs_tab> ).
      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'.
      INSERT ls_components INTO TABLE lt_components_tab.
      ls_components-name   = 'HIGH'.
      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 ).

      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 <fs_field_range>.

    ENDIF.

    ASSIGN <fs_field_range>-range_tab->* TO <fs_trange>.
    ASSIGN <fs_field_range>-range_wa->* TO <fs_srange>.

    ASSIGN COMPONENT 'SIGN'   OF STRUCTURE  <fs_srange> TO <fs1>.
    <fs1> = ls_filt-sign.
    ASSIGN COMPONENT 'OPTION' OF STRUCTURE  <fs_srange> TO <fs1>.
    <fs1> = ls_filt-option.
    ASSIGN COMPONENT 'LOW'   OF STRUCTURE  <fs_srange> TO <fs1>.
    <fs1> = ls_filt-low.
    ASSIGN COMPONENT 'HIGH'   OF STRUCTURE  <fs_srange> TO <fs1>.
    <fs1> = ls_filt-high.
    INSERT <fs_srange> INTO TABLE <fs_trange>.

  ENDLOOP.

* 2. Step: Now apply the fieldname ranges afterwards...
  LOOP AT wt_filt INTO ls_filt.
    LOOP AT <fs_tab> ASSIGNING <fs_stab>.
      ls_filter-rownumber   = sy-tabix.
      ASSIGN COMPONENT ls_filt-fieldname OF STRUCTURE <fs_stab> TO <fs>.
      READ TABLE lt_field_range WITH TABLE KEY fieldname = ls_filt-fieldname ASSIGNING <fs_field_range>.
      ASSERT FIELDS ls_filt-fieldname
                    'If you see this error, please contact: [email protected] and send him this dump.'
             CONDITION sy-subrc = 0.
      ASSIGN <fs_field_range>-range_tab->* TO <fs_trange>.
      IF <fs> IN <fs_trange>.
        ls_filter-columnname  = ls_filt-fieldname.
        INSERT ls_filter INTO TABLE et_filter.
      ENDIF.
    ENDLOOP.
  ENDLOOP.

Actually we implemented it at the end of this method as implicit enhancement because we needed a quick solution which still is able tu update the framework afterwards. But of course it is possible to simply override the current coding. Would be create if the host/hosts of this project could include it in the next release. BTW: it would be great to have all relevant classes declared as NOT final and a possibility to add custom classes to the framework. Currently it is defined in CLASS_CONSTRUCTOR in ZCL_EXCEL_CONVERTER. If you would make this more flexible you would unleash the power of ABAP OO ;-)

cheers 🍻 Thorsten

spid3r avatar Nov 07 '16 13:11 spid3r

Hi Thorsten,

thank you for finding a solution. Would you mind forking the project, apply the correction (first for this issue only) in your fork and then please send a pull request.

Best regards Gregor

gregorwolf avatar Nov 13 '16 14:11 gregorwolf

@spid3r any chance of you creating a PR as @gregorwolf suggested?

AndreaBorgia-Abo avatar Aug 12 '22 17:08 AndreaBorgia-Abo