개요 및 학습 포인트
ABAP Analytical Query는 CDS View 위에 다차원 분석(Dimension/Measure) 모델을 얹어, Fiori Elements의 Analytical List Page(ALP)에서 차트와 테이블이 자동 생성되도록 만드는 패턴입니다. 매출/판매량/재고 같은 KPI를 BAS에서 노코드에 가깝게 시각화할 수 있고, 어노테이션만 바꿔도 Bar/Line/Donut 차트가 즉시 반영됩니다. 이번 글에서 다루는 범위는 다음과 같습니다.
- Analytical Query CDS View(@Analytics.query: true) 작성법
- Metadata Extension(MEXT)으로 UI 어노테이션을 본문에서 분리하기
- @UI.chart, @UI.presentationVariant, @UI.lineItem 핵심 속성
- BAS에서 ALP 템플릿으로 앱을 생성하고 OData V4로 연결
- Bar/Line/Donut 차트 타입 전환과 KPI 카드 노출 패턴
먼저 알고 있으면 좋은 것
ABAP CDS View, Annotation 문법, SAP S/4HANA 또는 BTP ABAP Environment에서의 ADT(Eclipse) 사용 경험이 있다고 가정합니다. OData V4 Service Binding과 Fiori Elements 템플릿(List Report, Object Page) 개념을 한 번이라도 다뤄봤다면 ALP 흐름을 빠르게 따라올 수 있습니다. CDS의 Composite Provider, Aggregation(@DefaultAggregation) 키워드는 핵심 어휘이므로 익숙해지는 것이 좋습니다.
환경과 준비물
실습 기준 환경은 다음과 같이 권장합니다.
- SAP S/4HANA 2022 이상 또는 SAP BTP ABAP Environment(Steampunk) 2308 이상
- ABAP Development Tools(ADT) for Eclipse 2024-03 빌드 이상
- SAP Business Application Studio(BAS), Dev Space 타입:
SAP Fiori - Node.js 20.x,
@sap/generator-fiori1.13 이상 - 샘플 도메인: 판매 주문(VBAK/VBAP) 또는 BTP ABAP의 Sales Order 데모 데이터
- 권한:
S_DEVELOP,S_RFC, Business CatalogSAP_CORE_BC_EXT
Fiori Elements ALP는 OData V4 기준으로 진화하고 있으므로, 새 프로젝트는 V4 어노테이션을 우선 사용하는 것이 일반적으로 안전합니다. 레거시 V2 ALP는 SmartChart 기반이지만 신규 기능 반영이 늦은 편입니다.
핵심 개념 정리
Analytical Query는 OLAP 큐브에 비유할 수 있습니다. CDS Cube View(@Analytics.dataCategory: #CUBE)는 "창고"에 해당하고, Analytical Query View(@Analytics.query: true)는 그 위에 올라가는 "전시 진열대"입니다. ALP는 진열대를 그대로 가져와 차트와 테이블을 화면에 배치하는 "매장 인테리어" 역할을 합니다.
구성 요소를 도식으로 풀어보면 다음과 같습니다.
[기본 DDIC 테이블] -> I_CDS(Interface CDS, Cube) -> C_CDS_Query(@Analytics.query)
|
v
Service Definition + Binding(V4)
|
v
Fiori Elements ALP (chart + table)
핵심 어노테이션 3종은 역할이 다릅니다.
- @UI.lineItem: 테이블 컬럼 순서, 라벨, 중요도(High/Medium/Low)를 지정합니다. ALP의 하단 테이블 영역에 표시됩니다.
- @UI.chart: 차트 타입(Column, Line, Donut, Bar 등), Dimension/Measure 축 매핑을 정의합니다.
- @UI.presentationVariant: 정렬(SortOrder), 초기 차트/테이블 노출 방식, GroupBy 같은 "기본 보기" 상태를 저장합니다.
여기에 @UI.selectionField(필터바), @UI.dataPoint(KPI 카드), @UI.headerInfo(헤더 타이틀)를 곁들이면 ALP의 상단 필터-중간 차트-하단 테이블 3단 구조가 완성됩니다. Metadata Extension(MEXT)은 이 UI 어노테이션들을 CDS 본문에서 떼어내 별도 객체로 관리하는 방법입니다. 모델과 표현을 분리해두면 화면 요구가 바뀌어도 데이터 모델을 다시 활성화할 필요가 없습니다.
실전 코드 3단계
1단계: 기본 Analytical Query CDS
Sales Order Item을 Dimension(국가, 제품), Measure(매출액, 수량)로 풀어내는 가장 단순한 형태입니다. Cube View가 이미 ZI_SalesCube로 존재한다고 가정합니다.
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Sales Analytical Query'
@Analytics.query: true
@OData.publish: false
define view entity ZC_SalesQuery
as select from ZI_SalesCube
{
@AnalyticsDetails.query.axis: #ROWS
key Country,
@AnalyticsDetails.query.axis: #ROWS
key Product,
@AnalyticsDetails.query.axis: #COLUMNS
@DefaultAggregation: #SUM
NetAmount,
@AnalyticsDetails.query.axis: #COLUMNS
@DefaultAggregation: #SUM
Quantity,
@Semantics.currencyCode: true
Currency
}
여기서 @AnalyticsDetails.query.axis는 OLAP 축을 지정합니다. #ROWS는 Drilldown 가능한 Dimension, #COLUMNS는 Measure(수치)에 해당합니다. 이 상태에서 RSRT 또는 Query Browser로 결과 확인이 가능합니다.
2단계: MEXT로 UI 어노테이션 분리하고 차트 구성
본문에 @UI를 직접 박지 않고, Metadata Extension 객체로 분리합니다. Eclipse ADT에서 New > Other > ABAP > Metadata Extension을 선택해 만듭니다.
@Metadata.layer: #CORE
@UI.headerInfo: {
typeName: 'Sales Item',
typeNamePlural: 'Sales Analytics',
title: { value: 'Product' }
}
annotate entity ZC_SalesQuery with
{
@UI.selectionField: [{ position: 10 }]
@UI.lineItem: [{ position: 10, importance: #HIGH, label: 'Country' }]
Country;
@UI.selectionField: [{ position: 20 }]
@UI.lineItem: [{ position: 20, importance: #HIGH, label: 'Product' }]
Product;
@UI.lineItem: [{ position: 30, label: 'Net Amount' }]
@UI.dataPoint: { title: 'Net Amount', criticalityCalculation: { improvementDirection: #MAXIMIZE } }
NetAmount;
@UI.lineItem: [{ position: 40, label: 'Quantity' }]
Quantity;
}
차트와 기본 보기는 다음과 같이 별도 블록으로 선언합니다. @UI.chart는 배열을 받기 때문에 여러 차트 정의를 함께 둘 수 있습니다.
annotate entity ZC_SalesQuery with
@UI.chart: [{
qualifier: 'SalesByCountry',
title: 'Net Amount by Country',
chartType: #COLUMN,
dimensions: [ 'Country' ],
measures: [ 'NetAmount' ],
dimensionAttributes: [{ dimension: 'Country', role: #CATEGORY }],
measureAttributes: [{ measure: 'NetAmount', role: #AXIS_1, asDataPoint: true }]
}]
@UI.presentationVariant: [{
qualifier: 'Default',
visualizations: [
{ type: #AS_CHART, qualifier: 'SalesByCountry' },
{ type: #AS_LINEITEM }
],
sortOrder: [{ by: 'NetAmount', direction: #DESC }]
}]
{}
이렇게 분리하면 ZC_SalesQuery의 데이터 모델은 그대로 두고, 차트 타입만 #COLUMN → #BAR → #LINE → #DONUT으로 갈아끼울 수 있습니다.
3단계: 프로덕션 — Service Binding과 BAS ALP 생성, 다중 차트
Service Definition을 만들고 V4 바인딩까지 묶습니다. 로깅과 권한 체크를 켜는 것이 권장됩니다.
@EndUserText.label: 'Sales Analytics Service'
define service ZUI_SALES_ANALYTICS {
expose ZC_SalesQuery as SalesQuery;
}
Service Binding은 OData V4 - UI 타입으로 활성화합니다. 활성화 직후 "Preview" 버튼으로 ALP 미리보기가 가능하며, 메타데이터 URL은 /sap/opu/odata4/sap/zui_sales_analytics/srvd/.../SalesQuery 형태입니다.
BAS에서 ALP 앱을 생성하는 흐름은 다음과 같습니다.
- BAS Dev Space에서
Ctrl+Shift+P→ Fiori: Open Application Generator - Floorplan으로 Analytical List Page 선택
- Data Source: Connect to a System → Destination 선택 후 Service
ZUI_SALES_ANALYTICS지정 - Main entity:
SalesQuery, qualifier는 비워두면 Default Presentation Variant를 사용 - 모듈명/타이틀/네임스페이스 입력 후 생성
생성된 앱의 webapp/manifest.json에는 ALP 라우팅과 sap.ui5 의존성이 자동 추가됩니다. 핵심 부분은 다음과 같이 보입니다.
{
"sap.ui5": {
"routing": {
"targets": {
"SalesAnalyticsALP": {
"type": "Component",
"id": "SalesAnalyticsALP",
"name": "sap.fe.templates.AnalyticalListPage",
"options": {
"settings": {
"entitySet": "SalesQuery",
"navigation": {},
"chartSettings": { "colorPalette": ["#5cbae6", "#b6d957"] }
}
}
}
}
}
}
}
다중 차트는 @UI.chart 배열에 qualifier를 다르게 줘서 추가합니다. 예를 들어 Donut과 Line을 함께 노출하려면 아래처럼 선언합니다.
annotate entity ZC_SalesQuery with
@UI.chart: [
{ qualifier: 'ByCountryBar', title: 'Country', chartType: #BAR,
dimensions: ['Country'], measures: ['NetAmount'] },
{ qualifier: 'ByProductDonut', title: 'Product Mix', chartType: #DONUT,
dimensions: ['Product'], measures: ['NetAmount'] },
{ qualifier: 'TrendLine', title: 'Trend', chartType: #LINE,
dimensions: ['Country'], measures: ['Quantity'] }
]
{}
운영 단계에서는 ALP가 OLAP 쿼리를 매번 호출하므로 다음을 함께 점검하는 것이 일반적입니다.
- CDS Cube에
@Analytics.dataExtraction.enabled: true로 추출 최적화 - HANA 측 Result Cache 또는 Smart Data Access 활용
- Service Binding의 Authorization을
#CHECK로 설정해 권한 누락 방지 - BAS 측
npm run build:opt로 컴포넌트 프리로드 적용
자주 마주치는 실수와 FAQ
처음 ALP를 붙일 때 반복적으로 나오는 이슈를 정리합니다.
- 차트가 비어 보임:
@UI.chart의dimensions/measures이름이 CDS의 Element 이름과 정확히 일치해야 합니다. 대소문자도 동일하게 맞추세요. - ALP 미리보기에 차트 영역이 안 보임:
@UI.presentationVariant.visualizations에{ type: #AS_CHART }가 빠져 있을 가능성이 높습니다. - Filter Bar가 비어 있음:
@UI.selectionField가 하나도 없으면 ALP는 차트만 렌더링합니다. 최소 1개 이상 지정하는 것이 권장됩니다.
Q1. V2와 V4 ALP를 섞어 쓸 수 있나요? 같은 앱 안에서는 권장되지 않습니다. V4 기반으로 새로 만드는 것이 일반적으로 안전합니다.
Q2. MEXT를 여러 개 만들어 환경별로 다른 화면을 보일 수 있나요? @Metadata.layer를 #CORE, #INDUSTRY, #PARTNER, #CUSTOMER로 분리하면 상위 레이어가 하위 어노테이션을 덮어쓰는 구조로 운영 가능합니다.
Q3. KPI 카드(SmartMicroChart)를 ALP 상단에 띄우려면? @UI.dataPoint에 targetValue, criticalityCalculation을 정의하고 @UI.headerInfo와 결합하면 V4 ALP의 KPI Tag에 노출됩니다.
Q4. Service Binding 활성화 시 "Entity is not aggregatable" 오류가 납니다. Cube View 또는 Query View 어느 한쪽에 @Analytics.query: true가 빠졌거나, Measure 필드에 @DefaultAggregation이 없을 때 발생합니다.
다음으로 확장해볼 주제
ALP를 한 번 띄우고 나면 자연스럽게 다음 주제로 이어집니다.
- InA Protocol: SAC(SAP Analytics Cloud)에서 동일한 Analytical Query를 라이브 연결로 소비
- Variables & Parameters:
@Analytics.query.variable로 사용자 입력 필터 추가 - Hierarchy 드릴다운:
@Hierarchy.parentChild로 조직/제품 계층 분석 - RAP Custom Action: ALP의 행 선택 후 비즈니스 액션 호출
- SAP Build Work Zone에 ALP 타일 등록과 Cross-App 네비게이션
참고 자료
- help.sap.com - Analytical Queries in ABAP CDS
- help.sap.com - Fiori Elements Analytical List Page Overview
- help.sap.com - SAP Business Application Studio Guide
- SAPUI5 SDK - Analytical List Page Template
- SAP Community - ABAP CDS Analytical Query Blog Series
- SAP Developers Tutorial - Build an Analytical List Page
핵심 한 줄
Analytical Query CDS와 MEXT로 데이터-표현을 분리하고, @UI.chart/presentationVariant/lineItem 세 어노테이션으로 BAS의 ALP 템플릿에 Bar/Line/Donut 화면을 자동 조립한다.
댓글 0
아직 댓글이 없습니다.