본문 바로가기
MM 모듈

[SAP ABAP] 자재 분류(Classification) 표준 테이블 — KLAH·KSSK·KSML·CABN·AUSP 관계 정리

by Song.sh 2026. 5. 18.

SAP 분류 시스템(Classification) 을 ABAP 으로 다루다 보면 "자재 클래스가 뭐 뭐 있지", "이 자재에 어떤 클래스가 할당돼 있지", "이 클래스에는 어떤 특성이 있지" 같은 질문이 끊임없이 나옵니다. 매번 표준 BAPI 호출만으로는 답이 안 나오는 케이스가 많아 결국 표준 테이블 조인이 필요해집니다.

 

분류 시스템 관련 표준 테이블은 클래스 헤더 · 클래스↔특성 매핑 · 객체↔클래스 매핑 · 특성 마스터 · 특성값 으로 역할이 나뉘어 있습니다. 처음 마주하면 테이블 7~8 개가 흩어져 있어 복잡해 보이지만, 구조를 한 번 잡아두면 어떤 분류 관련 요구사항이 와도 같은 패턴으로 해결할 수 있습니다.

 

이 글은 자재 클래스(KLART = '001') 를 중심으로 표준 분류 테이블 8 종의 역할과 조인 키, 실무 조인 예시를 정리한 메모입니다. 같이 보면 좋은 글은 "BATCH 자재 특성값 조회 — AUSP·CABN·MCH1 조인""내부 특성(ATINN) 변환 — CONVERSION_EXIT_ATINN_INPUT/OUTPUT 사용법" 입니다.


핵심 — 분류 시스템 4계층 구조

표준 분류 시스템 테이블은 다음 4개 계층으로 묶을 수 있습니다. 각 계층마다 마스터 테이블과 텍스트(다국어) 테이블이 짝지어져 있는 경우가 많습니다.

계층 역할 대표 테이블
1. 클래스 유형 자재·배치·장비·고객 등 분류 가능한 객체 유형 정의 TCLA · TCLAT
2. 클래스 마스터 클래스 정의 (예: STEEL_RAW, PACKAGING) KLAH · KLAT
3. 매핑 (관계) "이 객체는 어느 클래스에" · "이 클래스에는 어느 특성이" KSSK · KSML
4. 특성·값 특성 정의 + 허용값 + 객체별 실제 값 CABN · CABNT · CAWN · CAWNT · AUSP

조인 핵심 키는 두 가지입니다.

역할
CLINT (NUMC 10) 내부 클래스 번호. 사용자가 보는 클래스명(CLASS) 대신 시스템 내부 키로 사용 — KLAH·KSSK·KSML 조인 키
KLART (CHAR 3) 클래스 유형. 001=자재, 002=장비, 017=고객, 023=배치 등

이 글에서는 가장 자주 쓰는 자재 클래스(KLART = '001') 기준으로 설명합니다. 다른 클래스 유형(배치·장비 등) 도 동일한 테이블 구조를 그대로 따릅니다.


1단계 — 클래스 헤더 (KLAH · KLAT · TCLA)

클래스 자체의 정의가 들어있는 테이블입니다. SAP CL01(클래스 생성) 트랜잭션에서 입력한 정보가 여기 쌓입니다.

테이블 설명 주요 필드
TCLA 클래스 유형 코드 마스터 KLART(001/002/023/...)
KLAH 클래스 헤더 — 클래스 정의 본체 CLINT(내부키), CLASS(클래스명), KLART(유형), STATU(상태)
KLAT 클래스 설명 텍스트 (다국어) CLINT, SPRAS(언어), KLAFT(설명)

핵심 포인트: 사용자는 CLASS(클래스명, 영문 30자) 로 인지하지만, 다른 테이블과의 조인은 무조건 CLINT(NUMC 10) 로 합니다. 클래스명으로 시작했다면 KLAH 에서 먼저 CLINT 를 얻은 뒤 다른 테이블로 넘어갑니다.

" 클래스명 → 내부 키 변환
SELECT SINGLE clint FROM klah
  INTO @DATA(lv_clint)
  WHERE class = 'STEEL_RAW'
    AND klart = '001'.        " 자재 클래스

2단계 — 클래스 ↔ 특성 매핑 (KSML)

한 클래스에 어떤 특성(CABN) 들이 속해 있는지 알려주는 매핑 테이블입니다.

테이블 설명 주요 필드
KSML 클래스에 할당된 특성 목록 CLINT(클래스 내부키), IMERK(내부 특성번호=ATINN), POSNR(순서)

핵심 필드 IMERK 가 곧 CABN-ATINN 과 같은 내부 특성 번호입니다. 이름은 다르지만 값은 같은 NUMC 10 키입니다.

" 클래스의 모든 특성 조회
SELECT ksml~imerk, cabn~atnam, cabnt~atbez
  FROM ksml
  INNER JOIN cabn   ON cabn~atinn = ksml~imerk
  LEFT  JOIN cabnt  ON cabnt~atinn = cabn~atinn
                   AND cabnt~adzhl = cabn~adzhl
                   AND cabnt~spras = @sy-langu
  INTO TABLE @DATA(lt_class_chars)
  WHERE ksml~clint = @lv_clint.

3단계 — 객체 ↔ 클래스 매핑 (KSSK · INOB)

"이 자재가 어느 클래스에 속해있나" 를 알려주는 매핑입니다. CL20N(객체 분류) 트랜잭션에서 자재에 클래스를 할당하면 여기 쌓입니다.

테이블 설명 주요 필드
KSSK 객체에 할당된 클래스 목록 (자재 분류의 메인 테이블) OBJEK(객체키=자재번호), CLINT(클래스), KLART(유형)
INOB 객체 → 내부 분류 번호 매핑 (배치 등 일부 객체 유형에서 사용) CUOBJ(내부 객체번호), OBTAB(테이블명), OBJEK(객체키)

자재 분류(KLART='001') 의 경우 OBJEK 에 자재번호(MATNR) 가 들어갑니다. INOB 는 배치 같은 일부 유형에서만 필요하며 자재 분류는 보통 KSSK 만으로 충분합니다.

" 자재가 속한 모든 클래스 조회
SELECT kssk~clint, klah~class, klat~klaft
  FROM kssk
  INNER JOIN klah  ON klah~clint = kssk~clint
  LEFT  JOIN klat  ON klat~clint = klah~clint
                  AND klat~spras = @sy-langu
  INTO TABLE @DATA(lt_obj_class)
  WHERE kssk~objek = @lv_matnr
    AND kssk~klart = '001'
    AND kssk~mafid = 'O'                  " O = Object, K = Class
    AND kssk~stdcl = 'X'.                  " 표준 클래스 (선택)

4단계 — 특성·값 (CABN · CABNT · CAWN · AUSP)

특성 정의와 객체별 실제 값이 들어있는 계층입니다. 별도 글 "BATCH 자재 특성값 조회 — AUSP·CABN·MCH1 조인" 에서 자세히 다룬 부분과 동일하지만, 자재 분류 관점에서 다시 정리합니다.

테이블 설명 주요 필드
CABN 특성 마스터 (정의) ATINN(내부키), ATNAM(특성명), ATFOR(포맷)
CABNT 특성 설명 텍스트 (다국어) ATINN, SPRAS, ATBEZ(설명)
CAWN 특성별 허용값 목록 (드롭다운 후보) ATINN, ATWRT(값), ATZHL(카운터)
CAWNT 허용값 텍스트 (다국어) ATINN, ATWRT, SPRAS, ATWTB(텍스트)
AUSP 객체별 실제 특성값 (분류 데이터의 본체) OBJEK(객체), ATINN, KLART, ATWRT(값), ATFLV(숫자)

특성값을 다룰 때는 CABN-ATFOR 포맷에 따라 AUSP-ATWRT(문자) 와 AUSP-ATFLV(숫자) 중 어느 컬럼에 값이 들어있는지 분기해야 합니다(068 글 참고).


5단계 — 전체 조인 예시 (자재 → 클래스 → 특성 → 값)

각 계층을 한 번에 조인해 자재의 모든 분류 정보를 끌어오는 SQL 예시입니다.

SELECT
  kssk~objek    AS matnr,        " 자재
  klah~class    AS class_name,   " 클래스명
  klat~klaft    AS class_desc,   " 클래스 설명
  cabn~atnam    AS char_name,    " 특성명
  cabnt~atbez   AS char_desc,    " 특성 설명
  ausp~atwrt    AS char_value,   " 특성 값 (문자)
  ausp~atflv    AS char_value_n  " 특성 값 (숫자)
  FROM kssk
  INNER JOIN klah   ON klah~clint  = kssk~clint
  LEFT  JOIN klat   ON klat~clint  = klah~clint
                    AND klat~spras = @sy-langu
  INNER JOIN ksml   ON ksml~clint  = klah~clint
  INNER JOIN cabn   ON cabn~atinn  = ksml~imerk
  LEFT  JOIN cabnt  ON cabnt~atinn = cabn~atinn
                    AND cabnt~adzhl = cabn~adzhl
                    AND cabnt~spras = @sy-langu
  LEFT  JOIN ausp   ON ausp~objek  = kssk~objek
                    AND ausp~atinn = cabn~atinn
                    AND ausp~klart = '001'
                    AND ausp~lkenz = ' '
  INTO TABLE @DATA(lt_full)
  WHERE kssk~objek = @lv_matnr
    AND kssk~klart = '001'
    AND kssk~mafid = 'O'.

이 한 SQL 로 자재의 모든 클래스, 각 클래스의 모든 특성, 그리고 그 특성의 실제 값까지 한 번에 끌어옵니다. 표준 BAPI(BAPI_OBJCL_GETDETAIL) 보다 빠르지만, 변환 로직(숫자 포맷·단위) 은 직접 처리해야 합니다.


흔히 빠뜨리는 함정

KSSK-MAFID 조건 누락

KSSK 는 객체↔클래스(MAFID = 'O') 와 클래스↔클래스(MAFID = 'K', 클래스 계층 구조) 매핑이 같이 들어있습니다. 자재 분류만 원할 때는 MAFID = 'O' 조건이 필수입니다.

CLINT 와 CLASS 헷갈림

CLINT(내부 NUMC 10) 와 CLASS(외부 CHAR 18) 는 다른 값입니다. KSSK·KSML 같은 매핑 테이블에는 CLINT 만 있고 CLASS 명은 없으므로, 사용자 입력 클래스명으로 시작했다면 KLAH 에서 변환부터 합니다.

IMERK vs ATINN

KSML-IMERKCABN-ATINN 은 같은 NUMC 10 값을 담지만 컬럼 이름이 다릅니다. 조인 시 두 컬럼이 같다는 것을 알고 있어야 합니다(cabnatinn = ksmlimerk).

다국어 텍스트 LEFT JOIN

KLAT·CABNT·CAWNT 는 언어별 텍스트 테이블이라 해당 언어로 등록되지 않았으면 비어있을 수 있습니다. INNER JOIN 으로 묶으면 텍스트 없는 행이 통째로 빠지므로 LEFT JOIN 을 사용합니다.

CABN-ADZHL 누락 → 같은 특성 중복

CABN 에는 같은 ATINN 에 여러 ADZHL(버전 카운터) 가 존재할 수 있습니다. 텍스트 테이블 조인 시 CABNADZHL = CABNTADZHL 조건을 빼면 중복 행이 발생합니다.

AUSP-LKENZ 삭제표시 필터링

AUSP-LKENZ = 'X' 인 행은 삭제 표시된 특성값입니다. 화면에서는 자동 제외되지만 SQL 조회는 그대로 가져오므로 AND lkenz <> 'X' 또는 AND lkenz = ' ' 조건이 필요합니다.

STDCL(표준 클래스) 사용 의도 확인

KSSK-STDCL = 'X' 는 자재의 "표준 클래스" 표시입니다. 한 자재가 여러 클래스에 속하는데 그중 대표 1개만 표시할 때 사용됩니다. 전체 클래스가 필요한지 표준 1개만 필요한지에 따라 조건을 다르게 설정합니다.

자재 분류 OBJEK 가 항상 MATNR 인 것은 아님

KSSK-OBJEK 는 CHAR 50 의 일반화된 객체 키입니다. 자재 분류(KLART='001') 에서는 자재번호가 그대로 들어가지만, 자재번호가 alpha-converted 되는 경우(앞 0 제거) 직접 SQL 비교 시 매칭 안 될 수 있습니다. 변수 사용 시 alpha conversion 주의(071 글 참고).


전체 코드 — 복사용 통합본

자재번호 입력 → 그 자재의 모든 클래스·특성·특성값을 한꺼번에 출력하는 분류 정보 통합 조회 프로그램입니다. SE38 에 그대로 붙여 실행 가능합니다.

REPORT z_material_class_query.

PARAMETERS: p_matnr TYPE matnr OBLIGATORY.

TYPES: BEGIN OF ty_full,
         matnr         TYPE matnr,
         class_name    TYPE klah-class,
         class_desc    TYPE klat-klaft,
         char_name     TYPE cabn-atnam,
         char_desc     TYPE cabnt-atbez,
         char_value_c  TYPE ausp-atwrt,
         char_value_n  TYPE ausp-atflv,
         char_format   TYPE cabn-atfor,
       END OF ty_full.

DATA: lt_full TYPE STANDARD TABLE OF ty_full,
      lv_obj  TYPE ausp-objek.

* ★ 1) Alpha conversion — 자재번호를 OBJEK 형태로 (선행 0 제거 필요시)
lv_obj = |{ p_matnr ALPHA = OUT }|.

* ★ 2) 자재 → 클래스 → 특성 → 값 한 번에 조인
SELECT
  kssk~objek    AS matnr,
  klah~class    AS class_name,
  klat~klaft    AS class_desc,
  cabn~atnam    AS char_name,
  cabnt~atbez   AS char_desc,
  ausp~atwrt    AS char_value_c,
  ausp~atflv    AS char_value_n,
  cabn~atfor    AS char_format
  FROM kssk
  INNER JOIN klah  ON klah~clint  = kssk~clint
  LEFT  JOIN klat  ON klat~clint  = klah~clint
                   AND klat~spras = @sy-langu
  INNER JOIN ksml  ON ksml~clint  = klah~clint
  INNER JOIN cabn  ON cabn~atinn  = ksml~imerk
  LEFT  JOIN cabnt ON cabnt~atinn = cabn~atinn
                   AND cabnt~adzhl = cabn~adzhl
                   AND cabnt~spras = @sy-langu
  LEFT  JOIN ausp  ON ausp~objek  = kssk~objek
                   AND ausp~atinn = cabn~atinn
                   AND ausp~klart = '001'
                   AND ausp~lkenz = ' '
  INTO TABLE @lt_full
  WHERE kssk~objek = @p_matnr             " ※ alpha 변환 필요시 lv_obj 사용
    AND kssk~klart = '001'                " 자재 분류
    AND kssk~mafid = 'O'.                  " Object (Class 가 아님)

IF sy-subrc <> 0.
  WRITE: / '해당 자재에 할당된 클래스가 없습니다:', p_matnr.
  RETURN.
ENDIF.

* ★ 3) 결과 출력 — 포맷별 분기
WRITE: / 'CLASS | CHAR | VALUE'.
ULINE.
LOOP AT lt_full ASSIGNING FIELD-SYMBOL(<ls>).
  CASE <ls>-char_format.
    WHEN 'CHAR' OR 'DATE' OR 'TIME'.
      WRITE: / <ls>-class_name, <ls>-char_name, <ls>-char_value_c.
    WHEN 'NUM' OR 'CURR'.
      WRITE: / <ls>-class_name, <ls>-char_name, <ls>-char_value_n.
    WHEN OTHERS.
      WRITE: / <ls>-class_name, <ls>-char_name,
              <ls>-char_value_c, <ls>-char_value_n.
  ENDCASE.
ENDLOOP.

요약

계층 테이블 조인 키
1 TCLA · KLAH · KLAT CLINT · KLART
2 KSML (클래스 ↔ 특성) CLINT · IMERK(=ATINN)
3 KSSK · INOB (객체 ↔ 클래스) OBJEK(=MATNR) · CLINT · MAFID='O'
4 CABN · CABNT · CAWN · AUSP ATINN · ADZHL · OBJEK
5 대안 표준 BAPI BAPI_OBJCL_GETDETAIL — 단건 상세 조회 시 권장

자재 분류 시스템은 클래스 헤더(KLAH) → 클래스-특성 매핑(KSML) → 객체-클래스 매핑(KSSK) → 특성·값(CABN·AUSP) 4계층으로 구성됩니다. 키 두 개(CLINT · KLART) 만 잡으면 어떤 자재든 분류 정보를 한 SQL 로 끌어올 수 있습니다. 다국어 텍스트는 LEFT JOIN, 삭제표시는 LKENZ 필터, 객체 키는 alpha conversion 만 주의하면 안정적인 결과를 얻을 수 있습니다. 단건 조회나 자동 포맷팅이 필요하면 직접 SQL 대신 표준 BAPI BAPI_OBJCL_GETDETAIL 을 권장합니다.


Disclaimer — 이 포스트는 실무 정리 노트를 바탕으로 AI 보조로 정리되었습니다.

KLAH · KLAT · KSSK · KSML · CABN · CABNT · CAWN · CAWNT · AUSP · INOB · TCLA 표준 분류 시스템 테이블과 BAPI_OBJCL_GETDETAIL 표준 BAPI 는 SAP NetWeaver 표준 기능으로 시스템 버전 의존 없이 동작합니다. 자재 분류는 KLART = '001', 배치 분류는 '023', 장비는 '002' 등 클래스 유형이 명확히 구분되어 있으니 잘못된 유형 코드 사용 시 조회 결과가 비거나 다른 객체 데이터가 섞일 수 있습니다. 회사별 커스터마이징으로 추가 KLART 가 정의되어 있을 수 있어 전체 목록은 TCLA 테이블에서 사전에 확인하시기 바랍니다. KSSK-OBJEK 와 자재번호의 alpha conversion 차이는 변수로 WHERE 절을 구성할 때 매칭 실패의 흔한 원인이므로, 변수 사용 시 |{ var ALPHA = OUT }| 처리를 권장합니다.