上一篇文章介紹了爲什麼要複式記賬,以及Beancount的基本特點。這篇言歸正轉,直接從實踐開始。
賬戶類別
複式記賬的最基本的特點就是以賬戶爲核心,Beancount的系統整體上就是圍繞賬戶來實現的。之前提到的會計恆等式中有資產、負債和權益三大部分,現在我們再增加兩個類別,分別是收入和支出。Beancount系統中預定義了五個分類:
- Assets 資產
- Liabilities 負債
- Equity 權益(淨資產)
- Expenses 支出
- Income 收入
這五類是Beancount的約定,除此了Equity之下一些特殊的賬戶外,沒有任何預先定義的賬戶。用戶可以定義各種各樣的賬戶,Beancount對賬戶的組織是樹形的,譬如我分別有這些資產賬戶:
Assets:Cash:JPY
Assets:Cash:USD
Assets:Bank:CH:UBS
Assets:Bank:CN:BoC
Assets:Bank:US:Chase:Checking
Assets:Bank:US:Chase:Saving
Assets:Bank:JP:SMBC:JPY
Assets:Bank:JP:SMBC:USD
Assets:Broker:US:IB
Assets:Points:Airline:JAL
Assets:Points:Airline:United
Beancount對這些賬戶的組織形式如下圖:
接下來是聲明賬戶的語法。Beancount要求每個使用的賬戶必須聲明開戶時間,格式是YYYY-mm-dd
。之後是關鍵詞open
,表示在這個日期開戶(或者開始記賬)。接下來是賬戶名稱,格式用:
隔開的樹形語法,最後是(可以省略的)賬戶的貨幣種類。貨幣種類不需要事先定義,也沒有系統內部的定義,一般來說我們使用三字母的貨幣代碼,但其實可以用任何的名字(惟一的限制是大寫字母和下劃線)。我在這個例子中使用了USD
、JPY
、CNY
、CHF
四個貨幣,以及我自定義的P_JAL
和P_UA
表示不同航空公司的里程。
2019-01-01 open Assets:Cash:JPY JPY
2019-01-01 open Assets:Cash:USD USD
2019-01-01 open Assets:Bank:CH:UBS CHF
2019-01-01 open Assets:Bank:CN:BoC CNY
2019-01-01 open Assets:Bank:US:Chase:Checking USD
2019-01-01 open Assets:Bank:US:Chase:Saving USD
2019-01-01 open Assets:Bank:JP:SMBC:JPY JPY
2019-01-01 open Assets:Bank:JP:SMBC:USD USD
2019-01-01 open Assets:Broker:US:IB USD, JPY, CHF
2019-01-01 open Assets:Points:Airline:JAL P_JAL
2019-01-01 open Assets:Points:Airline:United P_UA
賬戶如何組織分類完全看個人需求和喜好,譬如我先分賬戶類型,再分國家,然後是金融機構名,最後是具體賬戶。分類的作用是可視化的時候,可以看某個非字節點下面所有賬戶的彙總。
接下來是負債類別的賬戶,最常見的就是信用卡,組織方式和使用方法和資產賬戶沒有什麼區別,譬如:
2019-01-01 open Liabilities:CreditCard:US:Discover USD
2019-01-01 open Liabilities:CreditCard:JP:Rakuten JPY
在開始記賬之前,還差最後一步,就是收入和支出類別的定義。Beancount把收入支出的類別也想象成了一個賬戶,在語法上和資產、負債類賬戶沒有區別。譬如下面例子:
2019-01-01 open Expenses:Clothing
2019-01-01 open Expenses:Food:Dinner
2019-01-01 open Expenses:Transport:Airline
2019-01-01 open Expenses:Transport:Railway
2019-01-01 open Income:Salary
2019-01-01 open Income:Rebate
基本借貸記賬
有了以上定義的賬戶以後,我們終於可以開始實踐記賬了。複式記賬又叫作「借貸記賬」。之所以這麼叫,是因爲每一條記錄都至少有一條借記(Debit)和一條貸記(Credit)。可以看下面這個例子:
2019-01-01 * "日本航空" "紐約-東京"
Expenses:Transport:Airline 1000 USD
Liabilities:CreditCard:US:Discover -1000 USD
這個例子表示我在日本航空購買了紐約-東京的機票,消費1000美元(貸記),付款的信用卡Discover扣款1000美元(借記)。
Beancount基本的語法如下所示:
YYYY-mm-dd * ["payee"] "description"
posting 1
posting 2
...
第一行要有日期,接下來是*
。收款者payee
是可選的,如果*
後面只有一個字符串,那就是省略了payee
。從第二行開始,每一行開頭空兩個縮進,然後是賬戶名以及金額、貨幣。這裏有一個要點:要保證所有條目的總和是0,否則就會出現Transaction does not balance: (xxx USD)
這樣的錯誤。這個要求很好理解,因爲花出去的錢必須和賬戶上減少的錢一樣,否則就是所謂的「賬目不平」了。
Beancount語法的靈活性在於每個記賬單元可以有任意多個條目(借記和貸記),只要保證它們的總和是0就可以。於是我們還可以這樣記錄:
2019-01-01 * "Walmart" "在超市買兩件衣服和晚餐"
Expenses:Clothing 20 USD
Expenses:Clothing 10 USD
Expenses:Food:Dinner 10 USD
Liabilities:CreditCard:US:Discover -40 USD
更加複雜的例子可能是這樣的:
2016-01-01 * "Google" "工資"
Assets:Bank:US:Chase:Checking 500 USD
Assets:Bank:US:Chase:Saving 1839.35 USD
Assets:Pension:US:401k:PreTax 419.23 USD
Assets:Pension:US:401k:PreTax 209.62 USD
Expenses:Health:Insurance:Dental 3.14 USD
Expenses:Finance:Insurance:TermLife 7.67 USD
Expenses:Health:Insurance:Vision 0.98 USD
Expenses:Tax:US:Federal 763.26 USD
Expenses:Tax:US:Medicare 60.84 USD
Expenses:Tax:US:SocialSecurity 260.15 USD
Expenses:Tax:US:State:NY 212.59 USD
Expenses:Tax:US:City:NYC 131.57 USD
Expenses:Tax:US:State:NYDisability 1.2 USD
Income:Salary:Regular -4192.31 USD
Income:Allowance:TermLife -7.67 USD
Income:Salary:401kMatch -209.62 USD
實際的記賬中,一進一出的兩個賬戶佔了絕大多數。這個時候把正負的金額寫兩遍未免有點羅嗦了,所以Beancount還提供了金額插值的功能。簡單說就是假設總和一定是0,在有N個賬戶的時候,只要求N-1個賬戶聲明金額。於是最初的例子還可以寫成:
2019-01-01 * "日本航空" "紐約-東京"
Expenses:Transport:Airline 1000 USD
Liabilities:CreditCard:US:Discover
在我的實踐中,我只在正好是兩個賬戶的時候纔使用這個功能,因爲可以避免重複的數字。但有多個賬戶的時候,把每個金額都寫出來有助於避免錯誤,和「防禦性編程」的理念一樣。
在上面的例子中,我們還可以看出來,所有Expenses
類別的賬戶都是正數,所有Income
類別的賬戶都是負數。這是Beancount及類似工具使用負數來表示借記(Debit),正數表示貸記(Credit)的結果。簡單來說,借記就是把賬戶上的資金移除,貸記就是增加賬戶的資金。同理,通常Assets
類是正數,Liabilities
類是負數。本質上每個賬戶的數值只有絕對值有意義,正負號並沒有實際含義。
貨幣轉換
如果在去國外旅遊,免不了要進行貨幣轉換。事實上Beancount本身沒有定義任何貨幣,這也意味着你可以定義任何貨幣(或商品)。所以哪怕不出國,只要是記錄了非主要貨幣類資產,譬如投資品,代金券,航空公司里程,那麼就需要貨幣轉換了。
在使用多個貨幣之前,需要先定義「工作貨幣」。工作貨幣可以不止一個,例如:
option "operating_currency" "JPY"
option "operating_currency" "USD"
定義了工作貨幣以後,在fava界面中可以看到工作貨幣單獨列出的欄目。
Beancount貨幣轉換的語法有兩種,一種是使用@
記錄單位貨幣的轉換價格,例如:
2019-01-01 * "日本航空" "紐約-東京"
Expenses:Transport:Airline 1000 USD @ 110 JPY
Liabilities:CreditCard:JP:Rakuten -110000 JPY
另一種方式我更常用,使用@@
記錄轉換後的總額:
2019-01-01 * "日本航空" "紐約-東京"
Expenses:Transport:Airline 1000 USD @@ 110000 JPY
Liabilities:CreditCard:JP:Rakuten -110000 JPY
貨幣轉換不一定只在一個賬戶上。下面的這個例子是以2.5日圓每點的價格,買了10000日本航空里程,但是付款的信用卡是以美元計價的,所以兩遍都可以轉換爲25000日圓來平衡。
2019-01-01 * "日本航空" "購買里程"
Assets:Points:Airline:JAL 10000 P_JAL @ 2.5 JPY
Liabilities:CreditCard:US:Discover -220.0 USD @@ 25000 JPY
借貸管理
複式記賬的強大之處是每個賬戶都有狀態,而且每個操作都是原子的,這對複雜的資金進出記錄非常有幫助。
生活中一個常見的例子是朋友之間的借錢和相互墊付,就拿我最近遇到一個例子來說吧,我和X、Y三人一起出遊,從東京附近的橫須賀坐船到猿島,費用是每人1300日圓的船票和200日圓的登島費,其中船票可以用信用卡支付,而登島費只能付現金。我們一共需要付4500日圓,但是正好誰都沒有這麼多現金,於是決定我用信用卡付三人的船票,X用現金付三人的登島費,最後再結算。
2019-05-25 * "猿島" "渡輪"
Expenses:Transport:Ferry 1300 JPY ; 個人渡輪費用
Assets:Receivables:X 1300 JPY ; 對X應收賬款
Assets:Receivables:Y 1300 JPY ; 對Y應收賬款
Liabilities:CreditCard:JP:Rakuten -3900 JPY
2019-05-25 * "猿島" "登島費"
Expenses:Transport:Attraction 200 JPY ; 登島費
Liabilities:Payable:X -200 JPY ; 欠X的錢
第二天,三人結算完畢,X付給我現金,Y轉賬給我。
2019-05-26 * "猿島" "費用結算"
Assets:Receivables:X -1300 JPY ; X償還債務
Liabilities:Payable:X 200 JPY ; 償還對X的債務
Assets:Cash:JPY 1100 JPY ; X實際付給我的錢到賬
Assets:Receivables:Y -1300 JPY ; Y償還債務
Assets:Bank:JP:SMBC:JPY 1300 JPY ; Y實際付給我的錢到賬
最終可以看出來,我在Expenses:Transport:Ferry
類別消費1300 JPY
,在Expenses:Transport:Attraction
類別消費200 JPY
,信用卡扣款3900 JPY
,收到了1100 JPY
的現金,Assets:Bank:JP:SMBC:JPY
收到了1300 JPY
的轉賬。
以上這種記賬方法可以讓資金的流動一目瞭然,類別和金額也準確無誤。記錄對他人的債權(應收賬款)和欠他人的債務(應付賬款),我分別使用了Assets:Receivables
和Liabilities:Payable
下面的賬戶。
應收賬款和應付賬款的另一個用途是區分付款和到貨時間。一般來說交易是當場進行的,一個賬戶的借記和另一個賬戶的貸記同時發生,但是有些時候付款和到貨並不是同時發生的,如果需要精確區分發生的時間的話,可以用這種方法把他們分成兩筆記錄。
下面這個例子是,用信用卡買日本航空里程,但是不知道爲什麼過了1個月纔到賬:
2019-01-01 * "日本航空" "購買里程"
Assets:Receivables:JAL 10000 P_JAL @@ 25000 JPY
Liabilities:CreditCard:US:Discover -220.0 USD @@ 25000 JPY
2019-02-01 * "日本航空" "里程到賬"
Assets:Points:Airline:JAL 10000 P_JAL
Assets:Receivables:JAL
這篇文章到此爲止,Beancount最基本的用法已經介紹完畢了。用這些簡單的語法,我們已經可以滿足大部分的記賬需求了,但Beancount的強大之處遠遠不止於此。
下一篇我會繼續介紹Beancount的更多用法,包括如何高效對賬和資產折舊。同時歡迎加入Beancount中文討論:t.me/beancount_zh。
上次修改時間 2019-05-27