Loop through multiple rows in ABAP CDS by AMDP
If you have worked with ABAP CDS long enough, there is no function to really loop through multiple records and use them for a calculation of a row or certain field. While ABAP CDS syntax still does not offer such functions till today, there are few functions available in ABAP Managed Database Procedures(AMDP) table functions from which ABAP CDS can consume the calculated.
Exercise
We will create a CDS view that returns all the business partners and concatenate their business partner roles(customer, vendor, etc) into one field.

Create table function
Table function must define the fields structure required. The actual data fetching will not be done in the table function object but in the ABAP class that is triggered. So the ABAP class and the method must be defined in table function as well.

@EndUserText.label: 'table function' define table function ZTBL_FUNCTION with parameters @Environment.systemField: #CLIENT p_clnt :abap.clnt, @Environment.systemField: #SYSTEM_LANGUAGE p_lang :abap.lang returns { client : abap.clnt; salesdoc : vbeln_va; mergefunctiontext : abap.char( 1000 ); } implemented by method ZCL_TableFunction=>Get_Data;
Note that if you are using system fields in the SQL to fetch the data, I suggest to define them as parameters. This is because in the subsequent ABAP class where the SQL Script is performed, certain system fields are not available. If they are defined as parameters in table functions, they can be used in the SQL script. We will demonstrate that with client and system language fields.
Create ABAP class to fetch table function data
Class name and method must match the ones defined in table function. Few key points to mentions:
- INTERFACES if_amdp_marker_hdb is added to the public section
- Get_data method must define what database is used, script language, and the tables used in the script
- Use RETURN statement along with SQL to return the data to table function ztbl_function.
- Most importatntly, the SAP script is client dependent, so it must specify the client in SQL otherwise it will fetch the data from all clients in instance.
Few things to mention on the logic:
- bpfunctionconcat will return the “BP function code ( description ) ” for easier readability
- vbpa.posnr = ‘000000’ excludes all sales document that has BP specifically set for sales item
- As function text is language dependent, tpart.spras must be specified with system language therefore using p_langu defined in the table function.
CLASS zcl_tablefunction DEFINITION PUBLIC FINAL CREATE PUBLIC . PUBLIC SECTION. INTERFACES if_amdp_marker_hdb. CLASS-METHODS: get_data FOR TABLE FUNCTION ztbl_function. PROTECTED SECTION. PRIVATE SECTION. ENDCLASS. CLASS zcl_tablefunction IMPLEMENTATION. METHOD get_data BY DATABASE FUNCTION FOR HDB LANGUAGE SQLSCRIPT OPTIONS READ-ONLY USING vbak vbpa tpart. * Get the sales header BP functions it_data = select DISTINCT vbak.mandt as client, vbak.vbeln as salesdoc, vbpa.parvw as bpfunction, tpart.vtext as bpfunctiontext, concat(concat(concat(cast(vbpa.parvw as "$ABAP.type( parvw )" ), '('), tpart.vtext), ')') as bpfunctionconcat from vbak inner join vbpa on vbak.mandt = vbpa.mandt and vbpa.vbeln = vbak.vbeln and vbpa.posnr = '000000' inner join tpart on tpart.mandt = vbpa.mandt and tpart.parvw = vbpa.parvw and tpart.spras = :p_lang where vbak.mandt = :p_clnt; RETURN select client, salesdoc, string_agg(bpfunctionconcat, ', ' ORDER BY bpfunctionconcat) as mergefunctiontext FROM :it_data GROUP BY client, salesdoc; ENDMETHOD. ENDCLASS.
Consume table function
Create a CDS view to consume the table function. Pass the system fields client and language.
@AbapCatalog.viewEnhancementCategory: [#NONE] @AccessControl.authorizationCheck: #NOT_REQUIRED @EndUserText.label: 'Consume table function' @Metadata.ignorePropagatedAnnotations: true @ObjectModel.usageType:{ serviceQuality: #X, sizeCategory: #S, dataClass: #MIXED } define view entity ZTBL_FUNCTION_CONSUME as select from ZTBL_FUNCTION( p_clnt : $session.client, p_lang : $session.system_language ) { salesdoc, mergefunctiontext }
Preview this CDS in SE16n and you can see that mergefunctiontext returns all the business partner and it’s text in one single line.
