決算・レポーティング:仕訳データテンプレート
決算・レポーティング:仕訳データテンプレート
- 収集を推奨する属性
- 追跡すべき主要なアクティビティ
- 具体的な抽出方法
決算・レポーティング:仕訳処理の属性
| 名前 | 説明 | ||
|---|---|---|---|
| アクティビティ ActivityName | 仕訳プロセスの特定時点で発生した業務アクティビティの名称です。 | ||
| 説明 アクティビティは、仕訳のライフサイクルにおける具体的なステップまたはイベントです。たとえば、「仕訳を作成」、「仕訳を確認に回す」、「仕訳を転記」などが該当します。通常は、システムに記録された変更ログ、ステータス更新、トランザクションコードから導出します。 アクティビティを分析することで、プロセスフローを可視化し、一般的な経路を特定し、標準手順からの逸脱を検出できます。アクティビティの頻度、ステップ間の待ち時間、適合率などの指標を計算するための基本要素です。 重要な理由 プロセスの各ステップを定義し、プロセスマップの可視化とワークフローパターンの分析を可能にします。 入手先 ヘッダー・明細テーブルのステータス項目(BKPF-BSTATなど)、変更伝票ログ(CDHDR/CDPOS)、ワークフローログなど、さまざまなソースから導出します。 例 仕訳を作成仕訳を保留保存仕訳を確認に回す仕訳を承認仕訳を転記 | |||
| イベント時刻 EventTime | 仕訳について特定のアクティビティが発生した時点を示すタイムスタンプです。 | ||
| 説明 イベント時刻は、業務アクティビティが実行され、システムに記録された正確な日時です。ケース内の各アクティビティに固有のタイムスタンプがあり、イベントの時系列を構成します。 この属性は、時間に基づくプロセス分析に欠かせません。サイクル時間、アクティビティ間の所要時間、待ち時間の計算や、作業の時間的な分布の把握に使用します。信頼性の高いプロセスモデルを構築し、承認サイクル時間などの主要業績評価指標を計算するには、正確なタイムスタンプが必要です。 重要な理由 イベントの時系列を示します。すべての所要時間ベースの指標を計算し、プロセスの時間軸を把握するために欠かせません。 入手先 変更伝票ログ(CDHDR-UDATE、CDHDR-UTIME)、ワークフローログ、またはBKPFなどのテーブルにある作成・入力時刻(CPUDT、CPUTM)から取得します。 例 2023-10-26T10:05:00Z2023-11-15T14:30:15Z2024-01-20T09:00:45Z | |||
| 仕訳ID JournalEntryId | 財務仕訳を一意に識別するIDであり、プロセスの主要なケース識別子として機能します。 | ||
| 説明 仕訳IDは、SAP S/4HANAで各会計伝票の作成時に割り当てられる一意の番号です。この識別子によって、仕訳の作成または保留保存から、承認ワークフロー、最終転記、取消や消込に至るまで、ライフサイクル全体を追跡できます。 プロセスマイニング分析では、このIDを使って関連するすべてのアクティビティを1つのケースに結び付けます。共通の仕訳IDでイベントをグループ化することで、エンドツーエンドのプロセスフローを再構成し、サイクル時間を測定し、個々の財務取引におけるばらつきやボトルネックを特定できます。プロセス全体を表示するための基盤となる属性です。 重要な理由 この識別子によって関連するすべてのプロセスステップが結び付けられ、各仕訳の一連の流れを最初から最後まで分析できます。 入手先 通常は、会社コード(BKPF-BUKRS)、伝票番号(BKPF-BELNR)、会計年度(BKPF-GJAHR)を連結して作成する複合キーです。 例 1000-1000000001-20231710-1900000055-20242000-2100003412-2023 | |||
| 仕訳タイプ JournalEntryType | 資産計上、仕入先請求書、総勘定元帳への計上など、業務上の目的に基づいて仕訳を分類します。 | ||
| 説明 仕訳タイプは、SAPの用語では伝票タイプと呼ばれ、会計伝票を分類するキーです。伝票に割り当てる番号範囲や、計上を許可する勘定タイプなどを制御します。 仕訳タイプ別にプロセスを分析すると、業務内容ごとの動きを理解できます。たとえば、単純な未払計上(タイプSA)の承認プロセスは、複雑な資産取得(タイプAA)よりも大幅に簡単な場合があります。「仕訳タイプ別コンプライアンス」ダッシュボードの基盤となる項目です。 重要な理由 業務上の背景に基づいて仕訳を分類し、異なる財務取引におけるプロセスの違いやパフォーマンスを分析できます。 入手先 SAP S/4HANAテーブルBKPFのフィールドBLART(伝票タイプ)です。 例 SAKRAA | |||
| 会社コード CompanyCode | 仕訳が計上される会社または法人を一意に識別する値です。 | ||
| 説明 会社コードはSAP Financialsにおける基本的な組織単位で、財務諸表を作成する独立した法人を表します。すべての仕訳は特定の会社コードに割り当てられます。 この属性は、組織内の異なる部門や法人間でプロセスパフォーマンスを分けて比較するうえで重要です。特定の法人に絞ってプロセスビューを表示したり、会社コード間で却下率を比較したり、地域ごとのプロセスの違いを特定したりできます。 重要な理由 組織内の異なる法人や事業部門について、仕訳プロセスを抽出して比較できます。 入手先 SAP S/4HANAテーブルBKPFのフィールドBUKRS(会社コード)です。 例 10001710US01 | |||
| 作成ユーザー CreatedByUser | 仕訳を作成した担当者のユーザーIDです。 | ||
| 説明 この属性は、初期文書を作成して仕訳プロセスを開始したユーザーの一意の識別子を保持します。経理担当者、業務ユーザー、自動登録を行うシステムIDなどが該当します。 作成者別にプロセスを分析すると、特定のユーザーやチームに関連する傾向を把握できます。特定のユーザーの却下率が高い場合はトレーニングの必要性を示し、パフォーマンスの高い担当者を見つけることもできます。「ユーザーアクティビティと処理量」ダッシュボードに欠かせない属性です。 重要な理由 プロセスアクティビティを特定のユーザーに割り当て、パフォーマンス分析、作業負荷の平準化、トレーニング機会の特定に役立ちます。 入手先 SAP S/4HANAテーブルBKPFのフィールドUSNAM(ユーザー名)です。 例 ABROWNCJONESBATCH_USER | |||
| 現地通貨での金額 AmountInLocalCurrency | 会社コードの現地通貨で表した仕訳の合計金額です。 | ||
| 説明 この属性は、仕訳の金額規模を表します。通常は、伝票内のすべての借方または貸方明細の絶対値を合計し、会社コードの現地通貨に換算した値です。 金額別に分析すると、財務上の影響に応じてプロセスを分類できます。たとえば、高額な仕訳には、少額の仕訳よりも厳格な承認プロセスが適用される場合があります。財務リスクが最も高い取引に改善活動を優先的に行う際にも役立ちます。 重要な理由 仕訳の金額を示し、取引金額に応じてプロセスの動きがどのように変化するかを分析できます。 入手先 仕訳(BELNR)ごとに明細テーブルBSEGの金額(フィールドDMBTR)を合計し、正の値に変換して算出します。 例 1500.75125000.0050.20 | |||
| 転記日付 PostingDate | 仕訳が総勘定元帳に記録され、会計期間に反映される日付です。 | ||
| 説明 転記日付によって、取引が財務諸表に表示される会計期間が決まります。会計処理における重要な日付であり、文書を作成した日付やシステムに入力した日付とは異なる場合があります。 プロセスマイニングでは、転記日付を期間別のコホート分析に使用します。たとえば、月末決算プロセスを比較したり、異なる会計期間のパフォーマンス傾向を分析したりできます。また、仕訳の作成から実際の財務転記までの遅延時間を測定する際にも使われます。 重要な理由 財務上の背景を把握するために欠かせない属性で、月末や年度末など、特定の会計期間内のプロセスパフォーマンスを分析できます。 入手先 SAP S/4HANAテーブルBKPFのフィールドBUDAT(伝票の転記日付)です。 例 2023-10-312023-11-012024-02-29 | |||
| ソースシステム SourceSystem | 仕訳データの抽出元となるソースシステムを識別します。 | ||
| 説明 この属性は、仕訳データの取得元である記録システムを指定します。複数のERPインスタンスや、レガシーシステムと最新システムが混在する企業では、データソースを区別するために役立ちます。 分析では、異なるシステム間でプロセスパフォーマンスを比較したり、特定のソースのデータだけを抽出したりできます。データガバナンスを確保し、データの背景を正しく理解するうえで重要です。 重要な理由 データの取得元に関する背景を示します。複数のシステムが存在する環境で、正確なプロセス分析と比較を行うために欠かせません。 入手先 通常はデータ抽出時に追加される静的な値で、特定のSAP S/4HANAインスタンス(SIDや論理システム名など)を識別します。 例 S4H_PROD_100ECC_FIN_200S4C_US_EAST | |||
| トランザクションコード TransactionCode | 仕訳の作成または変更に使用したSAPのトランザクションコードです。 | ||
| 説明 トランザクションコード(T-Code)は、SAP内の特定の機能やプログラムを識別するショートカットです。仕訳では、FB01が手動の総勘定元帳転記、FV50が仮登録を示すなど、仕訳の作成方法をT-Codeから判断できます。システムが自動生成した仕訳には、自動処理用のコードが使われる場合があります。 この属性は、アクティビティがユーザーによって手動で実行されたのか、システムによって自動実行されたのかを判断する有力な指標です。手動転記率KPIの計算や、自動化の候補を特定する際に役立ちます。 重要な理由 仕訳の処理方法(手動か自動かなど)を示し、自動化の分析やプロセスの違いを理解するうえで重要です。 入手先 SAP S/4HANAテーブルBKPFのフィールドTCODE(トランザクションコード)です。 例 FB01FV50F-02 | |||
| 会計年度 FiscalYear | 仕訳が属する会計年度です。 | ||
| 説明 会計年度は、会社コードおよび伝票番号とともに、仕訳の一意のキーを構成します。文書が関連する会計年度を表します。 分析では、会計年度を長期的な傾向分析やケース識別子の一意性の確保に使用します。年度ごとにプロセス指標を比較すると、時間の経過に伴うパフォーマンスの改善や悪化を把握できます。 重要な理由 文書を一意に識別するための重要な要素であり、前年比でのプロセスパフォーマンス分析を可能にします。 入手先 SAP S/4HANAテーブルBKPFのフィールドGJAHR(会計年度)です。 例 202320242022 | |||
| 伝票ステータス DocumentStatus | 仕訳の現在の処理状態です。仮登録、転記済み、消込済みなどが該当します。 | ||
| 説明 伝票ステータスは、仕訳のライフサイクル上の状態を示します。たとえば、「仮登録」伝票は保存されていますが、まだ総勘定元帳には転記されていません。一方、「転記済み」伝票は処理が確定しています。 ステータスを分析すると、作業の流れを把握し、ボトルネックを特定できます。「仮登録」や「承認待ち」の伝票が長期間にわたって大量に残っている場合、プロセスの非効率を示している可能性があります。また、プロセスアクティビティを導出するための重要な情報源でもあります。 重要な理由 仕訳がライフサイクルのどの段階にあるかを示し、滞留やボトルネックの特定に役立ちます。 入手先 SAP S/4HANAテーブルBKPFのフィールドBSTAT(伝票ステータス)です。 例 VAB | |||
| 最終データ更新日時 LastDataUpdate | このレコードのデータがソースシステムから最後に更新された日時を示すタイムスタンプです。 | ||
| 説明 この属性は、ソースシステムから最後にデータを抽出または更新した日時を記録します。分析対象データの鮮度を明確に把握できます。 最終更新日時を確認することは、プロセス分析がどの時点の状況を示しているかを理解するうえで重要です。ほぼリアルタイムのデータを見ているのか、過去の期間のスナップショットを見ているのかを判断できるため、ダッシュボードやKPIを正しく解釈できます。 重要な理由 データの鮮度を示し、プロセス分析がどの程度最新の状態を反映しているかを把握できます。 入手先 メタデータ属性です。通常はデータ取り込みパイプラインで各レコードに生成され、付与されます。 例 2024-03-10T02:00:00Z2024-03-11T02:00:00Z2024-03-12T02:00:00Z | |||
| 取消理由 ReversalReason | 転記済みの仕訳を取り消した理由を示すコードです。 | ||
| 説明 転記済みの仕訳に誤りがある場合、削除することはできず、新しい伝票を作成して取り消す必要があります。取消理由コードは、転記日付や金額の誤りなど、取消を行った理由を示します。 取消理由を分析すると、決算・レポーティングプロセスでエラーが発生した根本原因を特定できます。特定の理由が頻繁に発生している場合、トレーニング不足や統制上の問題など、改善が必要な組織的な課題が見つかる可能性があります。 重要な理由 取消につながったエラーの根本原因を診断し、手戻りの削減とプロセス品質の向上に必要な情報を得られます。 入手先 SAP S/4HANAテーブルBKPFのフィールドSTGRD(取消理由)です。 例 010205 | |||
| 手動転記 IsManualPosting | 仕訳がユーザーによって手動で転記されたかどうかを示すブール値です。 | ||
| 説明 この属性は、システムジョブやインターフェースによる自動転記ではなく、ユーザーの手動操作によって転記された仕訳を識別します。通常は、伝票の転記に使用されたトランザクションコードから導出します。 このフラグは、手動転記率KPIの計算に使われ、組織が決算・レポーティングプロセスの自動化をどの程度進めているかを把握するのに役立ちます。手動転記に絞り込むことで、依然として人の操作が必要な具体的なケースを特定し、自動化の可能性を評価できます。 重要な理由 人による転記とシステムによる転記を区別し、自動化の水準を測定して自動化の候補を特定できます。 入手先 TransactionCodeから導出される計算属性です。手動トランザクションコードの定義済みリスト(「FB01」、「F-02」など)を使い、該当する場合はフラグをtrueに設定します。 例 truefalse | |||
| 手戻りあり IsRework | 仕訳に手戻りが発生したかどうかを示すブール値です。却下後の修正などが該当します。 | ||
| 説明 この計算属性は、仕訳が理想的な「ハッピーパス」から外れたかどうかを示します。ケース内で「仕訳却下」や「仕訳修正」などのアクティビティが発生した場合、通常はtrueに設定されます。 このフラグによって、プロセス効率を簡単に分析できます。手戻り率KPIをすぐに計算できるほか、手戻りのあるケースとないケースで、サイクルタイムやコストを直接比較できます。手戻りの原因を特定することは、多くのプロセス改善活動における主要な目的です。 重要な理由 修正や追加のループが必要だったケースを示し、プロセスの非効率を定量化して根本原因を分析できます。 入手先 ケース内のアクティビティの順序から導出される計算属性です。「仕訳却下」などのアクティビティが存在する場合、trueとして設定されます。 例 truefalse | |||
| 承認サイクルタイム ApprovalCycleTime | 仕訳を承認に提出してから、承認または却下されるまでの経過時間です。 | ||
| 説明 この計算指標は、承認段階にかかった時間を測定します。「仕訳レビュー提出」アクティビティから、その後の「仕訳承認」または「仕訳却下」アクティビティまでの時間を計測します。 このKPIは、承認ワークフロー内のボトルネックを特定するうえで重要です。承認サイクルタイムが長いと、プロセス全体が大幅に遅れる可能性があります。承認者、会社コード、仕訳タイプ別に分析すると、改善すべき具体的な領域を特定できます。 重要な理由 承認ステップの所要時間だけを切り出し、レビューおよび承認ワークフローのボトルネックを特定して改善できます。 入手先 「仕訳レビュー提出」イベントと「仕訳承認」または「仕訳却下」イベントの時間差から算出します。 例 1日2時間4時間25分5日0時間 | |||
| 承認ユーザー ApproverUser | 仕訳を承認または却下した担当者のユーザーIDです。 | ||
| 説明 この属性は、提出された仕訳を確認し、判断を下したユーザーを識別します。複数段階の承認ワークフローでは、1件の仕訳に複数の承認者が関与する場合があります。 承認プロセスを詳しく分析するうえで欠かせない情報です。承認者ごとの作業負荷を測定し、個人別の承認時間を計算し、承認経路のボトルネックを特定できます。「ユーザーアクティビティと処理量」ダッシュボードにも直接利用できます。 重要な理由 承認を担当した個人を特定し、承認者ごとの作業負荷、パフォーマンス、ボトルネックを分析できます。 入手先 ワークフローログ(SWW_WI2OBJ、SWWLOGなど)または変更文書テーブル(CDHDR/CDPOS)から、承認ステップを実行したユーザーを追跡して取得します。 例 DMILLERFWHITEKCHEN | |||
| 終了時刻 EndTime | アクティビティが完了した日時を示すタイムスタンプです。 | ||
| 説明 End Timeは、アクティビティの完了時点を示します。多くのイベントログでは、瞬時に発生するイベントを表すため、アクティビティのStart TimeとEnd Timeが同じです。一方、ユーザーが文書を確認する場合のように、所要時間を測定できるアクティビティでは、この属性によって処理時間を記録できます。 End Timeを個別に保持すると、アクティビティの処理時間と待機時間をより正確に計算できます。タスクが実際に処理されていた時間と、キューで待機していた時間を区別できます。 重要な理由 アクティビティの正確な処理時間を計算し、実作業時間と待機時間を分けて把握できます。 入手先 原子的なイベントでは通常StartTimeと同じです。所要時間のあるアクティビティでは、ワークフローログから取得するか、後続イベントを基に計算する場合があります。 例 2023-10-26T10:05:00Z2023-11-15T14:45:20Z2024-01-20T09:10:30Z | |||
決算・レポーティング:仕訳処理のアクティビティ
| アクティビティ | 説明 | ||
|---|---|---|---|
| 仕訳の取消を処理 | 以前に転記した仕訳を、逆方向の転記を行う新しい伝票を作成して取り消します。転記済み伝票のエラーを修正するための明示的で監査可能な取引です。 | ||
| 重要な理由 取消は、転記済み伝票にエラーがあったことを示します。取消率が高い場合、承認プロセスやデータ入力の品質に根本的な問題がある可能性があります。これを追跡することで、初回処理の正確性を高められます。 入手先 取消は明示的なイベントです。新しく作成された取消伝票のヘッダー(BKPF)には、取消元伝票への参照が取消元伝票番号(STBLG)項目に記録されます。新しい伝票の転記日がイベント時刻です。 取得 BKPF-STBLGに値が設定されている伝票を特定します。イベントのタイムスタンプには、取消伝票の転記日を使用します。 イベントタイプ explicit | |||
| 仕訳を作成 | このアクティビティは、システム内で仕訳伝票を最初に作成したことを示します。レコードはヘッダーテーブル(BKPF)に作成されますが、総勘定元帳にはまだ転記されていません。仕訳ライフサイクルの開始点です。 | ||
| 重要な理由 プロセスの主要な開始イベントです。このイベントから転記までの時間を分析することで、全体のサイクル時間を測定し、初期入力の遅延を特定できます。 入手先 このイベントは、特定の伝票番号(BELNR)について、SAPテーブルBKPFの作成日(CPUDT)と作成時刻(CPUTM)を使って明示的に取得できます。 取得 イベントのタイムスタンプにはBKPF-CPUDTとBKPF-CPUTMを使用します。 イベントタイプ explicit | |||
| 仕訳を承認 | 権限を持つ管理者が仕訳を最終承認し、その妥当性と正確性を確認します。このアクティビティは、伝票を総勘定元帳に転記する前の最終ゲートです。 | ||
| 重要な理由 承認サイクルを完了する重要なマイルストーンです。このステップに到達するまでの時間は、プロセス全体の所要時間を構成する主要な要素であり、承認者の処理効率を示す重要な指標です。 入手先 通常は、最終承認ステップを示すワークフローログ、または伝票のステータス変更から推定します。承認者のユーザーIDとタイムスタンプは、ワークフローデータまたは変更ログから取得できます。 取得 ワークフローログで最終承認ステップのタイムスタンプを特定するか、変更伝票でステータスが「承認」に変わった時点を特定します。 イベントタイプ inferred | |||
| 仕訳を消込 | 仕訳内の未消込明細が、請求書を支払って消込する場合など、別の転記によって相殺されます。このアクティビティは、特定の明細を照合してクローズすることを示します。 | ||
| 重要な理由 多くの仕訳、特に仮勘定や未消込明細管理の勘定に関する仕訳では、最終的な照合ステップにあたります。転記から消込までの時間を分析することで、照合の効率を測定できます。 入手先 このイベントは、明細テーブル(BSEGまたはACDOCAビュー)から推定します。明細が消し込まれると、その明細の消込日(AUGDT)と消込伝票(AUGBL)項目に値が設定されます。 取得 明細の消込日(BSEG-AUGDT)をイベントのタイムスタンプとして使用します。 イベントタイプ inferred | |||
| 仕訳を確認に回す | 仕訳の作成者が伝票を正式に確認・承認ワークフローへ申請します。このアクティビティは、データ入力から正式な統制プロセスへの引き継ぎを示し、承認サイクルを開始します。 | ||
| 重要な理由 承認サイクル時間の開始点です。この時点から最終承認または拒否までを測定することで、確認・承認ステージ内のボトルネックを切り分けられます。 入手先 通常は、業務オブジェクトに関連付けられたワークフローログ(テーブルSWW_WIHEAD、SWWLOG)から取得します。伝票ヘッダー(BKPF)のカスタム項目におけるステータス変更から推定することもできます。 取得 ワークフロー項目の作成タイムスタンプ、またはステータス項目が「申請済み」もしくは「確認中」に変わった時点を使用します。 イベントタイプ inferred | |||
| 仕訳を転記 | 仕訳が総勘定元帳に正式に記録され、会社の財務諸表に影響します。この時点で伝票は恒久的な財務記録になります。 | ||
| 重要な理由 主要な成功マイルストーンであり、中核処理サイクルの終了を示します。転記済み仕訳の処理量と、この段階に到達するまでの時間を分析することは、プロセスマイニングの基本指標です。 入手先 BKPFテーブルの転記日(BUDAT)で示される明示的なイベントです。転記済み伝票では伝票ステータス(BSTAT)が空欄になり、保留(「V」)や保留中(「D」)の伝票と区別できます。 取得 イベントのタイムスタンプには転記日(BKPF-BUDAT)と入力日(BKPF-CPUDT)を使用します。BKPF-BSTATが空欄であれば、転記済み伝票を示します。 イベントタイプ explicit | |||
| 仕訳を保留保存 | ユーザーが未完成の仕訳を転記せずに保存し、後で完成または確認できるようにします。これは、伝票ヘッダーレコードを作成し、ステータスを「保留」として未転記の状態に保持する明示的な操作です。 | ||
| 重要な理由 保留保存は、申請前によく行われるステップです。保留状態の期間を追跡することで、正式な確認・承認プロセスが始まる前のデータ完成や準備における遅延を特定できます。 入手先 BKPFテーブルでは、伝票ステータス項目(BSTAT)が「V」の値を持つ伝票を保留伝票として識別します。イベントのタイムスタンプには作成日(CPUDT)を使用します。 取得 作成時点でBKPF-BSTAT=「V」の伝票を抽出します。 イベントタイプ explicit | |||
| 仕訳を修正 | ユーザーが、仕訳を拒否された後、または修正のため差し戻された後に変更します。確認プロセスで指摘された問題に対応し、再申請するまでに必要な手戻り作業を示します。 | ||
| 重要な理由 このアクティビティによって手戻りの発生を数値化できます。修正の頻度と所要時間を分析することで、非効率の原因を特定し、トレーニングやプロセスの明確化に向けた改善機会を見つけられます。 入手先 BKPFテーブルの「最終変更日」(AEDAT)を追跡し、以前に「拒否」状態だった伝票について推定できます。変更伝票から、変更内容をより詳しく確認できます。 取得 拒否イベント後に行われた変更については、変更伝票ヘッダー(CDHDR-UDATE)のタイムスタンプを使用します。 イベントタイプ inferred | |||
| 仕訳を拒否 | 確認者または承認者が仕訳を否認し、転記できない状態にします。通常、伝票は修正のため作成者に差し戻され、手戻りが発生します。 | ||
| 重要な理由 拒否を追跡することは、プロセス品質を把握し、共通するエラーを特定するうえで重要です。拒否率が高い場合、データの正確性、ポリシーの理解、証憑の不足に問題がある可能性があります。 入手先 このイベントは、ワークフローログまたは仕訳伝票のカスタムステータス項目の変更から推定します。関連するステータス項目について、変更伝票ログ(CDHDR/CDPOS)からタイムスタンプを取得できます。 取得 変更伝票(CDHDR/CDPOS)またはワークフローログで、ステータス項目が「拒否」に変わったことを特定します。 イベントタイプ inferred | |||
| 手動転記を特定 | 仕訳が自動インターフェースやバッチジョブではなく、手動のトランザクションコードを使って転記されたことを示します。これは時間的なイベントではなく、転記アクティビティの分類です。 | ||
| 重要な理由 手動転記の特定は、自動化施策に欠かせません。手動転記の割合が高い場合、サブシステムの連携や自動転記プログラムの利用によってプロセスを効率化できる可能性があります。 入手先 伝票ヘッダーテーブル(BKPF)のトランザクションコード(TCODE)項目を分析して算出します。既知の手動T-Code(FB01、F-02、FB50など)の一覧を使って仕訳を分類します。 取得 転記時点で、BKPF-TCODEをあらかじめ定義した手動トランザクションコードの一覧と照合し、イベントを分類します。 イベントタイプ calculated | |||
| 証憑を添付 | ユーザーが請求書やスプレッドシートなどの証憑を1つ以上仕訳に添付します。通常は、確認・監査の際に取引の根拠と背景を示すために行います。 | ||
| 重要な理由 確認前に証憑が添付されていることは、コンプライアンスと承認効率のために重要です。このアクティビティによって、証憑に関するポリシーの遵守状況と、承認サイクル時間への影響を測定できます。 入手先 通常は、Generic Object Services(GOS)経由で関連付けられた添付ファイルの作成タイムスタンプを確認して推定します。SRGBTBRELテーブルによって、業務オブジェクト(BKPF伝票など)と添付ファイルが関連付けられます。 取得 GOS添付ファイルテーブル(SRGBTBRELなど)でBKPFオブジェクトへのリンクを検索し、添付ファイルの作成タイムスタンプを使用します。 イベントタイプ inferred | |||
| 転記後に仕訳を変更 | ユーザーが、仕訳を総勘定元帳に転記した後に、一部の項目を変更します。転記後はほとんどの財務データを変更できませんが、テキストや割当などの項目は変更できる場合があります。 | ||
| 重要な理由 このアクティビティは、コンプライアンス上の重要な警告です。転記後の変更は記録を改ざんしようとする行為を示す可能性があるため、不正防止とデータの完全性確保に向けて厳密に監視する必要があります。 入手先 変更伝票テーブル(CDHDR、CDPOS)から確実に推定できます。伝票番号に対応するCDHDRの記録で、転記日より後の変更日が確認された場合、転記後の変更を示します。 取得 CDHDRで、変更タイムスタンプ(UDATE/UTIME)が伝票の転記日(BKPF-BUDAT)より後になっているレコードを検索します。 イベントタイプ inferred | |||
抽出ガイド
ステップ
- 前提条件とアクセス権限:SAP S/4HANAの基盤データベースに対してクエリを実行するか、ABAPレポートを実行するために必要な権限を持つユーザーを用意します。CDS ViewのI_JournalEntry、I_JournalEntryItem、およびテーブルのCDHDR、CDPOS、SRGBREL、SOOD、SWW_WI2OBJ、SWWLOGHISTへの読み取りアクセスが必要です。通常はSAP HANA StudioやDBeaverなどのデータベースクライアント、またはEclipse向けSAP ABAP Development Tools(ADT)からアクセスします。
- システム固有の設定を確認:クエリを実行する前に、仕訳承認ワークフローで使用されるタスクコードを確認します。SAPワークフロー管理者に確認し、登録、却下、承認の各イベントに対応するタスクID(例:TS12345678)を特定してください。これらは最終クエリのプレースホルダーに設定します。
- SQLクエリを準備:
queryセクションに記載された完全なSQLクエリを、使用するSQLクライアントまたは開発ツールにコピーします。 - クエリパラメーターを設定:クエリ内のプレースホルダーを確認し、固有の値に置き換えます。[YourCompanyCode]、[StartDate]、[EndDate]を設定してください。また、ワークフロータスクIDのプレースホルダー([Workflow Submitted Task ID]、[Workflow Rejected Task ID]、[Workflow Approved Task ID])も、前の手順で確認した値に置き換えます。
- 抽出クエリを実行:変更したSQLクエリをSAP S/4HANAデータベースに対して実行します。日付範囲やデータ量によっては、完了までに時間がかかる場合があります。負荷の低い時間帯に実行することをお勧めします。
- 初期結果を確認:クエリの実行が完了したら、JournalEntryId、ActivityName、EventTimeなどのすべての列に想定どおり値が入っているか、出力の先頭数行を確認します。結果セットには、仕訳のライフサイクルにおける個別の業務イベントごとに1行が含まれている必要があります。
- データをCSVにエクスポート:SQLツールから結果セット全体を1つのCSVファイルにエクスポートします。特殊文字の問題を防ぐため、UTF-8エンコーディングを使用してください。
- アップロードの準備:プロセスマイニングツールにアップロードする前に、CSVファイルに必要なヘッダーが含まれていることを確認します。データはすでにイベントログとして構成されているため、通常は追加の変換やピボット処理は必要ありません。
設定
- Core Data Services(CDS)View:抽出では、主にヘッダーデータに
I_JournalEntry、明細および金額の詳細にI_JournalEntryItemを使用します。これらのViewは、ユニバーサルジャーナル(ACDOCA)に対する、簡潔で意味の明確なインターフェースを提供します。 - 関連テーブル:プロセス全体を把握するため、クエリでは複数の標準SAPテーブルも結合します。
CDHDRとCDPOS:伝票の変更を追跡します。SRGBRELとSOOD:Generic Object Services(GOS)によって添付ファイルがリンクされた時点を特定します。SWW_WI2OBJとSWWLOGHIST:承認ワークフローから主要なイベントを抽出します。
- 日付範囲による絞り込み:パフォーマンスを維持するため、特定の日付範囲でデータを絞り込むことが重要です。
WHERE句ではI_JournalEntry.CreationDateTimeフィールドを使用します。初回分析では、3~6か月の範囲をお勧めします。 - 組織による絞り込み:関連する法人に限定するため、必ず
CompanyCodeで絞り込んでください。大規模なシステムで全会社コードを一度に検索すると、実行時間が非常に長くなる場合があります。 - ワークフロータスクID:クエリにはワークフロータスクID(例:[Workflow Approved Task ID])のプレースホルダーが含まれています。これらはSAPの各インストール環境で異なるため、ワークフローのアクティビティを抽出するには正しく設定する必要があります。設定しない場合、登録、承認、却下のイベントは取得されません。
- 前提条件:実行ユーザーには、財務、システム、ワークフローの各テーブルを読み取るための広範な権限が必要です。これらの権限は標準では付与されないため、個別に割り当ててください。
a サンプルクエリ sql
WITH JournalEntryAmountCTE AS (
SELECT
CompanyCode,
AccountingDocument,
FiscalYear,
SUM(AmountInCompanyCodeCurrency) AS AmountInLocalCurrency
FROM I_JournalEntryItem
GROUP BY CompanyCode, AccountingDocument, FiscalYear
),
JournalEntryBaseCTE AS (
SELECT
JE.CompanyCode,
JE.AccountingDocument,
JE.FiscalYear,
JE.CreatedByUser,
JE.CreationDateTime,
JE.PostingDateTime,
JE.PostingDate,
JE.AccountingDocumentType,
JE.DocumentIsParked,
JE.ReversedJournalEntry,
JE.TransactionCode,
JEA.AmountInLocalCurrency
FROM I_JournalEntry AS JE
LEFT JOIN JournalEntryAmountCTE AS JEA
ON JE.CompanyCode = JEA.CompanyCode
AND JE.AccountingDocument = JEA.AccountingDocument
AND JE.FiscalYear = JEA.FiscalYear
WHERE JE.CompanyCode IN ('[YourCompanyCode]')
AND JE.CreationDateTime BETWEEN '[StartDate]' AND '[EndDate]'
)
-- 1. Journal Entry Created
SELECT
BJE.AccountingDocument AS "JournalEntryId",
'Journal Entry Created' AS "ActivityName",
BJE.CreationDateTime AS "EventTime",
BJE.CreatedByUser AS "CreatedByUser",
BJE.CompanyCode AS "CompanyCode",
BJE.AccountingDocumentType AS "JournalEntryType",
BJE.PostingDate AS "PostingDate",
BJE.AmountInLocalCurrency AS "AmountInLocalCurrency"
FROM JournalEntryBaseCTE AS BJE
UNION ALL
-- 2. Journal Entry Parked
SELECT
BJE.AccountingDocument AS "JournalEntryId",
'Journal Entry Parked' AS "ActivityName",
BJE.CreationDateTime AS "EventTime",
BJE.CreatedByUser AS "CreatedByUser",
BJE.CompanyCode AS "CompanyCode",
BJE.AccountingDocumentType AS "JournalEntryType",
BJE.PostingDate AS "PostingDate",
BJE.AmountInLocalCurrency AS "AmountInLocalCurrency"
FROM JournalEntryBaseCTE AS BJE
WHERE BJE.DocumentIsParked = 'X'
UNION ALL
-- 3. Supporting Documentation Attached
SELECT
BJE.AccountingDocument AS "JournalEntryId",
'Supporting Documentation Attached' AS "ActivityName",
TO_TIMESTAMP(SOOD.CREDAT || ' ' || SOOD.CRETIM, 'YYYYMMDD HH24MISS') AS "EventTime",
SOOD.OWNER AS "CreatedByUser",
BJE.CompanyCode AS "CompanyCode",
BJE.AccountingDocumentType AS "JournalEntryType",
BJE.PostingDate AS "PostingDate",
BJE.AmountInLocalCurrency AS "AmountInLocalCurrency"
FROM JournalEntryBaseCTE AS BJE
JOIN SRGBREL ON SRGBREL.INSTID_A = CONCAT(BJE.CompanyCode, BJE.AccountingDocument, BJE.FiscalYear)
AND SRGBREL.TYPEID_A = 'BKPF'
AND SRGBREL.CATID_A = 'BO'
JOIN SOOD ON SOOD.OBJTP = SRGBREL.TYPEID_B
AND SOOD.OBJYR = SRGBREL.INSTID_B(3)
AND SOOD.OBJNO = SRGBREL.INSTID_B(5)
UNION ALL
-- 4. Journal Submitted For Review
SELECT
BJE.AccountingDocument AS "JournalEntryId",
'Journal Submitted For Review' AS "ActivityName",
LOG.END_TS AS "EventTime",
LOG.EXEC_USER AS "CreatedByUser",
BJE.CompanyCode AS "CompanyCode",
BJE.AccountingDocumentType AS "JournalEntryType",
BJE.PostingDate AS "PostingDate",
BJE.AmountInLocalCurrency AS "AmountInLocalCurrency"
FROM JournalEntryBaseCTE AS BJE
JOIN SWW_WI2OBJ AS WF_LINK ON WF_LINK.INSTID = CONCAT(BJE.CompanyCode, BJE.AccountingDocument, BJE.FiscalYear)
AND WF_LINK.TYPEID = 'BKPF'
JOIN SWWLOGHIST AS LOG ON LOG.WI_ID = WF_LINK.WI_ID
WHERE LOG.METHOD = '[Workflow Submitted Task ID]'
UNION ALL
-- 5. Journal Entry Rejected
SELECT
BJE.AccountingDocument AS "JournalEntryId",
'Journal Entry Rejected' AS "ActivityName",
LOG.END_TS AS "EventTime",
LOG.EXEC_USER AS "CreatedByUser",
BJE.CompanyCode AS "CompanyCode",
BJE.AccountingDocumentType AS "JournalEntryType",
BJE.PostingDate AS "PostingDate",
BJE.AmountInLocalCurrency AS "AmountInLocalCurrency"
FROM JournalEntryBaseCTE AS BJE
JOIN SWW_WI2OBJ AS WF_LINK ON WF_LINK.INSTID = CONCAT(BJE.CompanyCode, BJE.AccountingDocument, BJE.FiscalYear)
AND WF_LINK.TYPEID = 'BKPF'
JOIN SWWLOGHIST AS LOG ON LOG.WI_ID = WF_LINK.WI_ID
WHERE LOG.METHOD = '[Workflow Rejected Task ID]'
UNION ALL
-- 6. Journal Entry Corrected (changed while parked)
SELECT DISTINCT
BJE.AccountingDocument AS "JournalEntryId",
'Journal Entry Corrected' AS "ActivityName",
TO_TIMESTAMP(CH.UDATE || ' ' || CH.UTIME, 'YYYYMMDD HH24MISS') AS "EventTime",
CH.USERNAME AS "CreatedByUser",
BJE.CompanyCode AS "CompanyCode",
BJE.AccountingDocumentType AS "JournalEntryType",
BJE.PostingDate AS "PostingDate",
BJE.AmountInLocalCurrency AS "AmountInLocalCurrency"
FROM JournalEntryBaseCTE AS BJE
JOIN CDHDR AS CH ON CH.OBJECTID = CONCAT(BJE.CompanyCode, BJE.AccountingDocument, BJE.FiscalYear)
AND CH.OBJECTCLASS = 'BELEG'
WHERE BJE.DocumentIsParked = 'X'
UNION ALL
-- 7. Journal Entry Approved
SELECT
BJE.AccountingDocument AS "JournalEntryId",
'Journal Entry Approved' AS "ActivityName",
LOG.END_TS AS "EventTime",
LOG.EXEC_USER AS "CreatedByUser",
BJE.CompanyCode AS "CompanyCode",
BJE.AccountingDocumentType AS "JournalEntryType",
BJE.PostingDate AS "PostingDate",
BJE.AmountInLocalCurrency AS "AmountInLocalCurrency"
FROM JournalEntryBaseCTE AS BJE
JOIN SWW_WI2OBJ AS WF_LINK ON WF_LINK.INSTID = CONCAT(BJE.CompanyCode, BJE.AccountingDocument, BJE.FiscalYear)
AND WF_LINK.TYPEID = 'BKPF'
JOIN SWWLOGHIST AS LOG ON LOG.WI_ID = WF_LINK.WI_ID
WHERE LOG.METHOD = '[Workflow Approved Task ID]'
UNION ALL
-- 8. Manual Posting Identified
SELECT
BJE.AccountingDocument AS "JournalEntryId",
'Manual Posting Identified' AS "ActivityName",
BJE.PostingDateTime AS "EventTime",
BJE.CreatedByUser AS "CreatedByUser",
BJE.CompanyCode AS "CompanyCode",
BJE.AccountingDocumentType AS "JournalEntryType",
BJE.PostingDate AS "PostingDate",
BJE.AmountInLocalCurrency AS "AmountInLocalCurrency"
FROM JournalEntryBaseCTE AS BJE
WHERE BJE.PostingDateTime IS NOT NULL AND BJE.TransactionCode IN ('FB01', 'F-02', 'FB50', 'FV50', 'FBB1', 'FBV1')
UNION ALL
-- 9. Journal Entry Posted
SELECT
BJE.AccountingDocument AS "JournalEntryId",
'Journal Entry Posted' AS "ActivityName",
BJE.PostingDateTime AS "EventTime",
BJE.CreatedByUser AS "CreatedByUser",
BJE.CompanyCode AS "CompanyCode",
BJE.AccountingDocumentType AS "JournalEntryType",
BJE.PostingDate AS "PostingDate",
BJE.AmountInLocalCurrency AS "AmountInLocalCurrency"
FROM JournalEntryBaseCTE AS BJE
WHERE BJE.PostingDateTime IS NOT NULL
UNION ALL
-- 10. Journal Entry Changed After Posting
SELECT DISTINCT
BJE.AccountingDocument AS "JournalEntryId",
'Journal Entry Changed After Posting' AS "ActivityName",
TO_TIMESTAMP(CH.UDATE || ' ' || CH.UTIME, 'YYYYMMDD HH24MISS') AS "EventTime",
CH.USERNAME AS "CreatedByUser",
BJE.CompanyCode AS "CompanyCode",
BJE.AccountingDocumentType AS "JournalEntryType",
BJE.PostingDate AS "PostingDate",
BJE.AmountInLocalCurrency AS "AmountInLocalCurrency"
FROM JournalEntryBaseCTE AS BJE
JOIN CDHDR AS CH ON CH.OBJECTID = CONCAT(BJE.CompanyCode, BJE.AccountingDocument, BJE.FiscalYear)
AND CH.OBJECTCLASS = 'BELEG'
WHERE BJE.PostingDateTime IS NOT NULL AND TO_TIMESTAMP(CH.UDATE || ' ' || CH.UTIME, 'YYYYMMDD HH24MISS') > BJE.PostingDateTime
UNION ALL
-- 11. Journal Entry Cleared
SELECT
JEI.AccountingDocument AS "JournalEntryId",
'Journal Entry Cleared' AS "ActivityName",
MIN(JEI.ClearingDateTime) AS "EventTime",
BJE.CreatedByUser AS "CreatedByUser", -- Note: Clearing user is not directly available here
BJE.CompanyCode AS "CompanyCode",
BJE.AccountingDocumentType AS "JournalEntryType",
BJE.PostingDate AS "PostingDate",
BJE.AmountInLocalCurrency AS "AmountInLocalCurrency"
FROM I_JournalEntryItem AS JEI
JOIN JournalEntryBaseCTE AS BJE ON JEI.AccountingDocument = BJE.AccountingDocument
AND JEI.CompanyCode = BJE.CompanyCode
AND JEI.FiscalYear = BJE.FiscalYear
WHERE JEI.ClearingDateTime IS NOT NULL
GROUP BY JEI.AccountingDocument, BJE.CreatedByUser, BJE.CompanyCode, BJE.AccountingDocumentType, BJE.PostingDate, BJE.AmountInLocalCurrency
UNION ALL
-- 12. Journal Entry Reversal Processed
SELECT
OriginalDoc.AccountingDocument AS "JournalEntryId",
'Journal Entry Reversal Processed' AS "ActivityName",
ReversalDoc.PostingDateTime AS "EventTime",
ReversalDoc.CreatedByUser AS "CreatedByUser",
OriginalDoc.CompanyCode AS "CompanyCode",
OriginalDoc.AccountingDocumentType AS "JournalEntryType",
OriginalDoc.PostingDate AS "PostingDate",
OriginalDoc.AmountInLocalCurrency AS "AmountInLocalCurrency"
FROM JournalEntryBaseCTE AS ReversalDoc
JOIN JournalEntryBaseCTE AS OriginalDoc
ON ReversalDoc.ReversedJournalEntry = OriginalDoc.AccountingDocument
AND ReversalDoc.CompanyCode = OriginalDoc.CompanyCode
AND ReversalDoc.ReversalFiscalYear = OriginalDoc.FiscalYear
WHERE ReversalDoc.ReversedJournalEntry IS NOT NULL; ステップ
- SAP HANAデータベースへの直接SQLアクセスが承認済みであり、抽出ユーザーにBKPFとACDOCA、およびシステムで設定されているワークフロー、添付ファイル、変更履歴、消込、取消の各データソースに対する読み取り権限があることを確認します。通常、直接データベースアクセスにはSAP HANA Database Explorer、SAP HANA Studio、または承認済みのSQLクライアントを使用します。システムが明示的にそのアクセスをサポートしていない限り、SAPアプリケーションのトランザクション内で抽出クエリを実行しないでください。
- クライアント、会社コード、会計年度、伝票番号、伝票タイプ、転記日、作成日、作成時刻、ユーザー、現地通貨金額、取消または消込に関するフィールドを含め、BKPFとACDOCAの物理スキーマを確認します。SAP S/4HANAの導入環境によってスキーマや利用可能なフィールドが異なるため、クエリ内の角括弧で囲まれたプレースホルダーは、システムで確認したフィールドに置き換えてください。
- ワークフローイベントと添付ファイルイベントの信頼できるデータソースを特定します。BKPFとACDOCAは会計伝票および明細データを提供しますが、保留、登録、却下、修正、承認、添付ファイルに関するすべてのイベントを単独で確実に公開するわけではありません。角括弧で囲まれたワークフローおよび添付ファイルのデータソースのプレースホルダーは、導入環境で承認されたViewまたはテーブルに置き換えます。利用できないデータソースからイベントを推測して作成しないでください。対応するデータソースを設定するか、承認を記録したうえでアクティビティを除外します。
- 必要な日付範囲、会社コード、伝票タイプ、クライアントの抽出パラメーターを設定します。初回検証では、3~6か月の範囲をお勧めします。合意したプロセス範囲に従い、業務イベントにはイベントのタイムスタンプ範囲を、会計イベントには転記日の範囲を使用します。
- 承認済みのHANA SQLクライアントで完全なSQLクエリを実行します。クエリは、明示的に抽出されたアクティビティごとに1行のイベントを作成します。会計イベントにはBKPFとACDOCAを使用し、ワークフロー、添付ファイル、変更、消込、取消のイベントには設定済みのソースViewを使用します。伝票の存在だけからアクティビティを推測することはありません。
- 出力スキーマを確認します。JournalEntryIdはケース識別子、ActivityNameはアクティビティ名、EventTimeはイベントのタイムスタンプです。推奨される業務属性は、利用可能な場合に返されます。EventTimeがタイムスタンプであり、すべての行に空でないJournalEntryIdとActivityNameがあることを確認します。
- 選択したクライアント、会社コード、会計年度、日付範囲について、JournalEntryIdの重複しない値と想定されるBKPFの件数を比較し、会計データの対象範囲を照合します。ワークフローと添付ファイルの対象範囲は、保持期間やタイムスタンプのルールが会計データと異なる場合があるため、個別に照合します。
- イベントの順序と重複の扱いを検証します。ACDOCAの複数の明細によって、会計イベントが重複して作成されてはいけません。ただし、プロセス設計上、明細レベルのイベントが必要な場合を除きます。クエリの集約ロジックを使い、仕訳とイベントタイプごとに1つの会計イベントを作成し、利用可能な場合は設定済みのソースイベント識別子を保持します。
- 結果をUTF-8のCSV、またはProcessMindがサポートする別の表形式でエクスポートします。列名JournalEntryId、ActivityName、EventTimeは正確に保持してください。ファイルをJournalEntryId、EventTimeの順に並べ、追加の属性は列として保持します。ファイルをProcessMindにアップロードし、JournalEntryIdをケース識別子、ActivityNameをアクティビティ、EventTimeをイベントのタイムスタンプとして設定します。
設定
- 日付範囲:まずは3~6か月から始めます。パフォーマンステストでは短い範囲を使用し、行数とイベントの網羅性を検証してから範囲を広げてください。
- クライアントと会社の範囲:[Client parameter]を設定し、CompanyCodeを必要な法人に限定します。複数クライアントのシステムでは、クライアント条件を省略しないでください。
- 会計の範囲:[Document type filter]を設定し、必要に応じて会計年度と転記日のフィルターも設定します。選択したデータソースが確実に表現できる場合に限り、転記済みと未転記の伝票を両方含めます。
- ワークフローの範囲:[Workflow event source]と、登録、却下、修正、承認の各アクティビティに対するイベントタイプの対応付けを設定します。タイムスタンプがワークフロー操作の作成、実行、完了のどれを示すのか確認してください。
- 添付ファイルの範囲:[Attachment event source]と、添付ファイルを仕訳に関連付ける関係フィールドを設定します。データソースが添付ファイルの作成、置換、削除のどれを記録するのか確認してください。
- 変更の範囲:転記後の変更について[Change history source]を設定します。データソースが仕訳を特定し、信頼できる変更時刻を提供することを確認してください。
- 消込の範囲:[Clearing source]と、消込対象の会計伝票と消込伝票の関係を設定します。イベントを元の仕訳、消込伝票、またはその両方のどれに割り当てるか決定します。
- 取消の範囲:[Reversal source]と、元伝票と取消伝票の関係を設定します。この関係を利用できる場合、クエリは取消アクティビティを元のJournalEntryIdに割り当てます。
- 手動転記の分類:[Manual posting source]または検証済みの転記元フィールドを設定します。Manual Posting Identifiedは分類イベントであるため、転記時刻または承認済みの別の時刻を一貫して使用してください。
- 通貨金額:ACDOCAは明細単位のデータです。クエリは仕訳ごとに現地通貨金額を集計します。符号の扱いと、統計行、元帳固有の行、拡張元帳の行を含めるかどうかを確認してください。
- パフォーマンス:必要な列だけを選択し、早い段階で絞り込み、ACDOCAの無制限スキャンを避け、承認されたレポート実行時間帯に実行します。サポートされている場合は、クライアント、会計年度、会社コード、転記日の条件でパーティションプルーニングを利用します。
- 重複処理:利用可能な場合はソースイベント識別子を使用します。データソースに技術的な重複レコードが含まれる可能性がある場合は、実際には別のワークフロー操作であるイベントを統合しないよう、文書化された重複排除ルールを適用します。
- 前提条件:必要なデータベース権限、承認済みのSAP HANA接続、設定済みのワークフローおよび添付ファイルのデータソースへのアクセス、適切なSAP財務会計およびワークフロー設定、ProcessMindがサポートするエクスポート形式。
a サンプルクエリ sql
WITH
accounting_base AS (
SELECT
b.[Client field] AS ClientId,
b.[Company code field] AS CompanyCode,
b.[Fiscal year field] AS FiscalYear,
b.[Document number field] AS AccountingDocumentNumber,
b.[Document type field] AS JournalEntryType,
b.[Created by field] AS CreatedByUser,
b.[Document date field] AS DocumentDate,
b.[Posting date field] AS PostingDate,
b.[Creation date field] AS CreationDate,
b.[Creation time field] AS CreationTime,
b.[Reversal document field] AS ReversalDocumentNumber,
b.[Reversed document field] AS ReversedDocumentNumber,
b.[Reversal fiscal year field] AS ReversalFiscalYear,
SUM(a.[Local currency amount field]) AS AmountInLocalCurrency,
MAX(a.[Local currency field]) AS LocalCurrency
FROM [Your schema].[BKPF] b
INNER JOIN [Your schema].[ACDOCA] a
ON a.[Client field] = b.[Client field]
AND a.[Company code field] = b.[Company code field]
AND a.[Fiscal year field] = b.[Fiscal year field]
AND a.[Document number field] = b.[Document number field]
WHERE b.[Client field] = '[Client parameter]'
AND b.[Company code field] IN ([Company code filter])
AND b.[Posting date field] BETWEEN '[Start date parameter]' AND '[End date parameter]'
AND b.[Document type field] IN ([Document type filter])
GROUP BY
b.[Client field],
b.[Company code field],
b.[Fiscal year field],
b.[Document number field],
b.[Document type field],
b.[Created by field],
b.[Document date field],
b.[Posting date field],
b.[Creation date field],
b.[Creation time field],
b.[Reversal document field],
b.[Reversed document field],
b.[Reversal fiscal year field]
),
base_cases AS (
SELECT
ClientId,
CompanyCode,
FiscalYear,
AccountingDocumentNumber,
CAST(CompanyCode || '/' || FiscalYear || '/' || AccountingDocumentNumber AS NVARCHAR(100)) AS JournalEntryId,
JournalEntryType,
CreatedByUser,
PostingDate,
AmountInLocalCurrency,
LocalCurrency,
CreationDate,
CreationTime,
ReversalDocumentNumber,
ReversedDocumentNumber,
ReversalFiscalYear
FROM accounting_base
),
created_events AS (
SELECT
JournalEntryId,
'Journal Entry Created' AS ActivityName,
CAST(CreationDate || ' ' || CreationTime AS TIMESTAMP) AS EventTime,
CreatedByUser,
CompanyCode,
JournalEntryType,
PostingDate,
AmountInLocalCurrency,
LocalCurrency
FROM base_cases
),
parked_events AS (
SELECT
CAST(w.[Journal entry ID field] AS NVARCHAR(100)) AS JournalEntryId,
'Journal Entry Parked' AS ActivityName,
CAST(w.[Event timestamp field] AS TIMESTAMP) AS EventTime,
w.[User field] AS CreatedByUser,
w.[Company code field] AS CompanyCode,
w.[Journal entry type field] AS JournalEntryType,
w.[Posting date field] AS PostingDate,
w.[Amount in local currency field] AS AmountInLocalCurrency,
w.[Local currency field] AS LocalCurrency
FROM [Your schema].[Workflow event source] w
WHERE w.[Client field] = '[Client parameter]'
AND w.[Event type field] = '[Parked event type]'
AND CAST(w.[Event timestamp field] AS DATE) BETWEEN '[Start date parameter]' AND '[End date parameter]'
),
attachment_events AS (
SELECT
CAST(x.[Journal entry ID field] AS NVARCHAR(100)) AS JournalEntryId,
'Supporting Documentation Attached' AS ActivityName,
CAST(x.[Event timestamp field] AS TIMESTAMP) AS EventTime,
x.[User field] AS CreatedByUser,
x.[Company code field] AS CompanyCode,
x.[Journal entry type field] AS JournalEntryType,
x.[Posting date field] AS PostingDate,
x.[Amount in local currency field] AS AmountInLocalCurrency,
x.[Local currency field] AS LocalCurrency
FROM [Your schema].[Attachment event source] x
WHERE x.[Client field] = '[Client parameter]'
AND x.[Event type field] = '[Attachment created event type]'
AND CAST(x.[Event timestamp field] AS DATE) BETWEEN '[Start date parameter]' AND '[End date parameter]'
),
submitted_events AS (
SELECT
CAST(w.[Journal entry ID field] AS NVARCHAR(100)) AS JournalEntryId,
'Journal Submitted For Review' AS ActivityName,
CAST(w.[Event timestamp field] AS TIMESTAMP) AS EventTime,
w.[User field] AS CreatedByUser,
w.[Company code field] AS CompanyCode,
w.[Journal entry type field] AS JournalEntryType,
w.[Posting date field] AS PostingDate,
w.[Amount in local currency field] AS AmountInLocalCurrency,
w.[Local currency field] AS LocalCurrency
FROM [Your schema].[Workflow event source] w
WHERE w.[Client field] = '[Client parameter]'
AND w.[Event type field] = '[Submitted event type]'
AND CAST(w.[Event timestamp field] AS DATE) BETWEEN '[Start date parameter]' AND '[End date parameter]'
),
rejected_events AS (
SELECT
CAST(w.[Journal entry ID field] AS NVARCHAR(100)) AS JournalEntryId,
'Journal Entry Rejected' AS ActivityName,
CAST(w.[Event timestamp field] AS TIMESTAMP) AS EventTime,
w.[User field] AS CreatedByUser,
w.[Company code field] AS CompanyCode,
w.[Journal entry type field] AS JournalEntryType,
w.[Posting date field] AS PostingDate,
w.[Amount in local currency field] AS AmountInLocalCurrency,
w.[Local currency field] AS LocalCurrency
FROM [Your schema].[Workflow event source] w
WHERE w.[Client field] = '[Client parameter]'
AND w.[Event type field] = '[Rejected event type]'
AND CAST(w.[Event timestamp field] AS DATE) BETWEEN '[Start date parameter]' AND '[End date parameter]'
),
corrected_events AS (
SELECT
CAST(w.[Journal entry ID field] AS NVARCHAR(100)) AS JournalEntryId,
'Journal Entry Corrected' AS ActivityName,
CAST(w.[Event timestamp field] AS TIMESTAMP) AS EventTime,
w.[User field] AS CreatedByUser,
w.[Company code field] AS CompanyCode,
w.[Journal entry type field] AS JournalEntryType,
w.[Posting date field] AS PostingDate,
w.[Amount in local currency field] AS AmountInLocalCurrency,
w.[Local currency field] AS LocalCurrency
FROM [Your schema].[Workflow event source] w
WHERE w.[Client field] = '[Client parameter]'
AND w.[Event type field] = '[Corrected event type]'
AND CAST(w.[Event timestamp field] AS DATE) BETWEEN '[Start date parameter]' AND '[End date parameter]'
),
approved_events AS (
SELECT
CAST(w.[Journal entry ID field] AS NVARCHAR(100)) AS JournalEntryId,
'Journal Entry Approved' AS ActivityName,
CAST(w.[Event timestamp field] AS TIMESTAMP) AS EventTime,
w.[User field] AS CreatedByUser,
w.[Company code field] AS CompanyCode,
w.[Journal entry type field] AS JournalEntryType,
w.[Posting date field] AS PostingDate,
w.[Amount in local currency field] AS AmountInLocalCurrency,
w.[Local currency field] AS LocalCurrency
FROM [Your schema].[Workflow event source] w
WHERE w.[Client field] = '[Client parameter]'
AND w.[Event type field] = '[Approved event type]'
AND CAST(w.[Event timestamp field] AS DATE) BETWEEN '[Start date parameter]' AND '[End date parameter]'
),
manual_events AS (
SELECT
JournalEntryId,
'Manual Posting Identified' AS ActivityName,
CAST(PostingDate AS TIMESTAMP) AS EventTime,
CreatedByUser,
CompanyCode,
JournalEntryType,
PostingDate,
AmountInLocalCurrency,
LocalCurrency
FROM base_cases
WHERE [Manual posting condition verified for this system]
),
posted_events AS (
SELECT
JournalEntryId,
'Journal Entry Posted' AS ActivityName,
CAST(PostingDate AS TIMESTAMP) AS EventTime,
CreatedByUser,
CompanyCode,
JournalEntryType,
PostingDate,
AmountInLocalCurrency,
LocalCurrency
FROM base_cases
WHERE [Posted document condition verified for this system]
),
changed_events AS (
SELECT
CAST(c.[Journal entry ID field] AS NVARCHAR(100)) AS JournalEntryId,
'Journal Entry Changed After Posting' AS ActivityName,
CAST(c.[Change timestamp field] AS TIMESTAMP) AS EventTime,
c.[User field] AS CreatedByUser,
c.[Company code field] AS CompanyCode,
c.[Journal entry type field] AS JournalEntryType,
c.[Posting date field] AS PostingDate,
c.[Amount in local currency field] AS AmountInLocalCurrency,
c.[Local currency field] AS LocalCurrency
FROM [Your schema].[Change history source] c
WHERE c.[Client field] = '[Client parameter]'
AND c.[Post posting change indicator field] = '[Post posting change value]'
AND CAST(c.[Change timestamp field] AS DATE) BETWEEN '[Start date parameter]' AND '[End date parameter]'
),
cleared_events AS (
SELECT
CAST(cl.[Journal entry ID field] AS NVARCHAR(100)) AS JournalEntryId,
'Journal Entry Cleared' AS ActivityName,
CAST(cl.[Clearing timestamp field] AS TIMESTAMP) AS EventTime,
cl.[User field] AS CreatedByUser,
cl.[Company code field] AS CompanyCode,
cl.[Journal entry type field] AS JournalEntryType,
cl.[Posting date field] AS PostingDate,
cl.[Amount in local currency field] AS AmountInLocalCurrency,
cl.[Local currency field] AS LocalCurrency
FROM [Your schema].[Clearing source] cl
WHERE cl.[Client field] = '[Client parameter]'
AND CAST(cl.[Clearing timestamp field] AS DATE) BETWEEN '[Start date parameter]' AND '[End date parameter]'
),
reversal_events AS (
SELECT
CAST(r.[Original journal entry ID field] AS NVARCHAR(100)) AS JournalEntryId,
'Journal Entry Reversal Processed' AS ActivityName,
CAST(r.[Reversal timestamp field] AS TIMESTAMP) AS EventTime,
r.[User field] AS CreatedByUser,
r.[Company code field] AS CompanyCode,
r.[Journal entry type field] AS JournalEntryType,
r.[Posting date field] AS PostingDate,
r.[Amount in local currency field] AS AmountInLocalCurrency,
r.[Local currency field] AS LocalCurrency
FROM [Your schema].[Reversal source] r
WHERE r.[Client field] = '[Client parameter]'
AND CAST(r.[Reversal timestamp field] AS DATE) BETWEEN '[Start date parameter]' AND '[End date parameter]'
)
SELECT JournalEntryId, ActivityName, EventTime, CreatedByUser, CompanyCode, JournalEntryType, PostingDate, AmountInLocalCurrency, LocalCurrency FROM created_events
UNION ALL
SELECT JournalEntryId, ActivityName, EventTime, CreatedByUser, CompanyCode, JournalEntryType, PostingDate, AmountInLocalCurrency, LocalCurrency FROM parked_events
UNION ALL
SELECT JournalEntryId, ActivityName, EventTime, CreatedByUser, CompanyCode, JournalEntryType, PostingDate, AmountInLocalCurrency, LocalCurrency FROM attachment_events
UNION ALL
SELECT JournalEntryId, ActivityName, EventTime, CreatedByUser, CompanyCode, JournalEntryType, PostingDate, AmountInLocalCurrency, LocalCurrency FROM submitted_events
UNION ALL
SELECT JournalEntryId, ActivityName, EventTime, CreatedByUser, CompanyCode, JournalEntryType, PostingDate, AmountInLocalCurrency, LocalCurrency FROM rejected_events
UNION ALL
SELECT JournalEntryId, ActivityName, EventTime, CreatedByUser, CompanyCode, JournalEntryType, PostingDate, AmountInLocalCurrency, LocalCurrency FROM corrected_events
UNION ALL
SELECT JournalEntryId, ActivityName, EventTime, CreatedByUser, CompanyCode, JournalEntryType, PostingDate, AmountInLocalCurrency, LocalCurrency FROM approved_events
UNION ALL
SELECT JournalEntryId, ActivityName, EventTime, CreatedByUser, CompanyCode, JournalEntryType, PostingDate, AmountInLocalCurrency, LocalCurrency FROM manual_events
UNION ALL
SELECT JournalEntryId, ActivityName, EventTime, CreatedByUser, CompanyCode, JournalEntryType, PostingDate, AmountInLocalCurrency, LocalCurrency FROM posted_events
UNION ALL
SELECT JournalEntryId, ActivityName, EventTime, CreatedByUser, CompanyCode, JournalEntryType, PostingDate, AmountInLocalCurrency, LocalCurrency FROM changed_events
UNION ALL
SELECT JournalEntryId, ActivityName, EventTime, CreatedByUser, CompanyCode, JournalEntryType, PostingDate, AmountInLocalCurrency, LocalCurrency FROM cleared_events
UNION ALL
SELECT JournalEntryId, ActivityName, EventTime, CreatedByUser, CompanyCode, JournalEntryType, PostingDate, AmountInLocalCurrency, LocalCurrency FROM reversal_events
ORDER BY JournalEntryId, EventTime, ActivityName; ステップ
- ABAPプログラムを作成:トランザクションコード
SE38を使用してABAPエディターにアクセスします。新しいプログラム名(例:Z_PM_JE_EXTRACT)を入力し、「作成」をクリックします。適切なタイトルを入力し、「タイプ」を「実行可能プログラム」に設定して、ローカルオブジェクトまたはパッケージに保存します。 - 選択画面を定義:プログラム内で、ユーザーがデータを絞り込めるパラメーターと選択オプションを定義します。仕訳の作成日(
P_CPUDT_FR、P_CPUDT_TO)の日付範囲、会社コード(SO_BUKRS)の選択オプション、アプリケーションサーバー上の出力ファイルパス(P_FPATH)を含めてください。 - データ構造を宣言:必要なイベントログ形式に一致する内部テーブル構造を定義します。この構造に最終出力を格納します。また、BKPF、ACDOCA、CDHDR、CDPOS、各種ワークフローテーブルなど、データを選択するSAPテーブル用の内部テーブルと作業領域も宣言します。
- データ選択ロジックを実装:必要な12種類のアクティビティごとにデータを取得するABAPロジックを記述します。コードを整理しやすくするため、アクティビティごとに個別のサブルーチン(FORM)を作成します。たとえば、
get_created_events、get_parked_events、get_workflow_eventsなどのFORMを作成します。 - 「作成済み」と「転記済み」のイベントを選択:ユーザーが選択画面で指定した条件に基づき、BKPFテーブルから読み取ります。BKPFのエントリは作成を示します。ステータス
BSTAT = ' 'の伝票は転記済みとみなされます。イベント時刻には作成タイムスタンプ(CPUDT、CPUTM)を使用します。 - 「保留」のイベントを選択:保留伝票のヘッダーを格納するVBKPFテーブルから読み取ります。このテーブルの作成タイムスタンプが保留イベントを示します。
- 「ワークフロー」のイベント(登録、承認、却下)を選択:SWW_WI2OBJなどのワークフローテーブルを検索し、仕訳オブジェクトをワークフローインスタンスに関連付けます。また、SWWLOGHISTまたはSWWIHEADから、特定のステップの詳細と時刻を取得します。システムで登録、承認、却下に使用されるワークフロータスクIDを特定する必要があります。
- 「変更」と「修正」のイベントを選択:変更文書テーブルのCDHDR(ヘッダー)とCDPOS(明細)を、
OBJECTCLAS = 'BELEG'で検索します。「転記後に変更」の場合は、変更時刻が伝票の転記日より後の変更に絞り込みます。「修正」の場合は、保留または却下された伝票への変更に絞り込みます。 - 「取消」と「消込」のイベントを選択:BKPFの
STBLGフィールド(取消伝票番号)に値が入っている伝票を検索して、取消を特定します。取消イベントの時刻には、取消伝票の作成時刻を使用します。消込イベントは、ACDOCAテーブルから仕訳の明細に対する最新の消込日(AUGDT)を取得して特定します。 - データを結合して並べ替え:各アクティビティのデータを選択するたびに、最終マスター内部テーブルへ結果を追加します。すべての選択が完了したら、ケースごとに時系列順となるよう、マスターテーブルを
JournalEntryIdとEventTimeで並べ替えます。 - 出力ファイルを生成:
OPEN DATASET、LOOP AT... TRANSFER、CLOSE DATASETステートメントを使用し、並べ替えた最終内部テーブルの内容をSAPアプリケーションサーバー上の指定パスに書き込みます。ファイルはヘッダー行を含むCSV形式にしてください。 - 実行をスケジュール:定期的に抽出する場合は、トランザクションコード
SM36を使用して、Z_PM_JE_EXTRACTプログラムを定義したスケジュール(例:週次または月次)で実行するバックグラウンドジョブを作成します。これにより、データエクスポートを自動化できます。
設定
- 日付範囲:選択画面には、仕訳の作成日(
CPUDT)の必須日付範囲を設定します。パフォーマンスを確保するため、3~6か月など、扱いやすい単位に分けてデータを抽出することをお勧めします。 - 会社コード(
BUKRS):プロセスマイニングの分析対象となる法人に抽出範囲を限定するための重要なフィルターです。すべての会社コードを一度に抽出することはお勧めしません。 - 伝票タイプ(
BLART):この任意のフィルターを追加して、「SA」(総勘定元帳転記)や「KR」(仕入先請求書)など、特定の仕訳タイプに絞り込めます。データ量を減らし、データセットの関連性を高めるのに役立ちます。 - ファイルパス:プログラムでは、出力ファイルを書き込むSAPアプリケーションサーバー上の論理ファイルパスが必要です。パスが有効であり、SAPシステムユーザーにそのディレクトリへの書き込み権限があることを確認します。トランザクション
AL11を使用して、サーバーディレクトリを管理および表示します。 - ワークフロータスクID:ワークフローイベント(登録、承認、却下)を抽出するロジックには、組織の仕訳承認ワークフローで使用される固有のタスクIDを設定する必要があります。多くの場合、これらはカスタム設定であり、ワークフローコンサルタントまたは開発者に確認する必要があります。
- 前提条件:プログラムを実行するユーザーまたはシステムアカウントには、ABAPプログラムの作成および実行(
S_DEVELOP)に必要な開発者権限と、財務テーブル(BKPF、ACDOCA)、変更ログテーブル(CDHDR、CDPOS)、ワークフローテーブル(SWW*)への広範な読み取りアクセスが必要です。
a サンプルクエリ abap
REPORT Z_PM_JE_EXTRACT.
*&---------------------------------------------------------------------*
*&-- Data Structures for Event Log --*
*&---------------------------------------------------------------------*
TYPES: BEGIN OF ty_event_log,
journalentryid TYPE string,
activityname TYPE string,
eventtime TYPE string,
createdbyuser TYPE uname,
companycode TYPE bukrs,
journalentrytype TYPE blart,
postingdate TYPE budat,
amountinlocalcurrency TYPE wrbtr,
END OF ty_event_log.
*&---------------------------------------------------------------------*
*&-- Selection Screen Definition --*
*&---------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-001.
PARAMETERS: p_erdat_fr TYPE dats OBLIGATORY DEFAULT sy-datum-30,
p_erdat_to TYPE dats OBLIGATORY DEFAULT sy-datum.
SELECT-OPTIONS: so_bukrs FOR bkpf-bukrs OBLIGATORY.
PARAMETERS: p_fpath TYPE string OBLIGATORY DEFAULT '/usr/sap/trans/tmp/je_event_log.csv'.
SELECTION-SCREEN END OF BLOCK b1.
*&---------------------------------------------------------------------*
*&-- Internal Tables --*
*&---------------------------------------------------------------------*
DATA: gt_event_log TYPE TABLE OF ty_event_log.
*&---------------------------------------------------------------------*
*&-- Main Processing Block --*
*&---------------------------------------------------------------------*
START-OF-SELECTION.
PERFORM get_created_posted_events.
PERFORM get_parked_events.
PERFORM get_attachment_events.
PERFORM get_workflow_events.
PERFORM get_change_events.
PERFORM get_cleared_events.
PERFORM get_reversal_events.
SORT gt_event_log BY journalentryid eventtime.
PERFORM write_output_file.
*&---------------------------------------------------------------------*
*&-- Subroutines for Extracting Individual Activities --*
*&---------------------------------------------------------------------*
FORM get_created_posted_events.
DATA: lt_bkpf TYPE TABLE OF bkpf,
ls_event_log TYPE ty_event_log,
lv_timestamp TYPE string.
SELECT * FROM bkpf INTO TABLE lt_bkpf
WHERE bukrs IN so_bukrs
AND cpudt BETWEEN p_erdat_fr AND p_erdat_to.
LOOP AT lt_bkpf ASSIGNING FIELD-SYMBOL(<fs_bkpf>).
CLEAR ls_event_log.
CONCATENATE <fs_bkpf>-bukrs <fs_bkpf>-belnr <fs_bkpf>-gjahr INTO ls_event_log-journalentryid.
ls_event_log-companycode = <fs_bkpf>-bukrs.
ls_event_log-journalentrytype = <fs_bkpf>-blart.
ls_event_log-postingdate = <fs_bkpf>-budat.
ls_event_log-createdbyuser = <fs_bkpf>-usnam.
" Timestamp format YYYY-MM-DDTHH:MI:SS
CONCATENATE <fs_bkpf>-cpudt(4) '-' <fs_bkpf>-cpudt+4(2) '-' <fs_bkpf>-cpudt+6(2) 'T' <fs_bkpf>-cputm(2) ':' <fs_bkpf>-cputm+2(2) ':' <fs_bkpf>-cputm+4(2) INTO lv_timestamp.
ls_event_log-eventtime = lv_timestamp.
" Activity: Journal Entry Created
ls_event_log-activityname = 'Journal Entry Created'.
SELECT SUM( hsl ) INTO ls_event_log-amountinlocalcurrency FROM acdoca WHERE belnr = <fs_bkpf>-belnr AND gjahr = <fs_bkpf>-gjahr AND bukrs = <fs_bkpf>-bukrs.
APPEND ls_event_log TO gt_event_log.
" Activity: Journal Entry Posted (if not parked)
IF <fs_bkpf>-bstat = ' '.
ls_event_log-activityname = 'Journal Entry Posted'.
APPEND ls_event_log TO gt_event_log.
" Activity: Manual Posting Identified (based on T-Code)
CASE <fs_bkpf>-tcode.
WHEN 'FB01' OR 'F-02' OR 'FB50' OR 'F-22' OR 'F-43'.
ls_event_log-activityname = 'Manual Posting Identified'.
APPEND ls_event_log TO gt_event_log.
ENDCASE.
ENDIF.
ENDLOOP.
ENDFORM.
FORM get_parked_events.
DATA: ls_event_log TYPE ty_event_log, lv_timestamp TYPE string.
SELECT * FROM vbkpf
WHERE bukrs IN so_bukrs
AND cpudt BETWEEN p_erdat_fr AND p_erdat_to.
CLEAR ls_event_log.
CONCATENATE vbkpf-bukrs vbkpf-belnr vbkpf-gjahr INTO ls_event_log-journalentryid.
CONCATENATE vbkpf-cpudt(4) '-' vbkpf-cpudt+4(2) '-' vbkpf-cpudt+6(2) 'T' vbkpf-cputm(2) ':' vbkpf-cputm+2(2) ':' vbkpf-cputm+4(2) INTO lv_timestamp.
ls_event_log-activityname = 'Journal Entry Parked'.
ls_event_log-eventtime = lv_timestamp.
ls_event_log-createdbyuser = vbkpf-usnam.
ls_event_log-companycode = vbkpf-bukrs.
ls_event_log-journalentrytype = vbkpf-blart.
ls_event_log-postingdate = vbkpf-budat.
APPEND ls_event_log TO gt_event_log.
ENDSELECT.
ENDFORM.
FORM get_attachment_events.
DATA: lt_bdocs TYPE TABLE OF srgbtbrel, ls_event_log TYPE ty_event_log, lv_timestamp TYPE string.
SELECT * FROM srgbtbrel INTO TABLE lt_bdocs
WHERE typeid_a = 'BUS2081' " Object type for Accounting Document
AND catid_a = 'BO'.
LOOP AT lt_bdocs ASSIGNING FIELD-SYMBOL(<fs_bdocs>).
CHECK <fs_bdocs>-instid_a(4) IN so_bukrs.
DATA(lv_bukrs) = <fs_bdocs>-instid_a(4).
DATA(lv_belnr) = <fs_bdocs>-instid_a+4(10).
DATA(lv_gjahr) = <fs_bdocs>-instid_a+14(4).
SELECT SINGLE cpudt, cputm, usnam, blart, budat FROM bkpf
INTO (DATA(lv_cpudt), DATA(lv_cputm), DATA(lv_usnam), DATA(lv_blart), DATA(lv_budat))
WHERE bukrs = lv_bukrs AND belnr = lv_belnr AND gjahr = lv_gjahr.
IF sy-subrc = 0 AND lv_cpudt BETWEEN p_erdat_fr AND p_erdat_to.
CLEAR ls_event_log.
CONCATENATE lv_bukrs lv_belnr lv_gjahr INTO ls_event_log-journalentryid.
" Note: Using document creation time as a proxy for attachment time.
CONCATENATE lv_cpudt(4) '-' lv_cpudt+4(2) '-' lv_cpudt+6(2) 'T' lv_cputm(2) ':' lv_cputm+2(2) ':' lv_cputm+4(2) INTO lv_timestamp.
ls_event_log-activityname = 'Supporting Documentation Attached'.
ls_event_log-eventtime = lv_timestamp.
ls_event_log-createdbyuser = lv_usnam.
ls_event_log-companycode = lv_bukrs.
ls_event_log-journalentrytype = lv_blart.
ls_event_log-postingdate = lv_budat.
APPEND ls_event_log TO gt_event_log.
ENDIF.
ENDLOOP.
ENDFORM.
FORM get_workflow_events.
" This is a simplified example. Real workflow logic can be complex.
" You must identify your specific Task IDs for these events.
DATA: ls_event_log TYPE ty_event_log, lv_timestamp TYPE string.
DATA: BEGIN OF ls_wi, wi_id TYPE sww_wiid, cr_date TYPE sww_cd, cr_time TYPE sww_ct, task TYPE sww_task, instid TYPE swo_typeid, END OF ls_wi.
SELECT h~wi_id h~cr_date h~cr_time h~wi_rh_task o~instid
FROM swwwihead AS h
JOIN sww_wi2obj AS o ON h~wi_id = o~wi_id
INTO @ls_wi
WHERE o~typeid = 'BUS2081' AND o~catid = 'BO'
AND h~cr_date BETWEEN @p_erdat_fr AND @p_erdat_to.
DATA(lv_bukrs) = ls_wi-instid(4).
DATA(lv_belnr) = ls_wi-instid+4(10).
DATA(lv_gjahr) = ls_wi-instid+14(4).
IF lv_bukrs IN so_bukrs.
CLEAR ls_event_log.
CONCATENATE lv_bukrs lv_belnr lv_gjahr INTO ls_event_log-journalentryid.
CONCATENATE ls_wi-cr_date(4) '-' ls_wi-cr_date+4(2) '-' ls_wi-cr_date+6(2) 'T' ls_wi-cr_time(2) ':' ls_wi-cr_time+2(2) ':' ls_wi-cr_time+4(2) INTO lv_timestamp.
ls_event_log-eventtime = lv_timestamp.
ls_event_log-companycode = lv_bukrs.
CASE ls_wi-task.
WHEN '[Your Submit Task ID]'. " e.g., TS20000139
ls_event_log-activityname = 'Journal Submitted For Review'.
APPEND ls_event_log TO gt_event_log.
WHEN '[Your Approve Task ID]'. " e.g., TS20000142
ls_event_log-activityname = 'Journal Entry Approved'.
APPEND ls_event_log TO gt_event_log.
WHEN '[Your Reject Task ID]'. " e.g., TS20000141
ls_event_log-activityname = 'Journal Entry Rejected'.
APPEND ls_event_log TO gt_event_log.
ENDCASE.
ENDIF.
ENDSELECT.
ENDFORM.
FORM get_change_events.
DATA: lt_cdhdr TYPE TABLE OF cdhdr, ls_event_log TYPE ty_event_log, lv_timestamp TYPE string.
SELECT * FROM cdhdr INTO TABLE lt_cdhdr
WHERE objectclas = 'BELEG'
AND udate BETWEEN p_erdat_fr AND p_erdat_to.
LOOP AT lt_cdhdr ASSIGNING FIELD-SYMBOL(<fs_cdhdr>).
DATA(lv_bukrs) = <fs_cdhdr>-objectid(4).
DATA(lv_belnr) = <fs_cdhdr>-objectid+4(10).
DATA(lv_gjahr) = <fs_cdhdr>-objectid+14(4).
IF lv_bukrs IN so_bukrs.
SELECT SINGLE bstat, budat, blart FROM bkpf
INTO (DATA(lv_bstat), DATA(lv_budat), DATA(lv_blart))
WHERE bukrs = lv_bukrs AND belnr = lv_belnr AND gjahr = lv_gjahr.
IF sy-subrc = 0.
CLEAR ls_event_log.
CONCATENATE lv_bukrs lv_belnr lv_gjahr INTO ls_event_log-journalentryid.
CONCATENATE <fs_cdhdr>-udate(4) '-' <fs_cdhdr>-udate+4(2) '-' <fs_cdhdr>-udate+6(2) 'T' <fs_cdhdr>-utime(2) ':' <fs_cdhdr>-utime+2(2) ':' <fs_cdhdr>-utime+4(2) INTO lv_timestamp.
ls_event_log-eventtime = lv_timestamp.
ls_event_log-createdbyuser = <fs_cdhdr>-username.
ls_event_log-companycode = lv_bukrs.
ls_event_log-journalentrytype = lv_blart.
ls_event_log-postingdate = lv_budat.
IF lv_bstat = ' ' AND <fs_cdhdr>-udate > lv_budat.
ls_event_log-activityname = 'Journal Entry Changed After Posting'.
APPEND ls_event_log TO gt_event_log.
ELSEIF lv_bstat <> ' '.
ls_event_log-activityname = 'Journal Entry Corrected'.
APPEND ls_event_log TO gt_event_log.
ENDIF.
ENDIF.
ENDIF.
ENDLOOP.
ENDFORM.
FORM get_cleared_events.
DATA: ls_event_log TYPE ty_event_log, lv_timestamp TYPE string.
DATA: BEGIN OF ls_clear, belnr TYPE belnr_d, gjahr TYPE gjahr, bukrs TYPE bukrs, augdt TYPE augdt, END OF ls_clear, lt_clear LIKE TABLE OF ls_clear.
SELECT belnr, gjahr, bukrs, MAX( augdt ) AS augdt FROM acdoca
INTO TABLE @lt_clear
WHERE bukrs IN @so_bukrs
AND augdt NE '00000000'
AND augdt BETWEEN @p_erdat_fr AND @p_erdat_to
GROUP BY belnr, gjahr, bukrs.
LOOP AT lt_clear INTO ls_clear.
SELECT SINGLE usnam, blart, budat FROM bkpf
INTO (DATA(lv_usnam), DATA(lv_blart), DATA(lv_budat))
WHERE bukrs = ls_clear-bukrs AND belnr = ls_clear-belnr AND gjahr = ls_clear-gjahr.
IF sy-subrc = 0.
CLEAR ls_event_log.
CONCATENATE ls_clear-bukrs ls_clear-belnr ls_clear-gjahr INTO ls_event_log-journalentryid.
CONCATENATE ls_clear-augdt(4) '-' ls_clear-augdt+4(2) '-' ls_clear-augdt+6(2) 'T12:00:00' INTO lv_timestamp. " Clearing date has no time, use midday
ls_event_log-activityname = 'Journal Entry Cleared'.
ls_event_log-eventtime = lv_timestamp.
ls_event_log-createdbyuser = lv_usnam.
ls_event_log-companycode = ls_clear-bukrs.
ls_event_log-journalentrytype = lv_blart.
ls_event_log-postingdate = lv_budat.
APPEND ls_event_log TO gt_event_log.
ENDIF.
ENDLOOP.
ENDFORM.
FORM get_reversal_events.
DATA: lt_reversals TYPE TABLE OF bkpf, ls_event_log TYPE ty_event_log, lv_timestamp TYPE string.
SELECT * FROM bkpf INTO TABLE lt_reversals
WHERE bukrs IN so_bukrs
AND cpudt BETWEEN p_erdat_fr AND p_erdat_to
AND stblg IS NOT NULL.
LOOP AT lt_reversals ASSIGNING FIELD-SYMBOL(<fs_rev>).
SELECT SINGLE usnam, blart, budat FROM bkpf
INTO (DATA(lv_usnam), DATA(lv_blart), DATA(lv_budat))
WHERE bukrs = <fs_rev>-bukrs AND belnr = <fs_rev>-stblg AND gjahr = <fs_rev>-gjahr.
IF sy-subrc = 0.
CLEAR ls_event_log.
CONCATENATE <fs_rev>-bukrs <fs_rev>-stblg <fs_rev>-gjahr INTO ls_event_log-journalentryid.
CONCATENATE <fs_rev>-cpudt(4) '-' <fs_rev>-cpudt+4(2) '-' <fs_rev>-cpudt+6(2) 'T' <fs_rev>-cputm(2) ':' <fs_rev>-cputm+2(2) ':' <fs_rev>-cputm+4(2) INTO lv_timestamp.
ls_event_log-activityname = 'Journal Entry Reversal Processed'.
ls_event_log-eventtime = lv_timestamp.
ls_event_log-createdbyuser = lv_usnam.
ls_event_log-companycode = <fs_rev>-bukrs.
ls_event_log-journalentrytype = lv_blart.
ls_event_log-postingdate = lv_budat.
APPEND ls_event_log TO gt_event_log.
ENDIF.
ENDLOOP.
ENDFORM.
FORM write_output_file.
DATA: lv_line TYPE string.
FIELD-SYMBOLS: <fs_event_log> TYPE ty_event_log.
OPEN DATASET p_fpath FOR OUTPUT IN TEXT MODE ENCODING UTF-8.
IF sy-subrc NE 0.
MESSAGE 'Error opening file.' TYPE 'E'.
RETURN.
ENDIF.
" Write Header
lv_line = 'JournalEntryId,ActivityName,EventTime,CreatedByUser,CompanyCode,JournalEntryType,PostingDate,AmountInLocalCurrency'.
TRANSFER lv_line TO p_fpath.
LOOP AT gt_event_log ASSIGNING <fs_event_log>.
CONCATENATE <fs_event_log>-journalentryid <fs_event_log>-activityname <fs_event_log>-eventtime <fs_event_log>-createdbyuser <fs_event_log>-companycode <fs_event_log>-journalentrytype <fs_event_log>-postingdate <fs_event_log>-amountinlocalcurrency
INTO lv_line SEPARATED BY ','.
TRANSFER lv_line TO p_fpath.
ENDLOOP.
CLOSE DATASET p_fpath.
WRITE: / 'File successfully written to', p_fpath.
ENDFORM. 準備はできていますか?
このテンプレートを使ってデータを確実に準備し、決算・レポーティングの仕訳プロセスに関する重要な情報を見つけ出します。今日からプロセス改善への取り組みを始めましょう。
決算・レポーティングの仕訳を効率化し、最大限の成果を実現
プロセスを見直し、決算・レポーティングの仕訳サイクルを30%短縮します。
クレジットカードは不要です。数分で設定できます。