Remove duplicate values from a BRF+ table
BRF+ does not support enforcing unique key constraints on its tables, even if the table is bound to a DDIC table type with a unique key. There is also no out of the box functionality to remove duplicates from a BRF+ table. I needed a simple and performance efficient solution for this requirement.
- The duplicate removal can be implemented by a simple ABAP function using SORT and DELETE ADJACENT DUPLICATES
- Using generic types for the method parameters makes for efficient procedure calls from BRF+
Our rule set consists of a list of rules that depending on input data modify parts (called entities) of a large data model (SAP Material). Due to performance constraints in the underlying system, only changed parts shall be written back and written only once. There is a n:m relationship between rules and data model parts. If a rule changes one or more entities, it adds the entity names to a list of entities to be written.
Alas, calling from BRF+ into ABAP comes at some price, as the framework uses a different data representation internally (inside BRF+) then externally (in the ABAP world), e.g. all text data is converted into a STRING type, and quantities and amounts are represented by structures (for details, see IF_FDT_TYPES in your system). So for every procedure call, the system needs to do a conversion internal → external for converting the method parameters when invoking the method and external → internal when retrieving the result.
Luckily we can circumvent the conversion process by working with the internal representation directly. This is done by using generic types for our method parameter.
The BRF+ table consists only of a text line. The corresponding ABAP type is
STANDARD TABLE OF if_fdt_types=>element_text WITH DEFAULT KEY
which is an unstructured table of STRING elements.
CLASS-METHODS make_unique_text_table CHANGING !ct_text TYPE TABLE.
The CHANGING parameter ct_text can be passed any table, triggering BRF+ to pass in its internal table format. Note that this also eliminates checks on the caller side, so you need to be careful in BRF+ later on to pass in only table types the method can actually work with.
METHOD make_unique_text_table. "Empty list means nothing to do IF lines( ct_text ) < 2. RETURN. ENDIF. "Sort & make unique SORT ct_text BY table_line. DELETE ADJACENT DUPLICATES FROM ct_text. ENDMETHOD.
The implementation merely contains the SORT & DELETE operations.
Using an expression of type Procedure Call makes the function available to BRF+.
The invocation code generated by BRF+ does not contain any copying of the table or parameter conversion. If you modify the parameter type to a concrete DDIC type, you will see that the method invocation is wrapped in conversion code that copies the internal BRF+ table to the table type you specified.
To Infinity! And beyond.
The above mentioned technique for efficient procedure calls could be extended to structured tables as well if you re-create the BRF+ tables internally used structure in your ABAP code. You can have a look a the generated BRF+ code to understand how BRF+ generates its internal types. You would then just have to cast the generic type to the concrete one and do your ABAP processing on the data.
Note however that you should only using ABAP coding as a last resort and for simplistic self-contained functionality, and stay in BRF+ as long as possible, for countless reasons (performance being the least of them). I have been using BRF+ for some years now, and this is the first occurrence of missing functionality that I encountered, and it was a minor one.