Update FILTER operator

This commit is contained in:
Daniel Reger
2023-01-11 13:56:38 +01:00
parent b513b97294
commit 93a2788207
4 changed files with 285 additions and 80 deletions

View File

@@ -776,24 +776,71 @@ ENDIF.
```
Creating an internal table by copying data from another internal table
filtering out lines that do not match the `WHERE` condition.
Using the [`FILTER`
operator](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_expression_filter.htm)
to extract data from internal tables ...
filtering out lines that do not match the `WHERE` condition using the [`FILTER`
operator](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_expression_filter.htm).
... by condition.
``` abap
DATA(filter1) = FILTER #( itab WHERE comp1 < i ).
```
- The
`FILTER` operator constructs an internal table according to a specified type (which can be an explicitly specified, non-generic table type or the # character as a symbol for the [operand type](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenoperand_type_glosry.htm) before the first parenthesis).
- The lines for the new internal table are taken from an
existing internal table based on conditions specified in a `WHERE` clause. Note that the table type of the existing internal table must be convertible to the specified target type.
- The conditions can either be based on single values or a [filter
table](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_expr_filter_table.htm).
- Additions:
... by condition with the addition `EXCEPT` that excludes data according to a condition.
``` abap
DATA(filter2) = FILTER #( itab EXCEPT WHERE comp1 < i ).
```
|Addition |Details |
|---|---|
|`USING KEY` | Specifies the [table key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentable_key_glosry.htm "Glossary Entry") with which the `WHERE` condition is evaluated: either a [sorted key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensorted_key_glosry.htm "Glossary Entry") or a [hash key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenhash_key_glosry.htm "Glossary Entry"). If the internal table has neither of them, a [secondary table key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensecondary_table_key_glosry.htm "Glossary Entry") must be available for the internal table which must then be specified after `USING KEY`. |
| `EXCEPT` | The specification of `EXCEPT` means that those lines of the existing table are used that do not meet the condition specified in the `WHERE` clause. Hence, if `EXCEPT` is not specified, the lines of the existing table are used that meet the condition. |
... by using a filter table.
``` abap
DATA(filter3) = FILTER #( itab IN filter_tab WHERE comp1 < i.
Examples:
```abap
"FILTER an conditions based on single values
"Assumption the component num is of type i.
DATA itab1 TYPE SORTED TABLE OF struc WITH NON-UNIQUE KEY num.
DATA itab2 TYPE STANDARD TABLE OF struc WITH NON-UNIQUE SORTED KEY sec_key COMPONENTS num.
DATA itab3 TYPE HASHED TABLE OF struc WITH UNIQUE KEY num.
"The lines meeting the condition are respected.
"Note: The source table must have at least one sorted or hashed key.
"Here, the primary key is used
DATA(f1) = FILTER #( itab1 WHERE num >= 3 ).
"USING KEY primary_key explicitly specified; same as above
DATA(f2) = FILTER #( itab1 USING KEY primary_key WHERE num >= 3 ).
"EXCEPT addition
DATA(f3) = FILTER #( itab1 EXCEPT WHERE num >= 3 ).
DATA(f4) = FILTER #( itab1 EXCEPT USING KEY primary_key WHERE num >= 3 ).
"Secondary table key specified after USING KEY
DATA(f5) = FILTER #( itab2 USING KEY sec_key WHERE num >= 4 ).
DATA(f6) = FILTER #( itab2 EXCEPT USING KEY sec_key WHERE num >= 3 ).
"Note: In case of a hash key, exactly one comparison expression for each key component is allowed;
"only = as comparison operator possible.
DATA(f7) = FILTER #( itab3 WHERE num = 3 ).
"Using a filter table
"In the WHERE condition, the columns of source and filter table are compared. Those lines in the source table
"are used for which at least one line in the filter table meets the condition. EXCEPT and USING KEY are also possible.
DATA filter_tab1 TYPE SORTED TABLE OF i
WITH NON-UNIQUE KEY table_line.
DATA filter_tab2 TYPE STANDARD TABLE OF i
WITH EMPTY KEY
WITH UNIQUE SORTED KEY line COMPONENTS table_line.
DATA(f8) = FILTER #( itab1 IN filter_tab1 WHERE num = table_line ).
"EXCEPT addition
DATA(f9) = FILTER #( itab1 EXCEPT IN filter_tab1 WHERE num = table_line ).
"USING KEY is specified for the filter table
DATA(f10) = FILTER #( itab2 IN filter_tab2 USING KEY line WHERE num = table_line ).
"USING KEY is specified for the source table, including EXCEPT
DATA(f11) = FILTER #( itab2 USING KEY sec_key EXCEPT IN filter_tab2 WHERE num = table_line ).
```
*Excursion:* Collecting values

View File

@@ -704,30 +704,68 @@ DATA(b) = SWITCH #( a
## `FILTER`
- The
[`FILTER`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_expression_filter.htm)
operator constructs an internal table line by line based on an
existing table and conditions specified in a `WHERE` clause.
`FILTER` operator constructs an internal table according to a specified type (which can be an explicitly specified, non-generic table type or the # character as a symbol for the [operand type](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenoperand_type_glosry.htm) before the first parenthesis).
- The lines for the new internal table are taken from an
existing internal table based on conditions specified in a `WHERE` clause. Note that the table type of the existing internal table must be convertible to the specified target type.
- The conditions can either be based on single values or a [filter
table](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_expr_filter_table.htm).
- Additions:
|Addition |Details |
|---|---|
|`USING KEY` | Specifies the [table key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentable_key_glosry.htm "Glossary Entry") with which the `WHERE` condition is evaluated, i. e. a [sorted key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensorted_key_glosry.htm "Glossary Entry") or a [hash key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenhash_key_glosry.htm "Glossary Entry"). If the internal table has neither of them, a [secondary table key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensecondary_table_key_glosry.htm "Glossary Entry") must be available and specified. |
|`USING KEY` | Specifies the [table key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentable_key_glosry.htm "Glossary Entry") with which the `WHERE` condition is evaluated: either a [sorted key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensorted_key_glosry.htm "Glossary Entry") or a [hash key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenhash_key_glosry.htm "Glossary Entry"). If the internal table has neither of them, a [secondary table key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensecondary_table_key_glosry.htm "Glossary Entry") must be available for the internal table which must then be specified after `USING KEY`. |
| `EXCEPT` | The specification of `EXCEPT` means that those lines of the existing table are used that do not meet the condition specified in the `WHERE` clause. Hence, if `EXCEPT` is not specified, the lines of the existing table are used that meet the condition. |
Examples:
``` abap
DATA(f1) = FILTER #( tab WHERE comp > 5 ).
```abap
"FILTER an conditions based on single values
"Assumption the component num is of type i.
DATA itab1 TYPE SORTED TABLE OF struc WITH NON-UNIQUE KEY num.
DATA itab2 TYPE STANDARD TABLE OF struc WITH NON-UNIQUE SORTED KEY sec_key COMPONENTS num.
DATA itab3 TYPE HASHED TABLE OF struc WITH UNIQUE KEY num.
DATA(f2) = FILTER #( tab EXCEPT WHERE comp < 3 ).
"The lines meeting the condition are respected.
"Note: The source table must have at least one sorted or hashed key.
"Here, the primary key is used
DATA(f1) = FILTER #( itab1 WHERE num >= 3 ).
DATA(f3) = FILTER #( tab USING KEY x WHERE comp = 4 ).
"USING KEY primary_key explicitly specified; same as above
DATA(f2) = FILTER #( itab1 USING KEY primary_key WHERE num >= 3 ).
"Filtering based on another table
DATA(f3) = FILTER #( tab IN filter_tab
                     WHERE comp = 3 ).
"EXCEPT addition
DATA(f3) = FILTER #( itab1 EXCEPT WHERE num >= 3 ).
DATA(f4) = FILTER #( itab1 EXCEPT USING KEY primary_key WHERE num >= 3 ).
"Secondary table key specified after USING KEY
DATA(f5) = FILTER #( itab2 USING KEY sec_key WHERE num >= 4 ).
DATA(f6) = FILTER #( itab2 EXCEPT USING KEY sec_key WHERE num >= 3 ).
"Note: In case of a hash key, exactly one comparison expression for each key component is allowed;
"only = as comparison operator possible.
DATA(f7) = FILTER #( itab3 WHERE num = 3 ).
"Using a filter table
"In the WHERE condition, the columns of source and filter table are compared. Those lines in the source table
"are used for which at least one line in the filter table meets the condition. EXCEPT and USING KEY are also possible.
DATA filter_tab1 TYPE SORTED TABLE OF i
WITH NON-UNIQUE KEY table_line.
DATA filter_tab2 TYPE STANDARD TABLE OF i
WITH EMPTY KEY
WITH UNIQUE SORTED KEY line COMPONENTS table_line.
DATA(f8) = FILTER #( itab1 IN filter_tab1 WHERE num = table_line ).
"EXCEPT addition
DATA(f9) = FILTER #( itab1 EXCEPT IN filter_tab1 WHERE num = table_line ).
"USING KEY is specified for the filter table
DATA(f10) = FILTER #( itab2 IN filter_tab2 USING KEY line WHERE num = table_line ).
"USING KEY is specified for the source table, including EXCEPT
DATA(f11) = FILTER #( itab2 USING KEY sec_key EXCEPT IN filter_tab2 WHERE num = table_line ).
```
<p align="right">(<a href="#top">back to top</a>)</p>

View File

@@ -19,7 +19,7 @@
* numbers (e. g. 1) ..., 2) ..., 3) ...) for the individual example
* sections. Plus, the variable name is displayed in most cases. Hence,
* to easier and faster find the relevant output in the console, just
* search in the console for the number/variable name (STRG+F in the
* search in the console for the number/variable name (CTRL+F in the
* console) or use the debugger.
*
* ----------------------------- NOTE -----------------------------------
@@ -948,41 +948,102 @@ CLASS ZCL_DEMO_ABAP_CONSTRUCTOR_EXPR IMPLEMENTATION.
output->next_section( `10. FILTER` ).
"The examples demonstrate the use of the FILTER operator.
"1) Method to fill internal table with demo values. The tables are
"displayed to show the original values of the internal table that is to
"be filtered.
"2) Filters an internal table based on a condition specified after
"WHERE. A new internal table is created that is declared inline.
"3) A new table is created based on filtering a table. Here, the
"addition EXCEPT is used that excludes data according to a condition
"specified after WHERE.
"4) The filtering is based on entries in a filter table.
"This section covers multiple examples demonstrating the syntactical variety
"of the FILTER operator.
"1) Method to fill demo internal table with values to work with.
"The table is displayed showing the values.
fill_struc_and_tab( ).
TYPES: BEGIN OF fi_str,
a TYPE i,
b TYPE c LENGTH 3,
c TYPE c LENGTH 3,
END OF fi_str.
"2) Filtering an internal table based on a condition.
DATA(filter1) = FILTER #( tab4 WHERE comp3 > 5 ).
"basic form, condition created with single values
"itab must have at least one sorted key or one hash key used for access.
"This variant of the filter operator is not possible for an internal table itab without a sorted key or hash key.
DATA fi_tab1 TYPE SORTED TABLE OF fi_str WITH NON-UNIQUE KEY a.
DATA fi_tab2 TYPE STANDARD TABLE OF fi_str WITH NON-UNIQUE SORTED KEY sec_key COMPONENTS a.
DATA fi_tab3 TYPE HASHED TABLE OF fi_str WITH UNIQUE KEY a.
"3) Filtering an internal table using EXCEPT addition
DATA(filter2) = FILTER #( tab4 EXCEPT WHERE comp3 < 3 ).
"Filling internal tables
fi_tab1 = VALUE #( ( a = 1 b = 'aaa' c = 'abc' )
( a = 2 b = 'bbb' c = 'def' )
( a = 3 b = 'ccc' c = 'hij' )
( a = 4 b = 'ddd' c = 'klm' )
( a = 5 b = 'eee' c = 'nop' ) ).
"4) Filtering an internal table using a filter table.
"Creating and filling a filter table.
DATA extract_tab TYPE SORTED TABLE OF i
fi_tab2 = fi_tab1.
fi_tab3 = fi_tab1.
"The lines meeting the condition are respected.
"Note: The source table must have at least one sorted or hashed key.
"Here, the primary key is used
DATA(f1) = FILTER #( fi_tab1 WHERE a >= 3 ).
output->display( input = f1 name = `f1` ).
"USING KEY primary_key explicitly specified; same as above
DATA(f2) = FILTER #( fi_tab1 USING KEY primary_key WHERE a >= 3 ).
output->display( input = f2 name = `f2` ).
"EXCEPT addition
DATA(f3) = FILTER #( fi_tab1 EXCEPT WHERE a >= 3 ).
output->display( input = f3 name = `f3` ).
DATA(f4) = FILTER #( fi_tab1 EXCEPT USING KEY primary_key WHERE a >= 3 ).
output->display( input = f4 name = `f4` ).
"Secondary table key specified after USING KEY
DATA(f5) = FILTER #( fi_tab2 USING KEY sec_key WHERE a >= 4 ).
output->display( input = f5 name = `f5` ).
DATA(f6) = FILTER #( fi_tab2 EXCEPT USING KEY sec_key WHERE a >= 3 ).
output->display( input = f6 name = `f6` ).
"Note: In case of a hash key, exactly one comparison expression for each key
"component is allowed; only = as comparison operator possible.
DATA(f7) = FILTER #( fi_tab3 WHERE a = 3 ).
output->display( input = f7 name = `f7` ).
"Using a filter table
"In the WHERE condition, the columns of source and filter table are compared.
"Those lines in the source table are used for which at least one line in the
"filter table meets the condition. EXCEPT and USING KEY are also possible.
"Declaring and filling filter tables
DATA filter_tab1 TYPE SORTED TABLE OF i
WITH NON-UNIQUE KEY table_line.
extract_tab = VALUE #( ( 3 ) ( 5 ) ).
DATA filter_tab2 TYPE STANDARD TABLE OF i
WITH EMPTY KEY
WITH UNIQUE SORTED KEY line COMPONENTS table_line.
DATA(filter3) = FILTER #( tab4 IN extract_tab
WHERE comp3 = table_line ).
filter_tab1 = VALUE #( ( 3 ) ( 5 ) ).
filter_tab2 = filter_tab1.
output->display( input = tab4 name = `tab4` ).
output->display( input = filter1 name = `filter1` ).
output->display( input = filter2 name = `filter2` ).
output->display( input = filter3 name = `filter3` ).
DATA(f8) = FILTER #( fi_tab1 IN filter_tab1 WHERE a = table_line ).
output->display( input = f8 name = `f8` ).
"EXCEPT addition
DATA(f9) = FILTER #( fi_tab1 EXCEPT IN filter_tab1 WHERE a = table_line ).
output->display( input = f9 name = `f9` ).
"USING KEY is specified for the filter table
DATA(f10) = FILTER #( fi_tab2 IN filter_tab2 USING KEY line WHERE a = table_line ).
output->display( input = f10 name = `f10` ).
"USING KEY is specified for the source table, including EXCEPT
DATA(f11) = FILTER #( fi_tab2 USING KEY sec_key EXCEPT IN filter_tab2 WHERE a = table_line ).
output->display( input = f11 name = `f11` ).
output->next_section( `11. Iteration Expressions with FOR` ).

View File

@@ -19,7 +19,7 @@
* numbers (e. g. 1) ..., 2) ..., 3) ...) for the individual example
* sections. Plus, the variable name is displayed in most cases. Hence,
* to easier and faster find the relevant output in the console, just
* search in the console for the number/variable name (STRG+F in the
* search in the console for the number/variable name (CTRL+F in the
* console) or use the debugger.
*
* ----------------------------- NOTE -----------------------------------
@@ -620,43 +620,102 @@ CLASS ZCL_DEMO_ABAP_INTERNAL_TABLES IMPLEMENTATION.
output->next_section( `22) FILTER: Filtering internal table by condition` ).
TYPES t_itab2filter TYPE SORTED TABLE OF zdemo_abap_tab1
WITH NON-UNIQUE KEY key_field.
"This section covers multiple examples demonstrating the syntactical variety
"of the FILTER operator.
DATA itab2filter TYPE t_itab2filter.
TYPES: BEGIN OF fi_str,
a TYPE i,
b TYPE c LENGTH 3,
c TYPE c LENGTH 3,
END OF fi_str.
"Retrieving data for the example in an internal table
SELECT key_field, char1, char2, num1, num2
FROM zdemo_abap_tab1
INTO CORRESPONDING FIELDS OF TABLE @itab2filter UP TO 4 ROWS.
"basic form, condition created with single values
"itab must have at least one sorted key or one hash key used for access.
"This variant of the filter operator is not possible for an internal table itab without a sorted key or hash key.
DATA fi_tab1 TYPE SORTED TABLE OF fi_str WITH NON-UNIQUE KEY a.
DATA fi_tab2 TYPE STANDARD TABLE OF fi_str WITH NON-UNIQUE SORTED KEY sec_key COMPONENTS a.
DATA fi_tab3 TYPE HASHED TABLE OF fi_str WITH UNIQUE KEY a.
"New internal table is constructed by filtering out lines from
"another one.
DATA(filtered1) = FILTER #( itab2filter WHERE key_field < 400 ).
"Filling internal tables
fi_tab1 = VALUE #( ( a = 1 b = 'aaa' c = 'abc' )
( a = 2 b = 'bbb' c = 'def' )
( a = 3 b = 'ccc' c = 'hij' )
( a = 4 b = 'ddd' c = 'klm' )
( a = 5 b = 'eee' c = 'nop' ) ).
output->display( input = filtered1 name = `filtered1` ).
fi_tab2 = fi_tab1.
fi_tab3 = fi_tab1.
output->next_section( `23) FILTER: Filtering internal table by ` &&
`condition with the addition EXCEPT that excludes data ` &&
`according to condition` ).
"The lines meeting the condition are respected.
"Note: The source table must have at least one sorted or hashed key.
"Here, the primary key is used
DATA(f1) = FILTER #( fi_tab1 WHERE a >= 3 ).
DATA(filtered2) = FILTER #( itab2filter
EXCEPT WHERE key_field < 300 ).
output->display( input = f1 name = `f1` ).
output->display( input = filtered2 name = `filtered2` ).
"USING KEY primary_key explicitly specified; same as above
DATA(f2) = FILTER #( fi_tab1 USING KEY primary_key WHERE a >= 3 ).
output->next_section( `24) FILTER: Filtering internal table by ` &&
`using another filter table` ).
output->display( input = f2 name = `f2` ).
"Filling the filter table.
DATA(extract) = VALUE t_itab2filter( ( key_field = 100 )
( key_field = 300 ) ).
"EXCEPT addition
DATA(f3) = FILTER #( fi_tab1 EXCEPT WHERE a >= 3 ).
DATA(filtered3) = FILTER #( itab2filter IN extract
WHERE key_field = key_field ).
output->display( input = f3 name = `f3` ).
output->display( input = filtered3 name = `filtered3` ).
DATA(f4) = FILTER #( fi_tab1 EXCEPT USING KEY primary_key WHERE a >= 3 ).
output->display( input = f4 name = `f4` ).
"Secondary table key specified after USING KEY
DATA(f5) = FILTER #( fi_tab2 USING KEY sec_key WHERE a >= 4 ).
output->display( input = f5 name = `f5` ).
DATA(f6) = FILTER #( fi_tab2 EXCEPT USING KEY sec_key WHERE a >= 3 ).
output->display( input = f6 name = `f6` ).
"Note: In case of a hash key, exactly one comparison expression for each key
"component is allowed; only = as comparison operator possible.
DATA(f7) = FILTER #( fi_tab3 WHERE a = 3 ).
output->display( input = f7 name = `f7` ).
"Using a filter table
"In the WHERE condition, the columns of source and filter table are compared.
"Those lines in the source table are used for which at least one line in the
"filter table meets the condition. EXCEPT and USING KEY are also possible.
"Declaring and filling filter tables
DATA filter_tab1 TYPE SORTED TABLE OF i
WITH NON-UNIQUE KEY table_line.
DATA filter_tab2 TYPE STANDARD TABLE OF i
WITH EMPTY KEY
WITH UNIQUE SORTED KEY line COMPONENTS table_line.
filter_tab1 = VALUE #( ( 3 ) ( 5 ) ).
filter_tab2 = filter_tab1.
DATA(f8) = FILTER #( fi_tab1 IN filter_tab1 WHERE a = table_line ).
output->display( input = f8 name = `f8` ).
"EXCEPT addition
DATA(f9) = FILTER #( fi_tab1 EXCEPT IN filter_tab1 WHERE a = table_line ).
output->display( input = f9 name = `f9` ).
"USING KEY is specified for the filter table
DATA(f10) = FILTER #( fi_tab2 IN filter_tab2 USING KEY line WHERE a = table_line ).
output->display( input = f10 name = `f10` ).
"USING KEY is specified for the source table, including EXCEPT
DATA(f11) = FILTER #( fi_tab2 USING KEY sec_key EXCEPT IN filter_tab2 WHERE a = table_line ).
output->display( input = f11 name = `f11` ).
output->next_section( `25) Inserting data into an internal table ` &&
`using a COLLECT statement` ).