이 글이 답하는 질문
월말 결산 때마다 GR/IR(입고미청구) 계정에 잔액이 남아 있어서 "이거 왜 안 지워졌지?"를 반복하고 있다면, 이 글이 그 원인을 구조적으로 짚어드립니다. 입고(GR)와 송장(IR)이 짝을 이루지 못하는 순간 잔액이 생기는데, 그 패턴은 생각보다 몇 가지로 정리됩니다. 이 글을 끝까지 읽으면 아래 항목에 스스로 답할 수 있습니다.
- GR/IR 계정이 왜 존재하고, WRX 거래키가 어디서 개입하는지 설명할 수 있다
- 잔액이 남는 대표 원인 4가지를 구분하고, 각각 어느 화면(MB5S, ME2N, EKBE)에서 확인하는지 안다
- ABAP으로 GR/IR 미결 잔액과 입고-송장 수량 차이를 직접 조회할 수 있다
- MR11로 정리해도 되는 건과 절대 지우면 안 되는 건을 구분할 수 있다
미리 깔고 가는 배경 지식
구매오더(PO) 생성 → 입고(MIGO) → 송장검증(MIRO)으로 이어지는 구매 프로세스의 기본 흐름을 알고 있다는 전제로 씁니다. 차변/대변 개념과 자동 계정결정(OBYC)이 무엇인지 대략 알면 충분하고, FI 결산 실무 경험까지는 필요 없습니다. ABAP 예제는 7.50 이상 문법(인라인 선언, SELECT 내 CASE)을 사용하므로 기초 문법을 읽을 수 있으면 됩니다.
테스트 환경
이 글의 예제는 다음 가상 환경을 기준으로 작성했습니다.
- 시스템: SAP S/4HANA 2023 On-Premise (ABAP Platform 7.5x 이상 문법 사용, ECC 6.0에서도 개념은 동일)
- 가상 회사: 전자부품 제조사 "한빛전자" — 회사코드
1200, 플랜트1201 - 자재: 적층세라믹콘덴서
HB-CAP-0031, 이동평균가 관리 - 공급업체:
100047동아케미칼, 구매오더4500017842 - GR/IR 계정:
2191000(정렬 키 014 = 구매문서 설정 가정) - 사용 트랜잭션: MIGO, MIRO, MB5S, ME2N, MR11, MR11SHOW, F.19, SE38
S/4HANA 관점 한 줄: S/4HANA에서는 자재문서가 MATDOC 테이블에 통합 저장되고 MSEG/MKPF는 호환 뷰로 제공되지만, 이 글에서 다루는 EKBE·BSIS 기반 조회 로직은 그대로 동작합니다(BSIS도 ACDOCA 기반 호환 뷰).
핵심 개념 — GR/IR 계정은 '환승 정거장'이다
택배를 받으면 인수증에 서명하고, 청구서는 며칠 뒤에 날아옵니다. 회사도 똑같습니다. 물건이 창고에 들어오는 시점(입고)과 공급업체가 대금을 청구하는 시점(송장)은 거의 항상 어긋납니다. 이 시차를 회계적으로 버텨주는 임시 계정이 바로 GR/IR(Goods Receipt/Invoice Receipt) 계정입니다. 입고와 송장이라는 두 열차가 만나서 서로를 상쇄하고 떠나는 환승 정거장이라고 보면 됩니다.
전기 구조는 이렇습니다. 한빛전자가 HB-CAP-0031 1,000개를 100만 원에 입고하면:
| 시점 | 차변 | 대변 |
| 입고(MIGO, 이동유형 101) | 재고 계정 100만 | GR/IR 계정 100만 |
| 송장검증(MIRO) | GR/IR 계정 100만 | 공급업체(AP) 100만 |
이때 GR/IR 계정이 어느 G/L 계정인지는 사람이 고르는 게 아니라 자동 계정결정이 정합니다. OBYC의 거래키 WRX가 평가그룹핑 코드·평가클래스 조합으로 GR/IR 계정을 결정합니다. 즉 "GR/IR 잔액 분석"은 곧 "WRX로 결정된 계정의 미결 항목 분석"입니다.
입고 시 대변 100만, 송장 시 차변 100만 — 짝이 맞으면 잔액은 0이 되고 미결 항목이 반제됩니다. 잔액이 남는다는 것은 이 짝이 깨졌다는 뜻이고, 깨지는 패턴은 크게 네 가지입니다.
- 입고만 되고 송장 미도착 — 대변 잔액이 남음. 가장 흔한 경우로, 공급업체 청구 지연이 대부분
- 송장만 오고 입고 미처리 — 차변 잔액이 남음. 운송 중(미착품)인데 송장이 먼저 도착했거나, 창고에서 입고 전기를 누락한 경우
- 수량·금액 부분 차이 — 1,000개 입고했는데 송장은 980개만 청구, 분할납품·부분송장이 얽히면 잔액이 조각으로 남음
- 반품·취소 미반영 — 102/122 이동유형으로 반품했는데 대변메모(Credit Memo)를 못 받았거나, 송장 취소 후 재입력이 누락된 경우
중요한 것은 GR/IR 잔액이 "오류"가 아니라 프로세스 시차의 자연스러운 결과라는 점입니다. 문제는 시차가 아니라 영원히 짝을 못 찾는 잔액이고, 월말 정리는 그 둘을 구분하는 작업입니다.
직접 해보기 — 조회에서 대사까지 3단계
1단계: 표준 화면으로 현황 파악
가장 먼저 볼 화면은 MB5S(GR/IR 잔액 리스트)입니다. 구매오더 항목 단위로 입고수량·송장수량·차이를 보여주므로 "어느 PO의 어느 항목에서 짝이 깨졌는지"가 바로 드러납니다. 회사코드 1200으로 실행하면 4500017842/00010에 입고 1,000 / 송장 0 같은 행이 보입니다. 보조로 ME2N에서 선택 파라미터 RECHNUNG(송장 미결) 또는 WE101(입고 미결)을 지정하면 원인 1·2번 후보를 구매 관점에서 걸러낼 수 있습니다. 개별 건의 타임라인은 EKBE(구매오더 이력) 테이블에서 VGABE = '1'(입고), '2'(송장) 레코드를 시간순으로 읽으면 됩니다.
2단계: ABAP으로 GR/IR 미결 잔액 직접 조회
표준 화면은 훌륭하지만, 월말마다 특정 조건(예: 잔액 존재 + 특정 구매그룹)만 뽑아 배포하려면 직접 조회가 편합니다. GR/IR 계정에 정렬 키 014를 걸어두면 미결 항목의 지정(ZUONR) 필드에 구매오더번호+항목이 들어가므로, FI 미결 항목을 PO 단위로 묶을 수 있습니다.
*&---------------------------------------------------------------------*
*& ZHB_GRIR_OPEN : GR/IR 미결 항목을 PO 단위로 집계 (한빛전자 1200)
*& 전제: GR/IR 계정 마스터에 정렬 키 014 → ZUONR = EBELN + EBELP
*&---------------------------------------------------------------------*
REPORT zhb_grir_open.
PARAMETERS: p_bukrs TYPE bukrs DEFAULT '1200',
p_hkont TYPE hkont DEFAULT '0002191000',
p_keydt TYPE budat DEFAULT sy-datum.
TYPES: BEGIN OF ty_bal,
zuonr TYPE dzuonr, " PO번호+항목
saldo TYPE dmbtr, " 부호 반영 잔액
END OF ty_bal.
DATA lt_bal TYPE HASHED TABLE OF ty_bal WITH UNIQUE KEY zuonr.
" 미결 항목은 BSIS(반제되면 BSAS로 이동)에서 조회
SELECT zuonr, shkzg, SUM( dmbtr ) AS dmbtr
FROM bsis
WHERE bukrs = @p_bukrs
AND hkont = @p_hkont
AND budat <= @p_keydt
GROUP BY zuonr, shkzg
INTO TABLE @DATA(lt_open).
LOOP AT lt_open INTO DATA(ls_open).
" 대변(H)은 음수로 뒤집어 순잔액 계산
DATA(lv_amt) = COND dmbtr(
WHEN ls_open-shkzg = 'H' THEN ls_open-dmbtr * -1
ELSE ls_open-dmbtr ).
COLLECT VALUE ty_bal( zuonr = ls_open-zuonr
saldo = lv_amt ) INTO lt_bal.
ENDLOOP.
DELETE lt_bal WHERE saldo = 0. " 짝이 맞은 건 제외
LOOP AT lt_bal INTO DATA(ls_bal).
" saldo < 0 : 대변 잔액 → 입고만 되고 송장 미도착 의심
" saldo > 0 : 차변 잔액 → 송장 선도착·입고 미처리(미착) 의심
WRITE: / ls_bal-zuonr, ls_bal-saldo CURRENCY 'KRW'.
ENDLOOP.
부호만 봐도 원인 1번(대변 잔액)과 2번(차변 잔액)이 갈립니다. 여기서 걸린 PO를 다음 단계에서 수량 관점으로 대사합니다.
3단계: 수량 대사 + 원인 분류 리포트 (프로덕션 수준)
금액 잔액만으로는 부분 차이(원인 3)와 반품 미반영(원인 4)을 구분하기 어렵습니다. EKBE에서 입고·송장 수량을 부호까지 반영해 집계하고, EKPO의 납품완료 지시자(ELIKZ)·최종송장 지시자(EREKZ)와 마지막 이동일을 붙여 원인을 자동 분류합니다. 실무 배포 시에는 권한 체크와 ALV 출력을 더하는 것이 일반적입니다.
*&---------------------------------------------------------------------*
*& ZHB_GRIR_RECON : PO별 입고-송장 수량 대사 및 원인 분류
*&---------------------------------------------------------------------*
REPORT zhb_grir_recon.
TABLES ekko.
SELECT-OPTIONS s_ebeln FOR ekko-ebeln.
PARAMETERS p_aged TYPE i DEFAULT 60. " 경과일 기준
AUTHORITY-CHECK OBJECT 'M_BEST_BSA' ID 'ACTVT' FIELD '03'.
IF sy-subrc <> 0.
MESSAGE '구매문서 조회 권한이 없습니다' TYPE 'E'.
ENDIF.
" 취소/반품(SHKZG='H')은 음수로 차감하여 순수량 집계
SELECT h~ebeln, h~ebelp, p~elikz, p~erekz,
MAX( h~budat ) AS last_budat,
SUM( CASE WHEN h~vgabe = '1' AND h~shkzg = 'S' THEN h~menge
WHEN h~vgabe = '1' AND h~shkzg = 'H' THEN h~menge * -1
ELSE 0 END ) AS gr_menge,
SUM( CASE WHEN h~vgabe = '2' AND h~shkzg = 'S' THEN h~menge
WHEN h~vgabe = '2' AND h~shkzg = 'H' THEN h~menge * -1
ELSE 0 END ) AS ir_menge
FROM ekbe AS h
INNER JOIN ekpo AS p
ON p~ebeln = h~ebeln AND p~ebelp = h~ebelp
WHERE h~ebeln IN @s_ebeln
AND h~vgabe IN ( '1', '2' )
AND p~loekz = @space
GROUP BY h~ebeln, h~ebelp, p~elikz, p~erekz
INTO TABLE @DATA(lt_recon).
LOOP AT lt_recon INTO DATA(ls_r) WHERE gr_menge <> ir_menge.
DATA(lv_diff) = ls_r-gr_menge - ls_r-ir_menge.
DATA(lv_age) = sy-datum - ls_r-last_budat.
DATA(lv_txt) = COND string(
WHEN lv_diff > 0 AND ls_r-erekz = 'X'
THEN |최종송장 완료인데 입고 초과 → 반품/취소 미반영 의심|
WHEN lv_diff > 0 AND lv_age > p_aged
THEN |송장 장기 미도착({ lv_age }일) → 독촉 또는 MR11 후보|
WHEN lv_diff > 0
THEN |송장 대기 중(정상 시차 가능)|
WHEN ls_r-elikz = 'X'
THEN |납품완료인데 송장 초과 → 수량 차이 정산 필요|
ELSE |입고 미처리(미착품) → 창고/운송 확인| ).
WRITE: / ls_r-ebeln, ls_r-ebelp, ls_r-gr_menge,
ls_r-ir_menge, lv_diff, lv_txt.
ENDLOOP.
이 리포트를 배치로 걸어 월말 3영업일 전에 구매·회계 담당자에게 배포하면, 정리 대상이 미리 좁혀져 결산 당일의 MR11 작업이 크게 줄어듭니다. 성능 관점에서는 EKBE 조회에 반드시 PO 범위를 걸고(풀스캔 방지), 대량 대사는 야간 배치로 돌리는 것이 권장됩니다.
정리 절차 요약(월말 루틴): ① MB5S/자체 리포트로 차이 목록 확보 → ② EKBE 이력으로 원인 판독 → ③ 조치 가능한 건 처리(송장 독촉, 입고 전기, 대변메모 수취) → ④ 회수 불가 판정 건만 MR11(계정 유지보수)로 정리 → ⑤ 결산 표시용으로는 F.19 재분류 실행. MR11은 차이 금액을 재고 계정(재고 커버리지가 있으면) 또는 가격차이/소비 계정으로 상대 전기하며 유지보수 전표를 생성합니다. 실수로 지웠다면 MR11SHOW에서 해당 전표를 찾아 취소할 수 있습니다.
삽질 노트 — 자주 막히는 지점
Q1. MB5S 차이 합계와 FI의 GR/IR 계정 잔액이 안 맞습니다.
MB5S는 구매오더 이력(EKBE) 기준, FI 잔액은 회계전표 기준입니다. GR/IR 계정에 수기 전표를 전기했거나, 정렬 키 014 없이 운영해 지정 필드가 비어 있으면 둘이 어긋납니다. GR/IR 계정은 전기 통제(자동전기만 허용)를 걸어 수기 전기를 막는 것이 일반적입니다.
Q2. 송장이 늦는 것뿐인데 MR11로 지워도 되나요?
안 됩니다. MR11 후 송장이 도착하면 차이가 다시 벌어지고 정산이 꼬입니다. MR11 전에 반드시 확인할 것: 납품완료(ELIKZ)·최종송장(EREKZ) 상태, 마지막 이동 후 충분한 경과일(예: 60일 이상), 공급업체에 추가 청구 계획이 없다는 확인. MR11의 "최종 이동일" 선택 조건을 활용해 최근 건이 섞이지 않게 하세요.
Q3. F.19를 돌리면 잔액이 정리되는 건가요?
아닙니다. F.19는 재무제표 표시 목적의 재분류(입고미청구/미착 구분 전기 후 익월 역분개)일 뿐, GR/IR 미결 항목 자체는 그대로 남습니다. 실제 정리는 송장/입고 처리 또는 MR11로만 이뤄집니다.
Q4. MR11 결과가 재고 계정이 아니라 손익으로 갔습니다.
이동평균가 자재라도 현재 재고 수량이 차이 수량보다 적으면(재고 커버리지 부족) 초과분이 가격차이 계정으로 전기됩니다. 표준원가 자재는 항상 가격차이로 갑니다. 오류가 아니라 평가 로직의 결과입니다.
더 파볼 주제
GR/IR 잔액 관리가 손에 익었다면 다음 주제로 확장해 보세요. 첫째, ERS(자동정산, MRRL) — 입고 기준으로 송장을 자동 생성해 원인 1번 자체를 줄이는 접근입니다. 둘째, 계획 배송비의 GR/IR — 운임(FR1 등)도 별도의 정산 계정 구조를 가지므로 같은 분석이 필요합니다. 셋째, S/4HANA의 GR/IR 대사 모니터링 Fiori 앱과 머신러닝 기반 자동 매칭(Situation Handling 연계)도 살펴볼 가치가 있습니다. 마지막으로 OBYC 계정결정 전체 구조(BSX, WRX, PRD, KDM)를 한 번에 정리해 두면 결산 분석이 훨씬 빨라집니다.
함께 보면 좋은 자료
- SAP Help Portal — SAP S/4HANA On-Premise 제품 문서 (MM 송장검증, 계정 유지보수 항목)
- SAP Help Portal — SAP ERP 문서 (Logistics Invoice Verification, GR/IR Clearing)
- SAP Help Portal 검색 — GR/IR Clearing Account Maintenance (MR11)
- SAP Help Portal 검색 — Analyze GR/IR Clearing Accounts (F.19 재분류)
- SAP Community — GR/IR 관련 실무 사례 토론(MM, FI 태그)
- SAP for Me — SAP Note 검색 (MR11·MB5S 관련 노트, 로그인 필요)
핵심 한 줄: GR/IR 잔액은 오류가 아니라 시차의 흔적이다 — 부호로 원인을 가르고, EKBE로 이력을 읽고, 회수 불가 판정이 끝난 건만 MR11로 지운다.
댓글 0
아직 댓글이 없습니다.