Consume CDS analytical query from ABAP program

This blog introduces Lightweight BICS API, which is a new SAP standard ABAP API to consume analytical query built on CDS and BW.

Refer to SAP note 3269710 for initial shipment information. 3269710 – LBA: Lightweight BICS API – initial shipment – SAP for Me

For functional roundups, please refer to SAP note 3340054 3340054 – LBA: Lightweight BICS API – functional roundups – SAP for Me.

LBA comes with 2 flavours:

  •  for classic analytical queries       ( CL_LBA_STD_QUERY )
  •  for CDS based analytical queries ( CL_LBA_CDS_QUERY )

In this blog, we will touch on the latter case as it is more mainstream to use CDS and embedded analytics engine in S4. We will create a demo CDS query and consume it using CL_LBA_CDS_QUERY in demo ABAP program.

Create a demo CDS query

@EndUserText.label: 'Test Query for ABAP consumtion'
@VDM.viewType: #CONSUMPTION
@Analytics.query: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@Metadata.ignorePropagatedAnnotations: true
define view entity YTEST_QUERY_FROM_ABAP
  with parameters

    P_CompanyCode : bukrs
    
  as select from I_GLAccountLineItemCube as I_GLAccountLineItemCube
{

  @Consumption.filter: {selectionType: #SINGLE, multipleSelections: false, mandatory: true}
  @Consumption.derivation: { lookupEntity: 'I_Ledger',
        resultElement: 'Ledger', binding: [
        { targetElement : 'IsLeadingLedger' , type : #CONSTANT, value : 'X' } ]
       }
  @AnalyticsDetails.query.variableSequence : 10
  @AnalyticsDetails.query.axis: #FREE
  @AnalyticsDetails.query.display: #KEY_TEXT
  Ledger,

  @Consumption.filter: {selectionType: #SINGLE, multipleSelections: true, mandatory: true}
  @AnalyticsDetails.query.variableSequence : 20
  @AnalyticsDetails.query.axis: #ROWS
  @AnalyticsDetails.query.totals: #SHOW
  @AnalyticsDetails.query.display: #KEY_TEXT
  CompanyCode,

  @Consumption.filter: { selectionType: #SINGLE, multipleSelections: true, mandatory: false }
  @AnalyticsDetails.query.variableSequence: 30
  @AnalyticsDetails.query.axis: #ROWS
  @AnalyticsDetails.query.totals: #SHOW
  @AnalyticsDetails.query.display: #KEY_TEXT
  GLAccount,

  @AnalyticsDetails.query.axis: #FREE
  @AnalyticsDetails.query.display: #KEY_TEXT
  ProfitCenter,

  @AnalyticsDetails.query.axis: #FREE
  PostingDate,

  @AnalyticsDetails.query.axis: #FREE
  @Consumption.filter: { selectionType: #RANGE, multipleSelections: true, mandatory: false }
  AccountingDocument,

  ///////////////////////////////////////////////////////////////////////
  // Measures - Amounts
  ///////////////////////////////////////////////////////////////////////
  @AnalyticsDetails.query.axis: #FREE
  CompanyCodeCurrency,

  @Semantics.amount.currencyCode: 'CompanyCodeCurrency'
  @AnalyticsDetails.query.axis: #COLUMNS
  @DefaultAggregation: #SUM
  AmountInCompanyCodeCurrency
}
where CompanyCode = $parameters.P_CompanyCode;

Go to tcode RSRT and preview the query with WD grid(or display of your choice).

Enter a company code and run the report. For the demo purpose, I will filter the data on the posting date on 31.12.2016.

In the next step, let’s create an ABAP program to call this query and filter the data so it will get exactly 2,499,996 USD.

ABAP program to consume CDS query

Create below program in ADT or SE80. The comments are self-explanatory but to add explanation,

  • Instantiation of cl_lba_cds_query requires query name ‘YTEST_QUERY_FROM_ABAP’.
  • Set all required dimensions and measures in lt_requested_columns
  • Set all required parameters in lt_parameter_values
  • Set filter is neessary in lt_filter
  • Call method get_resultset to consume CDS query
REPORT yay_test_call_cdsquery.
"Calling analytical query
DATA: lt_requested_columns TYPE cl_lba_std_query=>tn_t_columns_req,
      lt_parameter_values  TYPE cl_lba_cds_query=>tn_t_parameter_values,
      lt_filter            TYPE cl_lba_cds_query=>tn_t_filter_values.
FIELD-SYMBOLS:<lw_requested_columns> TYPE cl_lba_std_query=>tn_s_column_req,
              <lw_filter>            TYPE cl_lba_cds_query=>tn_s_filter_value,
              <lw_parameter_values>  TYPE cl_lba_cds_query=>tn_s_parameter_value.

"Create an instance of Lightweight BICS API 
TRY.
    DATA(lr_cds_query) = NEW cl_lba_cds_query( i_view_name = 'YTEST_QUERY_FROM_ABAP'  ).
  CATCH cx_lba_query.
    RETURN.
ENDTRY.

"Requested measures and dimenions.
APPEND INITIAL LINE TO lt_requested_columns ASSIGNING <lw_requested_columns>.
<lw_requested_columns>-name = 'CompanyCode'.
APPEND INITIAL LINE TO lt_requested_columns ASSIGNING <lw_requested_columns>.
<lw_requested_columns>-name = 'PostingDate'.
APPEND INITIAL LINE TO lt_requested_columns ASSIGNING <lw_requested_columns>.
<lw_requested_columns>-name = 'CompanyCodeCurrency'.
APPEND INITIAL LINE TO lt_requested_columns ASSIGNING <lw_requested_columns>.
<lw_requested_columns>-name = 'AmountInCompanyCodeCurrency'.

"Parameters
APPEND INITIAL LINE TO lt_parameter_values ASSIGNING <lw_parameter_values>.
<lw_parameter_values>-name = 'P_CompanyCode'.
<lw_parameter_values>-value = '1001'.
"Filters
APPEND INITIAL LINE TO lt_filter ASSIGNING <lw_filter>.
<lw_filter>-name = 'PostingDate'.
<lw_filter>-sign = 'I'.
<lw_filter>-opt = 'EQ'.
<lw_filter>-value_low = '20161231'.


TRY.
    "Call CDS analytical query
    lr_cds_query->get_resultset(
                   EXPORTING i_t_requested_columns = lt_requested_columns       "dimensions&keyfigures for resultset
                             i_t_parameter_values  = lt_parameter_values        "mandatory and optional variables
                             i_t_filter_values     = lt_filter                  "additional filters
                    IMPORTING e_r_resultset         = DATA(lr_resultset)         "resultset table
                              e_t_column_catalog    = DATA(lt_column_catalog) ). "resultset description
  CATCH cx_lba_query INTO DATA(lo_return).
    DATA(lv_text) = lo_return->get_text( ).
ENDTRY.

BREAK-POINT.

The query output is stored in lr_resultset and can be accessed via ‘LR_RESULTSET->*’. You can see that posting date is filtered to ‘20161231’ and amount 2,499,996 USD has been fetched.