Der List Report ist eine der meistgenutzten Fiori Elements Templates. Er zeigt Daten tabellarisch an und bietet Filter, Sortierung und Aktionen. Über CDS-Annotations kannst du das Erscheinungsbild detailliert anpassen – ohne eine Zeile UI5-Code.
Grundstruktur eines List Reports
Ein List Report besteht aus mehreren Bereichen:
┌─────────────────────────────────────────────────────────┐│ Header Area ││ ┌───────────────────────────────────────────────────┐ ││ │ Header Facets (KPIs, Charts, Status) │ ││ └───────────────────────────────────────────────────┘ │├─────────────────────────────────────────────────────────┤│ Filter Bar ││ [Field 1 ▼] [Field 2 ▼] [Field 3 ▼] [Go] [Adapt] │├─────────────────────────────────────────────────────────┤│ Table Toolbar ││ [Create] [Delete] [Custom Action] │├─────────────────────────────────────────────────────────┤│ Table Content ││ | Col 1 | Col 2 | Col 3 | Col 4 | ││ |-------|-------|-------|-------| ││ | Row 1 | ... | ... | ... | ││ | Row 2 | ... | ... | ... | │└─────────────────────────────────────────────────────────┘@UI.facet Annotation im Detail
Die @UI.facet Annotation ist der Schlüssel zur Anpassung von List Reports und Object Pages. Sie definiert, welche Facets (Abschnitte) angezeigt werden und wie sie strukturiert sind.
Facet-Typen
| Typ | Beschreibung | Verwendung |
|---|---|---|
#HEADER_SECTION | Bereich im Header | KPIs, Status-Indikatoren |
#COLLECTION | Container für mehrere Facets | Gruppierung |
#IDENTIFICATION_REFERENCE | Standard-Identifikationsfelder | Object Page Header |
#LINEITEM_REFERENCE | Tabellenansicht | Untergeordnete Entitäten |
#DATAPOINT_REFERENCE | Einzelner Datenpunkt | KPI, Kennzahl |
#CHART_REFERENCE | Diagramm | Visualisierungen |
#FIELDGROUP_REFERENCE | Feldgruppe | Formularbereiche |
Grundstruktur einer Facet-Definition
@UI.facet: [{ id: 'HeaderFacetID', -- Eindeutige ID purpose: #HEADER, -- #HEADER oder #STANDARD type: #DATAPOINT_REFERENCE, -- Facet-Typ targetQualifier: 'TotalAmount', -- Referenz auf @UI.dataPoint label: 'Gesamtbetrag', -- Anzeigetext position: 10 -- Reihenfolge}]Header und Collection Facets: Der Unterschied
Header Facets erscheinen im oberen Bereich (Header) eines List Reports oder einer Object Page. Sie zeigen verdichtete Informationen wie KPIs oder Status.
Collection Facets sind Container, die mehrere Facets gruppieren. Sie erscheinen typischerweise im Content-Bereich der Object Page.
@UI.facet: [ -- Header Facets (oben im Header) { id: 'HeaderKPI', purpose: #HEADER, -- Header-Bereich type: #DATAPOINT_REFERENCE, targetQualifier: 'TotalOrders', position: 10 },
-- Collection Facet (Content-Bereich) { id: 'GeneralInfo', purpose: #STANDARD, -- Content-Bereich type: #COLLECTION, -- Container label: 'Allgemeine Informationen', position: 20 }, { id: 'Details', purpose: #STANDARD, type: #FIELDGROUP_REFERENCE, targetQualifier: 'Details', parentId: 'GeneralInfo', -- Untergeordnet position: 10 }]Custom Header Facets (KPIs, Status-Indikatoren)
Header Facets eignen sich perfekt für KPIs und Statusanzeigen.
KPI mit DataPoint
@Metadata.allowExtensions: truedefine view entity ZC_SalesOrder as projection on ZI_SalesOrder{ key SalesOrderId,
@UI.dataPoint: { qualifier: 'TotalAmount', title: 'Bestellwert', valueFormat: { numberOfFractionalDigits: 2 } } @Semantics.amount.currencyCode: 'CurrencyCode' TotalAmount,
CurrencyCode,
@UI.dataPoint: { qualifier: 'ItemCount', title: 'Positionen', valueFormat: { numberOfFractionalDigits: 0 } } NumberOfItems,
@UI.dataPoint: { qualifier: 'OrderStatus', title: 'Status', criticality: 'StatusCriticality' } Status,
StatusCriticality}Die zugehörige Facet-Definition:
@UI.facet: [ { id: 'TotalAmountHeader', purpose: #HEADER, type: #DATAPOINT_REFERENCE, targetQualifier: 'TotalAmount', position: 10 }, { id: 'ItemCountHeader', purpose: #HEADER, type: #DATAPOINT_REFERENCE, targetQualifier: 'ItemCount', position: 20 }, { id: 'StatusHeader', purpose: #HEADER, type: #DATAPOINT_REFERENCE, targetQualifier: 'OrderStatus', position: 30 }]Status mit Criticality
Die Criticality bestimmt die Farbe des Status-Indikators:
| Wert | Bedeutung | Farbe |
|---|---|---|
| 0 | Neutral | Grau |
| 1 | Negativ | Rot |
| 2 | Kritisch | Orange |
| 3 | Positiv | Grün |
define view entity ZC_Order as projection on ZI_Order{ key OrderId,
Status,
-- Berechnung der Criticality case Status when 'OPEN' then 0 -- Grau when 'PENDING' then 2 -- Orange when 'COMPLETED' then 3 -- Grün when 'CANCELLED' then 1 -- Rot else 0 end as StatusCriticality}Custom Sections im List Report
Sections strukturieren den Content-Bereich. Mit #COLLECTION erstellst du gruppierte Abschnitte.
Mehrere Sections mit Feldgruppen
@UI.facet: [ -- Section 1: Bestellkopf { id: 'OrderHeader', purpose: #STANDARD, type: #COLLECTION, label: 'Bestellkopf', position: 10 }, { id: 'BasicData', purpose: #STANDARD, type: #FIELDGROUP_REFERENCE, targetQualifier: 'BasicData', parentId: 'OrderHeader', label: 'Stammdaten', position: 10 }, { id: 'Dates', purpose: #STANDARD, type: #FIELDGROUP_REFERENCE, targetQualifier: 'Dates', parentId: 'OrderHeader', label: 'Termine', position: 20 },
-- Section 2: Positionen { id: 'OrderItems', purpose: #STANDARD, type: #LINEITEM_REFERENCE, targetElement: '_Items', label: 'Positionen', position: 20 },
-- Section 3: Notizen { id: 'Notes', purpose: #STANDARD, type: #COLLECTION, label: 'Notizen & Anhänge', position: 30 }]Feldgruppen definieren
define view entity ZC_Order{ key OrderId,
@UI.fieldGroup: [{ qualifier: 'BasicData', position: 10 }] CustomerId,
@UI.fieldGroup: [{ qualifier: 'BasicData', position: 20 }] CustomerName,
@UI.fieldGroup: [{ qualifier: 'BasicData', position: 30 }] ShipToAddress,
@UI.fieldGroup: [{ qualifier: 'Dates', position: 10 }] OrderDate,
@UI.fieldGroup: [{ qualifier: 'Dates', position: 20 }] RequestedDeliveryDate,
@UI.fieldGroup: [{ qualifier: 'Dates', position: 30 }] ActualDeliveryDate}Conditional Facets (Datenabhängig)
Conditional Facets werden nur angezeigt, wenn bestimmte Bedingungen erfüllt sind. Dies geschieht über die hidden Eigenschaft.
Facet basierend auf Status ausblenden
@UI.facet: [ { id: 'ShippingInfo', purpose: #STANDARD, type: #FIELDGROUP_REFERENCE, targetQualifier: 'Shipping', label: 'Versandinformationen', position: 20, hidden: 'HideShipping' -- Referenz auf berechnetes Feld }]
define view entity ZC_Order{ key OrderId, Status,
-- Versandinfo nur bei bestimmten Status anzeigen case when Status in ('SHIPPED', 'DELIVERED') then abap_false else abap_true end as HideShipping,
@UI.fieldGroup: [{ qualifier: 'Shipping', position: 10 }] TrackingNumber,
@UI.fieldGroup: [{ qualifier: 'Shipping', position: 20 }] Carrier,
@UI.fieldGroup: [{ qualifier: 'Shipping', position: 30 }] ShippedDate}Mehrere Bedingungen kombinieren
define view entity ZC_Contract{ key ContractId,
ContractType, Status,
-- Facet nur für aktive Serviceverträge case when ContractType = 'SERVICE' and Status = 'ACTIVE' then abap_false else abap_true end as HideServiceDetails,
-- Facet nur für Verträge mit Verlängerungsoption case when HasRenewalOption = abap_true then abap_false else abap_true end as HideRenewalInfo}Chart Integration im Header
Charts im Header visualisieren Daten auf einen Blick.
Micro Chart im Header
@UI.facet: [{ id: 'SalesChart', purpose: #HEADER, type: #CHART_REFERENCE, targetQualifier: 'SalesTrend', position: 40}]
define view entity ZC_SalesOverview{ key SalesOrgId,
@UI.chart: [{ qualifier: 'SalesTrend', chartType: #COLUMN, title: 'Monatsumsatz', measures: ['Revenue'], dimensions: ['Month'] }] @Aggregation.default: #SUM Revenue,
Month}Verschiedene Chart-Typen
-- Bullet Chart für Zielerreichung@UI.chart: [{ qualifier: 'TargetAchievement', chartType: #BULLET, title: 'Zielerreichung', measures: ['ActualValue'], measureAttributes: [{ measure: 'ActualValue', role: #AXIS_1, asDataPoint: true }]}]
@UI.dataPoint: { qualifier: 'ActualValue', targetValue: 'TargetValue', forecastValue: 'ForecastValue', minimumValue: 0, criticality: 'AchievementCriticality'}ActualValue,TargetValue,ForecastValue,
-- Radial Chart für Prozentanzeige@UI.chart: [{ qualifier: 'CompletionRate', chartType: #DONUT, title: 'Fertigstellungsgrad', measures: ['CompletedPercent']}]CompletedPercentChart mit Criticality-Farben
define view entity ZC_ProjectStatus{ key ProjectId,
@UI.chart: [{ qualifier: 'BudgetChart', chartType: #BULLET, title: 'Budget', measures: ['SpentBudget'], measureAttributes: [{ measure: 'SpentBudget', role: #AXIS_1, asDataPoint: true }] }] @UI.dataPoint: { qualifier: 'SpentBudget', targetValue: 'TotalBudget', criticality: 'BudgetCriticality' } SpentBudget,
TotalBudget,
-- Criticality berechnen case when SpentBudget <= TotalBudget * 0.8 then 3 -- Grün when SpentBudget <= TotalBudget then 2 -- Orange else 1 -- Rot end as BudgetCriticality}Vollständiges Beispiel: Verkaufsübersicht
@Metadata.allowExtensions: true@UI.headerInfo: { typeName: 'Verkaufsbeleg', typeNamePlural: 'Verkaufsbelege', title: { value: 'SalesOrderId' }, description: { value: 'CustomerName' }}define view entity ZC_SalesOrderReport as projection on ZI_SalesOrder{ -- Facet-Definitionen @UI.facet: [ -- Header Facets { id: 'TotalValueHeader', purpose: #HEADER, type: #DATAPOINT_REFERENCE, targetQualifier: 'TotalValue', position: 10 }, { id: 'ItemCountHeader', purpose: #HEADER, type: #DATAPOINT_REFERENCE, targetQualifier: 'ItemCount', position: 20 }, { id: 'StatusHeader', purpose: #HEADER, type: #DATAPOINT_REFERENCE, targetQualifier: 'Status', position: 30 }, { id: 'TrendChart', purpose: #HEADER, type: #CHART_REFERENCE, targetQualifier: 'MonthlySales', position: 40 },
-- Content Sections { id: 'GeneralSection', purpose: #STANDARD, type: #COLLECTION, label: 'Allgemein', position: 10 }, { id: 'CustomerData', purpose: #STANDARD, type: #FIELDGROUP_REFERENCE, targetQualifier: 'Customer', parentId: 'GeneralSection', label: 'Kundendaten', position: 10 }, { id: 'OrderData', purpose: #STANDARD, type: #FIELDGROUP_REFERENCE, targetQualifier: 'Order', parentId: 'GeneralSection', label: 'Bestelldaten', position: 20 }, { id: 'ItemsSection', purpose: #STANDARD, type: #LINEITEM_REFERENCE, targetElement: '_Items', label: 'Positionen', position: 20 }, { id: 'ShippingSection', purpose: #STANDARD, type: #FIELDGROUP_REFERENCE, targetQualifier: 'Shipping', label: 'Versand', position: 30, hidden: 'HideShipping' } ]
@UI.lineItem: [{ position: 10 }] @UI.selectionField: [{ position: 10 }] key SalesOrderId,
@UI.lineItem: [{ position: 20 }] @UI.selectionField: [{ position: 20 }] @UI.fieldGroup: [{ qualifier: 'Customer', position: 10 }] CustomerId,
@UI.lineItem: [{ position: 30 }] @UI.fieldGroup: [{ qualifier: 'Customer', position: 20 }] CustomerName,
@UI.fieldGroup: [{ qualifier: 'Customer', position: 30 }] CustomerCity,
@UI.lineItem: [{ position: 40 }] @UI.selectionField: [{ position: 30 }] @UI.fieldGroup: [{ qualifier: 'Order', position: 10 }] OrderDate,
@UI.fieldGroup: [{ qualifier: 'Order', position: 20 }] RequestedDeliveryDate,
@UI.lineItem: [{ position: 50, criticality: 'StatusCriticality' }] @UI.selectionField: [{ position: 40 }] @UI.dataPoint: { qualifier: 'Status', title: 'Status', criticality: 'StatusCriticality' } Status,
StatusCriticality,
@UI.lineItem: [{ position: 60 }] @UI.dataPoint: { qualifier: 'TotalValue', title: 'Bestellwert' } @Semantics.amount.currencyCode: 'CurrencyCode' TotalValue,
CurrencyCode,
@UI.dataPoint: { qualifier: 'ItemCount', title: 'Positionen' } NumberOfItems,
@UI.fieldGroup: [{ qualifier: 'Shipping', position: 10 }] TrackingNumber,
@UI.fieldGroup: [{ qualifier: 'Shipping', position: 20 }] ShippedDate,
-- Conditional: Versand nur bei versendeten Aufträgen case when Status in ('SHIPPED', 'DELIVERED') then abap_false else abap_true end as HideShipping,
_Items}Best Practices
1. Facet-IDs konsistent benennen
-- Gute Namenskonvention{ id: 'HeaderStatus', -- Header + Inhalt id: 'SectionCustomer', -- Section + Thema id: 'FieldGroupAddress', -- Typ + Inhalt}2. Positionen mit Lücken vergeben
-- Mit Lücken für spätere Erweiterungenposition: 10position: 20position: 30
-- Nicht: 1, 2, 3 (keine Lücken für Erweiterungen)3. Criticality immer als separates Feld
-- Gut: Separates Feld für CriticalityStatus,StatusCriticality,
-- Vermeiden: Inline-Berechnung in Annotation4. Performance bei Charts beachten
-- Aggregationen für Charts optimieren@Aggregation.default: #SUMRevenue,
-- Datenmenge begrenzen für Header ChartsTypische Fehler und Lösungen
| Problem | Ursache | Lösung |
|---|---|---|
| Facet wird nicht angezeigt | purpose falsch | #HEADER vs. #STANDARD prüfen |
| Chart leer | Keine Aggregation | @Aggregation.default hinzufügen |
| Conditional funktioniert nicht | Feld nicht exponiert | Hidden-Feld in Projection aufnehmen |
| Feldgruppe nicht sichtbar | parentId fehlt | parentId auf Collection setzen |
Weiterführende Themen
- SAP Fiori Elements – Grundlagen der UI-Generierung
- CDS Annotations – Alle verfügbaren Annotationen
- RAP Grundlagen – RESTful ABAP Programming Basics
- Fiori Object Page – Object Page konfigurieren