Ledger CLIで家計簿をつけたい！入門1 銀行のお金の動きを捉える

[←前編](https://qiita.com/kikeg/items/5d363e5b13358e896a9a)

早速Ledger CLIを使って銀行のお金の動きをつけていきます。まだインストールしていない人はこちらから↓

https://qiita.com/kikeg/items/07c2794e226b9ae18205

## まずは最初の残高から

`ledger`コマンドは`-f <FILE>`オプションで読み込むファイルパスを指定できます。僕が仮にOkane銀行の口座を持ってるとして、`bank/okane/2022.ledger`というファイルにOkane銀行の2022年の起こったことを書いていくことにします。[^2]

```shell-session
# 適当にディレクトリを用意
~$ mkdir journal
~$ cd journal
~journal$ mkdir -p bank/okane
~journal$ emacs -nw bank/okane/2022.ledger
```

仮に私が12/1に12万円残高があったとしましょう。ではファイルに早速以下のことを書いていきます。

```ledger
2022/12/01 * 初期残高
    Assets:Banks:Okane                       120,000 JPY = 120,000 JPY
    Equity:Opening Balances

```

で、残高と出入金履歴を確認しておきます。

```shell-session
~journal$ ledger -f bank/okane/2022.ledger bal
         120,000 JPY  Assets:Banks:Okane
        -120,000 JPY  Equity:Opening Balances
--------------------
                   0

~journal$ ledger -f bank/okane/2022.ledger reg Assets:Banks:Okane
22-Dec-01 初期残高                                      Assets:Banks:Okane                                                   120,000 JPY                 120,000 JPY
```

俺は全部理解したという人は進んで次の「引き出し、給与、デビットカード」に進んでください。よくわかんない方はFAQを用意したのでどうぞ。

### この構文なんなの?

これを日本語でいうと「今年の12/1」に「初期残高」という名前の取引があり、その内容は「純資産:初期残高」から「Neon銀行」に「12万円」移動した、と言った感じです。
もうちょっと細かく構文を見ていきます。ちなみに`;`でインラインコメント書けるのでこれも文法的に正しいファイルです。

```ledger
;    +--- 日付 yyyy/m/d 方式で書く
;    |
;    |     +--- clearedサイン、なくてもいい。*をつけると「確認済」、!をつけると「未確認」みたいなニュアンス。
;    |     |
;    |     |    +--- 摘要欄、クレカの明細だとお店の名前とか入れるとこ。
;    |     |    |
;    v     v    v
2022/12/01 * 初期残高
    ; 取引の中の仕訳は一つ以上の空白を開けて始める。
    Assets:Banks:Okane                       120,000 JPY = 120,000 JPY
    ;   ^                   ^                    ^       ^
    ;   |                   |                    |       |
    ;   |                   |                    |       + 取引後残高。省略可。
    ;   |                   |                    |
    ;   |                   |                    +--- 金額 カンマは入れなくてもいい。通貨は必要。前配置も可(¥ 15)
    ;   |                   |
    ;   |                   +--- \tか半角スペース2個以上入れて口座名と金額を区切る
    ;   |                        ただEmacsとかVimとかledger printが広めのカラムにフォーマットしてくる
    ;   |
    ;   +--- 銀行の口座とか支出の科目とか書くところ。
    Equity:Opening Balances

```

### 拡張子のledgerって何?
何でもいいです。txtでもいいです。本家のドキュメントは`.dat`を使ってましたが、僕は嫌です。

### なんで口座のところ英語なの?
日本語でもいいです。ただ、Ledgerは段組みするとき日本語の全角文字も全部半角幅で計算してグチャグチャにしてくれるので、僕は全部英数にしてます。英語使うときは半角スペース二個以上入れるとだめなので気をつけてください。

あと`:`を使って区切ると階層構造を切ってくれるので、日本語使うとしても`資産:普通預金:ネオン`とか`純資産:初期残高`みたいにしておくと普通預金全部の残高とか資産全部の残高とかがすぐ取れるようになります。

### 通貨単位書かないとだめ?めんどくない?

書かないとだめです。のはずなんだけど書かなくても何故か動きます…でも書いておいたほうがいいです[^commodity]。日本語で`10円`とか書いても`$10`とか書いても動きます。後で触れますが、この通貨単位は所詮ただの文字列なので、`AAPL`とか株の銘柄とかにも使えます。

一応`D 100,000 JPY`とファイル先頭に書けば通貨単位を省略できる仕組みがあるようにドキュメントは読めるのですが、僕は使えないので使える人いたら教えて下さい。

### なんか動かないんだけど

Ledgerはファイルの最後に改行があるないに大変神経質です。とりあえず最後に改行2個位つけときましょう。いやエラー出すかまともに処理するかして欲しいですけどね。

### 取引後残高書いたほうがいいの?

Ledgerは各取引後の残高を計算してくれるので本当は一回も書かなくてもいいです。ただ、それをやると残高が食い違ったときに目を皿のようにして探さないといけなくなります。なので定期的に書いておくと便利です。Ledgerは取引後残高を書いておくと計算値と書いてある値が同じになるか検証して、違ったらエラーを吐いてくれます。

```shell-session
$ cat bank/okane/2022.ledger
2022/12/01 * 初期残高
    Assets:Banks:Okane                       120,000 JPY = 110,000 JPY ; 1万円ズレ
    Equity:Opening Balances

$ ledger -f bank/okane/2022.ledger
Ledger 3.2.1-20200518, the command-line accounting tool

Copyright (c) 2003-2019, John Wiegley.  All rights reserved.

This program is made available under the terms of the BSD Public License.
See LICENSE file included with the distribution for details and disclaimer.
While parsing file ".../bank/okane/2022.ledger", line 2:
While parsing posting:
  Assets:Banks:Okane                       120,000 JPY = 110,000 JPY
                                                         ^^^^^^^^^^^
Error: Balance assertion off by -10,000 JPY (expected to see 120,000 JPY)
```

こんなふうに「ホントは12万円じゃね」「1万円足りない」とか教えてくれます。

### なんで残高があることを表現したいだけなのにEquity(純資産)がいるの?これ何?

~~おまじないです。今は黙って覚えてください。~~ 突然ですがお金って作れますか?答えは「はい、でも作ると怒られる」です。日銀でもない私達にお金を印刷することは許されてません。[^3]ですから、我ら一般市民にとっては、「お金が湧いてくる」ないし「お金が消えた」ということは絶対に起こりえません[^4]。となると、お金は常にどこかからどこかに流れていくだけです。つまり毎回の取引はただ右から左にお金を移動させているだけなので、**すべての取引で増えたお金と減ったお金は常に同じ額になります**。（複式簿記でいうところの、借方と貸方の額は一致するっていうことです。）なので、Ledgerも取引の中でお金が減ったり増えたりするとエラーになります。

でもそうすると、「あ、家計簿をつけ始めよう！」と思った時は困ることになります。今銀行に入ってるお金の*出どころ*をこじつける必要があります。それに最適なのが「純資産」というもので、ざっくりいうと**初期所持金**を意味する項目です。会社の会計を知ってる人には怒られそうな説明ですが…ところで、実は上のファイルの中身は省略形です。お金が動いてるだけで増減していないことを示すために本当は次のように書いてもいいのです。

```ledger
2022/12/01 * 初期残高
    Assets:Banks:Neon          120,000 JPY
    Equity:Opening Balances   -120,000 JPY
```

そして、これを次のように変えてみるとエラーになることがわかります。

```shell-session
$ cat test.ledger
2022/12/01 * 初期残高
    Assets:Banks:Neon          110,000 JPY
    ; 一万円消えた。。。
    Equity:Opening Balances   -120,000 JPY
$ ledger -f test.ledger bal
While parsing file ".../2022.ledger", line 3:
While balancing transaction from ".../neon/2022.ledger", lines 1-3:
> 2022/12/01 * 初期残高
>     Assets:Banks:Neon                        110,000 JPY
>     Equity:Opening Balances                 -120,000 JPY
Unbalanced remainder is:
         -10,000 JPY
Amount to balance against:
         110,000 JPY
Error: Transaction does not balance
```

## 引き出し、給与、デビットカード

さて、最初の残高は記録できました。これから次のようなシナリオを記録します。

1. 12/1に早速渋谷のATMでお金を下ろす。
1. 12/3にデビットカードでコンビニで買物。銀行に記録されたのは結局週明けの12/5だった。
1. 12/5にバイト代が振り込まれていた。

結論から言うとこうなります。

```ledger
2022/12/01 * 初期残高
    Assets:Banks:Okane                       120,000 JPY = 120,000 JPY
    Equity:Opening Balances

; さっきの残高の下に追記していく

2022/12/01 * 渋谷ATM
    Assets:Banks:Okane                        -5,000 JPY
    Expenses:Cash

2022/12/03=2022/12/05 * (14142) コンビニ
    Assets:Banks:Okane                          -145 JPY
    Expenses:Grocery                             145 JPY

2022/12/05 * 丸の内支店
    Assets:Banks:Okane                        10,000 JPY
    Income:Baito                             -10,000 JPY
    ; マイナスの収入!!!

```

両方の仕訳(取引の中の一行のことです)に金額を書くか書かないかは個人の好みです。またしても残高と入出金を確認していきます。

```shell-session
$ ledger -f bank/okane/2022.ledger bal
         124,855 JPY  Assets:Banks:Okane
        -120,000 JPY  Equity:Opening Balances
           5,145 JPY  Expenses
           5,000 JPY    Cash
             145 JPY    Grocery
         -10,000 JPY  Income:Baito
--------------------
                   0

$ ledger -f bank/okane/2022.ledger reg Assets:Banks:Okane
22-Dec-01 初期残高                                      Assets:Banks:Okane                                                   120,000 JPY                 120,000 JPY
22-Dec-01 渋谷ATM                                       Assets:Banks:Okane                                                    -5,000 JPY                 115,000 JPY
22-Dec-03 コンビニ                                      Assets:Banks:Okane                                                      -145 JPY                 114,855 JPY
22-Dec-05 丸の内支店                                    Assets:Banks:Okane                                                    10,000 JPY                 124,855 JPY
```

なんでこうなるのかを解説します。

1.  渋谷のATMでお金を下ろすのは簡単です。明らかにお金は「銀行の預金」から「手元の現金」に移動しています。疑う余地もなくお金銀行の残高が5000円減り、現金が5000円増えます。

    ちなみに、ここで現金をExpenses(経費,支出)として分類し、Assets(資産)として分類していないのは本来間違っています。ですが、どうせほとんどカード決済してるので現金はどのみちほぼ使いません。なのでおろした瞬間無くなったという体にしています。

1.  次にデビットカードで買い物するのも簡単です。お金は「銀行の預金」から「支出」へ移動しました。よく考えると支出ってなんなんだよって話ですが、たしかにコンビニにお金は払ってるわけで間違いはなさそうです。

1.  最後のバイト代ですが、これはかなり不可思議です。なにせ「マイナス1万円の給料」と「1万円増えた銀行預金」が釣り合ってるわけで、なかなか不思議な釣り合いです。とりあえずそういうものと覚えるしか無いですが、**資産の反対は負債、収入の反対は支出**と思うと支出の反対の収入(Income)はマイナスになる気もしませんか？ここではこれくらいにしましょう。[^pl]

## まとめ

長くなりましたが今回は銀行でお金を扱う際のLedgerの書き方を解説しました。銀行や現金だけで生活してる限りこの三種のオペレーションでだいたい乗り切れます。しかし、実際にはかなりの多くの方がクレジットカードを使ってるのではないでしょうか?このクレジットカードこそが家計簿を複雑化させる要因なのです。明日はクレジットカードにまつわるLedgerの書き方を解説します。

https://qiita.com/kikeg/items/6e72c75755ed498cf695

[^1]: スマホアプリ一つで完結するスイス銀行(笑)です https://www.neon-free.ch/en/
[^2]: ディレクトリ構成は完全に個人の趣味なので、「全部うちは`my.txt`に書くねん」という人はどうぞ、止めません。ただ、個人的には銀行やカード種別ごとにファイルを分けたほうが色々と楽、年度ごとに分けると区切りがついていい、と思ってこのパスになっています。
[^commodity]: 僕は4通貨単位に加えて株のtickerも通貨として使ってるので通貨を強制する仕組みに助かっています
[^3]: 株式発行はこれに近いですが、家計簿には関係のない話です
[^4]: 消えたと思っていても絶対に何かを買ったり借金を返したり誰かにあげたり最悪なくしたりしただけのはずです。絶対。
[^pl]: 複式簿記でPL(損益計算書)の損を+で、益を-で記述しているようなもので、やはり普通はそうは書きません。通常の会計ソフトではここを益を+、損を-で書けるようにするために、そもそも貸方、借方に分けてしまい、勘定科目を5項目に予め割り振ることでこの複雑さをユーザーから見えないようにしています。ただやってることは同じですし、プログラムとして綺麗なのはこちらだと思います。分かりにくいけど。