sap-fiori-add-visual-filter について
sap-fiori-add-visual-filterは、SAP FioriのOData V4アプリに棒グラフまたは折れ線グラフのビジュアルフィルターを追加するスキルです。CAPとABAP RAPの実装におけるアノテーション、マニフェスト設定、有効化、検証を案内します。
主な機能
- 01棒グラフまたは折れ線グラフのフィルター追加
- 02CAPの集計とアノテーション設定
- 03ABAP RAPのチャートアノテーション設定
- 04マニフェストのコントロール設定
- 05有効化とODataメタデータの検証
活用シーン
- 01CAP Fioriアプリにチャートフィルターを追加
- 02ABAP RAPアプリにビジュアルフィルターを実装
- 03フィルターアノテーションの欠落や不一致を調査
MCP 対応
VS CodeでFioriアプリを変更するにはFiori MCP Serverが必要です。ABAP RAPでは、ABAPオブジェクトの有効化にABAP ADT MCPを使う手順も記載されています。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ sap/ open-ux-tools --skill sap-fiori-add-visual-filterインストール後、Claude Code で/sap-fiori-add-visual-filterを入力して読み込まれたか確認します。
詳細
SAP Fiori ビジュアルフィルター
目的
フィルターバーまたは値ヘルプダイアログ(OData V4)に**チャートベースのフィルター(棒/折れ線)**を追加します。
前提条件
CAP プロジェクト:
- ✅ VS Code または SAP Business Application Studio(BAS) - どちらの環境もサポートされています
- ✅ Fiori MCP Server - Fiori アプリの変更に必要です(VS Code のみ)
ABAP RAP プロジェクト:
- ✅ VS Code のみ - ABAP Development Tools 拡張機能は VS Code 専用です
- ✅ Fiori MCP Server - Fiori アプリの変更に必要です
- ✅ ABAP Development Tools for VS Code 拡張機能 - バックエンド開発に必要です(RAP 操作用の ADT MCP サーバーを含みます)
必須:最初に必要な入力を収集する
プロンプトに以下の入力が1つでも不足している場合は、作業を中断してユーザーにすべて確認してください:
- エンティティ - ビジュアルフィルターを追加するエンティティ
- ディメンションフィールド - フィルター対象のフィールド(例:Category、Status、Destination)
- メジャーフィールド - 集計する数値フィールド(例:Amount、TotalPrice、ReservationPrice)
- 集計方法 - 集計方法(有効な値は以下を参照)
- チャートタイプ - 棒または折れ線(デフォルトには棒を推奨)
すべての入力が確認できるまで、実装を進めないでください。
⚠️ 折れ線チャートのディメンション型の制約: ChartType: #Line がサポートするディメンションの型は、Edm.Date、Edm.TimeOfDay、Edm.DateTimeOffset のみです。要求されたディメンションが別の型(例:Status や Category などの文字列/関連コード)の場合は、代わりに #Bar を使用するか、作業を進める前にディメンションフィールドが日付/時刻型であることをユーザーに確認してください。
CAP の実装
集計を有効にする(必須)
@Aggregation.ApplySupported: {
Transformations: ['aggregate','groupby'],
AggregatableProperties: [{ Property: Amount }],
GroupableProperties: [Category]
}
集計対象プロパティ(メジャー)
Analytics.AggregatedProperty #Amount_sum : {
$Type: 'Analytics.AggregatedPropertyType',
Name: 'Amount_sum',
AggregatableProperty: Amount,
AggregationMethod: 'sum',
![@Common.Label]: 'Total Amount'
}
有効な AggregationMethod の値(小文字の文字列):
sum- null 以外の値の合計min- null 以外の値の最小値max- null 以外の値の最大値average- null 以外の値の合計を、null 以外の値の件数で割った値countdistinct- null 値を除外した個別の値の件数
⚠️ 重要: 値は小文字の文字列(例:'sum')にする必要があり、列挙値(例:#SUM)は使用できません。列挙値を使用すると、SQL の生成エラーが発生します。
チャート注釈
UI.Chart #visualFilter : {
ChartType: #Bar,
Dimensions: [Category],
DynamicMeasures: ['@Analytics.AggregatedProperty#Amount_sum']
}
✅ DynamicMeasures を使用します
PresentationVariant
UI.PresentationVariant #visualFilter: {
Visualizations: ['@UI.Chart#visualFilter']
}
スカラー型プロパティと管理アソシエーションのディメンション
注釈の配置場所は、CAP モデルでディメンションがどのように宣言されているかによって異なります。
- 直接のスカラー型プロパティには、インラインで注釈を付けられます。たとえば、
Category : String(80)は実際のエンティティ要素なので、annotate ... with { ... }ブロック内でCategory @Common.ValueList #visualFilterを使用します。 - 管理アソシエーションは異なります。たとえば、
Category : Association to Categoriesはローカル外部キーCategory_codeを生成します。Category_codeはソースエンティティで宣言された要素ではないため、そのブロック内でインライン注釈を付けることはできません。
スカラー型の Category ディメンションには、次の記述が有効です。
annotate MyService.Entity with {
Category @Common.ValueList #visualFilter: {
$Type: 'Common.ValueListType',
CollectionPath: 'Entity',
PresentationVariantQualifier: 'visualFilter',
Parameters: [
{ $Type: 'Common.ValueListParameterInOut',
LocalDataProperty: Category, ValueListProperty: 'Category' }
]
};
};
ディメンションが管理アソシエーション Category であるビジュアルフィルターには、以下で説明する独立したアソシエーションキーのターゲットを使用します。エンティティ注釈ブロック内で、ターゲットを Category_code に置き換えないでください。
⚠️ ディメンションが管理対象アソシエーションの外部キーの場合(例:Category_code、Status_ID)
ディメンション項目が管理対象アソシエーションの自動生成された外部キー列(例:Category : Association to Categories の Category_code)の場合、エンティティの annotate ... with { ... } ブロック内にインラインで注釈を付けることはできません。この場所では外部キー列が要素として認識されないためです。CDS コンパイラーは次のエラーを出します。
Element "Category_code" has not been found
✅ 正しい方法: アソシエーション自体を対象にする別の annotate 文を使用します。コンパイラーが外部キー列に書き換えます。
// Compiles to target Travels/Category_code in $metadata
annotate MyService.Entity:Category with @(
Common.ValueList #visualFilter: {
$Type : 'Common.ValueListType',
CollectionPath : 'Entity',
PresentationVariantQualifier: 'visualFilter',
Parameters : [
{ $Type: 'Common.ValueListParameterInOut',
LocalDataProperty: Category_code, ValueListProperty: 'Category_code' }
]
}
);
重要なポイント:
- 対象の構文:
annotate <Service>.<Entity>:<assoc>— 管理対象の単一アソシエーションの場合、コンパイラーはアソシエーションに付けられた注釈を、生成されたローカル外部キー要素にコピー/書き換えます。これは、文書化されている CAP コンパイラーの動作(CAP ドキュメントの「Managed Associations」を参照)に沿っています。他の注釈(例:Common.Label、Common.Text)が別の箇所ですでに同じアソシエーションを対象にしている場合、$metadataではAnnotations Target="...Entity/<assoc>_code"ブロックに統合されます。不明な場合は、cds compile --to edmxで確認してください。 LocalDataPropertyとValueListPropertyはどちらもアソシエーション名ではなく、外部キー列名(例:Category_code)を使用します。CollectionPathは、コードリストのエンティティセットではなく、チャートデータを保持する同じエンティティセット(自己参照)です。
❌ 誤った方法: エンティティブロック内のインライン注釈 — コンパイルに失敗します。
annotate MyService.Entity with { ... } {
Category_code @Common.ValueList #visualFilter: { ... }; // ❌ Element not found
};
SelectionFields
UI.SelectionFields: [Category]
マニフェストの設定(必須)
以下の CAP と RAP に共通するマニフェストの設定セクションが適用されます。
ABAP RAP の実装(4 ステップ)
重要:metadata.xml は絶対に編集しないでください — 読み取り専用です!
⚠️ 実装前チェックリスト — 実装前に確認してください
以下のいずれかが欠けていると、ビジュアルフィルターが機能しません。
- プロジェクションビュー(ZC_*)に
@OData.applySupportedForAggregation: #FULLがある - メジャー項目に
@Aggregation.default: #SUM(または #AVG、#MIN、#MAX)がある - メタデータ拡張に正しいクオリファイアーを指定した
@UI.chart注釈がある - ディメンション項目に
@UI.selectionFieldがある - annotation.xml にフロントエンドの
Common.ValueList注釈がある - ビジュアルフィルターの設定を含むマニフェストの
controlConfigurationがある - すべての CDS オブジェクトがアクティブ化済み
1. バックエンドのプロジェクションビュー(必須)— 集計のサポートを有効にする
⚠️ 重要:@OData.applySupportedForAggregation 注釈は必須です
この注釈がない場合:
- OData サービスは集計をサポートしません
- ビジュアルフィルターの読み込みに失敗します
- チャート注釈は無視されます
配置場所:
- ✅
TRANSACTIONAL_QUERYコントラクトを持つプロジェクションビュー(ZC_* または ZZZC_*)に指定する必要があります - ❌ インターフェースビュー(ZR_* または ZZZR_*)には指定しないでください
正しい例:
// MANDATORY! Must be present!
@OData.applySupportedForAggregation: #FULL
define root view entity ZC_ENTITY
provider contract TRANSACTIONAL_QUERY
as projection on ZR_ENTITY
{
@Aggregation.default: #SUM // Specify aggregation method for measure
Amount;
Category; // Dimension field (no aggregation annotation needed)
}
誤った例:
// ❌ WRONG - Don't put on interface view
// WRONG PLACE!
@OData.applySupportedForAggregation: #FULL
define root view entity ZR_ENTITY
as select from TABLE
2. バックエンドのメタデータ拡張(必須)— Chart、PresentationVariant、SelectionField の注釈を追加
⚠️ 重要:@UI.chart と @UI.presentationVariant はエンティティレベル(ヘッダー)の注釈です。
これらはヘッダーブロック内、annotate view ZC_ENTITY with の前(@UI.headerInfo.* と同じ場所)に配置してください。{ ... } の項目ブロック内や、項目(ディメンション項目など)には配置しないでください。@UI.chart を項目に付けると、次のエラーが発生してアクティブ化に失敗します:Annotation 'UI.chart.qualifier' used at wrong position (wrong scope)。
// ↓↓↓ HEADER SCOPE: these go BEFORE `annotate view`, never on a field ↓↓↓
@UI.chart: [{
qualifier: 'visualFilter',
chartType: #BAR,
dimensions: ['Category'],
measures: ['Amount']
}]
@UI.presentationVariant: [{
qualifier: 'visualFilter',
visualizations: [{
type: #AS_CHART,
qualifier: 'visualFilter'
}]
}]
annotate view ZC_ENTITY with
{
@UI.selectionField: [{ position: 10 }]
Category;
@EndUserText.label: 'Amount'
Amount;
}
3. フロントエンド(annotation.xml)— ValueList を追加
ディメンション項目への ValueList 注釈:
<Annotations Target="<YourServiceNamespace>.<YourEntityType>/Category">
<Annotation Term="Common.ValueList" Qualifier="visualFilter">
<Record Type="Common.ValueListType">
<PropertyValue Property="CollectionPath" String="<YourEntitySet>"/>
<PropertyValue Property="PresentationVariantQualifier" String="visualFilter"/>
<PropertyValue Property="Parameters">
<Collection>
<Record Type="Common.ValueListParameterInOut">
<PropertyValue Property="LocalDataProperty" PropertyPath="Category"/>
<PropertyValue Property="ValueListProperty" String="Category"/>
</Record>
</Collection>
</PropertyValue>
</Record>
</Annotation>
</Annotations>
重要: プレースホルダーを置き換えてください。
<YourServiceNamespace>— 例:com.sap.gateway.srvd.ztravel.v0001<YourEntityType>— 例:TravelType<YourEntitySet>— 例:Travel
4. 有効なアノテーションを確認する(必須)
DDLS と DDLX の両方を有効化した後、変更が反映されていることを確認します。
⚠️ 重要:DDLS と DDLX は別々のオブジェクトです
**プロジェクションビュー(DDLS ファイル)とメタデータ拡張(DDLX ファイル)**は、同じエンティティ名を共有しているだけの、別々の ABAP 開発オブジェクトです。
重要なポイント:
- DDLS = データ定義(プロジェクションビュー)- エンティティ定義、関連付け、フィールド、データアノテーションを含みます
- DDLX = メタデータ拡張 - UI アノテーション(@UI.chart、@UI.presentationVariant、フィールドラベルなど)を含みます
- 両方を個別に有効化する必要があります - 片方を有効化しても、もう片方は有効化されません
- ビジュアルフィルターを機能させるには、両方が存在する必要があります
有効化:
- ABAP ADT MCP を使用して ABAP オブジェクトを有効化します
- DDLS ファイルとDDLX ファイルを別々に有効化します
確認手順:
-
有効化ステータスを確認する:
- 有効化ツールの出力に成功メッセージがあることを確認します
- 有効化中にエラーが報告されていないことを確認します
- DDLS と DDLX の両方で有効化が成功していることを確認します
-
OData $metadata を確認する:
- ブラウザーでサービス URL を開きます:
<service-url>/$metadata - 次を検索します:
<Annotation Term="UI.Chart" Qualifier="visualFilter"> - 次も確認します:
<Annotation Term="UI.PresentationVariant" Qualifier="visualFilter"> - これらのアノテーションが $metadata にない場合、DDLX が有効化されていないか、サービスバインディングを再公開する必要があります
- ブラウザーでサービス URL を開きます:
5. マニフェストの設定(必須)
以下の共通マニフェスト設定セクションを使用します。
マニフェスト設定(CAP と RAP 共通)
manifest.json の完全な構造:
"sap.ui5": {
"routing": {
"targets": {
"<YourListReport>": { // Replace with your actual List Report target name
"type": "Component",
"name": "sap.fe.templates.ListReport",
"options": {
"settings": {
"contextPath": "/<YourEntitySet>", // Replace with your entity set path
"controlConfiguration": {
"@com.sap.vocabularies.UI.v1.SelectionFields": {
"layout": "CompactVisual",
"initialLayout": "Visual",
"filterFields": {
"Category": {
"visualFilter": {
"valueList": "com.sap.vocabularies.Common.v1.ValueList#visualFilter"
}
}
}
}
}
}
}
}
}
}
}
パス: sap.ui5.routing.targets.<ListReport>.options.settings.controlConfiguration
ビジュアルフィルターの設定は controlConfiguration の下に配置します。settings の直下には配置しません。
重要なプレースホルダー:
<YourListReport>- リストレポートのターゲット名(例:TravelList)<YourEntitySet>- エンティティセットのパス(例:/Travel)Category- ディメンションフィールド名visualFilter- アノテーション内のクオリファイアと一致させる必要があります
重要:マニフェスト設定の構造
ビジュアルフィルターの設定は controlConfiguration の下に配置します。settings の直下には配置しません!
テスト
テスト手順の詳細については、sap-fiori-app-development スキルのアプリケーションプレビューのガイドラインセクションを参照してください。次の内容が含まれます。
- ウォッチスクリプトを使用した CAP プロジェクトのテスト
- ライブバックエンドとモックモードを使用したスタンドアロン Fiori プロジェクトのテスト
- バックエンド変更後のメタデータ更新手順
主な違い
CAP:
- 集計とメジャーを CDS で定義します
- DynamicMeasures を使用します
- 集計とチャートを同じ場所で定義します
RAP:
- 集計はバックエンドの CDS のみで定義します
- Measures を使用します(DynamicMeasures ではありません)
- メタデータは読み取り専用です
よくある間違い
- バックエンドの変更を有効化していない
- Chart、ValueList、PresentationVariant、マニフェスト間でクオリファイアが一致していない
- マニフェストのパスが間違っている(完全な語彙パスを使用します)
- SelectionField アノテーションがない
- メジャーフィールドが数値型ではない
- マニフェストにコンパクトなビジュアルレイアウト設定がない
CAP:
- 管理関連付けの外部キー列(例:
Status_code)に対して、annotate ... with { ... }内でインラインアノテーションを付けようとしている —Element "..._code" has not been foundというエラーが発生します。代わりに、個別のannotate Service.Entity:assoc with (...)ステートメントを使用します(上記の「ディメンションが管理関連付けの外部キーの場合」を参照してください)。
RAP:
- バックエンドの集計サポートがない
- Measures ではなく DynamicMeasures を使用している
- Common.ValueList をフロントエンドではなくバックエンドに追加している(ValueList は必ずフロントエンドの annotation.xml に追加します)
- メタデータ拡張ではなく、CDS プロジェクションビューに UI アノテーションを直接追加している
- ビジュアルフィルターに @Consumption.valueHelpDefinition を使用しようとしている(これは値ヘルプダイアログ用であり、ビジュアルフィルター用ではありません)
ベストプラクティス
- テストの前に、必ず ADT MCP でバックエンドの変更を有効化してください
- ビジュアルフィルターごとに、ディメンションを1つ、メジャーを1つ使用してください
- 読みやすさを高めるため、棒グラフを使用してください
- すべてのアノテーションで修飾子名を統一してください
- データ量を変えてテストしてください
- manifest には必ず layout: "CompactVisual" と initialLayout: "Visual" を含めてください
RAP 固有の注意事項:
- バックエンドファイルの変更には、利用可能な場合、必ず ADT MCP を使用してください
- Chart + PresentationVariant → バックエンドメタデータ拡張(.ddlx.acds)
- Common.ValueList → フロントエンドの annotation.xml(バックエンドには記述できません)
参考資料
- SAP Fiori Elements ビジュアルフィルターのドキュメント: https://ui5.sap.com/#/topic/5ea9bb1d544a42eabf71822a8a2cb753
- ABAP RAP の集計サポート: https://help.sap.com/docs/abap-cloud/abap-rap/projection-view