Yennamani phani kumar
Yennamani phani kumar

Reputation: 11

how to Filter on internal table using multiple fields

My requirement is to filter internal table using multiple fields.

CONSTANTS:lc_star TYPE c VALUE '*'.

DATA: lit_x_all    TYPE STANDARD TABLE OF ztt WITH NON-UNIQUE KEY extsystem ccode ekorg werks matkl,
      lit_filter_e TYPE SORTED TABLE OF ztt-extsystem WITH NON-UNIQUE KEY table_line,
      lit_filter_o TYPE SORTED TABLE OF ztt-ekorg WITH NON-UNIQUE KEY table_line,
      lit_filter_c TYPE SORTED TABLE OF ztt-ccode WITH NON-UNIQUE KEY table_line,
      lit_filter_w TYPE SORTED TABLE OF ztt-werks WITH NON-UNIQUE KEY table_line.

SELECT * 
      FROM ztt 
      WHERE a = @i_a
      INTO TABLE @lit_x_all.

LOOP AT i_pit_input INTO DATA(lwa_input).

  "filter to avoid select statement in loop

  lit_filter_e = VALUE #( ( CONV #( lc_star ) ) ( lwa_input-extsystem ) ).
  DATA(lit_final_e) = FILTER #( lit_approver_all IN lit_filter_e WHERE extsystem = table_line ).

  lit_filter_o = VALUE #( ( CONV #( lc_star ) ) ( lwa_input-ekorg ) ).
  DATA(lit_final_o) = FILTER #( lit_final_e IN lit_filter_o WHERE ekorg = table_line ).

  lit_filter_c = VALUE #( ( CONV #( lc_star ) ) ( lwa_input-ccode ) ).
  DATA(lit_final_c) = FILTER #( lit_final_o IN lit_filter_c WHERE ccode = table_line ).

  lit_filter_w = VALUE #( ( CONV #( lc_star ) ) ( lwa_input-werks ) ).
  DATA(lit_final_w) = FILTER #( lit_final_c IN lit_filter_w WHERE werks = table_line ).

ENDLOOP.

Currently I am using above code with filter for each field. Can we achieve same requirement with single filter instead of multiple filters?

Thanks Phani

Upvotes: 1

Views: 3540

Answers (1)

Jonas Wilms
Jonas Wilms

Reputation: 138267

The documentation states:

Table filtering can also be performed using a table comprehension or a table reduction with an iteration expression for table iterations with FOR. The operator FILTER provides a shortened format for this special case and is more efficient to execute.

As in your case filtering with FILTER does not work as you're effectively ORing the 'star case' and 'filter value case', using the VALUE constructor to perform table comprehension is the better choice:

DATA(result) = VALUE #(
  FOR entry IN entries
    WHERE (
      ( a = '*' OR a = filter-a ) AND
      ( b = '*' OR b = filter-b )
      "...
    )
    ( entry )
).

This should also be by magnitutes faster as it avoids the creation of multiple intermediate internal tables.

Upvotes: 2

Related Questions