上大学后不久我开始用挖财记账,当时记得很随意,不会去追究一些不知道花在哪里的钱,不时就要强行修正账户余额,就这么一直用到了2019年中。后来挖财的启动时间越来越长,同时我不想看启动时的广告,便动了换记账软件的念头。
本想着试试MoneyWiz,但其价格令人望而却步,于是决定继续物色免费的记账工具,不久便遇到了GnuCash。由于它是GNU出品的,让我对其一开始便比较有好感,加上想尝试一下复式记账,便在同年9月份换到了GnuCash上。
可惜好景不长,我很快便发现了GnuCash的不足:
- 启动速度随着录入数据的增多显著变慢;
- UI不够美观;
- 比较依赖鼠标操作;
- 交易时间的精度只到天,且无法轻松调整一笔交易的位置——这一点是我尤其在意的,因为着意味着一旦我有一笔交易漏记了,再追加回去后,整个账本的交易数据次序也与银行记录的不一致了。
于是我抛弃了GnuCash,投向了ledger(以及ledger-mode)的怀抱。
ledger和ledger-mode
ledger
ledger是一个基于复式记账的、生成财务报表的命令行程序——它不具备录入的功能,它只生成报表。
要使用ledger,必须先将交易数据按它的语法写在一个文本文件中,然后才用ledger读取这个文件,生成各种各样的报表。百闻不如一见,下图便是ledger生成的报表
ledger-mode
记录交易数据的源文件是纯文本格式的,可以用任何文本编辑器(text editor,不是word processor)来编辑。如果打算用Emacs,那么就不容错过ledger-mode了。
ledger-mode是一个Emacs主模式,为编辑ledger的源文件(一般以ledger
为后缀名)提供诸多便利。
比如在上图中,ledger提供了语法高亮:日期(2020-03-04
)和描述(利口福
)是红色的,金额(-32
)和货币(CNY
)是紫色的,注释(分号及其后面的内容)是灰色的。ledger-mode还提供自动缩进,在输入了利口福
并回车后,光标会自动定位到字母L
的位置,下一行也是如此——连续敲入两个回车得到一行空行,标志着一笔交易记录结束。ledger-mode还支持在Emacs内查看ledger输出的报表(见下文)。
ledger的优势
用ledger记账至少有以下优势:
- 交易数据保存在本地,有利于保护用户的隐私;
- 交易数据保存为纯文本文件,用户可以依自己的喜好选择编辑工具(比如我就喜欢用Emacs),即使哪天ledger没法用了,这些数据也依旧可以查看;
- ledger支持自由定制符合个人习惯的资产和支出的层级。例如,我在
Assets
账户下细分了Checking
和Investment
子账户分别囊括消费和投资账户;Checking
下细分了三个储蓄卡、微信零钱,及支付宝余额账户;Investment
下细分了Fund
和WMP
,分别表示基金和银行理财产品;Expense
下有一个Food
,从上面的截图中可以看到,Food
下进一步分了十个子账户——只要愿意,就可以随意定制账户名称和层级; - ledger支持给每一笔交易添加元数据,其中一种便是tag(标签)。tag增强了ledger生成报表的灵活度,比如我给在公司点外卖的支出打上
:公司:
的tag后,便可以让ledger只生成在公司就餐的支出报表;
ledger的用法
初始化账户
用ledger记账,要先初始化每个账户的余额。基于复式记账的原则,ledger要求每一笔交易中所有账户的金额变化之和为0,因此若要往储蓄卡资产账户中“充值”,就必须从另一个账户中减去等额的钱。在ledger中,这个“另一个账户”便是Equity
。(在ledger的在线文档中有一个章节Understanding Equity可以帮助理解)。
所以,初始化账户余额就是添加一笔交易,将与账户余额等量的钱从Equity:Opening Balance
流到Assets
下的细分账户中,如下图所示
尽管在上图中,金额123
后的货币为CNY
,但ledger并不理解这三个字母是否真的为合法的货币名称——ledger只要求用户指定了即可。(可以参见ledger在线文档的Commodities and Currencies章节)
PS:在上图中没有明确写出Equity:Opening Balance
的变化为-123 CNY
,是因为ledger足够“聪明”,可以自己补足这个信息。
现在可以用ledger输出报表了
记录第一笔交易
有了钱便可以开始买买买了。假设早餐在楼下肠粉店花了6块钱吃了一份鸡蛋肠,可以记为
用ledger输出新的资产报表
还可以用ledger输出支出账户的明细,示例代码为
1 | ledger -f a.ledger register 'Expense' |
其它报表命令
除了查看资产余额和支出明细之外,我常用的报表还包括:
ledger -f a.txt balance ^assets and \( not 公积金 \) or ^liabilities
,查看不含公积金的资产和负债的余额,主要用于核对账本(a.txt
文件)与银行卡、信用卡余额是否一致;ledger -S '-date' -f ~/Dropbox/Accounting/a.txt register Liabilities
,查看信用卡的交易明细,用于在账单日核对银行的信用卡账单明细。参数-S 'date'表示按日期由近及远、从上往下排序
;ledger -e 10/01 -f a.txt balance '^Asset' and \( not '公积金' \) or '^Liabilities'
,统计至上月末为止的净资产(资产减去负债),用于了解自己的资产是上升还是下降的趋势。参数-e 10/01
表示计算范围截止于10月1日——每次运行时需要调整为本月一号;ledger -b 11/01 -e 11/30 -f a.txt balance '^Expense:Food'
,统计上个月在用餐方面的总支出,用于核对上个月的饮食开支是否超支。参数-b 11/01
表示计算范围开始于11月1日——每次运行时需要调整为上个月一号。
在Emacs中查看报表
ledger-mode允许用户直接在Emacs中查看报表:先按下组合键C-c C-o C-r
,然后在minibuffer中输入报表名称,最后输入完整的调用ledger的命令即可。Emacs会打开一个新的buffer展示ledger的输出
账户划分方法
ledger中划分账户的自由度很高,以下是我划分的一部分,供读者参考。
首先按照ledger在线文档的Structuring your Accounts的要求,划分出五个顶层的账户:
Assets
,表示用户的资产;Equity
,用于初始化时作为账户余额的来源;Expense
,表示用户的支出;Income
,表示用户的收入;Liabilities
,表示用户的负债。
在Assets
账户下,我还划分了
Assets:Checking
,表示用于消费的账户,其下还划分了储蓄卡账户、微信零钱、支付宝余额账户;Assets:Investment:Fund
,表示购买的基金,其下为不同的基金划分不同的账户;Assets:Investment:WMP
,表示购买的理财产品,其下按理财产品代号划分不同的账户。
在Expense
账户下,我细分了:
Expense:Clothes
,表示衣服鞋饰的支出;Expense:Education
,表示书籍、文具的支出;Expense:Entertainment
,表示电影、游戏等娱乐方面的支出;Expense:Food
,表示买菜、就餐方面的支出。
还有其它的许多账户,就不一一赘述了。