SAP 변경이력 조회 — 누가 언제 무엇을 바꿨는지 되짚기
회계전표와 마스터데이터의 필드별 변경 전후 값을 모아, 계좌번호 같은 민감필드와 심야·휴일 변경을 통제 관점에서 걸러내는 감사추적 화면입니다.
감사에서 가장 자주 나오는 질문은 금액이 맞느냐가 아니라 누가 언제 이걸 바꿨느냐입니다. 전표 금액이 수정됐거나, 거래처의 은행 계좌가 바뀌었거나, 지급방법이 조용히 달라졌을 때 그 흔적을 찾아야 합니다.
SAP는 이 흔적을 변경문서로 남깁니다. 다만 표준 화면에서는 대상별로 따로 조회해야 하고, 어떤 변경이 위험한지는 보는 사람이 판단해야 합니다. 표준 변경문서 구조를 그대로 이어받아 전표와 마스터를 한 화면에 모으고, 계좌번호 같은 민감필드와 심야·휴일 변경을 자동으로 표시하도록 OpenUI5 화면으로 확장한 것이 이 앱입니다. 실제 구동 화면 3종을 함께 공개합니다.
SAP 표준 기능을 그대로 이어받은 부분
- 변경문서 구조 — 헤더(
CDHDR)와 항목(CDPOS)의 변경 전/후 값 구조를 그대로 사용 - 대상 구분 — 회계전표 · GL계정 · 매입처 · 매출처 오브젝트 유형을 표준 분류대로 유지
- 변경 주체 — 사용자 ID와 T-code(
BKPF-TCODE)를 함께 남겨 어느 화면에서 바꿨는지 추적 - 회사코드 마스터 —
T001기준으로 회사코드와 명칭 표시
| 항목 | 내용 |
|---|---|
| 대응 T-code | FB04 (변경문서 표시) |
| 업무 영역 | 재무회계(FI) · 내부통제 · 감사추적 |
| Namespace | zui5.changelog |
| 셸 구조 | 조회조건 영역(우측 조회·초기화) + 변경 요약 목록, 행 선택 시 상세 다이얼로그 |
| 화면 수 | 조회 화면 1개 + 변경 항목 상세 |
| 데이터 | 변경 헤더 150건 · 변경 항목 284건 |
| 성격 | 조회형(Read-Only) — 변경문서 생성은 표준이 담당 |
| UI 테마 | sap_horizon 단일 적용 |
실제 화면 3종 둘러보기
회사코드·조회기간·오브젝트유형으로 조회하면 변경 건이 요약으로 모입니다 → 민감필드와 이상시간대 건수를 먼저 확인하고 → 행을 눌러 어떤 필드가 무엇에서 무엇으로 바뀌었는지 되짚습니다.
아래는 실제로 앱을 실행해 기능을 눌러 가며 캡처한 화면입니다. 이미지를 클릭하면 원본 크기로 확대됩니다.
조작 방법
- 회사코드와 조회기간을 넣습니다. 기간은 변경일시 기준이며, 결산 직전 구간을 좁혀 보는 데 주로 씁니다.
- 오브젝트유형으로 회계전표 · GL계정 · 매입처 · 매출처 중 볼 대상을 고릅니다. 비워 두면 전부 봅니다.
- 조회조건 입력필드에서 값을 바꾸거나 Enter 를 누르면 버튼을 누르지 않아도 즉시 조회됩니다.
- 요약 목록에서 민감필드와 이상시간대 건수가 0이 아닌 줄부터 봅니다.
- 행을 선택하면 상세 다이얼로그가 열려 필드별 변경 전/후 값을 확인할 수 있습니다.
- 결과는 CSV 다운로드로 내려받습니다. UTF-8 BOM 이 붙어 엑셀에서 한글이 깨지지 않습니다.
통제 판정 규칙
모든 변경을 똑같이 보면 아무것도 걸러지지 않습니다. 그래서 두 가지 기준으로만 표시를 답니다.
| 구분 | 무엇을 보는가 | 표시 |
|---|---|---|
| 민감필드 | 은행키·계좌번호·지급방법처럼 자금이 나가는 경로를 바꾸는 필드 | 변경 항목에 SensitiveField 표시, 요약에 건수 집계 |
| 이상시간대 | 심야·휴일 등 통상 업무시간이 아닌 때 이뤄진 변경 | 헤더에 OffHoursFlag 표시, 요약에 건수 집계 |
두 기준을 함께 보는 이유
계좌번호가 바뀐 것 자체는 정상 업무일 수 있습니다. 문제는 그것이 금요일 밤 11시에 바뀌었을 때입니다. 둘 중 하나만 보면 정상 변경까지 전부 걸려 확인 대상이 너무 많아지고, 둘 다 겹치는 건을 먼저 보면 실제로 물어볼 건이 손에 꼽힙니다. 그래서 요약에서 두 건수를 나란히 두었습니다.
추적 대상 4종
한 화면에서 전표와 마스터를 함께 봅니다. 사고는 대개 마스터를 바꾼 뒤 전표를 넣는 순서로 일어나기 때문입니다.
| 오브젝트 유형 | 무엇이 바뀌는가 | 주요 변경 경로 |
|---|---|---|
| 회계전표 | 금액·전기일·적요 등 전표 필드 수정 | FB02 |
| GL계정 마스터 | 계정 속성 변경 | FS00 |
| 매입처 마스터 | 은행키·계좌번호·지급방법 등 | FK02 · XK02 |
| 매출처 마스터 | 고객 결제조건·은행 정보 등 | FD02 · XD02 |
조회조건
| 필드 | 필수 | 설명 |
|---|---|---|
회사코드 Bukrs | 보조 필터 | 대상 회사코드. 비우면 전체 |
| 조회기간 | 필수 | 변경일시 기준 From~To |
| 오브젝트유형 | 보조 필터 | 회계전표 / GL계정 / 매입처 / 매출처 |
결과 컬럼
변경 요약
| 컬럼 | 의미 · 표시 |
|---|---|
오브젝트유형 ObjectTypeText | 전표·GL계정·매입처·매출처 구분 |
건수 Count | 해당 유형의 변경 건수 |
민감필드 SensitiveCount | 민감필드가 걸린 변경 건수. 0이 아니면 상태 색 표시 |
이상시간대 OffHoursCount | 업무시간 외 변경 건수 |
최근 변경일시 ChangedAt | 가장 최근에 바뀐 시각 |
변경 항목 상세
| 항목 | 내용 |
|---|---|
테이블 TableName | 변경이 일어난 표준 테이블 (예: LFA1) |
필드 FieldName · FieldText | 필드 기술명과 한글 명칭 |
변경 전 OldValue | 바뀌기 전 값 |
변경 후 NewValue | 바뀐 뒤 값 |
민감필드 SensitiveField | 민감필드 여부 표시 |
| 변경자 · 변경일시 · T-code | 누가 언제 어느 화면에서 바꿨는지 |
SAP 표준 기능 매핑
변경문서는 표준이 자동으로 남깁니다. 이 화면은 그 기록을 읽어 통제 관점으로 재구성할 뿐, 아무것도 쓰지 않습니다.
| 표준 | 역할 | 이 화면에서의 확장 |
|---|---|---|
CDHDR | 변경문서 헤더 — 오브젝트·변경자·변경일시·T-code | 오브젝트 유형별 요약으로 묶고 이상시간대 판정을 얹음 |
CDPOS | 변경문서 항목 — 테이블·필드·변경 전/후 값 | 민감필드 표시를 붙여 상세 다이얼로그에 표시 |
BKPF | 전표 헤더 — T-code·작성자 | 어느 화면에서 바꿨는지 추적 |
T001 | 회사코드 마스터 | 회사코드와 명칭 표시 |
FB04 | 표준 변경문서 표시 | 전표·마스터를 한 화면에 모으고 통제 신호를 더함 |
도입 시 확인이 필요한 부분
민감필드 목록과 업무시간 기준은 회사마다 다릅니다. 지급방법을 민감필드로 볼지, 토요일 오전을 업무시간으로 볼지는 내부통제 기준에 따라 정해야 합니다. 또 변경문서는 필드 단위로 기록 여부가 설정되므로, 보고 싶은 필드가 실제로 기록되고 있는지 데이터 요소 설정을 함께 확인해야 합니다.
참고 CDS 뷰
운영 서비스로 연결할 때는 변경문서 헤더와 항목을 묶고 회사코드 명칭을 붙인 뷰로 서빙하는 구성을 제안합니다.
@AbapCatalog.sqlViewName: 'ZCCHANGELOG'
@EndUserText.label: '변경이력 조회 (Z)'
define view Z_C_CHANGE_LOG
as select from cdhdr as Header
inner join cdpos as Item on Header.objectclas = Item.objectclas
and Header.objectid = Item.objectid
and Header.changenr = Item.changenr
left outer join t001 as Comp on Header.mandant = Comp.mandt
{
key Header.changenr,
key Item.tabname,
key Item.fname,
Header.objectclas as ObjectType,
Header.objectid as ObjectKey,
Header.username as ChangedBy,
Header.udate as ChangedDate,
Header.utime as ChangedTime,
Header.tcode as Tcode,
Item.value_old as OldValue,
Item.value_new as NewValue,
Comp.butxt as BukrsText
// 민감필드 여부와 이상시간대 판정은 소비 뷰에서
// 회사 기준 테이블(필드 목록·업무시간)과 조인해 계산
}
매핑 이해를 돕기 위한 참고용 설계입니다. 실제 도입 시에는 운영 환경의 변경문서 오브젝트 구성에 맞춰 조정합니다.
OpenUI5 구성
| 기능 | 사용 컨트롤 |
|---|---|
| 화면 골격 | sap.f.DynamicPage + 조회조건 영역 · 요약 테이블 |
| 조회조건 | sap.m.Select · sap.m.DatePicker — 우측 끝에 조회·초기화 |
| 요약 목록 | sap.m.Table — 유형별 집계, 위험 건수는 ObjectStatus 색으로 |
| 상세 화면 | sap.m.Dialog — 필드별 변경 전/후 |
| 안내 메시지 | sap.m.MessageStrip — 조회 전 안내와 조건 오류 |
| 이벤트 | 모든 버튼이 onPAI 단일 진입점, fcCode 로 분기 |
건수를 먼저 보여 주는 이유
변경이력은 열면 수백 줄입니다. 전부 나열하면 읽히지 않습니다. 유형별로 접어 건수만 먼저 보이게 하면 "이번 달 매입처 마스터에서 민감필드 3건" 처럼 확인할 대상이 문장 하나로 줄어듭니다. 상세는 그다음에 펼칩니다.
파일 구성
| 경로 | 역할 |
|---|---|
manifest.json | 앱 디스크립터 — 앱 ID(zui5.changelog) · ko 로케일 · sap_horizon |
view/Main.view.xml | 조회 화면 |
view/fragments/MainSearch.fragment.xml | 조회조건 폼과 우측 조회·초기화 |
view/fragments/MainTable.fragment.xml | 변경 요약 테이블 |
view/fragments/DetailDialog.fragment.xml | 필드별 변경 전/후 상세 |
controller/Main.controller.js | 조회 · 집계 · 통제 판정 · CSV |
js/formatter.js | 일시 · 상태 색 · 민감필드 표시 포맷터 |
localdata/changehdr.json | 변경 헤더 150건 (14개 필드) |
localdata/changeitem.json | 변경 항목 284건 (7개 필드) |
운영 전환 시에는 ModelMock 내부만 실제 서비스 호출로 바꾸면 화면 로직은 그대로 씁니다.
검증 결과
| 검증 항목 | 결과 |
|---|---|
| XML 전체 파싱 — View · Fragment | 오류 0건 |
| JSON 전체 파싱 — manifest + localdata | 오류 0건 |
| manifest 참조 무결성 — rootView · bundleName · controllerName | 전건 일치 |
| i18n 키 누락 대조 | 누락 0건 |
| 변경 항목이 헤더의 FieldCount 와 일치 | 통과 |
| 민감필드·이상시간대 집계 = 항목 재계산값 | 통과 |
| 화면 렌더링 — 실브라우저 조회 → 상세 실동작 후 캡처 | 3/3 |
| 테마 런타임 확인 | sap_horizon |
회사코드·거래처·변경자는 모두 검증용 데이터입니다.
자주 묻는 질문
민감필드는 어떻게 정하나요?
자금이 나가는 경로를 바꾸는 필드를 기준으로 봅니다. 은행키·계좌번호·지급방법이 대표적입니다. 목록은 회사 내부통제 기준에 따라 달라지므로 설정으로 관리하고, 앱은 그 목록에 걸린 항목만 표시합니다.
이상시간대는 몇 시부터인가요?
통상 업무시간 밖을 뜻하며 심야와 휴일이 여기 들어갑니다. 기준 시각과 휴일 달력은 회사마다 다르므로 도입 시 정하고, 판정은 변경일시를 그 기준에 대조해 자동으로 붙입니다.
전표 변경도 이력이 남나요?
남습니다. 다만 전기된 전표는 금액과 계정을 바꿀 수 없고, 적요·지정 같은 일부 필드만 수정할 수 있습니다. 그 수정이 변경문서로 기록되며 이 화면에서 회계전표 유형으로 조회됩니다.
SAP 표준 기능과 어떻게 이어지나요?
변경문서 생성은 표준이 자동으로 합니다. FB04 로 하나씩 열어 보던 것을 전표와 마스터를 한 화면에 모으고, 민감필드·이상시간대라는 통제 관점을 얹어 확인할 대상을 좁혀 주는 것이 이 화면의 역할입니다.