Beyond the Void
BYVoid
Beancount複式記賬(三):結餘與資產

先前一篇文章裏我介紹了Beancount的基本記賬方法和一切常見的規範。這篇繼續講述Beancount的常用語法,主要內容是對賬和資產折舊。

對賬

Beancount的語法檢查保證了每一筆交易的借記和貸記是平衡的,這已經可以避免許多會導致「賬不平」的錯誤,但是對於數額本身的錯誤,或者某調賬目漏記並沒有辦法。這就是爲什麼我們要定期對賬。

資產負債表

所謂對賬,就是看每個賬戶的結餘(Balance)是否正確。每個賬戶的餘額可以在資產負債表(Balance Sheet)頁面中找到,可以查看樣例資產負債表

資產負債表

fava資產負債表把資產列在左邊,負債和權益列在右邊。權益即淨資產,是根據資產和負債計算出來的(除了Equity:Opening-Balances,之後會講到)。

需要注意的是Beancount的債務和權益是負數,所以並不是資產 = 負債 + 權益,而是資產 + 負債 + 權益 = 0。我之前提過一次,這是Beancount使用正數來表示借記(Debit),負數表示貸記(Credit)的結果。在傳統的複式記賬中,數字的正負號並沒有這樣的意義,無論是借記還是貸記都是正數,所以絕對值資產 = abs(負債 + 權益)也許更好理解。

在資產負債表上點擊任意賬戶,可以進入賬戶的明細界面。賬戶的明細界面列出了涉及該賬戶的每一筆交易,點開後可以看到具體的交易信息。每一行的最右側是這一筆交易後的該賬戶結餘,這個數字就是對賬的關鍵。

賬戶明細

結餘斷言

假設已知賬戶的某日結餘金額,只要在這個賬戶明細界面看一看對應的日期的最後一筆交易後結餘是否正確就可以了。如果Beancount計算出的結餘和已知的是一樣的,那麼基本上就可以確定賬沒有問題。

這個步驟看似容易,但是隨着賬目增多,對賬的負擔會很重,而且容易看錯。更嚴重的問題是,如果因爲某種原因要修改過去的賬目,已經對好的賬就不一定正確了。惟一保險的辦法是每次修改了過去日期的交易後,把涉及到的賬戶未來的結餘再全部重新對一遍。好在這個過程是可以自動化的,方法就是使用結餘斷言(Balance Assertion)。

結餘斷言就是在記賬中加入已知事實,即某個日期開始的時候的某個賬戶結餘。如果你對單元測試有瞭解,這個方法肯定不會陌生。結餘斷言的語法非常簡單,如下例所示:

2017-08-20 balance Assets:US:BofA:Checking 2298.50 USD

惟一需要留意的地方是,結餘斷言是所聲明日期開始的時候的餘額,即當日的交易不算在內。

聲明結餘斷言之後,Beancount會自動檢查斷言是否正確,如果不正確就會有錯誤出現。如果每個賬戶都有適當的結餘斷言,修改過去的交易就可以放心進行了。

文檔鏈接

有了結餘斷言,接下來就是這個斷言的事實從哪裏來。最簡單的方法當然是看看現在有多少結餘,然後直接寫上今天的日期。這種方法適合現金和其他一些不方便查詢交易記錄的賬戶。

除此之外,推薦使用銀行月結單(Statement)上面的數字。許多國家的許多銀行、信用卡都會定期發送交易明細,一般來說是每月。Beancount提供了管理這些文件的一個語法,例如:

2013-03-20 document Assets:US:BofA:Checking "path/to/statement.pdf"

在fava中這條記錄也會被顯示出來,並且提供可以點擊的鏈接。這個路徑是相對於這條記錄所在的Beancount文件的目錄,這對於多文件記賬很重要(include語法,之後會講到)。

根據個人經驗還有一個重要的提醒,就是要看清楚月結單包含哪些交易,尤其是賬單週期末的哪些。因爲很多銀行、信用卡的交易並不是即時結算的,特別是有跨國交易的時候。如果發現某些交易還沒出賬或者賬單週期開始包含了上個週期的交易,一定要注意餘額斷言的數額。

結餘調整

接下來說一說賬對不上的情況。事實上,這是一種常態,人畢竟不是完美的,錯記漏記實在是太正常了。一旦結餘斷言失敗,當然是先看自己有沒有記錯什麼,如果實在困難,或者金額差距不大自己沒那麼在乎,可以考慮用結餘調整。

結餘調整並不是非要用什麼特別的語法不可,實際上只是一種規範。這個規範是使用Equity:Opening-Balances來表示初始結餘。下面是一個例子:

2015-01-01 * "賬戶初始"
  Assets:US:BofA:Checking 3490.52 USD
  Equity:Opening-Balances -3490.52 USD

這個例子的意思是,在2015年1月1日給Assets:US:BofA:Checking增加3490.52美元結餘。假設這個賬戶之前沒有記錄的話,那麼它現在的結餘就是3490.52美元,如果有就是在原來的基礎上加上3490.52美元。這3490.52美元從哪裏來呢?Beancount的規範是使用Equity:Opening-Balances

Equity:Opening-Balances是權益類別下面的賬戶,它是淨資產的一部分。Beancount中權益是負數,所以數字減少代表了淨資產的增加。這一部分資產的來源可以理解爲表外資產,即來源不明確,在Beancount賬本中沒有更詳細的記錄。

Beancount還提供了一個更加簡易的語法pad,結合了結餘斷言,功能是把結餘調整到使得下個餘額斷言滿足。用法如下所示:

2015-01-01 pad Assets:US:BofA:Checking Equity:Opening-Balances
2015-01-02 balance Assets:US:BofA:Checking 3490.52 USD

以上的效果是,無論Assets:US:BofA:Checking之前餘額多少,在2015年1月2日開始之前都調整到3490.52 USD,差額從Equity:Opening-Balances來。

一般來說除非是調試錯誤或者導入數據過程中,否則我不建議使用pad這個語法,因爲它會讓結餘斷言喪失一定的準確性。使用pad的風險是,如果自動調整的數額過大,當修改了過去其他的賬目導致需要調整的數額發生改變的時候,Beancount並不會出現任何警告和錯誤。我更傾向於把需要調整的金額明確寫出來,這樣一旦變化就會有錯誤提醒,避免更大的錯誤。

資產購入與折舊

生活中有一些交易我們需要考慮到底要記爲花費,還是資產的購入。在光譜的兩端一般沒什麼爭議,譬如喫飯肯定是消費,買房無疑是購入資產。中間許多類別就不一定了,這取決於個人的偏好和目的。

拿買汽車作爲例子,無論是新車還是舊車,許多人在開一段時間以後會選擇賣掉。如果我們把買車記爲消費,賣車記爲收入,這本身並沒有任何錯誤。問題是,對很多人來說汽車還是一筆不可忽略的資產,如果直接記爲消費,沒有對應的資產入賬,那就意味着淨資產突然大幅減值。幾年後賣出,淨資產又突然增加。

要解決這個問題,我們就要把汽車記爲一項資產,下面是例子:

2015-01-01 * "豐田汽車" "買入Corolla"
  Assets:Car:ToyotaCorolla 20000 USD
  Assets:US:BofA:Checking -5000 USD
  Liabilities:Loan:Car -15000 USD

2019-01-01 * "二手車商" "賣出Corolla"
  Assets:Car:ToyotaCorolla -20000 USD
  Assets:US:BofA:Checking 10000 USD
  Expenses:CarUsage 10000 USD

上面這個例子是2015年1月1日貸款買入了價格爲$20000的汽車,並計入資產Assets:Car:ToyotaCorolla。中間省略還貸款的過程,四年後2019年1月1日,把車賣給了二手商,獲得$10000,剩下的$10000就是三年來用車的消費了。

這個方法對買賣交易之間的這段時間內淨資產計算仍然不夠準確,並沒有完全解決淨資產跳變。因爲汽車的使用是三年來平均花費出去的,而不是最後賣的時候一下子花了$10000。要解決這個問題就要引入定期進行折舊(Depreciation)計算。一般的會計方法中把因爲資產使用或者隨着時間自然減值稱爲折舊,我記爲Expenses:Depreciation:CarUsage

接下來需要決定的是折舊的週期,即把車的使用費按照多大的粒度來記錄。這個完全因人而異,也因金額的大小而異。對於車我可以選擇按年折舊,因爲在許多國家(譬如美國),工作原因的資產折舊是可以按年抵稅的。如果希望每個月的花銷更加細緻,那麼按月折舊也是一個方案,只是需要多記錄幾筆而異。

2015-12-31 * "Corolla折舊"
  Assets:Car:ToyotaCorolla -2500 USD
  Expenses:Depreciation:CarUsage

2016-12-31 * "Corolla折舊"
  Assets:Car:ToyotaCorolla -2500 USD
  Expenses:Depreciation:CarUsage

2017-12-31 * "Corolla折舊"
  Assets:Car:ToyotaCorolla -2500 USD
  Expenses:Depreciation:CarUsage

2018-12-31 * "Corolla折舊"
  Assets:Car:ToyotaCorolla -2500 USD
  Expenses:Depreciation:CarUsage

下一個問題是,每次折舊減值多少。這個問題就是會計上可以操作的空間了,因爲實際的價格只有在出售的時候纔知道。一般會計準則是預估一個折舊年限,然後以此爲根據來折舊。譬如說,我們預期汽車的壽命是10年,即10年後該車的價值清零,這樣我們可以按照每年10%的折舊率每年減記。最終當實際賣出的時候,我們再根據賣出價格做調整,或者差額記爲其他類別。如果有特別的事件發生,還可以另外單獨折舊。例如發生了車禍,車的估值大幅下降,可以在此時額外減值。

Beancount並沒有自動折舊的功能,每一筆都是要自己寫的。如果怕忘了,其實可以把未來日期的折舊也寫上。另外還有第三方的插件beancount-interpolate可以嘗試使用。

到此爲止我差不多已經講到了日常使用中的大部分語法。如果把這個系列文章看成一個編程語言教程,那麼語法已經差不多講完了。下一篇文章我會講述「真實世界」裏的Beancount使用方法——把Beancount賬本看成一個項目,該如何管理。歡迎加入Beancount中文討論:t.me/beancount_zh


上次修改時間 2019-05-30

相關日誌