乍听之下,不无道理;仔细揣摩,胡说八道

0%

程序员的记账工具——ledger与ledger-mode

上大学后不久我开始用挖财记账,当时记得很随意,不会去追究一些不知道花在哪里的钱,不时就要强行修正账户余额,就这么一直用到了2019年中。后来挖财的启动时间越来越长,同时我不想看启动时的广告,便动了换记账软件的念头。

本想着试试MoneyWiz,但其价格令人望而却步,于是决定继续物色免费的记账工具,不久便遇到了GnuCash。由于它是GNU出品的,让我对其一开始便比较有好感,加上想尝试一下复式记账,便在同年9月份换到了GnuCash上。

可惜好景不长,我很快便发现了GnuCash的不足:

  1. 启动速度随着录入数据的增多显著变慢;
  2. UI不够美观;
  3. 比较依赖鼠标操作;
  4. 交易时间的精度只到天,且无法轻松调整一笔交易的位置——这一点是我尤其在意的,因为着意味着一旦我有一笔交易漏记了,再追加回去后,整个账本的交易数据次序也与银行记录的不一致了。

于是我抛弃了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记账至少有以下优势:

  1. 交易数据保存在本地,有利于保护用户的隐私;
  2. 交易数据保存为纯文本文件,用户可以依自己的喜好选择编辑工具(比如我就喜欢用Emacs),即使哪天ledger没法用了,这些数据也依旧可以查看;
  3. ledger支持自由定制符合个人习惯的资产和支出的层级。例如,我在Assets账户下细分了CheckingInvestment子账户分别囊括消费和投资账户;Checking下细分了三个储蓄卡、微信零钱,及支付宝余额账户;Investment下细分了FundWMP,分别表示基金和银行理财产品;Expense下有一个Food,从上面的截图中可以看到,Food下进一步分了十个子账户——只要愿意,就可以随意定制账户名称和层级;
  4. 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'

其它报表命令

除了查看资产余额和支出明细之外,我常用的报表还包括:

  1. ledger -f a.txt balance ^assets and \( not 公积金 \) or ^liabilities,查看不含公积金的资产和负债的余额,主要用于核对账本(a.txt文件)与银行卡、信用卡余额是否一致;
  2. ledger -S '-date' -f ~/Dropbox/Accounting/a.txt register Liabilities,查看信用卡的交易明细,用于在账单日核对银行的信用卡账单明细。参数-S 'date'表示按日期由近及远、从上往下排序
  3. ledger -e 10/01 -f a.txt balance '^Asset' and \( not '公积金' \) or '^Liabilities',统计至上月末为止的净资产(资产减去负债),用于了解自己的资产是上升还是下降的趋势。参数-e 10/01表示计算范围截止于10月1日——每次运行时需要调整为本月一号;
  4. 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的要求,划分出五个顶层的账户:

  1. Assets,表示用户的资产;
  2. Equity,用于初始化时作为账户余额的来源;
  3. Expense,表示用户的支出;
  4. Income,表示用户的收入;
  5. Liabilities,表示用户的负债。

Assets账户下,我还划分了

  1. Assets:Checking,表示用于消费的账户,其下还划分了储蓄卡账户、微信零钱、支付宝余额账户;
  2. Assets:Investment:Fund,表示购买的基金,其下为不同的基金划分不同的账户;
  3. Assets:Investment:WMP,表示购买的理财产品,其下按理财产品代号划分不同的账户。

Expense账户下,我细分了:

  1. Expense:Clothes,表示衣服鞋饰的支出;
  2. Expense:Education,表示书籍、文具的支出;
  3. Expense:Entertainment,表示电影、游戏等娱乐方面的支出;
  4. Expense:Food,表示买菜、就餐方面的支出。

还有其它的许多账户,就不一一赘述了。

Liutos wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客!
你的一点心意,我的十分动力。