1. EKET 테이블이란 무엇인가 — 구매 납기일정의 원본
SAP ERP/S/4HANA의 구매 모듈에서 가장 빈번하게 조회되는 테이블 중 하나가 바로 EKET입니다. EKET는 "Einkaufsbelegterminierung"의 약어로, 풀어쓰면 Purchasing Document: Delivery Schedule입니다. 즉 구매 오더(Purchase Order, EKKO/EKPO) 한 라인 아이템에 대해 언제, 얼마만큼 납품받기로 했는지를 나타내는 "납기 스케줄 라인"을 저장합니다.
구매 오더 한 건은 보통 다음 구조로 펼쳐집니다.
- EKKO: 헤더 (벤더, 회사코드, 결제조건)
- EKPO: 아이템 라인 (자재, 수량, 단가, 플랜트)
- EKET: 납기 스케줄 라인 (납기일자, 분할 수량, 인도된 수량)
예를 들어 자재 100개를 한 PO 아이템으로 발주했더라도, 실제로는 "1월 30개, 2월 50개, 3월 20개"로 나누어 받기로 했다면 EKET에는 3개의 레코드가 만들어집니다. 이 분할 단위가 바로 Schedule Line이며, MRP·재고 가용성·납기 지연 분석의 최소 입자(granule)입니다.
주요 키 필드는 EBELN(PO 번호), EBELP(PO 아이템 번호), ETENR(스케줄 라인 번호)이며, 분석 관점에서 중요한 비키 필드는 EINDT(납품 예정일), SLFDT(통계적 납품일), MENGE(예정 수량), WEMNG(입고 완료 수량) 등입니다.
2. I_ScheduleLine CDS 뷰의 역할과 설계 의도
S/4HANA 시대로 넘어오면서 SAP는 EKET 같은 베이스 테이블을 직접 SELECT하는 방식을 권장하지 않고 있습니다. 대신 Virtual Data Model(VDM)이라 부르는 CDS 계층을 통해 데이터를 노출합니다. I_ScheduleLine(또는 정확히는 I_PurchaseOrderScheduleLine 계열)이 바로 EKET를 감싸는 인터페이스(Interface) 레이어의 CDS 뷰입니다.
SAP가 굳이 CDS 한 겹을 더 둔 이유는 크게 세 가지입니다.
- 의미 있는 필드명:
EBELN이 아니라PurchaseOrder,EINDT가 아니라ScheduleLineDeliveryDate처럼 영어 비즈니스 용어로 통일 - Association 기반 모델링: PO 헤더·아이템·자재·플랜트·벤더와 그래프 형태로 연결되어 JOIN 없이 점(.) 표기로 탐색 가능
- 권한·확장성·릴리스 안정성: Behavior, Authority, Annotation을 한 곳에 묶고 업그레이드 시 호환성 보장
3. EKET 직접 조회 vs I_ScheduleLine — 무엇이 다른가
| 구분 | EKET 직접 SELECT | I_ScheduleLine |
|---|---|---|
| 필드명 | 독일어 약어 (EBELN, EINDT) | 의미 기반 영문명 (PurchaseOrder, ScheduleLineDeliveryDate) |
| 조인 | EKKO/EKPO/MARA 수동 JOIN | Association으로 점(.) 탐색 |
| 권한 체크 | AUTHORITY-CHECK 별도 구현 | Access Control(DCL)로 선언적 적용 |
| 릴리스 안정성 | 테이블 구조 변경 시 영향 | 인터페이스 계층이 흡수 |
| S/4HANA Cloud | 접근 불가 | Released API 사용 가능 |
특히 S/4HANA Cloud(Public Edition)에서는 EKET를 ABAP 코드에서 직접 SELECT할 수 없습니다. Released 객체로 분류된 CDS 뷰만 허용되므로, 향후 Cloud 이행을 염두에 둔다면 처음부터 CDS 기반으로 작성해 두는 편이 일반적으로 권장됩니다.
4. I_ScheduleLine 주요 필드 해설
I_ScheduleLine 계열 뷰에서 자주 쓰이는 필드를 묶어 보면 다음과 같습니다. (시스템 버전에 따라 네이밍이 I_PurOrdScheduleLine, I_PurchaseOrderScheduleLineTP 등으로 분기되니 SE11이나 ADT에서 확인하시기 바랍니다.)
PurchaseOrder/PurchaseOrderItem/ScheduleLine— 키 3종 세트ScheduleLineDeliveryDate— EINDT, 발주처에 약속된 납기일StatisticalDeliveryDate— SLFDT, MRP·통계용 납기일ScheduleLineOrderQuantity— MENGE, 해당 라인의 예정 수량OpenQuantityInBaseUnit— 미입고 잔량PurchasingDocumentDeletionCode— 삭제 플래그_PurchaseOrder,_PurchaseOrderItem,_Material,_Plant— Association
5. 실전 예제 — 납기 지연 분석 3단계
시나리오: "오늘 기준으로 납기일이 지났는데도 아직 입고가 끝나지 않은 PO 스케줄 라인을 찾아 지연일수와 함께 표시하기"
1단계 — 기본 SELECT
REPORT zr_late_delivery_basic.
SELECT PurchaseOrder,
PurchaseOrderItem,
ScheduleLine,
ScheduleLineDeliveryDate,
ScheduleLineOrderQuantity,
OpenQuantityInBaseUnit
FROM I_PurchaseOrderScheduleLineTP
WHERE ScheduleLineDeliveryDate < @sy-datum
AND OpenQuantityInBaseUnit > 0
INTO TABLE @DATA(lt_overdue).
LOOP AT lt_overdue INTO DATA(ls_line).
WRITE: / ls_line-purchaseorder,
ls_line-scheduleline,
ls_line-schedulelinedeliverydate,
ls_line-openquantityinbaseunit.
ENDLOOP.
2단계 — Association 활용 + 지연일 계산
REPORT zr_late_delivery_assoc.
TYPES: BEGIN OF ty_result,
po_number TYPE ekko-ebeln,
item TYPE ekpo-ebelp,
material TYPE matnr,
vendor TYPE lifnr,
plant TYPE werks_d,
due_date TYPE eindt,
open_qty TYPE menge_d,
delay_days TYPE i,
END OF ty_result.
DATA: lt_result TYPE TABLE OF ty_result.
SELECT sl~PurchaseOrder AS po_number,
sl~PurchaseOrderItem AS item,
item~Material AS material,
po~Supplier AS vendor,
item~Plant AS plant,
sl~ScheduleLineDeliveryDate AS due_date,
sl~OpenQuantityInBaseUnit AS open_qty,
( CAST( @sy-datum AS abap.dats ) - sl~ScheduleLineDeliveryDate ) AS delay_days
FROM I_PurchaseOrderScheduleLineTP AS sl
INNER JOIN sl~_PurchaseOrderItem AS item
ON item~PurchaseOrder = sl~PurchaseOrder
AND item~PurchaseOrderItem = sl~PurchaseOrderItem
INNER JOIN sl~_PurchaseOrder AS po
ON po~PurchaseOrder = sl~PurchaseOrder
WHERE sl~ScheduleLineDeliveryDate < @sy-datum
AND sl~OpenQuantityInBaseUnit > 0
AND item~PurchasingDocumentItemCategory = '0'
ORDER BY delay_days DESCENDING
INTO TABLE @lt_result.
cl_demo_output=>display( lt_result ).
3단계 — Custom CDS Consumption View
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Overdue Purchase Order Schedule Lines'
@Metadata.allowExtensions: true
@VDM.viewType: #CONSUMPTION
@Analytics.dataCategory: #FACT
define view entity ZC_OverduePOSchedule
as select from I_PurchaseOrderScheduleLineTP as ScheduleLine
association [1..1] to I_PurchaseOrderItem as _Item
on _Item.PurchaseOrder = ScheduleLine.PurchaseOrder
and _Item.PurchaseOrderItem = ScheduleLine.PurchaseOrderItem
association [1..1] to I_PurchaseOrder as _Header
on _Header.PurchaseOrder = ScheduleLine.PurchaseOrder
{
key ScheduleLine.PurchaseOrder,
key ScheduleLine.PurchaseOrderItem,
key ScheduleLine.ScheduleLine,
_Header.Supplier as SupplierID,
_Item.Material as MaterialID,
_Item.Plant as PlantID,
ScheduleLine.ScheduleLineDeliveryDate as DueDate,
ScheduleLine.OpenQuantityInBaseUnit as OpenQuantity,
cast( dats_days_between(
ScheduleLine.ScheduleLineDeliveryDate,
$session.system_date ) as abap.int4 ) as DelayDays,
_Item, _Header
}
where ScheduleLine.OpenQuantityInBaseUnit > 0
and ScheduleLine.ScheduleLineDeliveryDate < $session.system_date;
Consumption 뷰는 ALV, Fiori Elements List Report, RAP Query 등 어디서든 재사용할 수 있고, 권한 체크는 상위 인터페이스 뷰의 DCL을 그대로 상속받습니다.
6. CDS 뷰 확장 — Metadata Extension과 VDM 패턴
I_ScheduleLine 같은 SAP 표준 뷰를 직접 수정할 수는 없지만, Metadata Extension이나 CDS View Extension으로 안전하게 확장할 수 있습니다.
@Metadata.layer: #CUSTOMER
annotate view I_PurchaseOrderScheduleLineTP with
{
@UI.lineItem: [ { position: 10, label: 'PO Number' } ]
PurchaseOrder;
@UI.lineItem: [ { position: 20, label: 'Delivery Date' } ]
ScheduleLineDeliveryDate;
}
VDM 레이어 구조 4단계:
- Basic (B_) — 테이블 1:1 매핑
- Composite (R_) — 여러 Basic을 합쳐 비즈니스 의미 부여
- Interface (I_) — 외부에 노출되는 안정적 계약
- Consumption (C_) — UI/리포트 등 최종 소비처
7. 자주 하는 실수와 해결법
Q1. S/4HANA Cloud에서 "SELECT FROM eket" 하니 syntax error가 납니다.
Public Cloud에서는 Released 객체만 허용됩니다. I_PurchaseOrderScheduleLineTP가 Released 상태인지 확인하고, EKET 대신 그 뷰를 사용하세요.
Q2. 동일 PO 아이템인데 결과 행이 중복으로 나옵니다.
스케줄 라인이 분할되어 EKET에 여러 레코드가 존재하는 정상 상황입니다. PO 아이템 단위로 보고 싶다면 SUM(OpenQuantityInBaseUnit)으로 GROUP BY 하거나, I_PurchaseOrderItem의 잔량 필드를 사용하세요.
Q3. ScheduleLineDeliveryDate와 StatisticalDeliveryDate 중 무엇으로 지연을 판단해야 하나요?
운영(Operations) 관점의 지연 분석은 EINDT 기반의 ScheduleLineDeliveryDate, 계획(Planning) 관점의 가용성 분석은 SLFDT 기반의 StatisticalDeliveryDate를 사용하는 편이 자연스럽습니다.
Q4. Authorization 에러가 발생합니다.
@AccessControl.authorizationCheck: #CHECK가 설정된 뷰는 DCL을 통해 권한 객체 M_BEST_* 시리즈를 확인합니다. 사용자에게 구매 조직·플랜트별 권한이 부여되어 있는지 SU01/PFCG에서 점검하세요.
8. 정리 및 실무 적용 팁
EKET와 I_ScheduleLine의 관계를 한 줄로 요약하면 "원본 테이블의 키와 수치를 그대로 가지고 있되, 비즈니스 친화적인 이름·Association·권한 모델을 입힌 안정적 인터페이스"입니다. 실무에서 다음 원칙을 따르는 편이 일반적으로 권장됩니다.
- 새로운 보고서·Fiori 앱은 EKET 직접 SELECT 대신 I_ 계열 인터페이스 뷰로 시작
- 비즈니스 로직은 Z Consumption CDS 뷰에 응축하고, ABAP은 데이터 표시·이벤트 처리만
- 지연일·잔량 같은 파생 값은 가능하면 CDS 내부에서 계산해 HANA로 푸시다운
- 표준 뷰는 절대 수정하지 말고 Metadata Extension만 사용
- S/4HANA Cloud 이행 가능성을 염두에 두고 Released 객체 기반으로 작성
납기 지연 분석은 야간 배치로 결과를 Z 테이블에 적재해 두고, 주간 알림은 그 결과를 읽어 메일·Teams로 발송하는 구조가 안정적입니다. CDS 뷰는 실시간 조회용으로 두고, 무거운 집계는 CDS View with Parameters 또는 Analytics용 Cube 뷰(@Analytics.dataCategory: #CUBE)로 별도 분리하면 시스템 부하를 줄일 수 있습니다.
댓글 0
아직 댓글이 없습니다.