SAP

Readiness Check 빨간불 — 3가지 수정 패턴 #shorts #SAP #S4HANA

개요 — 이 글에서 다루는 것

S/4HANA 전환 프로젝트에서 SAP Readiness Check 리포트를 열었을 때 Custom Code 영역이 빨간불로 가득한 경험은 대부분의 마이그레이션 팀이 겪는 통과 의례입니다. 이 글은 ECC 6.0에서 S/4HANA(2022/2023 에디션 기준)로 전환할 때 ABAP 커스텀 코드가 비호환 판정을 받는 3가지 대표 패턴을 분석하고, 각 패턴별 Before/After 코드로 수정 방법을 정리한 실전 예제입니다.

  • Readiness Check의 Custom Code 항목이 빨간불이 되는 구조적 원인 이해
  • 삭제된 API / 테이블 구조 변경 / 문법 비호환 3가지 패턴 식별
  • ATC(ABAP Test Cockpit) 원격 검사와 Quick Fix로 수정 자동화
  • Simplification Item 기반 Migration Object List 처리 우선순위 수립

미리 알아두면 좋은 배경

ABAP 개발 경험(Open SQL, Function Module, Enhancement 개념)과 ECC의 SD/MM 기본 테이블 구조(VBAK, EKPO, MKPF/MSEG 등)를 알고 있으면 예제를 그대로 따라올 수 있습니다. ADT(ABAP Development Tools in Eclipse) 사용 경험이 있으면 Quick Fix 부분에서 유리합니다.

환경 · 버전 · 준비물

이 글의 예제는 다음 환경을 기준으로 작성했습니다.

  • 소스: SAP ECC 6.0 EHP7/EHP8 (NetWeaver 7.4~7.5)
  • 타깃: SAP S/4HANA 2023 (on-premise), ABAP Platform 7.58
  • 검사 시스템: NetWeaver 7.52 이상 또는 SAP BTP ABAP Environment의 Custom Code Migration 앱 — 원격 ATC 검사를 위해 RFC로 소스 시스템 연결
  • 필수 콘텐츠: Simplification Database(SYCM으로 다운로드 후 검사 시스템에 업로드), ATC 검사 변형 S4HANA_READINESS_2023
  • 사용 데이터: SCMON/SUSG로 최소 3개월 이상 수집한 실사용 통계(미사용 코드 제외 판단용)

Readiness Check 자체는 SAP for Me에서 분석 세션을 생성하고, 소스 시스템에서 수집 노트(예: SAP Note 3112362 계열)를 적용해 데이터를 추출하는 방식으로 동작합니다.

핵심 개념 — 왜 빨간불이 켜지는가

S/4HANA는 ECC의 단순 업그레이드가 아니라 데이터 모델 자체를 재설계한 제품입니다. 비유하자면 건물의 인테리어만 바꾼 것이 아니라 기둥과 배관 위치를 옮긴 리모델링에 가깝습니다. 기존 커스텀 코드는 옛 배관 위치를 하드코딩한 상태이므로, 그대로 옮기면 물이 새는 지점이 바로 Readiness Check의 빨간불입니다.

SAP는 변경 사항을 Simplification Item이라는 단위로 카탈로그화했고, Readiness Check와 ATC는 이 카탈로그(Simplification Database)와 커스텀 코드의 where-used를 대조해 충돌을 찾아냅니다. 충돌은 크게 3계층으로 나뉩니다.

패턴충돌 계층대표 사례
1. API 삭제/변경호출 인터페이스MB_CREATE_GOODS_MOVEMENT 삭제, MB* 트랜잭션 폐지
2. 테이블 구조 변경데이터 모델MKPF/MSEG→MATDOC, KONV→PRCD_ELEMENTS, VBUK 상태 필드→VBAK
3. 문법 비호환ABAP 언어/DB 동작암묵적 정렬 의존, MATNR 40자 확장, obsolete 구문

중요한 점은 SAP가 상당수 테이블에 Compatibility View(CDS 기반 프록시 뷰)를 제공한다는 것입니다. 예를 들어 MSEG를 SELECT하면 실제로는 MATDOC을 읽는 뷰로 리다이렉트됩니다. 덕분에 읽기 코드는 당장 동작하지만, 이는 성능 저하를 감수한 임시 다리일 뿐이며 INSERT/UPDATE 코드는 아예 동작하지 않습니다. 따라서 빨간불의 우선순위는 "쓰기 접근 > 삭제된 API > 읽기 접근(성능)" 순으로 잡는 것이 일반적으로 권장됩니다.

실전 코드 — 패턴별 3단계 수정

1단계 (패턴 1): 삭제된 API 교체 — 자재문서 생성

S/4HANA에서는 MB 계열 내부 Function Module이 제거되었습니다. BAPI로 교체하는 실전 예제입니다.

" [Before] ECC — S/4HANA에서 구문 오류 (FM 미존재)
CALL FUNCTION 'MB_CREATE_GOODS_MOVEMENT'
  EXPORTING
    imkpf = ls_header
  TABLES
    emseg = lt_items.

" [After] S/4HANA — 릴리스된 BAPI 사용
DATA(ls_gm_header) = VALUE bapi2017_gm_head_01(
  pstng_date = sy-datum
  doc_date   = sy-datum ).

DATA(lt_gm_items) = VALUE bapi2017_gm_item_create_t(
  ( material_long = lv_raw_material
    plant         = '1010'
    stge_loc      = '0001'
    move_type     = '101'
    entry_qnt     = lv_received_qty
    po_number     = lv_purchase_order
    po_item       = lv_po_item ) ).

CALL FUNCTION 'BAPI_GOODSMVT_CREATE'
  EXPORTING
    goodsmvt_header = ls_gm_header
    goodsmvt_code   = VALUE bapi2017_gm_code( gm_code = '01' )
  IMPORTING
    materialdocument = lv_mat_doc
  TABLES
    goodsmvt_item   = lt_gm_items
    return          = lt_return.

2단계 (패턴 2): 테이블 구조 변경 — 판매오더 상태 및 가격조건 재배치

판매오더 헤더 상태를 VBUK에서 읽던 코드는 S/4HANA에서 VBAK로 이관된 상태 필드를 직접 읽도록 바꿉니다. 가격조건 KONV도 PRCD_ELEMENTS로 교체합니다.

" [Before] ECC — VBUK/KONV 직접 접근
SELECT vbeln gbstk INTO TABLE lt_status
  FROM vbuk WHERE vbeln IN s_vbeln.

" [After] S/4HANA — 상태 필드가 VBAK로 통합됨
SELECT vbeln, gbstk, knumv
  FROM vbak
  WHERE vbeln IN @s_vbeln
  INTO TABLE @DATA(lt_so_status).

IF sy-subrc <> 0.
  MESSAGE e001(zsd_mig) WITH s_vbeln-low INTO DATA(lv_msg).
  zcl_mig_logger=>get_instance( )->add_error(
    iv_object = 'ZSD_STATUS_READ' iv_text = lv_msg ).
  RETURN.
ENDIF.

SELECT knumv, kposn, kschl, kbetr, waers
  FROM prcd_elements
  FOR ALL ENTRIES IN @lt_so_status
  WHERE knumv = @lt_so_status-knumv
  INTO TABLE @DATA(lt_pricing).

쓰기 접근이 있었다면(예: UPDATE konv) Compatibility View로도 구제되지 않으므로, 가격결정 BAdI나 릴리스된 API로 로직 자체를 재설계해야 합니다.

3단계 (패턴 3): 문법 비호환 — 암묵적 정렬 의존 제거

HANA에서는 클러스터/풀 테이블이 투명 테이블로 전환되며 암묵적 기본키 정렬이 사라집니다. 정렬 의존 로직은 명시적 ORDER BY가 없으면 데이터 오류로 이어집니다.

" [Before] ECC — 암묵적 정렬에 의존한 구매오더 품목 처리
SELECT * FROM ekpo INTO TABLE lt_po_items
  WHERE ebeln IN s_ebeln.
READ TABLE lt_po_items WITH KEY ebeln = lv_po
  BINARY SEARCH.

" [After] S/4HANA — 명시적 정렬 + SORTED TABLE + 필드 리스트
SELECT ebeln, ebelp, matnr, menge, netpr
  FROM ekpo
  WHERE ebeln IN @s_ebeln
  ORDER BY ebeln, ebelp
  INTO TABLE @DATA(lt_po_items).

DATA lt_sorted TYPE SORTED TABLE OF ty_po_item
  WITH UNIQUE KEY ebeln ebelp.
lt_sorted = CORRESPONDING #( lt_po_items ).

프로덕션 반영 전: ATC 검사 변형 S4HANA_READINESS_2023으로 실행하고 ADT Quick Fix로 반자동 수정, SUSG 사용 통계와 결합해 미사용 오브젝트(전체 지적 사항의 30~60%)를 먼저 삭제 목록으로 분리합니다.

흔한 실수와 트러블슈팅 FAQ

Q1. Compatibility View가 있으니 MSEG 읽기 코드는 안 고쳐도 되지 않나요?
동작은 하지만 MATDOC 조인·집계를 뷰가 대신 수행하므로 대량 조회에서 성능이 급격히 나빠질 수 있습니다. 배치·인터페이스처럼 볼륨이 큰 코드부터 MATDOC 직접 접근 또는 표준 CDS 뷰(NSDM 계열)로 전환하는 것이 권장됩니다.

Q2. ATC 결과가 수만 건인데 어디서부터 시작해야 하나요?
우선 SUSG 사용 데이터로 미사용 오브젝트를 제외하고, 남은 항목을 우선순위 1(구문 오류·삭제 API·쓰기 접근) → 2(기능 변경) → 3(성능 권고) 순으로 처리합니다. Priority 1을 방치하면 전환 후 덤프로 직결됩니다.

Q3. Implicit Enhancement가 걸어둔 표준 코드가 S/4HANA에서 사라졌습니다.
Enhancement Point 자체가 삭제되면 SPAU_ENH에서 조정 대상으로 나타납니다. 동일 시점의 명시적 BAdI(예: 가격결정은 PRC 계열 BAdI)로 로직을 이관하고, 원본 Enhancement는 비활성화하는 방식이 일반적입니다.

Q4. MATNR을 CHAR18 로컬 변수에 담던 코드가 경고를 냅니다.
S/4HANA에서 MATNR은 40자입니다. 로컬 타입을 matnr 데이터 엘리먼트 참조로 바꾸고, 외부 인터페이스(파일/IDoc)는 필드 길이 협의가 필요합니다. Quick Fix가 상당 부분 자동 변환해 줍니다.

이어서 보면 좋은 주제

  • Clean Core 전략 — 수정한 코드를 Tier 1/2/3 확장 모델로 재배치
  • ABAP Cloud와 Released API 기반 재개발(RAP 전환)
  • Custom Code Migration 앱의 Semi-automatic 스코핑 고도화
  • SDMI(Silent Data Migration)와 전환 후 데이터 검증

댓글 0

아직 댓글이 없습니다.