ABAP

QALS 직접 조회하면 큰일 — I_InspectionLot #shorts #SAP #ABAP

▶ YouTube에서 보기

이 글에서 다룰 것

S/4HANA의 QM(품질관리) 영역에서 검사 로트(Inspection Lot)는 입고, 생산, 변경 등 다양한 이벤트마다 생성되어 품질 검사의 단위가 됩니다. 전통적으로 ABAP 개발자는 QALS 테이블을 직접 SELECT하여 로트 정보를 가져왔지만, 필드명이 독일어 약자 기반이고(예: PRUEFLOS, MATNR, WERK) 상태값이 비트 문자열(STAT)로 저장되어 가독성과 유지보수성이 떨어집니다.

이 글에서는 SAP가 제공하는 VDM(Virtual Data Model) 표준 CDS 뷰인 I_InspectionLot을 사용해 QALS를 한 줄로 대체하는 방법을 다룹니다.

  • QALS 직접 조회의 한계와 I_InspectionLot 도입 배경
  • 기본 SELECT, 상태 필터링, 검사 결과 조인 패턴
  • 주요 필드 매핑과 실무 트러블슈팅

이 글을 보기 전에

이 글은 다음 내용을 이미 알고 있다고 가정합니다.

  • ABAP Open SQL SELECT ... FROM ... INTO TABLE @DATA(...) 신구문
  • CDS View 기본 개념(@AbapCatalog, define view entity)
  • QM 모듈의 검사 로트(Inspection Lot), 검사 특성(Inspection Characteristic) 개념
  • S/4HANA VDM 명명 규약(I_, C_, P_ 접두어)

QM이 처음이라면 QA01(수동 생성), QA32(워크리스트) 트랜잭션을 미리 한 번 다뤄보길 권장합니다.

환경 및 준비물

이 글의 코드는 일반적으로 다음 환경에서 동작이 확인됩니다.

  • SAP S/4HANA 2022 FPS01 이상 (Private/Public Cloud 또는 On-Premise)
  • ABAP Development Tools (ADT) for Eclipse 2023-09 이상
  • 권한: S_TABU_DIS(QALS 읽기), CDS 조회용 S_RS_AUTH 혹은 분석 권한
  • 네임스페이스: SAP 표준 I_InspectionLot, I_InspectionLotResult 사용

버전에 따라 일부 필드(예: 배치 관련, EWM 연계 필드)는 제공 여부가 다를 수 있으니 ADT의 Field Browser에서 사전 확인을 권장합니다.

QALS vs I_InspectionLot — 핵심 개념

QALS는 검사 로트의 원천 데이터베이스 테이블입니다. 1990년대 R/3 시절부터 사용된 구조라 필드명이 짧고 독일어 약자를 그대로 사용합니다. 반면 I_InspectionLot은 S/4HANA의 VDM 계층에서 정의된 CDS View로, QALS를 기반으로 하되 다음을 추가합니다.

  • 의미 있는 영문 필드명(InspectionLot, Material, Plant)
  • 연관관계(Association)를 통한 마스터 데이터 자동 조인 — 예: _Material, _Plant, _InspectionType
  • 상태 비트(STAT 32자리)를 의미 있는 컬럼으로 노출 — InspectionLotStatus, InspLotUsageDecisionHasBeenMade
  • OData/RAP 서비스 노출과 권한 객체 자동 적용

비유하자면 QALS는 "원재료 창고", I_InspectionLot은 "조리된 반찬 코너"입니다. 매번 원재료를 손질하는 대신 바로 꺼내 쓰면 됩니다.

* 도식: 호출 계층
*
*  Fiori App / OData / RAP
*           |
*      C_InspectionLot   (Consumption)
*           |
*      I_InspectionLot   (Interface/VDM)  <-- 우리가 쓸 계층
*           |
*         QALS           (Persistent Table)

실전 코드 1단계 — 기본 조회 비교

먼저 QALS 직접 조회와 I_InspectionLot 사용을 비교합니다. 같은 결과를 얻지만 코드 양과 가독성에 차이가 큽니다.

* (1) QALS 직접 조회 - 전통 방식
SELECT prueflos,
       matnr,
       werk,
       losmenge,
       mengeneinh,
       stat
  FROM qals
  INTO TABLE @DATA(lt_qals_raw)
  WHERE werk = '1010'
    AND erstelldat >= '20260101'.

* 필드명이 무엇을 뜻하는지 주석이 필수
* stat 필드는 32자리 비트 문자열이라 의미 해석이 추가로 필요
* (2) I_InspectionLot CDS 뷰 사용 - 권장 방식
SELECT InspectionLot,
       Material,
       Plant,
       InspectionLotQuantity,
       InspectionLotQuantityUnit,
       InspectionLotStatus
  FROM I_InspectionLot
  INTO TABLE @DATA(lt_lots)
  WHERE Plant = '1010'
    AND InspectionLotCreationDate >= '20260101'.

cl_demo_output=>display( lt_lots ).

같은 비즈니스 의미를 표현하는데 두 번째 코드는 누가 봐도 무엇을 조회하는지 명확합니다. 또한 권한 체크가 CDS 계층에서 일관되게 적용되므로 별도의 AUTHORITY-CHECK를 줄일 수 있습니다.

실전 코드 2단계 — 상태 필터링과 에러 처리

실무에서는 "사용 결정이 아직 안 된 로트만", "단기 검사가 완료된 로트만" 같은 상태 기반 조건이 자주 등장합니다. QALS의 STAT 비트를 해석하는 대신 I_InspectionLot의 의미 컬럼을 활용합니다.

METHOD get_open_inspection_lots.

  DATA(lv_today) = cl_abap_context_info=>get_system_date( ).

  TRY.
      SELECT InspectionLot,
             Material,
             Plant,
             InspectionLotType,
             InspectionLotStatus,
             InspectionLotQuantity,
             InspectionLotQuantityUnit,
             InspLotUsageDecisionHasBeenMade,
             InspectionLotCreationDate
        FROM I_InspectionLot
        INTO TABLE @DATA(lt_open_lots)
        WHERE Plant                          = @iv_plant
          AND InspLotUsageDecisionHasBeenMade = ' '   "UD 미수행
          AND InspectionLotCreationDate      >= @lv_today - 30.

      IF lt_open_lots IS INITIAL.
        " 0건은 정상 케이스로 INFO 로그
        cl_bali_log_factory=>create_log( )->add_free_text(
          severity = if_bali_constants=>c_severity_info
          text     = |Plant { iv_plant }: 미결 로트 없음| ).
        RETURN.
      ENDIF.

      rt_lots = lt_open_lots.

    CATCH cx_sy_open_sql_db INTO DATA(lx_sql).
      " DB 단 오류 - 권한/락/타임아웃 등
      RAISE EXCEPTION TYPE zcx_qm_read_error
        EXPORTING previous = lx_sql.
  ENDTRY.

ENDMETHOD.

핵심 포인트: InspLotUsageDecisionHasBeenMade는 X/공백으로 표현되어 QALS의 STAT35 비트를 해석할 필요가 없습니다. 또한 OpenSQL 예외를 잡아 도메인 예외로 래핑하면 호출자가 일관된 방식으로 에러를 처리할 수 있습니다.

실전 코드 3단계 — 검사 결과 조인과 성능

로트 정보와 함께 실제 측정 결과를 보려면 I_InspectionLotResult(또는 버전에 따라 I_InspLotCharacteristicResult)와 조인합니다. 프로덕션에서는 인덱스 사용을 고려해 필터 우선, 컬럼 최소화를 권장합니다.

SELECT lot~InspectionLot,
       lot~Material,
       lot~Plant,
       lot~InspectionLotQuantity,
       res~InspectionCharacteristic,
       res~InspectionResultMeasuredValue,
       res~InspectionResultValuationResult
  FROM I_InspectionLot AS lot
  INNER JOIN I_InspectionLotResult AS res
    ON  res~InspectionLot = lot~InspectionLot
  INTO TABLE @DATA(lt_lot_results)
  WHERE lot~Plant                          = @iv_plant
    AND lot~InspectionLotCreationDate      BETWEEN @iv_date_from AND @iv_date_to
    AND res~InspectionResultValuationResult = 'R'    "Rejected
  ORDER BY lot~InspectionLot, res~InspectionCharacteristic
  UP TO 5000 ROWS.

" 단위 테스트 예시 (ABAP Unit)
CLASS ltc_inspection_reader DEFINITION FINAL FOR TESTING
  DURATION SHORT
  RISK LEVEL HARMLESS.
  PRIVATE SECTION.
    METHODS reject_lots_should_return_results FOR TESTING.
ENDCLASS.

CLASS ltc_inspection_reader IMPLEMENTATION.
  METHOD reject_lots_should_return_results.
    " CDS Test Double Framework 활용 권장
    DATA(lo_env) = cl_cds_test_environment=>create(
      i_for_entities = VALUE #( ( i_for_entity = 'I_INSPECTIONLOT' )
                                ( i_for_entity = 'I_INSPECTIONLOTRESULT' ) ) ).
    " ... given/when/then
  ENDMETHOD.
ENDCLASS.

성능 팁:

  • 대용량 추출 시 UP TO n ROWS 또는 PACKAGE SIZE로 분할
  • Plant + 기간 조합은 QALS 표준 인덱스에 부합
  • 전사 단위 집계는 CDS 단에서 @Analytics.dataExtraction.enabled: true가 붙은 큐브성 뷰를 우선 검토
  • 보안: 사용자별 Plant 권한은 CDS의 @AccessControl.authorizationCheck: #CHECK가 처리하므로 임의로 우회 금지

주요 필드와 흔한 실수 — FAQ

I_InspectionLot 필드의미QALS 매핑
InspectionLot검사 로트 번호(12자리)PRUEFLOS
Material / Plant자재 / 플랜트MATNR / WERK
InspectionLotStatus로트 상태(시스템 상태 요약)STAT(비트)
InspectionLotType검사 유형(01 입고, 04 생산 등)HERKUNFT
InspLotUsageDecisionHasBeenMade사용 결정(UD) 완료 여부STAT35 비트

Q1. I_InspectionLot에 우리 회사 Z필드가 안 보입니다.
표준 VDM은 SAP 표준 필드만 노출합니다. CDS Extension(extend view entity)으로 Z필드를 추가하거나, QALS의 .APPEND 필드를 노출하는 커스텀 CDS를 만들어 조인하세요.

Q2. 상태 필터가 동작하지 않습니다(예: "검사 중"만 보고 싶음).
InspectionLotStatus는 요약 코드이며 실제 시스템 상태는 JEST/TJ02 기반입니다. 의미 필드(InspLotUsageDecisionHasBeenMade, InspectionLotIsSkipped 등)를 조합해 조건을 구성하는 것이 일반적으로 더 안정적입니다.

Q3. 결과 조인 시 행이 폭증합니다.
한 로트에는 다수의 특성(Characteristic)이 존재하므로 1:N 조인은 자연스럽게 행이 늘어납니다. 헤더만 필요하면 I_InspectionLot 단독으로, 집계가 필요하면 CDS Association(_Result)이나 GROUP BY를 활용하세요.

다음 단계와 관련 주제

이 글의 패턴을 익혔다면 다음 주제로 확장해 보세요.

  • RAP 기반 QM 앱: I_InspectionLot을 베이스로 한 Behavior Definition + Managed Scenario
  • Analytical Query: C_InspectionLotQuery 류의 분석용 뷰로 Fiori 분석 리스트 페이지 구성
  • 이벤트 기반 통합: Inspection Lot Created/Changed 비즈니스 이벤트 → BTP Event Mesh 연계
  • Quality Notification 연계: I_QualityNotification과의 조인으로 부적합 처리 흐름 추적

참고 자료

핵심 한 줄

I_InspectionLot은 QALS를 한 줄로 대체하는 QM 표준 VDM이다.

댓글 0

아직 댓글이 없습니다.