Beyond the Void
BYVoid
Beancount複式記賬(四):項目管理

Beancount系列文章的前三篇已經基本覆蓋了常用的複式記賬方法。記賬本身是一門經驗的學問,不僅包括賬本身怎麼記,還包括了「賬本」怎麼整理。這篇文章不涉及複雜的會計學概念,只是從更加微觀的角度來講一講我實際記賬過程中是怎麼組織的。

版本管理

文本記賬的最大優勢就是它便於使用版本管理系統,像管理代碼一樣管理賬本。最常見的代碼版本管理工具就是git了,所以我推薦使用git管理Beancount的賬本文件。使用git的好處是提升賬本的可維護性,尤其是能夠防止不小心改錯、誤刪這樣的動作,這在重構的過程中極其重要。

git如何使用我不再贅述,對於會寫代碼的人來說屬於基本技能。即使不熟悉,網上的資料和教程也是汗牛充棟了,更有Sourcetree這樣的可視化工具。

惟一需要注意的是,你需要保管好你的git倉庫,尤其是要避免盲目上傳到Github之類的網站。賬本信息屬於非常敏感的個人隱私,因爲其中可以透露出的信息非常豐富,甚至超過了日記能包含的。如果要上傳git倉庫備份,至少要使用支持私人倉庫的服務,或者自己搭建git服務器(支持SSH即可)。最好在上傳之前對整個倉庫加密,譬如使用git-crypt

標籤

標籤是一個講交易組織歸類的方法,是開支類別之外的另一個維度。每一個交易都能加上一個或多個標籤:

2019-06-01 * "奧地利航空" "東京-維也納" #2019-07-Europe-Trip
  Expenses:Transport:Airline 600 USD
  Liabilities:US:CreditCard:Citi

標籤的作用是方便查詢,在fava和bean-query中都可以按照標籤來過濾。

爲了避免重複,Beancount還提供了標籤堆棧語法:

pushtag #2019-07-Europe-Trip

2019-06-01 * "奧地利航空" "東京-維也納"
  Expenses:Transport:Airline 600 USD
  Liabilities:US:CreditCard:Citi

2019-06-01 * "奧地利航空" "維也納-莫斯科"
  Expenses:Transport:Airline 100 USD
  Liabilities:US:CreditCard:Citi

poptag #2019-07-Europe-Trip

除了標籤,Beancount還提供了一個類似的語法^,叫做鏈接(Link),本質上和標籤是一樣的作用,但是被建議用作將財務上關聯的交易組織在一起的方法。常見的使用場合是有時間跨度的一筆交易,例如匯款和收款,短期的債務,按次記錄但是按月徵收的某些銀行手續費,或者僅僅是兩個目的一致的交易。

2016-05-03 * "Chase" "取現" ^2016-05-overdraft
  Assets:Bank:US:Chase:Checking -75 USD
  Assets:Cash:USD 50 USD
  Expenses:Finance:BankFee:Overdraft 25 USD

2016-05-05 * "Chase" "還清欠款" ^2016-05-overdraft
  Assets:Bank:US:Chase:Checking 25 USD
  Assets:Bank:US:Chase:Saving

多文件組織

到此爲止我一直假設所有的Beancount記錄都是在單一文件中的,這個文件會隨着賬目的增多越來越膨脹,直到用編輯器維護不便。使用單一文件就像把一個巨大的程序寫到一個源文件中一樣,閱讀和修改都很困難。所以Beancount提供了include文件包含語法,用法和多數編程語言一樣。

include後面緊跟着要引入的文件名,路徑是相對於當前文件的。

; main.beancount
include "accounts.beancount"
include "categories.beancount"
include "books/books.beancount"

; books/books.beancount
include "2016.beancount"
include "2017.beancount"
include "2018.beancount"
include "2019.beancount"

利用這個簡單的語法,一個巨大的賬本就可以分成若干個較小的賬本組合起來了。

要注意,到目前(Beancount 2.2.1)爲止,標籤堆棧和文件包含是不能組合使用的,也就是說標籤堆棧內的include的文件不會自動加上標籤。我在Beancount的問題列表提出了這個問題,作者的答覆是也許以後會實現。

賬本劃分

接下來我終於要講到我的經驗之談了。儘管有文件包含語法,但每條記錄到底怎麼劃分還是一個見仁見智的話題。我使用了三種分割方法,分別是按日期劃分、按類別劃分和按賬戶劃分。這三種劃分方式都有道理,各有優劣。總而言之,劃分的目的是減少錯誤的可能,降低維護成本,節約注意力資源。下面我詳細說來。

按日期劃分

按日期劃分賬本是最直接的分割方法,我們可以按年份或者月份創建文件(譬如2019.beancount),每個文件內只包含這段時間內的記賬。一般來說除非是修正錯誤或者重構,舊的賬不會再修改,使用當前的賬本來記賬,把過去的賬分割儲存是一種有效節約注意力資源的方法。

除了按照日曆時間劃分,還可以結合標籤,把某些事件提取出來,最常見的是旅行。下面這個例子是我把2019年7月關於歐洲旅行的賬目全部放到2019-07-Europe-Trip.beancount中,並且結合標籤堆棧,把整個文件中的賬目標記上#2019-07-Europe-Trip標籤。

; 2019-07-Europe-Trip.beancount
pushtag #2019-07-Europe-Trip

2019-06-01 * "奧地利航空" "東京-維也納"
  Expenses:Transport:Airline 600 USD
  Liabilities:US:CreditCard:Citi

...
poptag #2019-07-Europe-Trip

使用單獨的文件來記錄某個時間段的某類事件相關的開銷的好處是,一旦這個事件結束,這個文件就可以進入封存狀態了。此外,哪怕是不使用任何可視化工具(如fava),這個文件的可讀性也非常高,甚至可以當作旅行日記了。

資產負債表

按類別劃分

按類別劃分指的是把統一類的重複記錄整理到一起,便於根據時間縱向比較。譬如說每月的工資單、房租、水電費、定期投資、以及其他自動扣費的服務。

; Tokyo-Electric-Power.beancount

2018-04-25 * "東京電力" "電費"
  Expenses:Utility 4621 JPY
  Liabilities:JP:PrestiaVisa

2018-05-25 * "東京電力" "電費"
  Expenses:Utility 4956 JPY
  Liabilities:JP:PrestiaVisa

2018-06-25 * "東京電力" "電費"
  Expenses:Utility 6648 JPY
  Liabilities:JP:PrestiaVisa

2018-07-25 * "東京電力" "電費"
  Expenses:Utility 9394 JPY
  Liabilities:JP:PrestiaVisa

以上的例子是每月25日扣費的東京電力賬目。這樣記錄的好處是每個月的開銷一目瞭然,還可以觀察不同月份的開銷變化。如果可以從扣費的服務導出賬單,就可以把單個來源放在一個文件。如果是手動記錄,這種組織方式也可以最大程度上減少漏記的可能性。

按賬戶劃分

我使用的第三種分割方法是按賬戶劃分。按賬戶劃分和按類別劃分差不多是相互對稱的兩種劃分方法,因爲這種方法是以賬目相關的賬戶爲依據,分割出了單獨的賬本。按賬戶劃分的最初目的是方便自動導入腳本,因爲許多銀行、信用卡都可以提供月對賬單,非常適合自動轉換爲Beancount格式,減少人工。

但是完全按照賬戶的缺點也顯而易見,那就是尤其和「按類別劃分」衝突,所以我的實際手段是儘可能不使用這個劃分方法。什麼時候會使用呢?我的原則是和賬戶的關聯性十分強的消費,包括銀行利息、銀行手續費、信用卡還款、返現返點、開戶獎勵、年費、賬戶間轉賬。

; AmexSPG.beancount
2019-02-01 * "American Express" "SPG年費"
  Expenses:Finance:CreditCardFee 33480 JPY
  Liabilities:JP:AmexSPG

2019-02-01 * "American Express" "Amex SPG開卡獎勵"
  Assets:Points:US:Marriott 30000 P_MRT
  Income:OpeningBonus

2019-02-22 document Liabilities:JP:AmexSPG "AmexSPG/2019-02.pdf"

2019-03-11 * "American Express" "2019年2月賬單還款"
  Assets:Bank:JP:SMBC -3254 JPY
  Liabilities:JP:AmexSPG

2019-03-22 document Liabilities:JP:AmexSPG "AmexSPG/2019-03.pdf"

2019-04-10 * "American Express" "2019年3月賬單還款"
  Assets:Bank:JP:SMBC -63935 JPY
  Liabilities:JP:AmexSPG

2019-04-22 document Liabilities:JP:AmexSPG "AmexSPG/2019-04.pdf"

2019-05-10 * "American Express" "2019年4月賬單還款"
  Assets:Bank:JP:SMBC -23718 JPY
  Liabilities:JP:AmexSPG

總結

我把我的原則總結成了以下規則,按順序判斷:

  • 如果該收支屬於一個特別的事件,那麼就將其加入這個事件對應的單獨文件,例如#2019-07-Europe-Trip
  • 如果該收支是一個週期項目,但跟某個銀行賬戶無關,則加入按類別劃分的文件,例如水電費、房租、工資。
  • 如果該收支跟某個銀行賬戶緊密相關,則加入該賬戶對應的文化,例如銀行手續費、信用卡還款、返現。
  • 不屬於以上情況,則加入按日期劃分的文件。

以上就是我目前對賬本管理的一些經驗之談,這些方法只是爲了達成我前面提到的三個目的:減少錯誤的可能,降低維護成本,節約注意力資源。如果之後我發現了更好的劃分方式,我會對賬本重構,到時候再來更新這篇文章。

在以後的文章中(如果有的話),我還會介紹更多實際的記賬方法,包括出差記賬、更細緻的資產記賬,價格追蹤,股票交易和多人記賬。歡迎加入Beancount中文討論:t.me/beancount_zh

以下鏈接是其他介紹:


上次修改時間 2019-07-08

相關日誌