Record to Report - 분개 데이터 템플릿
Record to Report - 분개 데이터 템플릿
- 심층 분석에 권장되는 속성
- 추적해야 할 주요 분개 활동
- SAP ECC 데이터 추출 실무 안내
Record to Report - 분개 속성
| 이름 | 설명 | ||
|---|---|---|---|
| 분개 ID JournalEntryId | 회사 코드, 문서 번호, 회계연도를 조합해 재무 회계 문서를 고유하게 식별하는 값입니다. | ||
| 설명 분개 ID는 분개의 전체 생애주기를 추적하는 기본 케이스 식별자입니다. 일반적으로 회사 코드(BUKRS), 문서 번호(BELNR), 회계연도(GJAHR)를 연결해 구성하는 복합 키로, SAP 시스템 전체에서 고유한 값을 보장합니다. 프로세스 분석에서는 이 ID를 사용해 생성, 임시 저장, 제출, 승인, 반려, 전기 등 관련 활동을 연결합니다. ID를 따라가면 각 분개의 전체 처리 과정을 구성하고, 처리 시간을 측정하며, 특정 분개의 프로세스 편차나 병목을 찾을 수 있습니다. 중요한 이유 분개 생성부터 최종 전기까지 추적하는 데 필요한 식별자로, 프로세스 전체 분석과 변형 비교를 가능하게 합니다. 확보 방법 일반적으로 BKPF 테이블의 회사 코드(BUKRS), 문서 번호(BELNR), 회계연도(GJAHR) 필드를 연결해 산출하는 속성입니다. 예시 1000-1000000123-20232000-1900000456-20231000-1800000789-2024 | |||
| 이벤트 시각 EventTime | 분개와 관련된 특정 활동이나 이벤트가 발생한 시각입니다. | ||
| 설명 이벤트 시각은 분개 프로세스의 각 활동이 발생한 날짜와 시간을 정확하게 나타냅니다. 처리 시간, 처리 소요 시간, 단계 간 지연 등 시간 기반 지표를 계산하는 데 중요합니다. 시각의 원천은 활동에 따라 다르며, 문서 생성 날짜와 시간(CPUDT/CPUTM) 또는 로그의 변경 시각(CDHDR-UDATE/UTIME)을 사용할 수 있습니다. 분석에서는 이벤트 시각을 기준으로 이벤트를 시간순으로 정렬해 프로세스 맵을 구성합니다. 평균 분개 처리 시간, 평균 승인 시간, 승인부터 전기까지 걸린 시간 등 시간 관련 KPI를 계산하는 데 필수적입니다. 중요한 이유 시간 기반 분석의 토대가 되는 시각으로, 처리 시간과 소요 시간, 병목을 계산할 수 있습니다. 확보 방법 활동에 따라 여러 필드에서 가져오며, 주로 BKPF의 생성 시각(CPUDT, CPUTM)이나 CDHDR의 변경 문서 시각(UDATE, UTIME)을 사용합니다. 예시 2023-10-26T09:00:00Z2023-10-26T14:30:15Z2023-10-27T11:05:00Z | |||
| 활동명 ActivityName | 분개 프로세스의 특정 시점에 발생한 업무 활동 또는 이벤트의 이름입니다. | ||
| 설명 활동명은 '분개 생성', '분개 승인', '분개 전기'와 같이 분개 생애주기의 특정 단계를 나타냅니다. 일반적으로 SAP의 여러 데이터 원천에서 가져오며, 트랜잭션 코드(TCODE), 변경 문서 로그(CDHDR 및 CDPOS 테이블), 문서 상태 필드 등이 포함됩니다. 활동 분석은 process mining의 핵심입니다. 이를 통해 프로세스 맵을 시각화하고 단계 간 처리 시간을 계산하며, '분개 반려' 후 '분개 수정'과 같은 재작업 반복을 찾을 수 있습니다. 이 데이터는 처리 시간, 재작업률, 프로세스 변형을 보여주는 대시보드의 기반이 됩니다. 중요한 이유 프로세스 맵의 단계를 정의해 분개 워크플로를 시각화하고 분석하며 최적화할 수 있도록 합니다. 확보 방법 BKPF의 트랜잭션 코드(TCODE), 문서 상태, SWW_WI2OBJ와 같은 테이블의 워크플로 로그, CDHDR 및 CDPOS의 변경 문서 등 여러 원천에서 가져옵니다. 예시 분개 생성분개 승인분개 최종 반려분개 전기 | |||
| 원천 시스템 SourceSystem | 프로세스 데이터를 추출한 시스템입니다. | ||
| 설명 이 속성은 데이터의 출처를 나타내며, 여기서는 특정 SAP ECC 인스턴스를 의미합니다. 일반적으로 데이터 추출 과정에서 고정값으로 추가됩니다. 단순한 속성이지만 ERP나 데이터 원천이 여러 개인 환경에서는 중요합니다. 데이터 계보를 명확히 하고 원천 시스템별로 분석을 필터링하거나 구분할 수 있습니다. 중요한 이유 데이터 계보를 명확히 하며, 특히 원천 시스템이 여러 개인 환경에서 데이터 품질을 추적하는 데 필요합니다. 확보 방법 일반적으로 데이터 변환 과정에서 추가되는 고정값으로, 특정 SAP ECC 인스턴스(예: 'ECC_PROD_100')를 식별합니다. 예시 SAP ECC EHP8ECC_FIN_PRODSAP_ERP_60 | |||
| 최종 데이터 갱신 시각 LastDataUpdate | 원천 시스템에서 데이터를 마지막으로 추출하거나 갱신한 시각입니다. | ||
| 설명 이 속성은 SAP ECC에서 데이터를 가장 최근에 가져온 날짜와 시간을 기록합니다. 분석 대상 데이터가 최신인지 파악하는 데 중요한 메타데이터 필드입니다. process mining 대시보드나 분석에서는 마지막 갱신 시각을 알아야 사용자가 데이터를 신뢰하고 근거에 기반해 의사결정을 내릴 수 있습니다. '이 정보는 얼마나 최신인가요?'라는 질문에 답하는 데 도움이 됩니다. 중요한 이유 데이터의 최신 상태를 알려 분석 대상 기간을 명확히 하고 결과에 대한 신뢰를 높입니다. 확보 방법 데이터 갱신 시 데이터 추출 도구나 ETL 프로세스가 생성하고 저장하는 메타데이터 필드입니다. 예시 2024-05-20T04:00:00Z2024-05-21T04:00:00Z2024-05-22T04:00:00Z | |||
| 문서 유형 DocumentType | 회계 문서의 처리 방식과 저장 방식을 결정하는 분류입니다. | ||
| 설명 문서 유형은 총계정원장 전표(SA), 공급업체 송장(KR), 자산 전기(AA) 등 다양한 업무 거래를 구분합니다. 시스템 설정에서 정의하며 각 분개에 지정됩니다. 거래의 성격에 따라 프로세스를 구분할 수 있어 분석에 중요한 속성입니다. '유형별 분개 처리량' 대시보드와 '분개 유형별 평균 처리 시간' KPI는 이 필드를 직접 사용합니다. 특정 유형의 분개에서 지연, 재작업, 역분개가 더 자주 발생하는지 파악하는 데 도움이 됩니다. 중요한 이유 거래 유형별로 분석을 구분해 특정 분개 유형에서만 프로세스 문제가 발생하는지 확인할 수 있습니다. 확보 방법 문서 헤더 테이블 BKPF의 BLART 필드에 있습니다. 예시 SAKRREAA | |||
| 사용자 User | 분개를 생성하거나 변경한 사람의 SAP 사용자 ID입니다. | ||
| 설명 이 속성은 문서 생성, 임시 저장, 전기 등 특정 활동을 수행한 SAP 사용자를 기록합니다. 문서 헤더나 변경 로그 테이블에서 직접 가져옵니다. 사용자 속성을 분석하면 팀과 개인의 업무 성과를 파악할 수 있습니다. 사용자별 활동량과 처리 시간을 추적해 사용자 생산성 대시보드를 구성할 수 있습니다. 또한 재작업 반복, 역분개, 규정 준수 편차에 관여한 사용자를 찾아 맞춤형 교육이나 프로세스 개선을 추진하는 데 도움이 됩니다. 중요한 이유 각 활동의 담당 사용자를 식별해 사용자별 성과, 업무량 분포, 재작업 패턴을 분석할 수 있습니다. 확보 방법 일반적으로 BKPF 테이블(작성자는 USNAM 필드) 또는 CDHDR 테이블(변경자는 USERNAME 필드)에서 가져옵니다. 예시 ABROWNCJONESDSMITH | |||
| 역분개 여부 IsReversed | 분개가 역분개되었는지를 나타내는 불리언 값입니다. | ||
| 설명 이 플래그는 다른 회계 문서에 의해 나중에 취소된 분개를 식별합니다. SAP에서는 취소된 문서가 취소 문서와 연결되어 명확한 감사 추적을 제공합니다. 이 속성은 '분개 취소 분석' 대시보드와 '분개 취소율' KPI에 필수적입니다. 취소된 분개만 따로 분석해 데이터 입력 오류나 잘못된 회계 처리와 같은 근본 원인을 조사하고, 취소 발생을 줄이는 데 활용할 수 있습니다. 중요한 이유 나중에 취소된 분개를 표시해 취소 분석을 지원합니다. 오류의 근본 원인을 파악하고 데이터 무결성을 높이는 데 도움이 됩니다. 확보 방법 BKPF 테이블의 취소 문서 번호 필드(STBLG)에서 가져옵니다. STBLG가 비어 있지 않으면 플래그는 true입니다. 예시 truefalse | |||
| 전기일 PostingDate | 거래가 총계정원장에 기록되어 재무 기간에 반영되는 날짜입니다. | ||
| 설명 전기일은 분개가 반영되는 회계 기간을 결정합니다. 회계 기간 마감 일정과 규정을 따라야 하므로 재무와 규정 준수 측면에서 중요한 날짜 필드입니다. process mining에서는 이 날짜를 사용해 규정 준수 여부를 모니터링합니다. '규정 준수 모니터링' 대시보드와 '규정 준수율' KPI는 이 속성을 사용해 분개가 올바른 기간에 전기되었는지 확인합니다. 시간에 따른 분개 건수 추이를 분석하는 데도 사용할 수 있습니다. 중요한 이유 재무 보고와 규정 준수 분석에 중요하며, 분개가 올바른 회계 기간에 전기되었는지 확인할 수 있습니다. 확보 방법 문서 헤더 테이블 BKPF의 BUDAT 필드에 있습니다. 예시 2023-10-312023-11-302024-01-15 | |||
| 트랜잭션 코드 TransactionCode | 분개를 생성하거나 처리하는 데 사용한 SAP 트랜잭션 코드입니다. | ||
| 설명 트랜잭션 코드(T-Code)는 SAP의 특정 기능이나 프로그램을 식별하는 고유 코드입니다. 분개의 경우 수동 입력(FB01, F-02), 임시 저장(FV50), 자동 인터페이스 등 분개 생성 방식을 나타냅니다. 이 속성은 '수동 작업 최적화' 대시보드에 유용합니다. T-Code를 분석해 수동 작업과 자동 작업을 구분하고, 시간이 가장 많이 걸리는 수동 프로세스를 찾아 수작업을 줄이고 효율성을 높일 자동화 기회를 파악할 수 있습니다. 중요한 이유 수동 프로세스와 자동 프로세스를 구분해 자동화와 프로세스 표준화 기회를 찾는 데 도움이 됩니다. 확보 방법 문서 헤더 테이블 BKPF의 TCODE 필드에 있습니다. 예시 FB01F-02FV50FBD1 | |||
| 회사 코드 CompanyCode | 재무제표를 작성하는 독립된 법인을 나타내는 조직 단위입니다. | ||
| 설명 회사 코드는 SAP Financials의 기본 조직 단위로, 법적으로 독립된 회사를 나타내며 분개 문서 헤더의 주요 필드입니다. 이 속성을 사용하면 법인별로 프로세스를 구분해 분석할 수 있습니다. 사업 부문별 프로세스 성과, 규정 준수율, KPI 결과를 비교할 수 있습니다. 예를 들어 특정 회사 코드에서 승인 지연이나 높은 역분개율이 발생하는지 확인할 수 있습니다. 중요한 이유 조직 내 여러 법인이나 사업 부문 간의 프로세스 성과를 필터링하고 비교할 수 있습니다. 확보 방법 문서 헤더 테이블 BKPF의 BUKRS 필드에 있습니다. 예시 10002000US01DE01 | |||
| 문서 총액 TotalDocumentAmount | 문서 통화로 표시한 분개 총액입니다. | ||
| 설명 이 속성은 분개의 총 재무 금액을 나타냅니다. 일반적으로 해당 문서의 모든 차변 또는 대변 개별 항목 금액의 절댓값을 합산해 계산합니다. 금액을 기준으로 프로세스를 분석하면 중요한 패턴을 찾을 수 있습니다. 예를 들어 고액 분개는 더 엄격한 승인 경로를 따를 수 있습니다. 이 속성으로 분석을 필터링하거나 구분해 분개 금액과 처리 시간, 반려율, 승인 지연 간의 관계를 확인할 수 있습니다. 중요한 이유 분개 금액과 처리 시간 또는 반려율의 관계를 분석하는 등 재무 영향 분석에 활용할 수 있습니다. 확보 방법 계산 필드입니다. 해당 분개의 BSEG 테이블에 있는 모든 개별 항목의 금액 필드(WRBTR 또는 DMBTR)를 합산해 산출합니다. 예시 1500.0025000.75125.50 | |||
| 승인 소요 시간 ApprovalTime | 분개를 승인 요청한 시점부터 승인 또는 거부될 때까지 걸린 시간입니다. | ||
| 설명 이 지표는 승인 하위 프로세스에 걸리는 시간을 측정합니다. 승인 단계는 전체 처리 시간에 큰 영향을 미치는 경우가 많습니다. '분개 승인 요청' 활동과 해당 분개의 '분개 승인' 또는 '분개 거부' 활동 사이의 시간 차이로 계산합니다. 승인 소요 시간은 '분개 승인 성과' 대시보드와 '평균 분개 승인 소요 시간' KPI의 주요 지표입니다. 이 시간을 분석하면 승인 워크플로의 병목을 파악하고, 승인 담당자의 처리 성과를 측정하며, 승인 기준 조정과 같은 프로세스 변경의 필요성을 검토할 수 있습니다. 중요한 이유 승인 단계에 걸리는 시간을 수치화해 검토 및 승인 워크플로의 지연을 파악하고 개선할 수 있습니다. 확보 방법 '분개 승인 요청' 이벤트의 타임스탬프에서 '분개 승인' 또는 '분개 거부' 이벤트의 타임스탬프까지의 시간 차이로 계산합니다. 예시 P1DT2HPT4H15MP3D | |||
| 임시 저장 여부 IsParked | 분개가 전기되기 전에 임시 저장 문서로 저장되었는지 나타내는 불리언 플래그입니다. | ||
| 설명 문서를 임시 저장하면 미완성 분개를 저장해도 재무 잔액에 영향을 주지 않습니다. 이후 다른 사용자가 내용을 보완하거나 검토한 뒤 전기할 수 있습니다. 이 플래그는 임시 저장 단계를 거친 분개를 식별합니다. 이 속성을 분석하면 임시 저장 기능의 사용 방식을 파악할 수 있습니다. 임시 저장이 비공식 검토 단계로 사용되어 지연을 일으키는지 확인할 수 있습니다. 또한 전체 처리 시간을 분석할 때 바로 전기된 분개와 먼저 임시 저장된 분개를 구분할 수 있습니다. 중요한 이유 임시 저장 기능을 사용한 분개를 식별합니다. 이 단계는 지연의 원인이 되거나 비공식 검토 절차를 나타낼 수 있습니다. 확보 방법 BKPF 테이블의 문서 상태 필드(BSTAT)에서 가져옵니다. 'V'는 임시 저장 문서를 나타냅니다. 예시 truefalse | |||
| 재작업 여부 IsRework | 분개가 거부된 후 수정되는 등 재작업 과정을 거쳤는지 나타내는 불리언 플래그입니다. | ||
| 설명 이 플래그는 일반적인 처리 경로에서 벗어나 수정 조치가 필요했던 사례를 식별합니다. 특정 분개에서 '분개 거부' 다음에 '분개 수정'과 같은 활동이 관찰되면 보통 true로 설정합니다. 이 속성은 '분개 재작업률' KPI 계산과 '재작업 및 거부율' 대시보드 분석에 필수적입니다. 프로세스의 비효율 정도를 수치화하고, 요구사항이 불명확하거나 문서가 부족한 경우처럼 재작업의 근본 원인을 조사하는 데 활용할 수 있습니다. 중요한 이유 수정이 필요했던 분개를 표시해 재작업 규모와 근본 원인을 분석하고, 첫 처리에서 정확하게 완료되는 비율을 높일 수 있습니다. 확보 방법 사례별 활동 순서를 분석해 계산하는 속성입니다. 거부 또는 수정 활동이 발생하면 재작업 과정으로 식별합니다. 예시 truefalse | |||
| 취소 사유 ReversalReason | 분개를 취소한 이유를 나타내는 코드입니다. | ||
| 설명 문서를 취소할 때 SAP에서 사유 코드를 지정할 수 있습니다. 이 코드는 잘못된 전기일이나 데이터 입력 오류 등 취소가 필요한 이유를 구조화된 형태로 기록합니다. 이 속성은 '분개 취소 분석' 대시보드의 주요 입력 데이터입니다. 자주 발생하는 취소 사유를 분석하면 프로세스의 구조적 문제나 교육 부족을 파악하고, 향후 오류와 취소율을 줄이기 위한 조치를 취할 수 있습니다. 중요한 이유 취소가 발생한 이유를 직접 파악해 근본 원인을 분석하고 향후 오류를 줄이는 데 도움이 됩니다. 확보 방법 문서 헤더 테이블 BKPF의 STGRD 필드에 있습니다. 예시 010205 | |||
| 코스트 센터 CostCenter | 비용이 발생하는 부서를 나타내는 관리회계 영역 내 조직 단위입니다. | ||
| 설명 코스트 센터는 관리회계(CO) 모듈의 주요 마스터 데이터로, 분개 개별 항목에 지정되는 경우가 많습니다. 특정 부서, 기능 또는 장소의 비용을 추적하는 데 사용합니다. 코스트 센터를 포함하면 분개 프로세스를 더 세밀하게 분석할 수 있습니다. 특정 부서에서 재작업이 더 많이 발생하는지, 처리 시간이 더 긴지, 수기 입력 건수가 더 많은지 파악할 수 있어 부서별 프로세스 효율을 살펴볼 수 있습니다. 중요한 이유 부서나 기능 영역별 프로세스 성과를 분석해 해당 영역의 비효율을 파악할 수 있습니다. 확보 방법 문서 개별 항목 테이블 BSEG의 KOSTL 필드에 있습니다. 예시 4100CC_FINANCE_US10010101 | |||
| 통화 키 CurrencyKey | 분개 금액에 적용되는 통화 코드입니다. | ||
| 설명 이 속성은 분개 금액의 통화를 USD, EUR, JPY 등으로 나타냅니다. 문서에 기록된 금액을 해석하는 데 필요한 정보를 제공합니다. 항상 주요 분석 기준으로 사용되는 것은 아니지만, 금액을 정확히 해석하는 데 중요합니다. 글로벌 조직에서는 외화 분개와 현지 통화 분개를 구분해 프로세스 차이를 분석할 때도 활용할 수 있습니다. 중요한 이유 금액을 정확하게 분석하고 해석하는 데 필요한 정보를 제공합니다. 확보 방법 문서 헤더 테이블 BKPF의 WAERS 필드에 있습니다. 예시 USDEURGBPJPY | |||
Record to Report - 분개 활동
| 활동 | 설명 | ||
|---|---|---|---|
| 분개 승인 | 이 활동은 워크플로에서 분개가 최종 승인되어 전기할 수 있는 상태가 되었음을 나타냅니다. 워크플로 로그에서 마지막 '승인' 또는 '릴리스' 단계가 완료되면 기록됩니다. | ||
| 중요한 이유 승인 프로세스를 마무리하는 주요 기준점입니다. 이 활동까지 걸린 시간은 승인 효율성을 측정하는 중요한 KPI이며, 이 이벤트부터 전기까지의 시간은 승인 후 지연을 보여줍니다. 확보 방법 SAP Business Workflow 로그에서 최종 승인 단계가 완료된 시각을 바탕으로 추론합니다. 문서가 전기되거나 전기 준비 상태가 되기 전 마지막 승인 작업입니다. 기록 워크플로 로그에서 마지막 '승인' 또는 '릴리스' 단계의 완료를 확인합니다. 이벤트 유형 inferred | |||
| 분개 승인 요청 | 이 활동은 임시 저장된 분개를 작성자가 확정해 검토와 승인을 받을 준비가 되었음을 나타냅니다. 일반적으로 임시 저장 문서와 연결된 SAP Business Workflow 작업이 시작될 때 기록됩니다. | ||
| 중요한 이유 작성자에서 승인자로 업무가 넘어가는 시점으로, 승인 주기 KPI 측정이 시작됩니다. 승인 워크플로의 효율성을 측정하는 주요 기준점입니다. 확보 방법 재무 문서 객체와 연결된 승인 워크플로 인스턴스의 시작 시각을 바탕으로 추론합니다. 특정 회사 코드, 문서 번호, 회계연도에 대해 시작된 워크플로를 찾으려면 SWW_WI2OBJ와 같은 워크플로 로그 테이블을 분석해야 합니다. 기록 임시 저장 문서 객체의 워크플로 시작 이벤트를 확인합니다. 이벤트 유형 inferred | |||
| 분개 역분개 처리 | 이 활동은 이전에 전기된 분개의 역분개를 나타냅니다. 역분개는 원래 분개를 상쇄하는 새 회계 문서입니다. | ||
| 중요한 이유 데이터 품질과 프로세스 정확성을 측정하는 중요한 이벤트입니다. 역분개 비율이 높으면 최초 입력이나 승인 단계에 구조적인 문제가 있을 수 있으며, 역분개 건마다 재작업이 발생합니다. 확보 방법 원본 문서의 헤더(BKPF 테이블)에서 확인합니다. 문서를 역분개하면 SAP가 역분개 문서 번호(BKPF-STBLG)와 역분개 사유(BKPF-STGRD)를 입력합니다. 이벤트 시각은 새 역분개 문서의 전기일입니다. 기록 원본 문서의 BKPF-STBLG가 입력된 시점을 확인합니다. 시각은 역분개 문서의 전기일을 사용합니다. 이벤트 유형 explicit | |||
| 분개 임시 저장 | 이 활동은 분개를 총계정원장에 공식 전기하기 전에 임시 상태로 처음 생성하는 단계입니다. SAP에서 사용자가 임시 저장 트랜잭션으로 문서를 저장해 상태를 '임시 저장'으로 설정하면 이 활동이 명시적으로 기록됩니다. | ||
| 중요한 이유 검토와 승인이 필요한 프로세스의 중요한 시작 이벤트입니다. 임시 저장부터 전기까지 걸리는 시간을 분석하면 전기 전 단계와 승인 단계의 지연을 파악할 수 있습니다. 확보 방법 이 이벤트는 문서 헤더 테이블 BKPF에서 확인합니다. BKPF-BSTAT = 'V' 상태로 생성된 문서를 임시 저장 문서로 봅니다. 이벤트 시각은 생성 날짜와 시간인 BKPF-CPUDT 및 BKPF-CPUTM입니다. 기록 BKPF에서 BKPF-BSTAT이 'V'인 문서 생성을 확인합니다. 이벤트 유형 explicit | |||
| 분개 전기 | 분개가 총계정원장에 공식 기록되어 재무제표에 반영되는 주요 활동입니다. 문서 상태가 '전기됨'으로 설정되고 전기일이 지정되면 이 이벤트가 명시적으로 기록됩니다. | ||
| 중요한 이유 분개 처리가 성공적으로 완료되었음을 나타내는 가장 중요한 기준점입니다. 전체 처리 시간은 보통 이 시점까지 측정하며, 재무 마감 분석에서도 주요 이벤트로 사용됩니다. 확보 방법 BKPF 테이블의 문서에 전기일(BKPF-BUDAT)이 있으면 확인할 수 있습니다. 임시 저장 문서의 경우 BKPF-BSTAT 상태가 'V'에서 공란으로 바뀌는 시점에 해당합니다. 전기 시각은 입력 날짜인 BKPF-CPUDT입니다. 기록 BKPF-BSTAT이 'V'에서 공란으로 바뀌는 시점을 확인합니다. 직접 전기된 문서는 생성 이벤트를 기준으로 합니다. 이벤트 유형 explicit | |||
| 분개 개별 항목 반제 | 은행 정산 계정처럼 개별 항목 관리 대상인 총계정원장 계정의 미결 항목을 대사하는 활동입니다. 한 개별 항목을 다른 항목과 매칭해 미결 상태를 해소할 때 발생합니다. | ||
| 중요한 이유 은행 계정 조정과 같은 프로세스에서는 항목 반제까지 걸리는 시간이 중요한 KPI입니다. 이 활동을 통해 대사와 월말 마감 절차의 효율성을 분석할 수 있습니다. 확보 방법 개별 항목 테이블 BSEG에서 확인합니다. 항목이 반제되면 반제일(BSEG-AUGDT)과 반제 문서(BSEG-AUGBL) 필드가 채워집니다. 이벤트 시각은 반제일입니다. 기록 개별 항목의 반제일(BSEG-AUGDT)이 입력된 시점을 확인합니다. 이벤트 유형 explicit | |||
| 분개 생성 | 임시 저장 단계를 거치지 않고 바로 전기되는 분개의 생성을 나타냅니다. SAP에서 직접 전기 트랜잭션으로 문서를 생성하면 기록됩니다. | ||
| 중요한 이유 승인 워크플로가 필요하지 않은 단순한 분개 프로세스의 대체 시작점입니다. 단순 직접 전기와 더 복잡한 임시 저장 문서를 구분하는 데 도움이 됩니다. 확보 방법 이 이벤트는 BKPF 테이블에서 문서 상태 BKPF-BSTAT이 공란인 경우(전기됨)에 해당합니다. 이벤트 시각은 생성 날짜인 BKPF-CPUDT입니다. 이 문서에서는 '생성'과 '전기' 이벤트가 동시에 발생합니다. 기록 BKPF에서 BKPF-BSTAT이 공란인 문서 생성을 확인합니다. 이벤트 유형 explicit | |||
| 분개 수정 | 이 활동은 수정 요청을 받은 뒤 원 작성자가 임시 저장된 분개를 변경했음을 나타냅니다. '수정 요청' 이벤트 이후 문서 변경을 감지해 추론합니다. | ||
| 중요한 이유 수정 내역을 추적하면 재작업에 투입된 노력을 정량화할 수 있습니다. 수정 요청부터 실제 수정까지 걸리는 시간을 보면 제출된 분개의 문제 해결이 지연되는 정도를 파악할 수 있습니다. 확보 방법 임시 저장 문서의 변경 문서 로그(CDHDR 및 CDPOS 테이블)를 분석해 추론합니다. 워크플로에서 반려된 뒤 변경 기록이 있으면 수정이 이루어진 것으로 봅니다. 시각은 CDHDR 테이블에서 가져옵니다. 기록 반려 이벤트 이후 CDHDR/CDPOS에 기록된 변경 로그 항목을 확인합니다. 이벤트 유형 inferred | |||
| 분개 수정 요청 | 승인자가 분개를 검토한 뒤 수정을 위해 작성자에게 돌려보내는 워크플로 단계입니다. 워크플로 로그에 기록된 '반려' 또는 '반송' 사용자 결정으로 확인합니다. | ||
| 중요한 이유 이 활동은 비효율과 프로세스 편차의 주요 원인인 재작업 반복을 파악하는 데 중요합니다. 이 이벤트가 자주 발생하면 분개 품질에 문제가 있거나 요구사항이 명확하지 않을 수 있습니다. 확보 방법 SAP Business Workflow 로그에서 '반려' 또는 '수정 요청'에 해당하는 특정 사용자 결정 단계의 시각을 바탕으로 추론합니다. 기록 워크플로 로그에서 '반려' 또는 '재작업' 결정 시각을 확인합니다. 이벤트 유형 inferred | |||
| 분개 최종 반려 | 이 활동은 분개가 최종 반려되어 더 이상 전기되지 않음을 나타냅니다. 일반적으로 승인 워크플로의 종료 상태이며, 이후 임시 저장 문서가 삭제될 수 있습니다. | ||
| 중요한 이유 반려를 추적하는 일은 품질 관리에 중요합니다. 반려 사유와 빈도를 분석하면 분개를 처음부터 정확하게 처리하는 비율을 높일 수 있습니다. 확보 방법 SAP Business Workflow 로그에서 프로세스를 종료하는 최종 '반려' 사용자 결정으로 기록됩니다. 이후 임시 저장 문서가 삭제될 수 있습니다. 기록 문서의 워크플로 로그에서 종료 상태인 '반려'를 확인합니다. 이벤트 유형 inferred | |||
| 수기 입력 여부 확인 | 분개가 수동 온라인 트랜잭션으로 생성되었는지, 자동 인터페이스나 배치 프로세스로 생성되었는지 확인하는 활동입니다. 사용자 작업이 아니라 시스템 데이터에서 산출하는 분개 속성입니다. | ||
| 중요한 이유 수동 입력과 자동 입력을 구분하면 개선 과제를 구체적으로 정할 수 있습니다. 수동 프로세스는 표준화와 자동화의 주요 대상인 경우가 많습니다. 확보 방법 문서 헤더 테이블 BKPF의 필드를 분석해 산출합니다. 'FB01', 'FB50', 'FV50'과 같은 트랜잭션 코드(BKPF-TCODE)는 수동 입력을 나타내며, 그 외 T-code나 특정 배치 입력 이름(BKPF-AWKEY)은 자동화를 나타낼 수 있습니다. 기록 BKPF-TCODE 또는 문서 헤더의 다른 원천 시스템 지표를 바탕으로 산출합니다. 이벤트 유형 calculated | |||
| 임시 저장 분개 삭제 | 전기되지 않은 임시 저장 분개의 삭제를 나타냅니다. 반려 후 삭제되거나 분개가 잘못 생성된 경우 발생할 수 있습니다. | ||
| 중요한 이유 이 활동은 프로세스가 성공적으로 완료되지 않았음을 나타냅니다. 임시 저장 문서가 삭제된 이유를 분석하면 중복 입력이나 프로세스 오해 등의 문제를 찾을 수 있습니다. 확보 방법 BKPF 테이블에서 임시 저장 문서의 상태가 변경되면 이 이벤트가 기록됩니다. 상태 필드 BKPF-BSTAT이 'Z'(임시 저장 문서 삭제됨)로 업데이트됩니다. 변경 시각은 문서 변경 로그(CDHDR)에서 확인할 수 있습니다. 기록 BKPF-BSTAT이 'Z'로 업데이트된 시점을 확인합니다. 이벤트 유형 explicit | |||
| 증빙 문서 첨부 | 사용자가 송장이나 스프레드시트 같은 증빙 문서를 분개에 첨부하는 활동입니다. 표준 회계 이벤트로 명시적으로 기록되지는 않으며, 일반적으로 회계 문서 객체에 연결된 첨부 파일의 생성 여부를 확인해 추론합니다. | ||
| 중요한 이유 이 활동을 추적하면 증빙 문서 제출을 요구하는 정책의 준수 여부를 확인할 수 있습니다. 문서 첨부가 늦어지면 승인 주기가 길어지는 원인이 될 수 있습니다. 확보 방법 이 활동을 시각이 기록된 이벤트로 안정적으로 포착하기는 어렵습니다. SOOD와 같은 Generic Object Services (GOS) 첨부 파일 테이블을 분석하고, 첨부 파일 생성 시각을 분개 객체 키와 연결해 추론할 수 있습니다. 기록 GOS 테이블(예: SOOD)에서 연결된 객체의 생성 시각을 바탕으로 추론합니다. 이벤트 유형 inferred | |||
| 회사 간 전기 여부 확인 | 둘 이상의 회사 코드에 영향을 미치는 분개를 표시하는 산출 활동입니다. 단일 재무 문서의 개별 항목을 분석해 판별합니다. | ||
| 중요한 이유 회사 간 거래는 처리와 승인 요건이 더 복잡할 수 있습니다. 이를 식별하면 처리 시간과 프로세스 경로를 별도로 분석해 고유한 병목을 찾을 수 있습니다. 확보 방법 해당 문서 번호(BELNR)의 개별 항목 테이블 BSEG를 확인해 산출합니다. 개별 항목에 서로 다른 회사 코드(BSEG-BUKRS)가 둘 이상 있으면 회사 간 전기로 봅니다. 기록 단일 BKPF-BELNR에 대해 서로 다른 BSEG-BUKRS 값이 여러 개 있는지 확인합니다. 이벤트 유형 calculated | |||
데이터 추출 가이드
단계
- ABAP 프로그램 만들기: SAP 시스템에서 트랜잭션 코드 SE38(ABAP Editor)로 이동합니다. 새 프로그램 이름을 입력합니다. 예를 들어 Z_PM_JE_EXTRACTION을 입력한 뒤 만들기를 선택합니다. 적절한 제목을 입력하고 프로그램 유형을 'Executable Program'으로 설정합니다.
- 선택 화면 정의하기: 프로그램 소스 코드에서 선택 화면을 정의합니다. 사용자가 문서 생성일 범위, 회사 코드, 문서 유형 등의 매개변수를 지정해 추출 데이터의 양을 제한할 수 있습니다.
- 데이터 구조 선언하기: 최종 이벤트 로그 데이터를 담을 내부 테이블 구조를 정의합니다. 이 구조에는 JournalEntryId, ActivityName, EventTime, SourceSystem, LastDataUpdate와 User, CompanyCode, PostingDate 등의 권장 속성이 포함되어야 합니다.
- 데이터 선택 로직 구현하기: 필수 활동 14개 각각의 데이터를 추출하는 ABAP SQL 쿼리를 작성합니다. BKPF(헤더)와 BSEG(개별 항목) 같은 기본 테이블, 변경 로그 테이블 CDHDR 및 CDPOS, SWWLOGHIST 같은 워크플로 테이블, BSAS 및 BSAK 같은 반제 테이블에서 데이터를 선택합니다.
- 임시 저장 문서와 전기 문서 추출하기: '분개 임시 저장' 이벤트는 문서 상태(BSTAT)가 'V'인 BKPF 레코드를 선택합니다. '분개 생성' 및 '분개 전기' 이벤트는 상태가 공백인 BKPF 레코드를 선택합니다. 공백은 정상적으로 전기된 문서를 나타냅니다.
- 변경 및 삭제 이벤트 추출하기: 변경 문서 테이블 CDHDR 및 CDPOS에서 객체 클래스 'BELEG'를 조회합니다. 문서 키를 기준으로 필터링해 '분개 수정' 또는 '임시 저장 분개 삭제' 활동에 해당하는 변경 사항을 찾습니다.
- 워크플로 이벤트 추출하기: '분개 승인 요청', '분개 승인', '분개 거부', '변경 요청' 등의 활동을 기록하려면 워크플로 테이블을 조회합니다. SWW_WI2OBJ 테이블로 회계 문서와 워크플로 인스턴스를 연결한 다음, SWWLOGHIST에서 사용자 결정이나 상태 변경을 확인합니다.
- 계산된 이벤트 식별하기: '수기 입력 식별'은 트랜잭션 코드(BKPF-TCODE)를 알려진 수기 입력 t-code 목록과 대조해 확인합니다. '회사 간 전기 식별'은 문서의 BSEG 개별 항목을 분석해 여러 회사 코드가 포함되었는지 확인합니다.
- 데이터 통합 및 변환하기: 각 활동의 데이터를 선택할 때 최종 이벤트 로그 구조에 맞게 변환합니다. 회사 코드, 문서 번호, 회계연도를 결합해 JournalEntryId를 만들고, SAP 날짜와 시간을 하나의 EventTime 타임스탬프로 변환합니다. 각 쿼리의 결과를 최종 내부 테이블에 추가합니다.
- 파일 내보내기 구현하기: OPEN DATASET, LOOP AT, TRANSFER, CLOSE DATASET 등의 ABAP 파일 처리 구문을 사용해 통합된 내부 테이블을 SAP 애플리케이션 서버 디렉터리의 CSV 또는 일반 텍스트 파일로 저장합니다. 트랜잭션 AL11에서 해당 디렉터리를 확인할 수 있습니다.
- 백그라운드 작업으로 예약하기: 트랜잭션 SM36(백그라운드 작업 정의)으로 이동합니다. 새 작업을 만들고 ABAP 프로그램을 실행하는 단계를 정의한 뒤, 업무량이 적은 시간대에 매일 밤이나 매주 실행되도록 예약해 추출을 자동화합니다.
- 파일 가져오기 및 형식 확인하기: 트랜잭션 CG3Y를 사용하거나 시스템 관리자에게 요청해 생성된 파일을 애플리케이션 서버에서 로컬 컴퓨터로 다운로드합니다. 파일 인코딩과 형식이 process mining 도구에 업로드하기에 적합한지 확인합니다.
구성
- 날짜 범위: 성능을 관리하려면 날짜 범위를 반드시 지정해야 합니다. 기본 필터로 문서 생성일(BKPF-CPUDT)을 사용합니다. 초기 분석에는 3~6개월 범위를 권장합니다. 테스트할 때는 데이터가 있는 것으로 확인된 며칠 범위를 사용하세요.
- 회사 코드 필터: 회사 코드(BKPF-BUKRS)로 항상 필터링하세요. 모든 회사 코드의 데이터를 한 번에 추출하면 시스템 리소스를 많이 사용할 수 있습니다. 관련 회사 코드 한 개 또는 소수의 코드부터 시작하세요.
- 문서 유형 필터: 모든 문서 유형을 분석할 필요가 없다면 문서 유형 필터(BKPF-BLART)를 사용해 범위를 좁히세요. 예를 들어 G/L 문서인 'SA'만 선택할 수 있습니다.
- 워크플로 작업 ID: 워크플로 이벤트 추출 로직은 시스템에서 승인, 거부, 제출에 사용하는 특정 작업 ID에 따라 달라집니다. 회사의 워크플로 정의를 기준으로 프로그램 소스 코드에 해당 ID를 설정해야 합니다.
- 성능 고려 사항: 이 프로그램은 CDPOS와 워크플로 이력 테이블 등 대용량 테이블 여러 개를 조인합니다. 업무량이 많은 시간에 실행하면 시스템 성능에 영향을 줄 수 있습니다. 업무량이 적은 시간대에 백그라운드 작업으로 실행하도록 예약하세요. 성능 문제가 반복되면 보조 데이터베이스 인덱스 생성을 검토하세요.
- 사전 요건: 이 방법을 사용하려면 ABAP 개발 권한(SE38)과 백그라운드 작업 생성 및 관리 권한(SM36)이 있는 사용자가 필요합니다. 사용자 또는 작업에는 관련 재무, 워크플로, 시스템 테이블(BKPF, BSEG, CDHDR, CDPOS, SWWLOGHIST 등)에 대한 읽기 권한도 있어야 합니다.
샘플 쿼리 abap
REPORT Z_PM_JE_EXTRACTION.
*&---------------------------------------------------------------------*
*& Data Structures for Final Event Log
*&---------------------------------------------------------------------*
TYPES: BEGIN OF ty_event_log,
journalentryid TYPE string,
activityname TYPE string,
eventtime TYPE timestamp,
sourcesystem TYPE string,
lastdataupdate TYPE timestamp,
username TYPE uname,
companycode TYPE bukrs,
documenttype TYPE blart,
postingdate TYPE budat,
transactioncode TYPE tcode,
isreversed TYPE abap_bool,
END OF ty_event_log.
DATA: lt_final_log TYPE STANDARD TABLE OF ty_event_log.
DATA: ls_event TYPE ty_event_log.
*&---------------------------------------------------------------------*
*& Selection Screen Parameters
*&---------------------------------------------------------------------*
SELECT-OPTIONS: s_bukrs FOR bkpf-bukrs OBLIGATORY,
s_blart FOR bkpf-blart,
s_cpudt FOR bkpf-cpudt OBLIGATORY.
PARAMETERS: p_sysid TYPE sy-sysid DEFAULT sy-sysid.
*&---------------------------------------------------------------------*
*& Main Logic
*&---------------------------------------------------------------------*
START-OF-SELECTION.
DATA(lv_last_update) = cl_abap_context_info=>get_system_timestamp( ).
" 1. Journal Entry Parked
SELECT CONCAT( a~bukrs, a~belnr, a~gjahr ) AS journalentryid,
'Journal Entry Parked' AS activityname,
a~cpudt, a~cputm,
a~usnam AS username,
a~bukrs AS companycode,
a~blart AS documenttype,
a~bldat AS postingdate,
a~tcode AS transactioncode
FROM bkpf AS a
WHERE a~bukrs IN s_bukrs
AND a~blart IN s_blart
AND a~cpudt IN s_cpudt
AND a~bstat = 'V' " Parked Document
INTO TABLE @DATA(lt_parked).
IF sy-subrc = 0.
LOOP AT lt_parked ASSIGNING FIELD-SYMBOL(<fs_parked>).
ls_event-journalentryid = <fs_parked>-journalentryid.
ls_event-activityname = <fs_parked>-activityname.
CONVERT DATE <fs_parked>-cpudt TIME <fs_parked>-cputm INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
ls_event-sourcesystem = p_sysid.
ls_event-lastdataupdate = lv_last_update.
ls_event-username = <fs_parked>-username.
ls_event-companycode = <fs_parked>-companycode.
ls_event-documenttype = <fs_parked>-documenttype.
ls_event-postingdate = <fs_parked>-postingdate.
ls_event-transactioncode = <fs_parked>-transactioncode.
APPEND ls_event TO lt_final_log.
ENDLOOP.
ENDIF.
" 2. Journal Entry Created (directly posted, not parked first)
" 9. Journal Entry Posted
" These two events happen at the same time for a direct posting.
SELECT CONCAT( bukrs, belnr, gjahr ) AS journalentryid,
cpudt, cputm, usnam, bukrs, blart, budat, tcode, stblg
FROM bkpf
WHERE bukrs IN s_bukrs
AND blart IN s_blart
AND cpudt IN s_cpudt
AND bstat = '' " Normal, posted document
INTO TABLE @DATA(lt_posted).
IF sy-subrc = 0.
LOOP AT lt_posted ASSIGNING FIELD-SYMBOL(<fs_posted>).
" Activity: Journal Entry Created
ls_event-journalentryid = <fs_posted>-journalentryid.
ls_event-activityname = 'Journal Entry Created'.
CONVERT DATE <fs_posted>-cpudt TIME <fs_posted>-cputm INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
ls_event-sourcesystem = p_sysid.
ls_event-lastdataupdate = lv_last_update.
ls_event-username = <fs_posted>-usnam.
ls_event-companycode = <fs_posted>-bukrs.
ls_event-documenttype = <fs_posted>-blart.
ls_event-postingdate = <fs_posted>-budat.
ls_event-transactioncode = <fs_posted>-tcode.
ls_event-isreversed = COND #( WHEN <fs_posted>-stblg IS NOT INITIAL THEN abap_true ELSE abap_false ).
APPEND ls_event TO lt_final_log.
" Activity: Journal Entry Posted
ls_event-activityname = 'Journal Entry Posted'.
APPEND ls_event TO lt_final_log.
ENDLOOP.
ENDIF.
" 3. Documentation Attached (via GOS)
SELECT a~instid_a, c~cr_timestamp
FROM srgbtbrel AS a
INNER JOIN sood AS b ON a~instid_b = b~objid
INNER JOIN socf AS c ON b~filid = c~filid
WHERE a~typeid_a = 'BKPF'
AND a~bukrs IN s_bukrs
INTO TABLE @DATA(lt_attachments).
IF sy-subrc = 0.
LOOP AT lt_attachments ASSIGNING FIELD-SYMBOL(<fs_attach>).
ls_event-journalentryid = |{ <fs_attach>-instid_a(4) }{ <fs_attach>-instid_a+4(10) }{ <fs_attach>-instid_a+14(4) }|.
ls_event-activityname = 'Documentation Attached'.
ls_event-eventtime = <fs_attach>-cr_timestamp.
" Other attributes may need to be looked up from BKPF if needed.
APPEND ls_event TO lt_final_log.
ENDLOOP.
ENDIF.
" 4, 5, 6, 7, 8: Workflow events (Submitted, Changes Requested, Corrected, Approved, Rejected)
" This is a simplified example. Real logic depends on specific workflow templates.
SELECT a~instid, b~wi_cd, b~wi_ct, b~wi_aagent, b~wi_text
FROM sww_wi2obj AS a
INNER JOIN swwloghist AS b ON a~wi_id = b~wi_id
WHERE a~typeid = 'BKPF'
AND a~catid = 'BO'
AND a~bukrs IN s_bukrs
AND b~wi_cd BETWEEN s_cpudt-low AND s_cpudt-high
INTO TABLE @DATA(lt_workflow).
IF sy-subrc = 0.
LOOP AT lt_workflow ASSIGNING FIELD-SYMBOL(<fs_wf>).
ls_event-journalentryid = |{ <fs_wf>-instid(4) }{ <fs_wf>-instid+4(10) }{ <fs_wf>-instid+14(4) }|.
ls_event-activityname = CASE <fs_wf>-wi_text. " Simplified logic based on work item text
WHEN '[Placeholder for Submit Text]' THEN 'Journal Entry Submitted'
WHEN '[Placeholder for Approve Text]' THEN 'Journal Entry Approved'
WHEN '[Placeholder for Reject Text]' THEN 'Journal Entry Rejected'
WHEN '[Placeholder for Rework Text]' THEN 'Journal Entry Changes Requested'
ELSE ''
ENDCASE.
IF ls_event-activityname IS NOT INITIAL.
CONVERT DATE <fs_wf>-wi_cd TIME <fs_wf>-wi_ct INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
ls_event-username = <fs_wf>-wi_aagent.
APPEND ls_event TO lt_final_log.
ENDIF.
ENDLOOP.
ENDIF.
" 10. Manual Entry Identified & 11. Cross-Company Posting Identified
SELECT bukrs, belnr, gjahr, tcode FROM bkpf
WHERE bukrs IN s_bukrs AND blart IN s_blart AND cpudt IN s_cpudt
INTO TABLE @DATA(lt_calc_base).
LOOP AT lt_calc_base ASSIGNING FIELD-SYMBOL(<fs_calc>).
ls_event-journalentryid = |{ <fs_calc>-bukrs }{ <fs_calc>-belnr }{ <fs_calc>-gjahr }|.
" Check for manual entry T-Codes
IF <fs_calc>-tcode = 'FB01' OR <fs_calc>-tcode = 'F-02' OR <fs_calc>-tcode = 'FB50'.
ls_event-activityname = 'Manual Entry Identified'.
APPEND ls_event TO lt_final_log.
ENDIF.
" Check for cross-company posting
SELECT SINGLE bukrs FROM bseg WHERE belnr = <fs_calc>-belnr AND gjahr = <fs_calc>-gjahr AND bukrs <> <fs_calc>-bukrs INTO @DATA(lv_cross_bukrs).
IF sy-subrc = 0.
ls_event-activityname = 'Cross-Company Posting Identified'.
APPEND ls_event TO lt_final_log.
ENDIF.
ENDLOOP.
" 12. Journal Entry Line Item Cleared
SELECT a~bukrs, a~belnr, a~gjahr, a~augdt, a~augbl
FROM bsas AS a " G/L Cleared Items
WHERE a~bukrs IN s_bukrs
AND a~budat IN s_cpudt
INTO TABLE @DATA(lt_cleared_gl).
IF sy-subrc = 0.
LOOP AT lt_cleared_gl ASSIGNING FIELD-SYMBOL(<fs_clr>).
ls_event-journalentryid = |{ <fs_clr>-bukrs }{ <fs_clr>-belnr }{ <fs_clr>-gjahr }|.
ls_event-activityname = 'Journal Entry Line Item Cleared'.
CONVERT DATE <fs_clr>-augdt INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
" User is often not directly available for clearing events
APPEND ls_event TO lt_final_log.
ENDLOOP.
ENDIF.
" 13. Parked Journal Entry Deleted & 6. Journal Entry Corrected
SELECT objectid, changenr, username, udate, utime FROM cdhdr
WHERE objectclas = 'BELEG'
AND udate IN s_cpudt
INTO TABLE @DATA(lt_cdhdr).
LOOP AT lt_cdhdr ASSIGNING FIELD-SYMBOL(<fs_cdhdr>).
SELECT SINGLE tcode FROM cdpos WHERE changenr = <fs_cdhdr>-changenr AND fname = 'BSTAT' AND value_new = 'Z' INTO @DATA(lv_deleted_tcode).
ls_event-journalentryid = |{ <fs_cdhdr>-objectid(4) }{ <fs_cdhdr>-objectid+4(10) }{ <fs_cdhdr>-objectid+14(4) }|.
CONVERT DATE <fs_cdhdr>-udate TIME <fs_cdhdr>-utime INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
ls_event-username = <fs_cdhdr>-username.
IF sy-subrc = 0.
ls_event-activityname = 'Parked Journal Entry Deleted'.
APPEND ls_event TO lt_final_log.
ELSE.
ls_event-activityname = 'Journal Entry Corrected'.
APPEND ls_event TO lt_final_log.
ENDIF.
ENDLOOP.
" 14. Journal Entry Reversal Processed
SELECT CONCAT( a~bukrs, a~belnr, a~gjahr ) AS journalentryid,
a~cpudt, a~cputm, a~usnam
FROM bkpf AS a
WHERE a~bukrs IN s_bukrs
AND a~blart IN s_blart
AND a~cpudt IN s_cpudt
AND a~stblg IS NOT NULL " Document is a reversal
INTO TABLE @DATA(lt_reversals).
IF sy-subrc = 0.
LOOP AT lt_reversals ASSIGNING FIELD-SYMBOL(<fs_rev>).
ls_event-journalentryid = <fs_rev>-journalentryid.
ls_event-activityname = 'Journal Entry Reversal Processed'.
CONVERT DATE <fs_rev>-cpudt TIME <fs_rev>-cputm INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
ls_event-username = <fs_rev>-usnam.
APPEND ls_event TO lt_final_log.
ENDLOOP.
ENDIF.
" Final step: Output to file
DATA(lv_filename) = |/tmp/je_extraction_{ sy-datum }_{ sy-uzeit }.csv|.
OPEN DATASET lv_filename FOR OUTPUT IN TEXT MODE ENCODING UTF-8.
IF sy-subrc = 0.
" Write header
DATA(lv_header) = 'JournalEntryId,ActivityName,EventTime,SourceSystem,LastDataUpdate,User,CompanyCode,DocumentType,PostingDate,TransactionCode,IsReversed'.
TRANSFER lv_header TO lv_filename.
LOOP AT lt_final_log INTO ls_event.
DATA(lv_line) = |"{ ls_event-journalentryid }","|
|{ ls_event-activityname }","|
|{ ls_event-eventtime }","|
|{ ls_event-sourcesystem }","|
|{ ls_event-lastdataupdate }","|
|{ ls_event-username }","|
|{ ls_event-companycode }","|
|{ ls_event-documenttype }","|
|{ ls_event-postingdate }","|
|{ ls_event-transactioncode }","|
|{ ls_event-isreversed }"|.
TRANSFER lv_line TO lv_filename.
ENDLOOP.
CLOSE DATASET lv_filename.
ENDIF. 단계
- 데이터베이스 연결 설정하기: SAP ECC 데이터베이스의 읽기 전용 계정 정보를 받습니다. DBeaver, SAP HANA Studio, SQL Server Management Studio 등의 표준 SQL 클라이언트로 데이터베이스에 연결합니다.
- SQL 쿼리 준비하기: 이 문서의 'query' 섹션에 있는 전체 SQL 쿼리를 복사해 SQL 클라이언트에 붙여 넣습니다.
- 추출 매개변수 설정하기: 실행 전에 쿼리의 자리 표시자를 설정해야 합니다. '[START_DATE]'와 '[END_DATE]'를 원하는 날짜 범위로 바꾸고, 날짜 형식은 'YYYYMMDD'로 지정합니다. '[COMPANY_CODE_1]', '[COMPANY_CODE_2]'는 분석할 SAP 회사 코드로 바꿉니다.
- 소스 시스템 지정하기: 기본
SELECT문에서 자리 표시자 '[Your SAP System ID]'를 실제 SAP System ID(SID)로 바꿔 데이터 소스를 정확히 식별합니다. - 쿼리 실행하기: 설정한 SQL 쿼리를 SAP 데이터베이스에서 실행합니다. 실행 시간은 날짜 범위와 데이터베이스 테이블의 크기에 따라 달라집니다.
- 초기 결과 확인하기: 쿼리가 완료되면 반환된 행을 간단히 살펴 데이터가 예상대로 채워졌는지 확인합니다. 다양한 활동이 포함되어 있는지,
JournalEntryId와EventTime같은 주요 필드가 비어 있지 않은지 확인하세요. - 타임스탬프 처리하기: 쿼리는 날짜와 시간 필드를 결합해
YYYYMMDDHHMMSS문자열을 만듭니다. 후처리 시스템이나 대상 시스템에서 이 형식을 읽을 수 있는지 확인하세요. 데이터베이스에서 지원한다면 SQLCONCAT함수를 수정해YYYY-MM-DDTHH:MI:SS와 같은 ISO 8601 형식으로 바꿀 수 있습니다. - 데이터 내보내기: SQL 클라이언트에서 전체 결과를 CSV 파일로 내보냅니다. 특수 문자 문제를 방지하려면 UTF-8 인코딩을 사용하세요.
- 업로드 준비하기: process mining 도구에 업로드하기 전에 열 제목이 필수 데이터 스키마와 일치하는지 확인합니다.
JournalEntryId,ActivityName,EventTime은 필수입니다.LastDataUpdate열을 추가하고 추출을 수행한 시점의 타임스탬프를 입력합니다. - 최종 검증하기: 분석을 시작하기 전에 'validationSteps' 섹션의 절차에 따라 추출한 데이터가 완전하고 정확한지 확인합니다.
구성
- 데이터베이스 권한: 데이터베이스 사용자는 다음 SAP 테이블에 대한 읽기 권한이 필요합니다. BKPF, BSEG, CDHDR, CDPOS, T001, V_USERNAME. 워크플로 관련 활동을 분석하려면 SWW_WI2OBJ 및 SWWLOGHIST에 대한 접근 권한도 필요합니다. 일반적으로 이러한 권한은 전문 기술 팀에만 부여됩니다.
- 날짜 범위 필터링: 쿼리 성능을 위해 특정 날짜 범위로 데이터를 반드시 필터링해야 합니다. 제공된 쿼리의 시작일과 종료일 자리 표시자는 문서 생성일(
BKPF.CPUDT)에 적용됩니다. 초기 분석에는 3~6개월 범위를 권장합니다. - 회사 코드 필터링: 데이터 양을 관리하고 분석 범위를 정하려면 회사 코드(
BKPF.BUKRS)로 항상 필터링하세요. 관련 분개 유형만 포함하도록 문서 유형(BKPF.BLART)도 필터링할 수 있습니다. 예를 들어 G/L 문서인 'SA'만 포함하고, 범위에 포함되지 않는 송장이나 지급 같은 운영 문서는 제외할 수 있습니다. - 성능 고려 사항: BSEG 및 CDPOS 같은 핵심 테이블을 직접 조회하면 시스템 리소스를 많이 사용할 수 있습니다. 최종 사용자의 시스템 성능에 영향을 주지 않도록 업무량이 적은 시간대에 추출하는 것이 좋습니다. 한 번에 1년을 초과하는 데이터를 추출하지 마세요.
- 워크플로 작업 ID: 쿼리에는
'[WF_TASK_ID_SUBMIT]'및'[WF_TASK_ID_APPROVE]'와 같은 자리 표시자가 있습니다. 이를 시스템의 분개 워크플로 설정에서 사용하는 실제 작업 ID로 바꿔야 합니다. SAP Workflow 전문가와 협의하거나 트랜잭션 PFTC에서 기술 워크플로 정의를 분석해 ID를 확인할 수 있습니다.
샘플 쿼리 sql
WITH DOC_HEADERS AS (
SELECT
BUKRS,
BELNR,
GJAHR,
BLART,
BLDAT,
BUDAT,
CPUDT,
CPUTM,
USNAM,
TCODE,
BSTAT,
STBLG,
XRECH
FROM BKPF
WHERE CPUDT BETWEEN '[START_DATE]' AND '[END_DATE]'
AND BUKRS IN ('[COMPANY_CODE_1]', '[COMPANY_CODE_2]')
)
-- Event 1: Journal Entry Created (Directly Posted)
SELECT
CONCAT(H.BUKRS, H.BELNR, H.GJAHR) AS "JournalEntryId",
'Journal Entry Created' AS "ActivityName",
TO_TIMESTAMP(CONCAT(H.CPUDT, H.CPUTM), 'YYYYMMDDHH24MISS') AS "EventTime",
U.NAME_TEXT AS "User",
H.BUKRS AS "CompanyCode",
H.BLART AS "DocumentType",
H.BUDAT AS "PostingDate",
H.TCODE AS "TransactionCode",
CASE WHEN H.STBLG IS NOT NULL AND H.STBLG <> '' THEN TRUE ELSE FALSE END AS "IsReversed"
FROM DOC_HEADERS H
LEFT JOIN V_USERNAME U ON H.USNAM = U.BNAME
WHERE H.BSTAT = '' OR H.BSTAT = 'U'
UNION ALL
-- Event 2: Journal Entry Parked
SELECT
CONCAT(H.BUKRS, H.BELNR, H.GJAHR) AS "JournalEntryId",
'Journal Entry Parked' AS "ActivityName",
TO_TIMESTAMP(CONCAT(H.CPUDT, H.CPUTM), 'YYYYMMDDHH24MISS') AS "EventTime",
U.NAME_TEXT AS "User",
H.BUKRS AS "CompanyCode",
H.BLART AS "DocumentType",
H.BUDAT AS "PostingDate",
H.TCODE AS "TransactionCode",
FALSE AS "IsReversed"
FROM DOC_HEADERS H
LEFT JOIN V_USERNAME U ON H.USNAM = U.BNAME
WHERE H.BSTAT = 'V'
UNION ALL
-- Event 3: Journal Entry Posted (from Parked state)
SELECT
CONCAT(H.BUKRS, H.BELNR, H.GJAHR) AS "JournalEntryId",
'Journal Entry Posted' AS "ActivityName",
TO_TIMESTAMP(CONCAT(C.UDATE, C.UTIME), 'YYYYMMDDHH24MISS') AS "EventTime",
U.NAME_TEXT AS "User",
H.BUKRS AS "CompanyCode",
H.BLART AS "DocumentType",
H.BUDAT AS "PostingDate",
C.TCODE AS "TransactionCode",
CASE WHEN H.STBLG IS NOT NULL AND H.STBLG <> '' THEN TRUE ELSE FALSE END AS "IsReversed"
FROM DOC_HEADERS H
JOIN CDHDR C ON C.OBJECTCLAS = 'BELEG' AND C.OBJECTID = CONCAT(H.BUKRS, H.BELNR, H.GJAHR)
JOIN CDPOS P ON C.CHANGENR = P.CHANGENR AND P.OBJECTCLAS = 'BELEG' AND P.OBJECTID = C.OBJECTID
LEFT JOIN V_USERNAME U ON C.USERNAME = U.BNAME
WHERE H.BSTAT <> 'V'
AND P.TABNAME = 'BKPF'
AND P.FNAME = 'BSTAT'
AND P.VALUE_OLD = 'V'
AND P.VALUE_NEW <> 'V'
UNION ALL
-- Event 4: Parked Journal Entry Deleted
SELECT
CONCAT(H.BUKRS, H.BELNR, H.GJAHR) AS "JournalEntryId",
'Parked Journal Entry Deleted' AS "ActivityName",
TO_TIMESTAMP(CONCAT(C.UDATE, C.UTIME), 'YYYYMMDDHH24MISS') AS "EventTime",
U.NAME_TEXT AS "User",
H.BUKRS AS "CompanyCode",
H.BLART AS "DocumentType",
H.BUDAT AS "PostingDate",
C.TCODE AS "TransactionCode",
FALSE AS "IsReversed"
FROM DOC_HEADERS H
JOIN CDHDR C ON C.OBJECTCLAS = 'BELEG' AND C.OBJECTID = CONCAT(H.BUKRS, H.BELNR, H.GJAHR) AND C.TCODE = 'FBV0'
JOIN CDPOS P ON C.CHANGENR = P.CHANGENR AND P.OBJECTCLAS = 'BELEG' AND P.OBJECTID = C.OBJECTID
LEFT JOIN V_USERNAME U ON C.USERNAME = U.BNAME
WHERE P.TABNAME = 'BKPF'
AND P.FNAME = 'BSTAT'
AND P.VALUE_OLD = 'V'
AND P.VALUE_NEW = 'Z'
UNION ALL
-- Event 5: Journal Entry Reversal Processed
SELECT
CONCAT(H.BUKRS, H.STBLG, H.GJAHR) AS "JournalEntryId", -- Linking to the original document
'Journal Entry Reversal Processed' AS "ActivityName",
TO_TIMESTAMP(CONCAT(H.CPUDT, H.CPUTM), 'YYYYMMDDHH24MISS') AS "EventTime",
U.NAME_TEXT AS "User",
H.BUKRS AS "CompanyCode",
H.BLART AS "DocumentType",
H.BUDAT AS "PostingDate",
H.TCODE AS "TransactionCode",
TRUE AS "IsReversed"
FROM DOC_HEADERS H
LEFT JOIN V_USERNAME U ON H.USNAM = U.BNAME
WHERE H.STBLG IS NOT NULL AND H.STBLG <> ''
UNION ALL
-- Event 6: Journal Entry Line Item Cleared
SELECT
CONCAT(B.BUKRS, B.BELNR, B.GJAHR) AS "JournalEntryId",
'Journal Entry Line Item Cleared' AS "ActivityName",
TO_TIMESTAMP(B.AUGDT, 'YYYYMMDD') AS "EventTime", -- Clearing date used as event time
U.NAME_TEXT AS "User",
B.BUKRS AS "CompanyCode",
H.BLART AS "DocumentType",
H.BUDAT AS "PostingDate",
NULL AS "TransactionCode", -- Clearing transaction is in the clearing document header, complex to retrieve here
CASE WHEN H.STBLG IS NOT NULL AND H.STBLG <> '' THEN TRUE ELSE FALSE END AS "IsReversed"
FROM BSEG B
JOIN DOC_HEADERS H ON B.BUKRS = H.BUKRS AND B.BELNR = H.BELNR AND B.GJAHR = H.GJAHR
LEFT JOIN V_USERNAME U ON H.USNAM = U.BNAME
WHERE B.AUGBL IS NOT NULL AND B.AUGBL <> '' AND B.AUGDT <> '00000000'
UNION ALL
-- Event 7: Journal Entry Corrected (changes to a parked document)
SELECT
CONCAT(H.BUKRS, H.BELNR, H.GJAHR) AS "JournalEntryId",
'Journal Entry Corrected' AS "ActivityName",
TO_TIMESTAMP(CONCAT(C.UDATE, C.UTIME), 'YYYYMMDDHH24MISS') AS "EventTime",
U.NAME_TEXT AS "User",
H.BUKRS AS "CompanyCode",
H.BLART AS "DocumentType",
H.BUDAT AS "PostingDate",
C.TCODE AS "TransactionCode",
FALSE AS "IsReversed"
FROM DOC_HEADERS H
JOIN CDHDR C ON C.OBJECTCLAS = 'BELEG' AND C.OBJECTID = CONCAT(H.BUKRS, H.BELNR, H.GJAHR)
LEFT JOIN V_USERNAME U ON C.USERNAME = U.BNAME
WHERE H.BSTAT = 'V' AND C.TCODE IN ('FBV2', 'FBV4') -- FBV2 is change parked doc, FBV4 is change parked doc header
UNION ALL
-- Event 8: Documentation Attached (inferred from GOS attachment creation, requires configuration)
SELECT
CONCAT(H.BUKRS, H.BELNR, H.GJAHR) AS "JournalEntryId",
'Documentation Attached' AS "ActivityName",
TO_TIMESTAMP(CONCAT(REL.RECDATE, '000000'), 'YYYYMMDDHH24MISS') AS "EventTime",
U.NAME_TEXT AS "User",
H.BUKRS AS "CompanyCode",
H.BLART AS "DocumentType",
H.BUDAT AS "PostingDate",
H.TCODE AS "TransactionCode",
FALSE AS "IsReversed"
FROM DOC_HEADERS H
JOIN SRGBTBREL REL ON REL.INSTID_A = CONCAT('BUS2081', H.BUKRS, H.BELNR, H.GJAHR) -- BUS2081 is object type for BKPF
LEFT JOIN V_USERNAME U ON REL.RECUNAM = U.BNAME
WHERE REL.TYPEID_A = 'BUS2081' AND REL.RELTYPE = 'ATTA'
UNION ALL
-- Events 9-13 from Workflow (Submitted, Changes Requested, Approved, Rejected) requires specific workflow config
-- This is a generic template. The WI_RH_TASK must be adapted to your system.
SELECT
CONCAT(H.BUKRS, H.BELNR, H.GJAHR) AS "JournalEntryId",
CASE
WHEN LOG.WI_RH_TASK = '[WF_TASK_ID_SUBMIT]' THEN 'Journal Entry Submitted'
WHEN LOG.WI_RH_TASK = '[WF_TASK_ID_APPROVE]' AND LOG.METHOD = 'DECISION' AND LOG.EVT_ID = 'COMPLETED' THEN 'Journal Entry Approved'
WHEN LOG.WI_RH_TASK = '[WF_TASK_ID_REJECT]' AND LOG.METHOD = 'DECISION' AND LOG.EVT_ID = 'COMPLETED' THEN 'Journal Entry Rejected'
WHEN LOG.WI_RH_TASK = '[WF_TASK_ID_CHANGES_REQ]' AND LOG.METHOD = 'DECISION' AND LOG.EVT_ID = 'COMPLETED' THEN 'Journal Entry Changes Requested'
ELSE NULL
END AS "ActivityName",
TO_TIMESTAMP(CONCAT(LOG.EVT_DATE, LOG.EVT_TIME), 'YYYYMMDDHH24MISS') AS "EventTime",
U.NAME_TEXT AS "User",
H.BUKRS AS "CompanyCode",
H.BLART AS "DocumentType",
H.BUDAT AS "PostingDate",
NULL AS "TransactionCode",
FALSE AS "IsReversed"
FROM DOC_HEADERS H
JOIN SWW_WI2OBJ WIOBJ ON WIOBJ.INSTID = CONCAT(H.BUKRS, H.BELNR, H.GJAHR) AND WIOBJ.TYPEID = 'BKPF'
JOIN SWWLOGHIST LOG ON WIOBJ.WI_ID = LOG.WI_ID
LEFT JOIN V_USERNAME U ON LOG.EXEC_USER = U.BNAME
WHERE LOG.WI_RH_TASK IN ('[WF_TASK_ID_SUBMIT]', '[WF_TASK_ID_APPROVE]', '[WF_TASK_ID_REJECT]', '[WF_TASK_ID_CHANGES_REQ]')
UNION ALL
-- Event 14: Manual Entry Identified
SELECT
CONCAT(H.BUKRS, H.BELNR, H.GJAHR) AS "JournalEntryId",
'Manual Entry Identified' AS "ActivityName",
TO_TIMESTAMP(CONCAT(H.CPUDT, H.CPUTM), 'YYYYMMDDHH24MISS') AS "EventTime",
U.NAME_TEXT AS "User",
H.BUKRS AS "CompanyCode",
H.BLART AS "DocumentType",
H.BUDAT AS "PostingDate",
H.TCODE AS "TransactionCode",
CASE WHEN H.STBLG IS NOT NULL AND H.STBLG <> '' THEN TRUE ELSE FALSE END AS "IsReversed"
FROM DOC_HEADERS H
LEFT JOIN V_USERNAME U ON H.USNAM = U.BNAME
WHERE H.TCODE IN ('FB01', 'F-02', 'FB50', 'F-04', 'F-22', 'F-43', 'FB60', 'FB70', 'FV50', 'FV60', 'FV70')
UNION ALL
-- Event 15: Cross-Company Posting Identified
SELECT
CONCAT(H.BUKRS, H.BELNR, H.GJAHR) AS "JournalEntryId",
'Cross-Company Posting Identified' AS "ActivityName",
TO_TIMESTAMP(CONCAT(H.CPUDT, H.CPUTM), 'YYYYMMDDHH24MISS') AS "EventTime",
U.NAME_TEXT AS "User",
H.BUKRS AS "CompanyCode",
H.BLART AS "DocumentType",
H.BUDAT AS "PostingDate",
H.TCODE AS "TransactionCode",
CASE WHEN H.STBLG IS NOT NULL AND H.STBLG <> '' THEN TRUE ELSE FALSE END AS "IsReversed"
FROM DOC_HEADERS H
LEFT JOIN V_USERNAME U ON H.USNAM = U.BNAME
WHERE H.XRECH = 'X' 단계
- SAP 연결 설정: 타사 ETL 도구에서 SAP ECC 시스템에 연결할 새 소스를 설정합니다. 일반적으로 애플리케이션 서버 정보, 클라이언트, 시스템 번호와 필요한 RFC 권한이 있는 전용 SAP 사용자 계정이 필요합니다.
- 데이터 소스 정의: 추출 프로젝트에 필요한 SAP 테이블을 데이터 소스로 추가합니다. 주요 테이블은 BKPF(회계 문서 헤더), BSEG(회계 문서 항목), VBSEGK(보류 문서 헤더), CDHDR(변경 문서 헤더), CDPOS(변경 문서 항목), SWW_WI2OBJ(워크플로와 객체 간 연결), SWWLOGHIST(워크플로 로그), SRGBTBREL(GOS 첨부 파일 관계)입니다.
- 기본 이벤트 추출(생성 및 보류): 초기 이벤트를 추출하는 첫 번째 데이터 흐름을 만듭니다. '분개 보류' 이벤트에는 VBSEGK를 소스로 사용합니다. '분개 생성' 이벤트에는 BKPF를 사용하고, 역분개가 아니며 처음부터 보류 상태가 아니었던 문서만 필터링합니다. VBSEGK와 안티 조인해 처리할 수 있습니다.
- 워크플로 이벤트 추출: 객체 키(회사 코드 + 문서 번호 + 회계연도)를 사용해 BKPF와 SWW_WI2OBJ를 조인하고 워크플로 인스턴스 ID를 찾습니다. 이 결과를 SWWLOGHIST와 조인해 로그에 기록된 워크플로 작업 결과와 사용자 결정에 따라 '제출', '승인', '거부', '수정 요청' 등의 이벤트를 추출합니다.
- 변경 및 삭제 이벤트 추출: CDHDR와 CDPOS 테이블을 사용해 변경 사항을 식별합니다. '분개 수정' 이벤트는 보류 문서(Object Class 'FIPP')에 대한 변경으로 필터링합니다. '보류 분개 삭제' 이벤트는 보류 문서의 변경 로그에서 삭제 표시를 찾습니다.
- 첨부 파일 이벤트 추출: '문서 첨부' 이벤트를 수집하려면 객체 유형이 'BKPF'이고 관계가 '[Your attachment relationship type]'인 SRGBTBREL 레코드를 BKPF와 조인합니다. 링크 생성일을 이벤트 시각으로 사용합니다.
- 반제 및 역분개 이벤트 추출: '분개 항목 반제' 이벤트는 반제 문서 필드(AUGBL)에 값이 있는 BSEG 레코드를 조회합니다. 이벤트 시각은 반제 문서의 전기일(AUGDT)입니다. '분개 역분개 처리' 이벤트는 역분개 문서 필드(STBLG)에 값이 있는 BKPF 문서를 조회해 식별합니다.
- 계산 이벤트 도출: 계산 이벤트별로 별도의 로직 블록을 만듭니다. '수기 입력 식별' 이벤트는 수기 거래 코드 목록(예: FB01, FB50, F-02)을 기준으로 BKPF를 필터링합니다. '회사 간 전기 식별' 이벤트는 BSEG를 문서 ID별로 그룹화하고 회사 코드가 두 개 이상인 문서를 찾습니다.
- 모든 이벤트 흐름 결합: ETL 도구의 UNION 변환을 사용해 개별 이벤트 흐름(생성, 보류, 승인 등)의 결과를 하나의 이벤트 로그 테이블로 합칩니다. 모든 흐름에서 열 이름과 데이터 유형이 일치하는지 확인합니다.
- 최종 스키마에 매핑: 결합한 데이터를 필요한 이벤트 로그 구조에 매핑해
JournalEntryId,ActivityName,EventTime,사용자와 기타 필수 및 권장 속성을 만듭니다.SourceSystem과 같은 고정 열을 추가하고 ETL 작업 실행 시각을LastDataUpdate에 사용합니다. - 증분 적재 설정: 정기적으로 추출하려면 증분 적재 전략을 설정합니다. 마지막 실행 이후 새로 생성되거나 업데이트된 레코드만 가져오도록 마지막 생성일 또는 변경일(예: BKPF.CPUDT, CDHDR.UDATE)을 워터마크로 사용합니다.
- ProcessMind에 업로드할 파일 내보내기: 추출 작업을 예약하고 최종 단계에서 이벤트 로그를 CSV 또는 Parquet 파일로 저장하도록 설정합니다. ProcessMind에 업로드할 수 있는 위치에 파일을 저장합니다.
구성
- 사전 요건: 전용 SAP 커넥터가 포함된 라이선스 보유 타사 ETL 도구(예: Theobald Xtract Universal, Informatica, Talend)가 필요합니다. 또한 RFC 접근 권한과 재무 테이블(예: 테이블 그룹 F_00, F_WF에 대한 S_TABU_DIS), 워크플로 데이터, 변경 로그를 읽을 권한이 있는 SAP 사용자 계정이 필요합니다.
- 연결 매개변수: SAP 애플리케이션 서버 IP 주소 또는 호스트 이름, 시스템 번호, 클라이언트 ID가 필요합니다. SAP 사용자 이름과 비밀번호는 안전한 자격 증명 관리 방식을 사용해 관리해야 합니다.
- 주요 필터: 데이터량을 제한하려면 소스에서 회사 코드(BKPF.BUKRS)와 회계연도(BKPF.GJAHR)를 항상 필터링합니다. 추출 기간을 지정할 수 있도록 문서 생성일(BKPF.CPUDT)도 필터링하는 것이 좋습니다. 예를 들어 최근 6개월을 지정할 수 있습니다.
- 기간 선택: 최초 로드에는 3~6개월과 같이 대표성 있는 기간을 선택합니다. 이후 델타 로드에서는
CPUDT와 같은 타임스탬프 필드에 워터마크를 설정해 새 레코드만 가져옵니다. - 성능 고려 사항: BSEG, CDPOS, 워크플로 테이블을 조인하면 처리 속도가 크게 느려질 수 있습니다. 가능한 경우 ETL 도구가 필터를 SAP 소스에 푸시다운하도록 설정합니다. 도구에서 지원하면 특히 과거 데이터를 대량으로 로드할 때 데이터를 작은 청크나 패키지로 나눠 추출합니다.
- 워크플로 사용자 지정: '승인' 또는 '거부'와 같은 워크플로 활동을 식별하는 로직은 사용 중인 워크플로 템플릿에 따라 달라집니다. 필터에 사용할 올바른 워크플로 작업 ID와 사용자 결정 키를 시스템에서 확인해야 합니다.
샘플 쿼리 sql
/*
This is a logical representation of the extraction configuration in a third-party ETL tool.
It is not executable SQL but defines the sources, joins, and transformations for each activity.
Placeholders like [Your SAP Source], [Date Filter], and [Company Code Filter] must be configured in the tool.
*/
-- Extraction block for 'Journal Entry Parked'
SELECT
CONCAT(v.BUKRS, v.VBELN, v.GJAHR) AS JournalEntryId,
'Journal Entry Parked' AS ActivityName,
CAST(CONCAT(v.CPUDT, v.CPUTM) AS TIMESTAMP) AS EventTime,
'SAP ECC' AS SourceSystem,
NOW() AS LastDataUpdate,
v.USNAM AS User,
v.BUKRS AS CompanyCode,
v.BLART AS DocumentType,
v.BUDAT AS PostingDate,
v.TCODE AS TransactionCode,
FALSE AS IsReversed
FROM [Your SAP Source].VBSEGK v
WHERE [Date Filter on v.CPUDT] AND [Company Code Filter on v.BUKRS]
UNION ALL
-- Extraction block for 'Journal Entry Created'
SELECT
CONCAT(h.BUKRS, h.BELNR, h.GJAHR) AS JournalEntryId,
'Journal Entry Created' AS ActivityName,
CAST(CONCAT(h.CPUDT, h.CPUTM) AS TIMESTAMP) AS EventTime,
'SAP ECC' AS SourceSystem,
NOW() AS LastDataUpdate,
h.USNAM AS User,
h.BUKRS AS CompanyCode,
h.BLART AS DocumentType,
h.BUDAT AS PostingDate,
h.TCODE AS TransactionCode,
FALSE AS IsReversed
FROM [Your SAP Source].BKPF h
LEFT JOIN [Your SAP Source].VBSEGK v ON h.AWKEY = CONCAT(v.BUKRS, v.VBELN, v.GJAHR)
WHERE h.BSTAT = '' AND v.VBELN IS NULL AND h.STBLG IS NULL
AND [Date Filter on h.CPUDT] AND [Company Code Filter on h.BUKRS]
UNION ALL
-- Extraction block for 'Journal Entry Posted' (from parked)
SELECT
CONCAT(h.BUKRS, h.BELNR, h.GJAHR) AS JournalEntryId,
'Journal Entry Posted' AS ActivityName,
CAST(CONCAT(h.CPUDT, h.CPUTM) AS TIMESTAMP) AS EventTime, -- Or a more precise posting time from change logs if available
'SAP ECC' AS SourceSystem,
NOW() AS LastDataUpdate,
h.USNAM AS User,
h.BUKRS AS CompanyCode,
h.BLART AS DocumentType,
h.BUDAT AS PostingDate,
h.TCODE AS TransactionCode,
FALSE AS IsReversed
FROM [Your SAP Source].BKPF h
JOIN [Your SAP Source].VBSEGK v ON h.AWKEY = CONCAT(v.BUKRS, v.VBELN, v.GJAHR)
WHERE [Date Filter on h.CPUDT] AND [Company Code Filter on h.BUKRS]
UNION ALL
-- Extraction block for 'Journal Entry Submitted', 'Approved', 'Rejected', 'Changes Requested'
SELECT
CONCAT(SUBSTRING(o.INSTID, 3, 4), SUBSTRING(o.INSTID, 7, 10), SUBSTRING(o.INSTID, 17, 4)) AS JournalEntryId,
CASE
WHEN wl.WI_TEXT LIKE '%Submit%' THEN 'Journal Entry Submitted'
WHEN wl.WI_TEXT LIKE '%Approve%' THEN 'Journal Entry Approved'
WHEN wl.WI_TEXT LIKE '%Reject%' THEN 'Journal Entry Rejected'
WHEN wl.WI_TEXT LIKE '%Request Changes%' THEN 'Journal Entry Changes Requested'
END AS ActivityName,
CAST(CONCAT(wl.WI_CD, wl.WI_CT) AS TIMESTAMP) AS EventTime,
'SAP ECC' AS SourceSystem,
NOW() AS LastDataUpdate,
wl.EXEC_USER AS User,
SUBSTRING(o.INSTID, 3, 4) AS CompanyCode,
NULL AS DocumentType,
NULL AS PostingDate,
NULL AS TransactionCode,
FALSE AS IsReversed
FROM [Your SAP Source].SWW_WI2OBJ o
JOIN [Your SAP Source].SWWLOGHIST wl ON o.WI_ID = wl.WI_ID
WHERE o.TYPEID = 'BKPF' AND o.CATID = 'BO'
AND wl.WI_TEXT IN ('[Your Submit Task Name]', '[Your Approve Task Name]', '[Your Reject Task Name]', '[Your Changes Request Task Name]')
AND [Date Filter on wl.WI_CD]
UNION ALL
-- Extraction block for 'Journal Entry Corrected'
SELECT
CONCAT(cd.OBJECTID_LONG_CHAR(3,4), cd.OBJECTID_LONG_CHAR(7,10), cd.OBJECTID_LONG_CHAR(17,4)) AS JournalEntryId,
'Journal Entry Corrected' AS ActivityName,
CAST(CONCAT(cd.UDATE, cd.UTIME) AS TIMESTAMP) AS EventTime,
'SAP ECC' AS SourceSystem,
NOW() AS LastDataUpdate,
cd.USERNAME AS User,
cd.OBJECTID_LONG_CHAR(3,4) AS CompanyCode,
NULL AS DocumentType,
NULL AS PostingDate,
cd.TCODE AS TransactionCode,
FALSE AS IsReversed
FROM [Your SAP Source].CDHDR cd
WHERE cd.OBJECTCLAS = 'FIPP' AND cd.CHANGE_IND = 'U'
AND [Date Filter on cd.UDATE]
UNION ALL
-- Extraction block for 'Parked Journal Entry Deleted'
SELECT
CONCAT(cd.OBJECTID_LONG_CHAR(3,4), cd.OBJECTID_LONG_CHAR(7,10), cd.OBJECTID_LONG_CHAR(17,4)) AS JournalEntryId,
'Parked Journal Entry Deleted' AS ActivityName,
CAST(CONCAT(cd.UDATE, cd.UTIME) AS TIMESTAMP) AS EventTime,
'SAP ECC' AS SourceSystem,
NOW() AS LastDataUpdate,
cd.USERNAME AS User,
cd.OBJECTID_LONG_CHAR(3,4) AS CompanyCode,
NULL AS DocumentType,
NULL AS PostingDate,
cd.TCODE AS TransactionCode,
FALSE AS IsReversed
FROM [Your SAP Source].CDHDR cd
WHERE cd.OBJECTCLAS = 'FIPP' AND cd.CHANGE_IND = 'D'
AND [Date Filter on cd.UDATE]
UNION ALL
-- Extraction block for 'Documentation Attached'
SELECT
CONCAT(SUBSTRING(r.INSTID_A, 3, 4), SUBSTRING(r.INSTID_A, 7, 10), SUBSTRING(r.INSTID_A, 17, 4)) AS JournalEntryId,
'Documentation Attached' AS ActivityName,
-- Note: A precise timestamp is often unavailable. Using document creation time as a proxy.
CAST(CONCAT(h.CPUDT, h.CPUTM) AS TIMESTAMP) AS EventTime,
'SAP ECC' AS SourceSystem,
NOW() AS LastDataUpdate,
h.USNAM AS User,
h.BUKRS AS CompanyCode,
h.BLART AS DocumentType,
h.BUDAT AS PostingDate,
h.TCODE AS TransactionCode,
FALSE AS IsReversed
FROM [Your SAP Source].SRGBTBREL r
JOIN [Your SAP Source].BKPF h ON h.BUKRS = SUBSTRING(r.INSTID_A, 3, 4) AND h.BELNR = SUBSTRING(r.INSTID_A, 7, 10) AND h.GJAHR = SUBSTRING(r.INSTID_A, 17, 4)
WHERE r.TYPEID_A = 'BKPF' AND r.RELTYPE = '[Configure based on your system]'
AND [Date Filter on h.CPUDT] AND [Company Code Filter on h.BUKRS]
UNION ALL
-- Extraction block for 'Journal Entry Reversal Processed'
SELECT
CONCAT(h.BUKRS, h.BELNR, h.GJAHR) AS JournalEntryId,
'Journal Entry Reversal Processed' AS ActivityName,
CAST(CONCAT(h.CPUDT, h.CPUTM) AS TIMESTAMP) AS EventTime,
'SAP ECC' AS SourceSystem,
NOW() AS LastDataUpdate,
h.USNAM AS User,
h.BUKRS AS CompanyCode,
h.BLART AS DocumentType,
h.BUDAT AS PostingDate,
h.TCODE AS TransactionCode,
TRUE AS IsReversed
FROM [Your SAP Source].BKPF h
WHERE h.STBLG IS NOT NULL AND h.STBLG <> ''
AND [Date Filter on h.CPUDT] AND [Company Code Filter on h.BUKRS]
UNION ALL
-- Extraction block for 'Is Reversed' flag on original document
SELECT
CONCAT(h_orig.BUKRS, h_orig.BELNR, h_orig.GJAHR) AS JournalEntryId,
'Is Reversed' AS ActivityName, -- This is an attribute update, modeled as an event
CAST(CONCAT(h_rev.CPUDT, h_rev.CPUTM) AS TIMESTAMP) AS EventTime,
'SAP ECC' AS SourceSystem,
NOW() AS LastDataUpdate,
h_rev.USNAM AS User,
h_orig.BUKRS AS CompanyCode,
h_orig.BLART AS DocumentType,
h_orig.BUDAT AS PostingDate,
h_orig.TCODE AS TransactionCode,
TRUE AS IsReversed
FROM [Your SAP Source].BKPF h_rev
JOIN [Your SAP Source].BKPF h_orig ON h_rev.STBLG = h_orig.BELNR AND h_rev.BUKRS = h_orig.BUKRS AND h_rev.GJAHR_S = h_orig.GJAHR
WHERE h_rev.STBLG IS NOT NULL AND h_rev.STBLG <> ''
AND [Date Filter on h_rev.CPUDT] AND [Company Code Filter on h_rev.BUKRS]
UNION ALL
-- Extraction block for 'Journal Entry Line Item Cleared'
SELECT
CONCAT(i.BUKRS, i.BELNR, i.GJAHR) AS JournalEntryId,
'Journal Entry Line Item Cleared' AS ActivityName,
CAST(i.AUGDT AS TIMESTAMP) AS EventTime,
'SAP ECC' AS SourceSystem,
NOW() AS LastDataUpdate,
NULL AS User, -- User who performed clearing is on the clearing document header
i.BUKRS AS CompanyCode,
NULL AS DocumentType,
NULL AS PostingDate,
NULL AS TransactionCode,
FALSE AS IsReversed
FROM [Your SAP Source].BSEG i
WHERE i.AUGBL IS NOT NULL AND i.AUGBL <> ''
AND [Date Filter on i.AUGDT] AND [Company Code Filter on i.BUKRS]
UNION ALL
-- Extraction block for 'Manual Entry Identified'
SELECT
CONCAT(h.BUKRS, h.BELNR, h.GJAHR) AS JournalEntryId,
'Manual Entry Identified' AS ActivityName,
CAST(CONCAT(h.CPUDT, h.CPUTM) AS TIMESTAMP) AS EventTime, -- Same time as creation
'SAP ECC' AS SourceSystem,
NOW() AS LastDataUpdate,
h.USNAM AS User,
h.BUKRS AS CompanyCode,
h.BLART AS DocumentType,
h.BUDAT AS PostingDate,
h.TCODE AS TransactionCode,
FALSE AS IsReversed
FROM [Your SAP Source].BKPF h
WHERE h.TCODE IN ('FB01', 'F-02', 'FB50', 'FV50', '[Add other manual T-Codes]')
AND [Date Filter on h.CPUDT] AND [Company Code Filter on h.BUKRS]
UNION ALL
-- Extraction block for 'Cross-Company Posting Identified'
SELECT
JournalEntryId,
'Cross-Company Posting Identified' AS ActivityName,
EventTime, -- Same time as creation
'SAP ECC' AS SourceSystem,
NOW() AS LastDataUpdate,
User,
CompanyCode,
DocumentType,
PostingDate,
TransactionCode,
IsReversed
FROM (
SELECT
CONCAT(h.BUKRS, h.BELNR, h.GJAHR) AS JournalEntryId,
CAST(CONCAT(h.CPUDT, h.CPUTM) AS TIMESTAMP) AS EventTime,
h.USNAM AS User,
h.BUKRS AS CompanyCode,
h.BLART AS DocumentType,
h.BUDAT AS PostingDate,
h.TCODE AS TransactionCode,
FALSE AS IsReversed,
(SELECT COUNT(DISTINCT i.BUKRS) FROM [Your SAP Source].BSEG i WHERE i.BELNR = h.BELNR AND i.BUKRS = h.BUKRS AND i.GJAHR = h.GJAHR) as CompanyCodeCount
FROM [Your SAP Source].BKPF h
WHERE [Date Filter on h.CPUDT] AND [Company Code Filter on h.BUKRS]
) AS CrossCompanyCheck
WHERE CompanyCodeCount > 1 시작할 준비가 되셨나요?
이 데이터 템플릿을 활용해 Record to Report - 분개 프로세스의 process mining을 시작하세요. 재무 운영을 더 자세히 파악하고 효율을 높일 수 있습니다.
지금 Record to Report - 분개 프로세스를 개선하세요
분개 처리 시간을 30% 줄이고 정확한 재무 보고를 지원하세요.
신용카드 없이 지금 바로 개선을 시작할 수 있습니다.