Embedded Analytics mit CDS Queries - mit Query Template

Embedded Analytics mit CDS Queries - mit Query Template

Veröffentlicht am 22. Dezember 2021 von

Jörg Brandeis

| ABAP | CDS | S/4HANA |

Was sind CDS Queries?

Das Reporting direkt im transaktionalen ERP System (z.B. S/4HANA) mittels CDS Views wird als Embedded Analytics bezeichnet. Mit den CDS Queries haben wir hierbei die gleichen Möglichkeiten wie bei den SAP BW-Queries aus dem Query Designer. Sie können auch in den selben Tools konsumiert werden, z.B. Transaktion RSRT oder Analysis for Office und in Fiori Kacheln eingebunden werden. In diesem Artikel wollen wir die wichtigsten Elemente der Queries zeigen und am Ende ein Query Template als Kopiervorlage bereit stellen, das als Ausgangsbasis für eigene CDS Queries dienen kann.

Ein Query CDS View kann nur aus einem CDS InfoProvider lesen.

Der CDS InfoProvider wird durch die Annotation @Analytics.DataCategory: #CUBE oder #DIMENSION definiert. Er bringt einige Eigenschaften mit, die in der Query geerbt werden. Dazu gehören unter anderem:

  • Verknüpfungen vom Cube zu den Dimension Views
  • Verknüpfungen von den Dimension Views zu den zugehörigen Text-Views
  • Aggregationsverhalten von Kennzahlen
  • Semantische Klassifizierung der Felder
  • Abhängigkeiten zwischen Feldern

Die CDS InfoProvider modellieren diese Eigenschaften zentral und können in mehreren Queries wiederverwendet werden. Sie entsprechen in vielen Punkten einem Composite Provider im SAP BW. Dem Aufbau von CDS InfoProvidern haben wir einen separaten Blog-Post gewidmet.

CDS Queries

CDS Queries können nur aus CDS InfoProvidern Daten lesen

Analytic Annotations auf View-Ebene

Ein CDS View wird durch die folgende Analytic Annotation zu einer CDS Query:

@Analytics.query: true

Damit ist der CDS View unter dem Namen des SQL-Views mit dem Präfix 2C in den Tools sichtbar, beispielsweise in der RSRT Transaktion oder dem Analysis for Office. Auf Ebene des Views kann dann noch die Darstellung von Nullen festgelegt werden:

@Analytics.settings.zeroValues: { handling:   #HIDE_IF_ALL, // #HIDE, #SHOW
                                  hideOnAxis: #ROWS_COLUMNS // #COLUMNS, #ROWS
}

Analytic Annotations auf Feld-Ebene

In diesem Abschnitt sind die einzelnen Annotationen nach Thema gruppiert. Dabei haben wir jeweils die wichtigsten Annotationen ausgewählt. Für weitere Details empfiehlt sich der Blick in die Referenzdokumentation der SAP.

Für alle Felder kann der Anzeigetext so festgelegt werden:

@EndUserText.label: ''

Parameter zum Filtern in CDS Queries

Eingabeparameter können entweder als CDS Parameter oder, nur zum Filtern, über die Annotation @Consumption.filter implementiert werden. Die CDS Parameter sind immer Einzelwerte, die beliebig in Ausdrücken verwendet werden können. Beispielsweise in Berechnungen oder als Parameter für SQL-Funktionen. Die Filter über Annotationen sind nicht auf Einzelwerte Beschränkt; Liste von Einzelwerten, Select-Options, einzelne oder mehrere Hierarchieknoten. Die beiden Konzepte können auch kombiniert werden.

  @Consumption.filter:{ selectionType:      #RANGE,       // #INTERVAL, #SINGLE, #HIERARCHY_NODE
                        multipleSelections: false,
                        mandatory:          true,
                        hidden:             false,        //Default: false
                        defaultValue:       '0000000000011675'  }

Annotationen für Zeilen (Merkmale)

  @AnalyticsDetails.query:{ display:       #KEY,    //#KEY_TEXT, #TEXT
                            axis:          #ROWS,   //#COLUMNS
                            totals:        #HIDE,   //#SHOW
                            hidden:        false,   //Default: false
                            sortDirection: #ASC     //#DESC
  }

Annotationen für Kennzahlen

Kennzahlen werden standardmäßig als Spalte dargestellt. Die zugehörige Annotation kann weggelassen werden. Die Nachkommastellen werden mit decimals festgelegt und mit scaling kann der Wert um Zehnerpotenzen verschoben werden. Das ist praktisch, wenn z.B. nur TEUR (=Tausend Euro) statt in EUR berichtet werden soll.

@AnalyticsDetails.query:{ axis:     #COLUMNS,  //optional - Standard value for keyfigures
                          decimals: 2,         //Decimals
                          scaling:  0,         //Default value - to scale by powers of 10
                          hidden:   false      //true = initialy invisible
}

Berechnungen mit Formeln

Mit der Annotation @AnalyticsDetails.query.formula können in der Query Berechnungen durchgeführt werden. Diese werden nur durchgeführt, wenn der CDS View vom OLAP Prozessor verarbeitet wird. Bei einer Datenvorschau sehen wir diese Berechnungen nicht.

  @EndUserText.label: 'Profit'
  @AnalyticsDetails.query:{ formula: '(price_vk - price_vek) * nodim(quant_b)' }
  1 as profit,

Ausnahmeaggregation

  @EndUserText.label: 'Anzahl Belege'
  @AnalyticsDetails.exceptionAggregationSteps:
              [{ exceptionAggregationBehavior: #COUNT,
                 exceptionAggregationElements: ['doc_number'] }]
    1 as doc_count

Annotationen für freie Merkmale

Alle Kennzahlen, die nicht mit der Annotation @AnalyticsDetails.query.axis auf die Achsen #ROW und #COLUMN verteilt wurden, sind freie Merkmale. Das bedeutet, sie sind nicht im initialen Aufriss der Query vorhanden, können aber nach belieben einer der beiden Achsen hinzugefügt werden. Dies wird mit der folgenden, für Merkmale optionalen, Annotation festgelegt:

@AnalyticsDetails.query.axis: #FREE

Das Query Template

Dieses Query Template verwende ich als Kopiervorlage für meine Queries. In den Kommentaren stehen die anderen möglichen Werte für die Annotationen. Die bekommt man zwar auch mit der Code-Completion vorgeschlagen, aber so ist es übersichtlicher, alle Möglichkeiten zu visualisieren.

@AbapCatalog.sqlViewName: 'ZSQL_DEMO_QUERY'
@EndUserText.label: 'Demo Query'

@Analytics.query: true
@Analytics.settings.zeroValues: { handling:   #HIDE_IF_ALL, // #HIDE, #SHOW
                                  hideOnAxis: #ROWS_COLUMNS // #COLUMNS, #ROWS
}
define view zcds_demo_Query
  as select from ZJB_DEMO_cube
{

///////////////////
// Parameter
///////////////////
  @EndUserText.label: 'Kennzahl (Menge)'
  @Consumption.filter:{ selectionType:      #RANGE,       // #INTERVAL, #SINGLE, #HIERARCHY_NODE
                        multipleSelections: false,
                        mandatory:          true,
                        hidden:             false,
                        defaultValue:       '0000000000011675'  }

  @AnalyticsDetails.query:{ hidden: true }
  measure,

///////////////////
// Merkmale
///////////////////
  @AnalyticsDetails.query:{ display:       #KEY,
                            axis:          #ROWS,
                            totals:        #HIDE,
                            sortDirection: #ASC  }
  calday,


///////////////////
// Kennzahlen
///////////////////
  @AnalyticsDetails.query:{ decimals: 4}
  price_vk,

  @AnalyticsDetails.query.hidden: true
  price_vek,

  @AnalyticsDetails.query:{ decimals: 0}
  quant_b,

// Formel
  @EndUserText.label: 'Profit'
  @AnalyticsDetails.query:{ formula: '(price_vk - price_vek) * nodim(quant_b)' }
  1 as profit,

// Ausnahmeaggregation
  @EndUserText.label: 'Unterschiedl. Artikel'
  @AnalyticsDetails.exceptionAggregationSteps:
              [{ exceptionAggregationBehavior: #COUNT,
                 exceptionAggregationElements: ['material'] }]
  1 as materialCount,


///////////////////
// Freie Merkmale
///////////////////
  @EndUserText.label: 'Material'
  @AnalyticsDetails.query:{ display:       #KEY_TEXT,
                            axis:          #FREE,
                            totals:        #HIDE}
  material,
  doc_currcy,
  base_uom
}

Fazit

Diese Zusammenfassung ist bei meiner Arbeit für das Cheat Sheet CDS Plakat entstanden, da ich die Themen für mich noch etwas sortieren musste. Bislang hatte ich nicht sauber gearbeitet und die Trennung zwischen CDS Queries und CDS InfoProvider war verschwommen. Die Hierarchien habe ich bislang in diesem Beitrag ausgeklammert. Falls ich diese mal benötige und damit Erfahrungen sammele, werde ich das hier noch mit einbringen. Falls Euch noch etwas Wichtiges fehlt, Ihr Fehler entdeckt oder einfach nur Feedback geben wollt, freue ich mich über Kommentare.