CHAPTER 10 ・ 総合演習 / Lesson 40
仕訳データを検証する
借方・貸方の一致、勘定科目マスタとの照合、日付の妥当性。会計データのチェックを自動化します。
このレッスンが終わったら
「仕訳データに対して、貸借一致・マスタ照合・日付チェックを自動で行い、問題を分類してレポートにできる」と言える。
課題とデータを見る
最後の総合演習は、会計データの検証です。会計システムに取り込む前、あるいは月次の締めの前に、仕訳データの入力ミスを洗い出す作業を自動化します。
仕訳は、お金の動きを「借方(左)」と「貸方(右)」に分けた記録です。1つの取引は、伝票番号でひとまとまりになり、複数の行からできています。たとえば、売上なら、次のような形です。
J001 行1 借方 売掛金 1,100,000円
J001 行2 貸方 売上高 1,000,000円
J001 行3 貸方 仮受消費税 100,000円決まりごとは、借方の合計と貸方の合計が、必ず同じになること(貸借一致)です。10月分の仕訳が、journal.csv(10伝票・21行)に入っています。
伝票番号,行,日付,科目コード,借貸,金額,摘要 J001,1,2025-10-01,1310,借,1100000,アオイ電機 売上 J001,2,2025-10-01,4110,貸,1000000,アオイ電機 売上 J001,3,2025-10-01,2220,貸,100000,仮受消費税 J002,1,2025-10-02,6110,借,1240,交通費 J002,2,2025-10-02,1110,貸,1240,交通費 J003,1,2025-10-03,6140,借,8800,コピー用紙 J003,2,2025-10-03,2210,貸,8800,コピー用紙 J004,1,2025-10-05,1120,借,1320000,アオイ電機 入金 J004,2,2025-10-05,1310,貸,1320000,アオイ電機 入金 J005,1,2025-10-07,6120,借,98000,取引先 会食 J005,2,2025-10-07,1110,貸,89000,取引先 会食 J006,1,2025-10-08,6150,借,5500,携帯電話 J006,2,2025-10-08,1120,貸,5500,携帯電話 J007,1,2025-10-10,6130,借,3600,会議費 J007,2,2025-10-10,1110,貸,3600,会議費 J008,1,2026-10-12,6110,借,2100,セミナー交通費 J008,2,2026-10-12,1110,貸,2100,セミナー交通費 J009,1,2025-10-14,5110,借,0,仕入 J009,2,2025-10-14,2110,貸,0,仕入 J010,1,2025-10-15,1310,借,484000,ミドリ商事 売上 J010,2,2025-10-15,4110,貸,484000,ミドリ商事 売上
使ってよい勘定科目は、科目の一覧(マスタ)である accounts.csv に決まっています。
科目コード,科目名,区分 1110,現金,資産 1120,普通預金,資産 1310,売掛金,資産 2110,買掛金,負債 2210,未払金,負債 4110,売上高,収益 5110,仕入高,費用 6110,旅費交通費,費用 6120,接待交際費,費用 6130,会議費,費用 6140,消耗品費,費用 6150,通信費,費用
まず、人が手でやるのと同じように、伝票ごとの借方と貸方を合計してみましょう。
この欄では、サンプルファイルが使えます。実行のたびに、ファイルは最初の状態に戻ります。
▶ 実行を押すと、ここに結果が出ます
貸借が合っていない伝票が見つかりました。このような確認を、5種類のチェックすべてについて、自動で行えるようにします。
検証するのは、次の5つです。
| 検証 | 内容 |
|---|---|
| ① 貸借一致 | 伝票ごとに、借方の合計と貸方の合計が同じか |
| ② マスタ照合 | 科目コードが、accounts.csv にあるか |
| ③ 日付 | 2025年10月(10/1〜10/31)の範囲か。日付として読めるか |
| ④ 金額 | 0円や、マイナスになっていないか |
| ⑤ 摘要 | 空欄になっていないか |
さらに、見つけた問題をエラーと警告に分けます。「このままでは使えない」ものがエラー、「使えるかもしれないが、人が見たほうがよい」ものが警告です。どちらにするかは、社内のルールで決まることなので、コードの上のほうに、設定として切り出しておきます。
設計:ルールは関数、結果はひとまとまりのデータ
Lesson 38 と同じく、検証を1つずつ関数にして、リストに並べます。違うのは、結果の持ち方です。問題を見つけるたびに、何が・どこで・どう直すとよいかを、1件分のデータにまとめます。これを dataclass(Lesson 16)で表します。
- ① 読み込む仕訳とマスタ
- ② 検証する5つのルールを当てる
- ③ 分類するエラーと警告に分け、並べ替える
- ④ レポートにする画面とExcel
voucherどの伝票か(伝票番号)lineどの行か(0なら、伝票全体の問題)levelエラーか、警告かkind問題の種類(貸借不一致、未登録の科目、など)detail何が起きているか(数字を入れて、具体的に)fix修正案。提案するだけで、自動では直さない実際に、1件の「発見」を作ってみましょう。
▶ 実行を押すと、ここに結果が出ます
dataclass にしておくと、f.level のように名前で取り出せ、asdict で辞書にも直せます(あとで表にするときに便利です)。
最後の「修正案」が、大事なところです。データを勝手に書き換えないのが、会計データの鉄則です。金額がどちらの側で正しいのか、本当の日付はいつか、は、証憑を見た人にしか決められません。出力は、「修正のための手がかりを添えた一覧」にとどめます。
部品を1つずつ作る
貸借一致のルール。 伝票ごとに、借方と貸方を合計します。辞書で集計する(Lesson 06)、いつもの形です。
▶ 実行を押すと、ここに結果が出ます
貸方が2行に分かれていても合計が合えばよいこと、複数の伝票を混ぜずに、伝票ごとに数えることを、テストで確かめました。差額の 9,000 は9の倍数です。桁の入れ替え(98,000 を 89,000 と打つ)をすると、差額が必ず9の倍数になるので、手がかりとして「疑い」の一文を添えています。
1行だけで決まるルール。 科目コード・日付・金額・摘要の4つは、行ごとに調べられます。サンプルの journal.csv には無い「マイナス」「摘要の空欄」「日付の書き方の間違い」も、小さなデータでテストしておきます。
▶ 実行を押すと、ここに結果が出ます
日付の書き方が間違っていても、プログラムが止まらないよう、try / except(Lesson 09)で受けて、「日付の形式」という問題として記録しています。期間の初日と最終日がどちらも範囲内であることも、境界のテストとして残しました。
組み合わせて完成させる
5つのルールをリストに並べ、エラー→警告の順に並べ替えて、画面とExcelに出します。修正案には、未登録の科目のために「近いコード」の候補も添えます。
この欄では、サンプルファイルが使えます。実行のたびに、ファイルは最初の状態に戻ります。
▶ 実行を押すと、ここに結果が出ます
サンプルデータにわざと入れた問題が、すべて見つかりました。
- J001 行3(エラー):科目コード 2220 は、マスタにありません。借方と貸方の合計は合っているので、貸借のチェックは通ります。「近いコード」として 2210 未払金が挙がりますが、参考です。仮受消費税という科目が必要なのであれば、マスタに加えるかどうかを、経理の責任者に相談します
- J005(エラー):借方 98,000円・貸方 89,000円で、差額は 9,000円です。Lesson 38 の経費申請 E009 も 98,000円(接待交際費・会食)なので、借方が正しい可能性が高そうです。ただし、決めるのは証憑を見た人です
- J008 の2行(エラー):日付が 2026-10-12 です。年の打ち間違いかもしれません。2025-10-12 は日曜日なので、本当の日付かどうかも、証憑で確かめたいところです
- J009 の2行(警告):金額が0円です。借方と貸方が合っているので、エラーにはせず、警告にしました
「問題なし」の6伝票は、貸借の合計が合い、科目・日付・金額・摘要に問題が見つからなかったものです。問題が見つからないことは、仕訳の内容が正しいことの証明ではありません。たとえば、売上を別の科目に入れていても、このチェックでは分かりません。
ブラウザでは、Excelをダウンロードできません。そこで、書き出した 仕訳検証.xlsx を読み直して、シートごとの行数と、エラー・警告の件数を確かめました。自分のパソコンで動かせば、ファイルができます。
自分で書く
お題① 重さを変える。 次の設定では、「金額が0」は警告です。これをエラーに変えると、エラーの件数は何件になるでしょう。設定を1か所だけ書き換えて、エラーの件数を表示してください。
▶ 実行を押すと、ここに結果が出ます
ヒントを見る
書き換えるのは、SEVERITY の中の「金額が0」の右側だけです。WARNING を ERROR に変えます。
答えの例を見る
ERROR, WARNING = "エラー", "警告"
SEVERITY = {"貸借不一致": ERROR, "未登録の科目": ERROR, "日付が期間外": ERROR, "金額が0": ERROR}
# 見つかった問題(伝票番号, 種類)
found_kinds = [
("J001", "未登録の科目"), ("J005", "貸借不一致"),
("J008", "日付が期間外"), ("J008", "日付が期間外"),
("J009", "金額が0"), ("J009", "金額が0"),
]
errors = [v for v, kind in found_kinds if SEVERITY[kind] == ERROR]
print(len(errors))お題② ルールを足す。 1行の金額が1,000,000円以上の行を「高額」として見つけるルール check_big(rows) を完成させてください。該当する(伝票番号, 行)のリストを表示します。
この欄では、サンプルファイルが使えます。実行のたびに、ファイルは最初の状態に戻ります。
▶ 実行を押すと、ここに結果が出ます
ヒントを見る
[(r["伝票番号"], r["行"]) for r in rows if r["金額"] >= 1000000] の形です。
答えの例を見る
import csv
with open("journal.csv", encoding="utf-8") as f:
rows = list(csv.DictReader(f))
for r in rows:
r["行"] = int(r["行"])
r["金額"] = int(r["金額"])
def check_big(rows):
return [(r["伝票番号"], r["行"]) for r in rows if r["金額"] >= 1000000]
print(check_big(rows))お題③ 自分の書き方で作る。 check_balance を使わずに、貸借の差額が0でない伝票を、辞書(伝票番号 → 差額)で表示してください。差額は「借方合計 − 貸方合計」です。
この欄では、サンプルファイルが使えます。実行のたびに、ファイルは最初の状態に戻ります。
▶ 実行を押すと、ここに結果が出ます
ヒントを見る
diffs = defaultdict(int) を作り、借なら diffs[伝票番号] += 金額、貸なら -= 金額 とします(金額は int(...) で数字にします)。最後に、{v: d for v, d in diffs.items() if d != 0} で絞ります。
答えの例を見る
import csv
from collections import defaultdict
with open("journal.csv", encoding="utf-8") as f:
rows = list(csv.DictReader(f))
diffs = defaultdict(int)
for r in rows:
amount = int(r["金額"])
if r["借貸"] == "借":
diffs[r["伝票番号"]] += amount
else:
diffs[r["伝票番号"]] -= amount
print({v: d for v, d in diffs.items() if d != 0})振り返りと、これから
理解チェック検証の結果を「エラー」と「警告」に分けておく、いちばんの利点は何でしょう?
理解チェック貸借不一致の伝票を見つけたとき、プログラムが借方か貸方の金額を「自動で直さない」のはなぜでしょう?