SAP Fiori Elements のリスト画面(List Report)に、集計データを使った分析チャート(グラフとテーブルの組み合わせ)を追加できます。CAP と ABAP RAP(OData V4)に対応しています。
Add analytical chart (chart + table hybrid) to SAP Fiori Elements List Report using aggregated data. Supports CAP and ABAP RAP (OData V4).
集計データを可視化するために、分析グラフ+テーブル(ハイブリッド表示) を追加します。
プロンプトに以下の情報が不足している場合は、すべてをユーザーに確認してから先に進んでください:
すべての入力が確認されるまで、実装を進めないでください。
@Aggregation.ApplySupported: {
Transformations: ['aggregate','groupby'],
AggregatableProperties: [{Property: Amount}],
GroupableProperties: [Category]
}
Analytics.AggregatedProperty #Amount_avg: {
Name: 'Amount_avg',
AggregatableProperty: Amount,
AggregationMethod: 'average',
![@Common.Label]: 'Average Amount'
}
有効なAggregationMethodの値(小文字の文字列):
sum - ヌル以外の値の合計min - ヌル以外の値の最小値max - ヌル以外の値の最大値average - ヌル以外の値の合計をヌル以外の値の個数で割ったものcountdistinct - ヌル値を除いた異なる値の個数⚠️ 重要: 小文字の文字列(例:'sum')である必要があり、列挙型(例:#SUM)ではいけません。列挙型を使用するとSQL生成エラーが発生します。
UI.Chart #AnalyticalChart: {
$Type: 'UI.ChartDefinitionType',
Title: 'Chart Title',
ChartType: #Column,
Dimensions: [Category],
DynamicMeasures: ['@Analytics.AggregatedProperty#Amount_avg'],
MeasureAttributes: [{
$Type: 'UI.ChartMeasureAttributeType',
DynamicMeasure: '@Analytics.AggregatedProperty#Amount_avg',
Role: #Axis1
}],
DimensionAttributes: [{
$Type: 'UI.ChartDimensionAttributeType',
Dimension: Category,
Role: #Category
}]
},
UI.PresentationVariant #ChartView: {
$Type: 'UI.PresentationVariantType',
Text: 'Chart View',
Visualizations: ['@UI.Chart#AnalyticalChart']
},
UI.PresentationVariant #TableView: {
$Type: 'UI.PresentationVariantType',
Text: 'Table View',
Visualizations: ['@UI.LineItem']
}
✅ DynamicMeasuresを使用しています
これらが不足するとアプリが起動しません:
@OData.applySupportedForAggregation: #FULLがある@Aggregation.default: #AVG(または#SUM、#MIN、#MAX)がある@UI.chart注釈があるtargets.<ListReport>.options.settings.views.paths設定がある⚠️ 重要: @OData.applySupportedForAggregation注釈は必須です
この注釈がない場合:
配置場所:
TRANSACTIONAL_QUERY契約を指定正しい例:
@OData.applySupportedForAggregation: #FULL ← 必須! 必ず記入!
define root view entity ZC_ENTITY
provider contract TRANSACTIONAL_QUERY
as projection on ZR_ENTITY
{
@Aggregation.default: #AVG ← メジャーの集計方法を指定
Amount;
Category; ← ディメンションフィールド(集計注釈は不要)
}
間違った例:
// ❌ 間違い - インターフェースビューに配置しない
@OData.applySupportedForAggregation: #FULL ← 間違った場所!
define root view entity ZR_ENTITY
as select from TABLE
@UI.chart: [{
qualifier: 'AnalyticalChart',
title: 'Chart Title',
description: 'Chart description',
chartType: #COLUMN,
dimensions: ['Category'],
measures: ['Amount'],
dimensionAttributes: [{
dimension: 'Category',
role: #CATEGORY
}],
measureAttributes: [{
measure: 'Amount',
role: #AXIS_1
}]
}]
@UI.presentationVariant: [{
qualifier: 'ChartView',
text: 'Chart View',
visualizations: [{
type: #AS_CHART,
qualifier: 'AnalyticalChart'
}]
},
{
qualifier: 'TableView',
text: 'Table View',
visualizations: [{
type: #AS_LINEITEM
}]
}]
annotate view ZC_ENTITY with
{
// その他のフィールド注釈...
@EndUserText.label: 'Amount'
Amount;
@EndUserText.label: 'Category'
Category;
}
マニフェスト:
"targets": {
"<ListReport>": { // 実際のリストレポートターゲット名に置き換え
"type": "Component",
"name": "sap.fe.templates.ListReport",
"options": {
"settings": {
"contextPath": "/<YourEntity>", // エンティティセットパスに置き換え
"views": {
"paths": [
{
"primary": [
{ "annotationPath": "com.sap.vocabularies.UI.v1.Chart#AnalyticalChart" }
],
"secondary": [
{ "annotationPath": "com.sap.vocabularies.UI.v1.LineItem" }
],
"defaultPath": "both"
}
]
}
}
}
}
}
マニフェスト:
"targets": {
"<ListReport>": { // 実際のリストレポートターゲット名に置き換え
"type": "Component",
"name": "sap.fe.templates.ListReport",
"options": {
"settings": {
"contextPath": "/<YourEntity>", // エンティティセットパスに置き換え
"views": {
"paths": [
{
"key": "ChartView",
"annotationPath": "com.sap.vocabularies.UI.v1.PresentationVariant#ChartView"
},
{
"key": "TableView",
"annotationPath": "com.sap.vocabularies.UI.v1.PresentationVariant#TableView"
}
]
}
}
}
}
}
npm run watch-<app-name> # 例: npm run watch-manage-travel
# または利用可能なジェネリックウォッチスクリプトを使用
cds watch
npm run start-mock # メタデータ更新が必要
npm start # 更新不要 - 実行時にライブバックエンドからメタデータを取得
エラーを避けるため、この順序に従ってください:
投影ビューを修正(ZC_ENTITY)
@OData.applySupportedForAggregation: #FULLを追加@Aggregation.default: #AVGを追加メタデータ拡張を修正
@UI.chart注釈を追加@UI.presentationVariant注釈を追加Fioriアプリマニフェストを更新
targets.<ListReport>.options.settingsの下にviews.pathsを追加(controlConfigurationの内側ではなく)テスト
npm startを実行(ライブメタデータを取得 - 再発行不要)原因1: @OData.applySupportedForAggregation: #FULLが不足している
原因2: 注釈が間違ったビューに記述されている
原因3: メジャーフィールドが数値型ではない
原因4: マニフェスト内の修飾子が間違っている
@UI.chart: [{ qualifier: 'AnalyticalChart' }]と一致することを確認原因5: メジャーに@Aggregation.defaultが不足している
@Aggregation.default: #AVG(または#SUM、#MIN、#MAX)を追加原因: 集計方法が間違っている
@Aggregation.defaultの値を変更(#AVG、#SUM、#MIN、#MAX)CAP:
RAP:
共通:
RAP特有:
@OData.applySupportedForAggregation: #FULLが不足 → アプリが起動しない@Aggregation.defaultがないTRANSACTIONAL_QUERYである必要がある)PresentationVariantを使用して、グラフまたはテーブルの個別ビューをタブで表示Add analytical chart + table (hybrid view) to visualize aggregated data.
CAP Projects:
ABAP RAP Projects:
STOP and ASK the user for ALL of these inputs if ANY are missing from the prompt:
DO NOT proceed with implementation until all inputs are confirmed.
@Aggregation.ApplySupported: {
Transformations: ['aggregate','groupby'],
AggregatableProperties: [{Property: Amount}],
GroupableProperties: [Category]
}
Analytics.AggregatedProperty #Amount_avg: {
Name: 'Amount_avg',
AggregatableProperty: Amount,
AggregationMethod: 'average',
![@Common.Label]: 'Average Amount'
}
Valid AggregationMethod values (lowercase string):
sum - Sum of the non-null valuesmin - Smallest of the non-null valuesmax - Largest of the non-null valuesaverage - Sum of non-null values divided by count of non-null valuescountdistinct - Count of distinct values, omitting null values⚠️ CRITICAL: Must be a lowercase string (e.g., 'sum'), NOT an enum (e.g., #SUM). Using an enum will cause SQL generation errors.
UI.Chart #AnalyticalChart: {
$Type: 'UI.ChartDefinitionType',
Title: 'Chart Title',
ChartType: #Column,
Dimensions: [Category],
DynamicMeasures: ['@Analytics.AggregatedProperty#Amount_avg'],
MeasureAttributes: [{
$Type: 'UI.ChartMeasureAttributeType',
DynamicMeasure: '@Analytics.AggregatedProperty#Amount_avg',
Role: #Axis1
}],
DimensionAttributes: [{
$Type: 'UI.ChartDimensionAttributeType',
Dimension: Category,
Role: #Category
}]
},
UI.PresentationVariant #ChartView: {
$Type: 'UI.PresentationVariantType',
Text: 'Chart View',
Visualizations: ['@UI.Chart#AnalyticalChart']
},
UI.PresentationVariant #TableView: {
$Type: 'UI.PresentationVariantType',
Text: 'Table View',
Visualizations: ['@UI.LineItem']
}
✅ Uses DynamicMeasures
Missing ANY of these will cause the app to fail/not load:
@OData.applySupportedForAggregation: #FULL on projection view (ZC_*)@Aggregation.default: #AVG (or #SUM, #MIN, #MAX) on measure field@UI.chart annotation with correct qualifier in metadata extensiontargets.<ListReport>.options.settings.views.paths configuration⚠️ CRITICAL: @OData.applySupportedForAggregation annotation is MANDATORY
WITHOUT this annotation:
Placement:
TRANSACTIONAL_QUERY contractCORRECT Example:
@OData.applySupportedForAggregation: #FULL ← MANDATORY! Must be present!
define root view entity ZC_ENTITY
provider contract TRANSACTIONAL_QUERY
as projection on ZR_ENTITY
{
@Aggregation.default: #AVG ← Specify aggregation method for measure
Amount;
Category; ← Dimension field (no aggregation annotation needed)
}
WRONG Example:
// ❌ WRONG - Don't put on interface view
@OData.applySupportedForAggregation: #FULL ← WRONG PLACE!
define root view entity ZR_ENTITY
as select from TABLE
@UI.chart: [{
qualifier: 'AnalyticalChart',
title: 'Chart Title',
description: 'Chart description',
chartType: #COLUMN,
dimensions: ['Category'],
measures: ['Amount'],
dimensionAttributes: [{
dimension: 'Category',
role: #CATEGORY
}],
measureAttributes: [{
measure: 'Amount',
role: #AXIS_1
}]
}]
@UI.presentationVariant: [{
qualifier: 'ChartView',
text: 'Chart View',
visualizations: [{
type: #AS_CHART,
qualifier: 'AnalyticalChart'
}]
},
{
qualifier: 'TableView',
text: 'Table View',
visualizations: [{
type: #AS_LINEITEM
}]
}]
annotate view ZC_ENTITY with
{
// Other field annotations...
@EndUserText.label: 'Amount'
Amount;
@EndUserText.label: 'Category'
Category;
}
After activating both DDLS and DDLX, verify the changes are live:
⚠️ IMPORTANT: DDLS and DDLX are Separate Objects
The projection view (DDLS file) and metadata extension (DDLX file) are separate ABAP development objects that happen to share the same entity name.
Key points:
Activation:
Verification Steps:
Verify Activation Status:
Check OData $metadata:
<service-url>/$metadata<Annotation Term="UI.Chart" Qualifier="AnalyticalChart"><Annotation Term="UI.PresentationVariant" Qualifier="ChartView">Manifest:
"targets": {
"<ListReport>": { // Replace with your actual List Report target name
"type": "Component",
"name": "sap.fe.templates.ListReport",
"options": {
"settings": {
"contextPath": "/<YourEntity>", // Replace with your entity set path
"views": {
"paths": [
{
"primary": [
{ "annotationPath": "com.sap.vocabularies.UI.v1.Chart#AnalyticalChart" }
],
"secondary": [
{ "annotationPath": "com.sap.vocabularies.UI.v1.LineItem" }
],
"defaultPath": "both"
}
]
}
}
}
}
}
Manifest:
"targets": {
"<ListReport>": { // Replace with your actual List Report target name
"type": "Component",
"name": "sap.fe.templates.ListReport",
"options": {
"settings": {
"contextPath": "/<YourEntity>", // Replace with your entity set path
"views": {
"paths": [
{
"key": "ChartView",
"annotationPath": "com.sap.vocabularies.UI.v1.PresentationVariant#ChartView"
},
{
"key": "TableView",
"annotationPath": "com.sap.vocabularies.UI.v1.PresentationVariant#TableView"
}
]
}
}
}
}
}
npm run watch-<app-name> # e.g., npm run watch-manage-travel
# or use generic watch script if available
cds watch
npm run start-mock # Needs metadata refresh - see below
npm start # No refresh needed - fetches metadata from live backend at runtime
Refreshing metadata for start-mock:
npm run start-mock, the app uses locally cached metadata.xmlsap-fiori-app-development skillFollow this sequence to avoid errors:
Modify Projection View (ZC_ENTITY) - DDLS file
@OData.applySupportedForAggregation: #FULL at top@Aggregation.default: #AVG to measure fieldModify Metadata Extension (ZC_ENTITY) - DDLX file
@UI.chart annotation with qualifier@UI.presentationVariant annotationsVerify Annotations are Active (see Step 3 in ABAP RAP Implementation section above)
Update Fiori App Manifest
views.paths under targets.<ListReport>.options.settings (NOT inside controlConfiguration)Test
npm start (fetches live metadata - no republishing needed)Full error message:
Annotation Path for the primary visualization com.sap.vocabularies.UI.v1.Chart#AnalyticalChart not found
Cause: The metadata extension (DDLX) is NOT active, so the @UI.chart annotation is not exposed in the OData $metadata.
Solution:
<service-url>/$metadata (search for Chart#AnalyticalChart)npm startNote: Even if you edited the DDLX, it won't take effect until explicitly activated. The DDLS and DDLX are separate objects.
Cause 1: Missing @OData.applySupportedForAggregation: #FULL
Cause 2: Annotation on wrong view
Cause 3: Measure field not numeric
Cause 4: Wrong qualifier in manifest
@UI.chart: [{ qualifier: 'AnalyticalChart' }]Cause 5: Missing @Aggregation.default on measure
@Aggregation.default: #AVG (or #SUM, #MIN, #MAX) to measure fieldCause 6: DDLX not activated (see console error above)
Cause: Wrong aggregation method
@Aggregation.default value (#AVG, #SUM, #MIN, #MAX)CAP:
RAP:
General:
RAP-Specific:
@OData.applySupportedForAggregation: #FULL → App won't load@Aggregation.default on measure fieldTRANSACTIONAL_QUERY)PresentationVariant for separate view tabs (chart or table)原文・著作権は Anthropic および各プラグイン作者に帰属します。日本語訳は Claude API による自動翻訳です。