자재마스터(MM01) 를 자동으로 만들어야 하는 시나리오는 ABAP 개발에서 자주 만납니다. 외부 시스템에서 자재 정보를 수신해 SAP 에 동기화하거나, 엑셀 업로드 프로그램에서 한 번에 수십~수백 건의 자재를 생성하거나, MM01 자체에 BDC 를 거는 대신 표준 BAPI 로 깔끔하게 처리하고 싶을 때 — 표준 도구가 BAPI_MATERIAL_SAVEDATA 입니다.
다만 이 BAPI 는 옵션이 많아 첫 호출이 부담스럽습니다. 어떤 뷰를 만들지(기본·구매·MRP·회계·저장위치·원가) HEADDATA 의 플래그로 결정해야 하고, 뷰별로 데이터 구조체(BAPI_MARA·BAPI_MARC·BAPI_MBEW 등) 와 그 X-구조체(BAPI_MARAX·BAPI_MARCX 등) 를 한 쌍으로 매번 채워야 합니다. 회사 자체 확장 필드(BAPI_TE_MARA) 까지 들어가면 코드 라인 수가 더 늘어납니다.
이 글은 BAPI_MATERIAL_SAVEDATA 의 시그니처 전체 → HEADDATA 의 뷰 플래그 → CLIENTDATA·PLANTDATA·VALUATIONDATA·STORAGELOCATIONDATA 4종 뷰 데이터 + X-구조체 패턴 → MATERIALDESCRIPTION(자재내역) → EXTENSIONIN(자사 확장 필드) → COMMIT/ROLLBACK 흐름을 한 화면에 모은 메모입니다. 노트의 실제 호출 패턴을 그대로 살려 신규 자재 ROH(원료) 한 건을 생성하는 풀 예제를 끝에 같이 둡니다.
핵심 — IMPORTING 구조체 + X-구조체 한눈 비교
BAPI_MATERIAL_SAVEDATA 의 IMPORTING 은 "뷰별 데이터 구조체 + X-구조체 한 쌍" 패턴이 반복되는 구조.
| 파라미터 | 타입 | 담는 뷰 / 데이터 |
|---|---|---|
HEADDATA (필수) |
BAPIMATHEAD |
자재번호·산업분야·자재유형 + 어떤 뷰를 만들지 플래그 |
CLIENTDATA + X |
BAPI_MARA·BAPI_MARAX |
기본 뷰 — 자재그룹·기본단위·제품군·배치관리·중량 |
PLANTDATA + X |
BAPI_MARC·BAPI_MARCX |
플랜트 뷰 — MRP 유형·가용성점검·로트사이즈·손익센터 |
VALUATIONDATA + X |
BAPI_MBEW·BAPI_MBEWX |
회계 뷰 — 평가유형·평가영역·평가클래스 |
STORAGELOCATIONDATA + X |
BAPI_MARD·BAPI_MARDX |
저장위치 뷰 — 플랜트 + 저장위치 키 |
SALESDATA + X |
BAPI_MVKE·BAPI_MVKEX |
영업 뷰 — 영업조직·유통채널·품목범주그룹 |
FORECASTPARAMETERS + X |
BAPI_MPOP·BAPI_MPOPX |
예측 파라미터 — Forecasting 뷰 |
PLANNINGDATA + X |
BAPI_MPGD·BAPI_MPGDX |
계획 파라미터 — Demand Planning |
핵심 한 줄: "데이터 + X-구조체 한 쌍" 패턴이 모든 뷰에 동일하게 적용됩니다. CLIENTDATA 에 값을 채우고 CLIENTDATAX 의 같은 필드에 'X' 마크 — BAPI_PO_CHANGE / BAPI_BATCH_CHANGE 와 동일한 패턴.
1단계 — HEADDATA: 자재 키 + 뷰 플래그
가장 먼저 채우는 부분. 자재번호·산업분야·자재유형 + 어떤 뷰를 만들지 를 결정하는 플래그가 들어 있습니다.
DATA(ls_headdata) = VALUE bapimathead(
material = 'TEST-MAT-001' " 자재번호
ind_sector = 'M' " 산업분야 (M=Mechanical Engineering)
matl_type = 'ROH' " 자재유형 (ROH=원료, FERT=완제품)
" ★ 뷰 플래그 — 어떤 뷰를 만들지 결정
basic_view = abap_true " 기본데이터 뷰
purchase_view = abap_true " 구매 뷰
mrp_view = abap_true " MRP 1~4 뷰
account_view = abap_true " 회계 뷰
storage_view = abap_true " 저장위치 뷰 + 일반 플랜트 데이터
cost_view = abap_true ). " 원가 뷰
| 뷰 플래그 | 활성화되는 화면 |
|---|---|
BASIC_VIEW |
기본데이터 1 / 기본데이터 2 |
PURCHASE_VIEW |
구매 / 해외무역(수입) / 구매오더 텍스트 |
MRP_VIEW |
MRP 1 / 2 / 3 / 4 |
ACCOUNT_VIEW |
회계 1 / 2 |
STORAGE_VIEW |
일반 플랜트 데이터 / 저장위치 1·2 |
SALES_VIEW |
영업 1 / 영업 2 / 영업 일반 |
COST_VIEW |
원가계산 1 / 2 |
플래그를 켜지 않은 뷰는 BAPI 가 만들지 않습니다. 즉 "이 자재는 구매하지 않고 사내 생산만" 이라면 PURCHASE_VIEW 를 abap_false 로 두면 됩니다.
2단계 — CLIENTDATA: 기본 뷰 데이터 + X-구조체
BASIC_VIEW = abap_true 면 CLIENTDATA 에 값 채우기.
DATA(ls_clientdata) = VALUE bapi_mara(
matl_group = '001' " 자재그룹
base_uom = 'KG' " 기본단위
division = '10' " 제품군
prod_hier = 'W' " 제품계층구조
item_cat = 'NORM' " 일반품목범주 그룹
batch_mgmt = abap_true " 배치 관리
po_unit = 'MT' " 구매 단위
net_weight = '1' " 순중량
unit_of_wt = 'KG' ). " 중량 단위
" 변경 의도 매핑 — 채운 필드만 'X'
DATA(ls_clientdatax) = VALUE bapi_marax(
matl_group = abap_true
base_uom = abap_true
division = abap_true
prod_hier = abap_true
item_cat = abap_true
batch_mgmt = abap_true
po_unit = abap_true
net_weight = abap_true
unit_of_wt = abap_true ).
X-구조체의 동작 원리: BAPI 는 CLIENTDATAX 의 같은 필드에 'X' 가 있는 필드만 실제로 적용합니다. CLIENTDATA 에 값을 채워도 X-구조체에 마크 안 하면 무시됨. 두 구조체를 항상 한 쌍으로 관리.
3단계 — PLANTDATA: 플랜트 확장 (MRP·재고)
같은 패턴. 플랜트 단위로 MRP 유형·가용성점검·손익센터 등을 지정.
DATA(ls_plantdata) = VALUE bapi_marc(
plant = '0001' " 플랜트
mrp_type = 'X0' " MRP 유형
availcheck = '02' " 가용성 점검
mrp_ctrler = '200' " MRP 관리자
sm_key = '000' " 일정 마진 키
lotsizekey = 'WB' " 로트 크기
profit_ctr = 'P100' ). " 손익센터
DATA(ls_plantdatax) = VALUE bapi_marcx(
plant = '0001' " 키 필드는 X-구조체에도 값 그대로 (X 가 아닌 값)
mrp_type = abap_true
availcheck = abap_true
mrp_ctrler = abap_true
sm_key = abap_true
lotsizekey = abap_true
profit_ctr = abap_true ).
키 필드(플랜트) 의 특이점: 플랜트(PLANT) 같은 키 필드는 X-구조체에도 'X' 가 아니라 실제 값 을 채워야 합니다. BAPI 가 "어느 플랜트의 데이터인지" 식별하는 데 사용.
4단계 — VALUATIONDATA: 회계 뷰 (평가)
회계 뷰는 평가유형·평가영역(플랜트)·평가클래스를 가집니다.
DATA(ls_valuationdata) = VALUE bapi_mbew(
val_type = '01' " 평가유형
val_area = '0001' " 평가영역 (= 플랜트)
val_class = '3000' ). " 평가클래스 (회계 코드 카테고리)
DATA(ls_valuationdatax) = VALUE bapi_mbewx(
val_type = '01' " 키 — 그대로 값
val_area = '0001' " 키 — 그대로 값
val_class = abap_true ). " 'X' 마크
평가클래스는 회사가 IMG 에서 사전 정의한 값이므로 회사 정책 확인 후 채움. VAL_TYPE 은 일반적으로 비어 있고, 평가가 여러 유형으로 나뉘는 자재에만 채웁니다.
5단계 — STORAGELOCATIONDATA: 저장위치
플랜트 + 저장위치 키만 채우면 끝. 다른 필드는 거의 없습니다(저장위치는 키 자체가 데이터).
DATA(ls_storagelocationdata) = VALUE bapi_mard(
plant = '0001' " 플랜트
stge_loc = '0001' ). " 저장위치
DATA(ls_storagelocationdatax) = VALUE bapi_mardx(
plant = '0001' " 키
stge_loc = '0001' ). " 키
저장위치는 X-구조체에 별도 마크할 필드가 거의 없어 두 구조체가 거의 동일합니다.
6단계 — MATERIALDESCRIPTION: 자재 내역 (TABLES)
자재내역은 언어별 여러 줄이 가능하므로 TABLES 파라미터.
DATA: lt_makt TYPE TABLE OF bapi_makt.
APPEND VALUE #(
langu = sy-langu " 한국어
langu_iso = cl_i18n_languages=>sap1_to_sap2( im_lang_sap1 = sy-langu ) " ISO 코드 (KO)
matl_desc = '테스트 자재 - 원료' )
TO lt_makt.
" 영어 자재내역도 같이 등록하려면 한 줄 더
APPEND VALUE #(
langu = 'E'
langu_iso = 'EN'
matl_desc = 'Test Material - Raw' )
TO lt_makt.
LANGU_ISO 가 필수 입력. SY-LANGU(SAP 한 자리) 와 ISO(KO/EN) 변환은 CL_I18N_LANGUAGES=>SAP1_TO_SAP2 메소드 사용.
7단계 — EXTENSIONIN: 자사 확장 필드
자재마스터에 회사 자체 필드(ZZ_*) 를 추가한 경우 표준 CLIENTDATA 에는 그 필드가 없습니다. 대신 EXTENSIONIN(BAPIPAREX) 에 자사 확장 구조체(BAPI_TE_MARA) 를 넣어 전달.
" 자사 확장 구조체 (Append Structure)
DATA(ls_teitem) = VALUE bapi_te_mara(
material = 'TEST-MAT-001'
zgubun = 'D' ). " 자사 추가 필드
DATA(ls_teitemx) = VALUE bapi_te_marax(
material = 'TEST-MAT-001'
zgubun = abap_true ).
" EXTENSIONIN 테이블에 담기
DATA: lt_extensionin TYPE TABLE OF bapiparex,
lt_extensioninx TYPE TABLE OF bapiparexx.
APPEND VALUE #(
structure = 'BAPI_TE_MARA' " 자사 확장 구조체 이름
valuepart1 = ls_teitem ) " 데이터를 캐스팅
TO lt_extensionin.
APPEND VALUE #(
structure = 'BAPI_TE_MARAX'
valuepart1 = ls_teitemx )
TO lt_extensioninx.
주의: EXTENSIONIN 이 작동하려면 IMG 의 BAPI 매핑 등록 + BAdI 구현 이 사전에 되어 있어야 합니다. 단순 코드만 짜고 매핑이 빠지면 BAPI 가 EXTENSIONIN 데이터를 받기는 받지만 자재마스터에 반영 안 됨.
자사 환경에 따라 BAPI_TE_MARA·BAPI_TE_MARAX 외에 플랜트 확장(BAPI_TE_MARC)·회계 확장(BAPI_TE_MBEW) 도 같은 패턴으로 추가.
8단계 — BAPI 호출 + COMMIT/ROLLBACK
데이터 준비 끝나면 BAPI 한 줄 호출. 결과 메시지 확인 후 명시적 COMMIT 또는 ROLLBACK.
DATA: ls_return TYPE bapiret2,
lt_returnmessages TYPE TABLE OF bapi_matreturn2.
CALL FUNCTION 'BAPI_MATERIAL_SAVEDATA'
EXPORTING
headdata = ls_headdata
clientdata = ls_clientdata
clientdatax = ls_clientdatax
plantdata = ls_plantdata
plantdatax = ls_plantdatax
valuationdata = ls_valuationdata
valuationdatax = ls_valuationdatax
storagelocationdata = ls_storagelocationdata
storagelocationdatax = ls_storagelocationdatax
IMPORTING
return = ls_return
TABLES
materialdescription = lt_makt
returnmessages = lt_returnmessages
extensionin = lt_extensionin
extensioninx = lt_extensioninx.
" 상세 메시지 출력
LOOP AT lt_returnmessages ASSIGNING FIELD-SYMBOL(<msg>).
WRITE: / |[{ <msg>-type }] { <msg>-id } { <msg>-number } { <msg>-message }|.
ENDLOOP.
" 결과 분기
IF ls_return-type = 'E' OR ls_return-type = 'A'.
CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
WRITE: / |❌ 자재 생성 실패: { ls_return-message }|.
ELSE.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT' EXPORTING wait = 'X'.
WRITE: / |✅ 자재 { ls_headdata-material } 생성 완료|.
ENDIF.
핵심 포인트:
RETURN(단일) +RETURNMESSAGES(TABLES) 두 가지 메시지 — 둘 다 확인BAPI_TRANSACTION_COMMIT안 부르면 DB 반영 안 됨wait = 'X'동기 커밋 권장 (이어지는 코드가 자재 즉시 조회 가능)
흔히 빠뜨리는 함정
CLIENTDATAX 'X' 마크 누락
" ❌ 값만 채우고 X-구조체 안 채움
ls_clientdata-matl_group = '001'.
" ls_clientdatax-matl_group = abap_true. 누락
BAPI 가 "변경 의도 없음" 으로 해석해 그 필드를 무시. 자재는 생성되지만 자재그룹이 비어 있는 사고. 값 채우는 줄과 X 마크 줄을 한 쌍으로 관리.
BAPI_TRANSACTION_COMMIT 누락
CALL FUNCTION 'BAPI_MATERIAL_SAVEDATA' ...
" ❌ COMMIT 안 부름 → DB 반영 X
SELECT SINGLE * FROM mara WHERE matnr = lv_matnr ... " 결과 없음
BAPI 자체는 DB 직접 안 씀. BAPI_TRANSACTION_COMMIT 호출 필수.
자재유형(MTART) 누락
ls_headdata-material = 'TEST-MAT-001'.
" ❌ matl_type 누락 → BAPI 에러
MATL_TYPE·IND_SECTOR 는 자재 생성 시 필수. 변경(이미 있는 자재) 시는 생략 가능하지만 신규는 필수.
뷰 플래그 안 켜고 데이터만 채움
ls_headdata-mrp_view = abap_false. " ❌ MRP 뷰 안 만듦
ls_plantdata-mrp_type = 'X0'. " 그런데 MRP 데이터는 채움
뷰 플래그가 꺼져 있으면 해당 데이터는 무시됩니다. 데이터를 채우면 그 뷰의 플래그도 같이 켜기.
LANGU_ISO 누락
APPEND VALUE #(
langu = sy-langu
matl_desc = '테스트' )
TO lt_makt.
" ❌ langu_iso 누락 → BAPI 가 거부
자재내역(BAPI_MAKT) 은 LANGU(1자리 SAP 코드) + LANGU_ISO(2자리 ISO) 둘 다 필수. 변환은 CL_I18N_LANGUAGES.
EXTENSIONIN IMG 매핑 누락
자사 확장 필드(BAPI_TE_MARA)를 코드로 넘겨도 SAP IMG 에 BAPI 매핑 + BAdI 구현 등록이 안 되어 있으면 BAPI 가 받기만 하고 자재마스터에 반영 안 합니다. 운영팀과 사전 셋업 확인 필수.
RETURNMESSAGES 무시
IF ls_return-type = 'E'.
" ❌ lt_returnmessages 안 보고 단일 RETURN 만 확인
ENDIF.
RETURN 은 마지막 한 줄만 담고, RETURNMESSAGES 가 전체 메시지. 부분 실패(예: 자재는 생성됐는데 특정 뷰 일부만 실패) 같은 케이스는 RETURNMESSAGES 봐야 정확한 진단.
동일 키 재호출 시 에러 처리
" 자재가 이미 존재하는데 신규 생성 의도로 같은 키 호출
" → BAPI 가 변경 모드로 처리 (생성 안 함)
" → RETURN 은 성공이지만 데이터 갱신만 됨
BAPI_MATERIAL_SAVEDATA 는 자재 존재 여부에 따라 자동으로 생성/변경을 결정. 의도적으로 "존재하면 실패" 가 필요하면 호출 전 SELECT SINGLE FROM mara 로 존재 확인.
전체 코드 — 복사용 통합본
신규 자재 ROH(원료) 한 건을 6개 뷰로 생성하는 전체 예제. 노트의 패턴 그대로 + 마스킹.
REPORT zr_bapi_material_savedata_demo.
TYPES: ty_makt TYPE TABLE OF bapi_makt WITH DEFAULT KEY,
ty_extin TYPE TABLE OF bapiparex WITH DEFAULT KEY,
ty_extinx TYPE TABLE OF bapiparexx WITH DEFAULT KEY.
DATA: ls_return TYPE bapiret2,
lt_returnmessages TYPE TABLE OF bapi_matreturn2.
* === HEADDATA: 자재 키 + 뷰 플래그 ===
DATA(ls_headdata) = VALUE bapimathead(
material = 'TEST-MAT-001'
ind_sector = 'M'
matl_type = 'ROH'
basic_view = abap_true
purchase_view = abap_true
mrp_view = abap_true
account_view = abap_true
storage_view = abap_true
cost_view = abap_true ).
* === CLIENTDATA: 기본 뷰 ===
DATA(ls_clientdata) = VALUE bapi_mara(
matl_group = '001'
base_uom = 'KG'
division = '10'
prod_hier = 'W'
item_cat = 'NORM'
batch_mgmt = abap_true
po_unit = 'MT'
net_weight = '1'
unit_of_wt = 'KG' ).
DATA(ls_clientdatax) = VALUE bapi_marax(
matl_group = abap_true
base_uom = abap_true
division = abap_true
prod_hier = abap_true
item_cat = abap_true
batch_mgmt = abap_true
po_unit = abap_true
net_weight = abap_true
unit_of_wt = abap_true ).
* === PLANTDATA: 플랜트 (MRP 1~4) ===
DATA(ls_plantdata) = VALUE bapi_marc(
plant = '0001'
mrp_type = 'X0'
availcheck = '02'
mrp_ctrler = '200'
sm_key = '000'
lotsizekey = 'WB'
profit_ctr = 'P100' ).
DATA(ls_plantdatax) = VALUE bapi_marcx(
plant = '0001'
mrp_type = abap_true
availcheck = abap_true
mrp_ctrler = abap_true
sm_key = abap_true
lotsizekey = abap_true
profit_ctr = abap_true ).
* === VALUATIONDATA: 회계 뷰 ===
DATA(ls_valuationdata) = VALUE bapi_mbew(
val_area = '0001'
val_class = '3000' ).
DATA(ls_valuationdatax) = VALUE bapi_mbewx(
val_area = '0001'
val_class = abap_true ).
* === STORAGELOCATIONDATA: 저장위치 ===
DATA(ls_storagelocationdata) = VALUE bapi_mard(
plant = '0001'
stge_loc = '0001' ).
DATA(ls_storagelocationdatax) = VALUE bapi_mardx(
plant = '0001'
stge_loc = '0001' ).
* === MATERIALDESCRIPTION: 자재 내역 (TABLES) ===
DATA(lt_makt) = VALUE ty_makt(
( langu = sy-langu
langu_iso = cl_i18n_languages=>sap1_to_sap2( im_lang_sap1 = sy-langu )
matl_desc = '테스트 자재 - 원료' )
( langu = 'E'
langu_iso = 'EN'
matl_desc = 'Test Material - Raw' ) ).
* === EXTENSIONIN: 자사 확장 필드 (선택) ===
DATA(ls_teitem) = VALUE bapi_te_mara(
material = 'TEST-MAT-001'
zgubun = 'D' ).
DATA(ls_teitemx) = VALUE bapi_te_marax(
material = 'TEST-MAT-001'
zgubun = abap_true ).
DATA(lt_extensionin) = VALUE ty_extin(
( structure = 'BAPI_TE_MARA' valuepart1 = ls_teitem ) ).
DATA(lt_extensioninx) = VALUE ty_extinx(
( structure = 'BAPI_TE_MARAX' valuepart1 = ls_teitemx ) ).
* === BAPI 호출 ===
CALL FUNCTION 'BAPI_MATERIAL_SAVEDATA'
EXPORTING
headdata = ls_headdata
clientdata = ls_clientdata
clientdatax = ls_clientdatax
plantdata = ls_plantdata
plantdatax = ls_plantdatax
valuationdata = ls_valuationdata
valuationdatax = ls_valuationdatax
storagelocationdata = ls_storagelocationdata
storagelocationdatax = ls_storagelocationdatax
IMPORTING
return = ls_return
TABLES
materialdescription = lt_makt
returnmessages = lt_returnmessages
extensionin = lt_extensionin
extensioninx = lt_extensioninx.
* === 상세 메시지 출력 ===
LOOP AT lt_returnmessages ASSIGNING FIELD-SYMBOL(<m>).
WRITE: / |[{ <m>-type }] { <m>-id }-{ <m>-number } { <m>-message }|.
ENDLOOP.
* === COMMIT / ROLLBACK ===
IF ls_return-type = 'E' OR ls_return-type = 'A'.
CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
WRITE: /, / |❌ 자재 생성 실패: { ls_return-message }|.
ELSE.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT' EXPORTING wait = 'X'.
WRITE: /, / |✅ 자재 { ls_headdata-material } 생성 완료|.
ENDIF.
이 미니 리포트를 SE38 에 그대로 붙여 실행하면 자재번호 + 6개 뷰 + 한글/영문 자재내역 + 자사 확장 필드까지 한 번에 생성됩니다. 자사 환경의 자재그룹·평가클래스·플랜트·MRP 컨트롤러 코드만 사내 표준값으로 교체.
요약
| 단계 | 파라미터 | 핵심 |
|---|---|---|
| 1 | HEADDATA | 자재키 + 6개 뷰 플래그 (BASIC/PURCHASE/MRP/ACCOUNT/STORAGE/COST) |
| 2 | CLIENTDATA + X | 기본 뷰 — 자재그룹·단위·중량 |
| 3 | PLANTDATA + X | MRP 유형·로트사이즈·손익센터 |
| 4 | VALUATIONDATA + X | 평가클래스·평가영역 |
| 5 | STORAGELOCATIONDATA + X | 플랜트 + 저장위치 키 |
| 6 | MATERIALDESCRIPTION | 언어별 자재내역 (LANGU + LANGU_ISO) |
| 7 | EXTENSIONIN + X | 자사 확장 필드 (BAPI_TE_MARA / IMG 매핑 필요) |
| 8 | COMMIT | BAPI_TRANSACTION_COMMIT 명시 호출 (wait = 'X') |
BAPI_MATERIAL_SAVEDATA 의 핵심은 "데이터 구조체 + X-구조체 한 쌍" 패턴이 모든 뷰에 동일하게 적용된다는 점입니다. 첫 호출은 부담스럽지만 한 번 패턴을 잡으면 자재유형별·플랜트별 변형을 쉽게 만들 수 있고, 외부 시스템에서 받은 자재 정보를 자동 동기화하는 인터페이스에 그대로 재사용 가능합니다. 자재유형 누락·X-마크 누락·BAPI_TRANSACTION_COMMIT 누락 세 가지 함정만 피하면 안정적으로 동작하며, 자사 확장 필드(EXTENSIONIN) 는 코드 외에 IMG 매핑이 같이 가야 작동한다는 점만 기억하면 됩니다.
Disclaimer — 이 포스트는 실무 정리 노트를 바탕으로 AI 보조로 정리되었습니다.
BAPI_MATERIAL_SAVEDATA 는 SAP MM 표준 BAPI(Function Group 1001UEB, Package MGA) 로 ECC 6.0 / S/4HANA on-premise 환경에서 동일하게 동작합니다.
HEADDATA(BAPIMATHEAD) 의 view 플래그(BASIC_VIEW · PURCHASE_VIEW · MRP_VIEW · ACCOUNT_VIEW · STORAGE_VIEW · COST_VIEW · SALES_VIEW) 가 어떤 뷰를 생성/변경할지 결정하며, 데이터 구조체(BAPI_MARA · BAPI_MARC · BAPI_MBEW · BAPI_MARD 등) 의 변경 의도는 항상 대응되는 X-구조체(BAPI_MARAX · BAPI_MARCX 등) 의 같은 필드에 'X' 마크로 표현되어야 합니다.
BAPI 호출 후 BAPI_TRANSACTION_COMMIT 을 명시적으로 호출해야 DB 에 반영되며, 자사 확장 필드(BAPI_TE_MARA 등) 를 EXTENSIONIN 으로 전달할 경우 SAP IMG 의 BAPI 매핑 등록 + BAdI 구현이 사전에 되어 있어야 데이터가 실제로 자재마스터에 반영됩니다. 본문의 자재번호·플랜트·평가클래스·MRP 컨트롤러 등은 회사 정책에 따라 다르므로 사내 표준값으로 교체하여 사용하시기 바랍니다.