이 글에서 다루는 내용과 도달 지점
Fiori Elements 앱에서 사용자가 입력 필드 옆의 돋보기 아이콘(F4)을 눌렀을 때 뜨는 값 도움말(Value Help)은 UX 품질을 좌우하는 핵심 요소입니다. 이 글은 ABAP CDS View에 @Consumption.ValueHelpDefinition, @ObjectModel.foreignKey.association, @Search.searchable 같은 어노테이션을 조합해 F4 도움말을 선언적으로 구성하는 흐름을 실무 관점에서 정리합니다. 구매 오더(PurchaseOrder), 공급업체(Vendor), 자재(Material) 시나리오를 축으로 잡고, 단순 코드 밸류 헬프에서 시작해 필터 매핑, Collective Search Help, Fiori Elements List Report의 SelectionField 연동까지 확장합니다.
- CDS 기반 Value Help 아키텍처와 SE11 Search Help의 차이 이해
- 단일 필드 F4 도움말 CDS View 작성 및 Consumption View에 연결
- 다중 검색 도움말(Collective) 및 아웃/인 파라미터 매핑 설정
- Fiori Elements 어노테이션(UI.SelectionField, UI.LineItem)과의 통합
- 흔한 오류(빈 결과, 필터 미적용, 캐시 문제) 진단 방법 습득
사전에 갖추면 좋은 배경
이 글은 ABAP CDS View의 define view 문법과 association, @Annotation 사용법을 다뤄본 개발자를 대상으로 합니다. Fiori Elements(List Report / Object Page) 앱을 한 번 이상 배포해봤거나, SEGW/RAP로 OData 서비스를 노출해본 경험이 있다면 이해가 빠릅니다. SAP GUI 기반 SE11 Search Help의 구조(Selection Method, 파라미터 IMPORT/EXPORT)도 개념적으로 알면 CDS Value Help와의 매핑 지점을 잡기 수월합니다.
실습에 필요한 환경과 버전
이 글의 예제는 다음 환경을 기준으로 작성되었습니다. 릴리스 차이에 따라 어노테이션 지원 범위가 조금씩 다르므로, 사용 중인 넷위버 스택을 먼저 확인하는 것을 권장합니다.
- SAP NetWeaver AS ABAP 7.55 이상 또는 S/4HANA 2021 이상
- ABAP Development Tools(ADT) for Eclipse 3.30 이상
- Fiori Elements 앱은 SAP UI5 1.96 이상, SAP Gateway OData V2/V4 서비스
- 테스트용 DB 뷰:
ZI_VENDOR,ZI_MATERIAL,ZI_PURCHASEORDER(본인 네임스페이스로 변경) - 권한:
S_DEVELOP(개발),/IWFND/*게이트웨이 서비스 등록 권한
온프렘 시스템은 하위 릴리스에서 @Consumption.valueHelpDefinition이 미지원일 수 있으니, 이 경우에는 @ObjectModel.foreignKey.association 방식으로 대체하는 것이 일반적으로 안전합니다.
Value Help 동작 원리와 핵심 어노테이션
CDS Value Help는 "값이 붙는 필드"와 "값을 공급하는 뷰"를 어노테이션으로 연결하는 구조입니다. SE11 Search Help가 GUI 트랜잭션 화면에 특화된 반면, CDS Value Help는 OData 메타데이터로 노출되어 Fiori 프론트엔드가 이를 해석해 F4 팝업을 그립니다. 이때 핵심 부품은 세 가지입니다.
비유하자면, Consumption View는 "주문서"이고 Value Help View는 "카탈로그"입니다. Association은 두 문서 사이의 배송 경로이며,
@Consumption.valueHelpDefinition은 배송 규칙(어떤 컬럼을 사용자에게 보여주고 어떤 값을 되돌려줄지)을 정의합니다.
- @Search.searchable / @Search.defaultSearchElement: 팝업 상단 검색창에서 어떤 컬럼을 대상으로 fuzzy/like 검색할지 지정합니다. HANA fuzzy search가 활성화된 시스템에서는
@Search.fuzzinessThreshold로 유사도 임계값을 조정할 수 있습니다. - @ObjectModel.text.element: 코드-텍스트 쌍(예: VendorID + VendorName)을 프론트엔드가 자동으로 짝지어 보여주도록 힌트를 줍니다.
- @Consumption.valueHelpDefinition: Consumption 계층 CDS View의 필드에 붙여 "이 필드의 F4는 어떤 뷰의 어떤 파라미터로 매핑되는가"를 선언합니다.
localElement와element로 필드 매핑을,usage로 result/filter/selector 여부를 지정합니다.
Value Help 계층은 보통 3단으로 나눕니다. Basic Interface View(ZI_*, DDIC 테이블 직결), Composite Interface View(association 조합), Consumption View(ZC_*, Fiori에 직접 노출). Value Help 전용 View는 관례적으로 ZI_*_VH 접미어를 붙이며, 여기에는 UI에 필요한 최소 컬럼과 검색 어노테이션만 남깁니다. 이렇게 계층을 분리해 두면 하나의 Value Help를 여러 Consumption View가 재사용할 수 있고, 성능 튜닝(인덱스, 캐시)도 한 곳에서 관리됩니다.
1단계: 단일 필드 F4 도움말 만들기
가장 단순한 형태부터 시작합니다. 구매 오더 헤더에서 공급업체 ID(VendorID) 입력 시 이름으로 검색 가능한 F4를 붙이는 시나리오입니다. 먼저 Value Help용 Interface View를 정의합니다.
@AbapCatalog.sqlViewName: 'ZIVENDORVH'
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Vendor Value Help'
@Search.searchable: true
@ObjectModel.resultSet.sizeCategory: #S
define view ZI_Vendor_VH as select from lfa1 {
@Search.defaultSearchElement: true
@Search.fuzzinessThreshold: 0.8
key lifnr as VendorID,
@Search.defaultSearchElement: true
@Semantics.text: true
name1 as VendorName,
land1 as Country,
ort01 as City
}
다음으로 Consumption View의 VendorID 필드에 이 뷰를 F4로 연결합니다.
@AbapCatalog.sqlViewName: 'ZCPURCHORD'
@OData.publish: true
@UI.headerInfo: { typeName: 'Purchase Order', typeNamePlural: 'Purchase Orders' }
define view ZC_PurchaseOrder as select from ekko {
@UI.lineItem: [{ position: 10, label: 'PO Number' }]
key ebeln as PurchaseOrderID,
@UI.lineItem: [{ position: 20, label: 'Vendor' }]
@UI.selectionField: [{ position: 10 }]
@Consumption.valueHelpDefinition: [{
entity: { name: 'ZI_Vendor_VH', element: 'VendorID' }
}]
lifnr as VendorID,
@UI.lineItem: [{ position: 30 }]
bedat as OrderDate
}
이 상태로 OData 서비스를 활성화하고 Fiori Elements List Report에 붙이면, VendorID 필터 필드 오른쪽에 F4 아이콘이 자동 생성됩니다. 팝업에는 VendorName 컬럼이 함께 표시되며, 상단 검색창에서 이름 일부를 입력해 fuzzy 검색이 가능합니다.
2단계: 필터 전파와 다중 파라미터 매핑
실무에서는 "국가별로 공급업체를 필터링해 보여달라"거나 "이미 입력한 자재 카테고리 안에서만 자재 F4가 뜨게 해달라"는 요구가 흔합니다. 이때 additionalBinding으로 인/아웃 매핑을 구성하고, 서비스 계층에서 로깅을 통해 필터 전파 여부를 확인합니다.
@AbapCatalog.sqlViewName: 'ZIMATVH'
@Search.searchable: true
@AccessControl.authorizationCheck: #CHECK
define view ZI_Material_VH as select from mara
association [0..1] to t023t as _MatGroupText
on $projection.MaterialGroup = _MatGroupText.matkl
and _MatGroupText.spras = $session.system_language
{
@Search.defaultSearchElement: true
key matnr as MaterialID,
@Search.defaultSearchElement: true
@Semantics.text: true
maktx_placeholder as MaterialDescription,
matkl as MaterialGroup,
_MatGroupText.wgbez as MaterialGroupText
}
Consumption View에서는 이미 선택된 MaterialGroup 값을 F4 팝업의 필터로 자동 전달합니다.
@UI.selectionField: [{ position: 20 }]
@Consumption.valueHelpDefinition: [{
entity: { name: 'ZI_Material_VH', element: 'MaterialID' },
additionalBinding: [
{ localElement: 'MaterialGroup',
element: 'MaterialGroup',
usage: #FILTER_AND_RESULT }
]
}]
matnr as MaterialID,
@UI.selectionField: [{ position: 21 }]
matkl as MaterialGroup,
usage 옵션은 실무에서 가장 헷갈리는 지점입니다. #FILTER_AND_RESULT는 팝업 결과와 최종 반환값 모두에 영향을 주고, #FILTER는 검색 조건에만, #RESULT는 결과 컬럼에만 적용됩니다. 사용자 로그로 어떤 값이 넘어가는지 추적하려면 CDS View에 임시로 _LogHelper 어소시에이션을 붙이거나, ADT의 SQL 트레이스(ST05)로 실제 쿼리에 WHERE MATKL = ? 조건이 붙는지 확인하는 것이 일반적으로 확실합니다.
3단계: Collective Search Help와 프로덕션 고려사항
실서비스에서는 하나의 필드에 여러 검색 관점을 제공해야 할 때가 많습니다. 예를 들어 공급업체는 "ID로 찾기", "이름으로 찾기", "국가+도시로 찾기" 탭을 제공하고 싶을 수 있습니다. 이때 개별 Value Help View를 만들고 하나의 Collective View로 묶습니다.
@AbapCatalog.sqlViewName: 'ZIVENDORCOL'
@Search.searchable: true
@ObjectModel.resultSet.sizeCategory: #M
@EndUserText.label: 'Vendor Collective Search'
define view ZI_Vendor_Collective as select from ZI_Vendor_VH
union all select from ZI_Vendor_ByCountry_VH
{
key VendorID,
VendorName,
Country,
City
}
그리고 Consumption View 필드에서 Collective View를 참조하도록 바꾸면, Fiori F4 팝업 상단에 검색 관점 탭이 자동으로 나타납니다. 여기에 더해 프로덕션 배포 전 체크할 항목은 다음과 같습니다.
- 권한 체크: Value Help View의
@AccessControl.authorizationCheck를#CHECK로 유지하고, DCL(Data Control Language)로 조직 단위(구매조직, 회사코드) 필터를 강제하는 것이 안전합니다. - 성능:
@ObjectModel.resultSet.sizeCategory로 예상 결과 규모(S/M/L/XL/XXL)를 힌트로 주면 HANA 옵티마이저가 조인 순서를 조정합니다. 100만 건 이상 예상되면@Search.fuzzinessThreshold는 0.85 이상으로 높여 팝업 응답 시간을 줄이는 편이 좋습니다. - 테스트: ADT에서 F8로 뷰를 실행해 원시 데이터 확인 →
/IWFND/MAINT_SERVICE에서 메타데이터 확인 → Gateway Client(/IWFND/GW_CLIENT)로$metadata에ValueList어노테이션이 노출되는지 검증 → Fiori Elements Preview로 실제 팝업을 확인하는 4단계 순서를 권장합니다. - 캐싱: 자주 조회되는 마스터성 Value Help는
@ClientDependent: false가 가능한지 확인하고, HANASELECT캐시를 활용하도록 별도 인덱스를 검토합니다.
자주 마주치는 문제와 진단 순서
F4 관련 이슈는 대부분 "어노테이션은 저장됐지만 프론트엔드가 인식 못 함" 유형입니다. 아래 FAQ 순서대로 확인하면 원인을 좁힐 수 있습니다.
- Q1. F4 아이콘 자체가 안 뜹니다. 우선
$metadata에서 해당 필드의sap:value-list또는com.sap.vocabularies.Common.v1.ValueList가 존재하는지 확인합니다. 없다면 Consumption View의 어노테이션이 활성화되지 않은 것이며, ADT에서 뷰를 다시 활성화하고 게이트웨이 캐시(/IWFND/CACHE_CLEANUP)를 비워야 합니다. - Q2. 팝업은 뜨지만 데이터가 비어 있습니다. Value Help View에 대한 사용자 권한을 먼저 의심하세요. DCL 규칙이 너무 강하거나,
authorizationCheck: #CHECK인데 해당 조직 데이터 접근 권한이 없는 경우가 흔합니다. SU53으로 최근 권한 실패를 확인하고, 필요하면 임시로#NOT_REQUIRED로 바꿔 격리 테스트합니다. - Q3. 필터가 전파되지 않습니다.
additionalBinding의localElement는 Consumption View의 원본 필드명(alias 이전),element는 Value Help View의 필드명이어야 합니다. 두 값의 방향을 반대로 쓰는 실수가 매우 잦으므로, ST05 SQL 트레이스로 실제 WHERE 절에 값이 들어가는지 최종 확인하는 것이 확실합니다. - Q4. 텍스트가 코드와 함께 안 보입니다. Value Help View 텍스트 컬럼에
@Semantics.text: true가 있는지, 그리고 코드 컬럼에@ObjectModel.text.element가 지정됐는지 확인하세요. Fiori Elements는 두 어노테이션 조합을 근거로 자동 텍스트 표시를 결정합니다.
실무에서 확장해볼 방향
기본 F4가 안정화되면, RAP(RESTful ABAP Programming Model)의 Behavior Definition에서 determine on modify와 Value Help를 결합해 입력 즉시 검증 로직을 붙이는 방향으로 확장할 수 있습니다. 또한 Fiori Elements V4 어노테이션에서는 Common.ValueListWithFixedValues로 드롭다운 방식 값 도움말을 구성할 수 있어, 소규모 코드 리스트(예: 결제 조건, 인코텀즈)에 적합합니다. UI.SelectionField와 UI.LineItem 커스터마이징, Adaptation Project를 통한 팝업 컬럼 재배치도 함께 살펴보면 UX 완성도를 한층 높일 수 있습니다.
댓글 0
아직 댓글이 없습니다.