家計簿を付けたいと長い間思っている。
ぼくはお金を何の気なしにすぐ使ってしまう方で、大して楽しい思いをした覚えもないのに手元に残らない。
だらしないタイプの浪費家であって、家計簿が効きそうだ。



せっかくiPhoneを持っているので、それを使いたい。
でも家にはパソコンがあるので、それを同期して管理したい。
あっ、でも、この話、前にも書いたわ。
そうそう、以前はTwitterで消費をつぶやいて、それをPerlで集計してとか大きなことを言っていた。
基本は出来ていたのだが、面倒な割りに機能が少ない。
それに、ツイッターを使うと、普通のアカウントに「しゃぶしゃぶ温野菜 3480円」とかあらぬことをつぶやいてしまいそうで恥ずかしい。

以前は「マネールック」「OCN家計簿」というクラウド財務サービスを使おうと思っていた。
しかしこれもセキュリティ不安案件であって、銀行の暗証番号やインターネットバンキングの乱数表を全部(!)サーバーに預けなければならない。
金曜の楽天カードの件といい最近暗証番号づいているが、銀行も暗証番号を他人に知られた上での金融事故は消費者の自己責任としている。
マネールックやOCN家計簿は、銀行でも消費者でもない「他人」には違いないわけで、サービスから何らかの漏洩が起こったりして(あるいは手元のPCでマネールック/OCN家計簿へのアクセスをインターラプトされて)事故が起こったとき、誰が責任を取るのかハッキリしない。
もちろんそういうことがおきないようにいろいろ防衛措置は取られていると思うが、不安があるわりに機能はそこまでリッチという感じはしなくて、ぼく個人としては撤退してしまった。

ということで、基本iPhoneで家計簿をつけ、ネットを経由してCSVでエクスポートして家ではExcelで管理、という普通のやり方に落ち着いた。

まず入力だが、iPhoneアプリのCashFlowを使っている。



ぼくは広告なしの有料版にした。
結構シンプル&高機能で、以前作者の方に仕様の問題を伺ったら即効で対応してくださったので気に入って使っている。

これに、現金、銀行、クレカ、PASMOなどの金融資産を入れている。
CashFlowTotal
つけ始めの状態からスタートするので、最初はそのときの残高をそのまま引き写す。
クレカは仕様限度額からの差分を持っているという考え方で、常にマイナス残高だ。
ぼくは一回払いしか今のところ使っていないので、来月払う借金ということになる。
これで残高は「現金の保有額 - カードを使った額」と言うことになる。
カードを使いすぎると全体が赤字になる。
これは実感に合っている。

いつ〆(ご破算)にするかを考えるのだが、iPhoneは無限に〆にしないことにした。
過去からの取引がすべて入っている。
(まだこの運用にしてから2ヶ月しか経っていないが)
で、毎日日記を付けるときに、今日の分の取引をPCにバックアップしている。

バックアップにはCashFlowの「エクスポート」機能を使う。
CashFlowExport
メール、Web(iPhoneがサーバーになってWiFiでアクセスする)、Dropboxの3つがある。
で、形式はCSV、範囲は過去7日間にしている。

これで過去一週間の取引がCSVになる。
現実には過去一日の分だけでいいのだが、余計な過去一週間が抽出されてしまう。

このCSVをPCで見てみる。
CashFlowCSV
まず、Shift_JISで保存されているのだが、このまま何も指定せずにExcelで開くと文字化けする。
Unicode(UTF-16)にするとちゃんと開ける。
WindowsがShift_JISを読めないなんて時代を感じる。
ということで、Unicodeに変換したい。

あと、カンマ区切りで、

 口座名1
 Serial,Date,Value,Balance,Description,Category,Memo
 番号1,日付1,金額1,残高1,適用1,費目1,メモ1
 番号2,日付3,金額3,残高3,適用3,費目3,メモ3
 。。。
 口座名2
 Serial,Date,Value,Balance,Description,Category,Memo
 番号2,日付2,金額2,残高2,適用2,費目2,メモ2
 番号4,日付4,金額4,残高4,適用4,費目4,メモ4
 。。。

となっている。ぼくはこれを、

 File Date Value Description Category Memo
 口座名1 日付1 金額1 適用1 費目1 メモ1
 口座名2 日付2 金額2 適用2 費目2 メモ2
 口座名1 日付3 金額3 適用3 費目3 メモ3
 口座名2 日付4 金額4 適用4 費目4 メモ4
 。。。

という風に一まとめにしたい。
(日付でソートする)
これには、次のアイコンをダブルクリックする。
CashFlowIcon
家計簿_today.batというアイコンをダブルクリックすると今日の分を、家計簿_yesterday.batをダブルクリックすると昨日の分を抽出する。

これは、寝る前に日記を着ける余裕がある場合は今日の分を、身を持ち崩して遊び呆けて日記を付けるのが翌日になってしまった場合は前日の分を集計するものだ。

家計簿_yesterday.batの中身はこうなっている。
 REM 家計簿_yesterday.bat
 kakeibo.pl 1
 del CashFlow.csv

家計簿_today.batの中身はこうなっている。
 REM 家計簿_today.bat
 kakeibo.pl 0
 del CashFlow.csv

要はkakeibo.plというPerlのスクリプトに引数で今日の場合はゼロ、昨日の場合は1を渡している。
コマンドラインで日付を指定すれば、何日前の家計簿でも付けられる。
ていうか急にPerlでスミマセン。
ちなみにスクリプトの内容はこうなっている。
#! perl
# kakeibo.pl

use strict;
use warnings;
my $in = "CashFlow.csv";
my $out = "Kakeibo.txt";
my $asset;
my $total = 0;

use Date::Calc qw(:all);

my $today = join "\/", Add_Delta_Days(Today(), (- shift));

open IN, "<:encoding(Shift_JIS)", $in or die "$in cannot be openned as IN because $!";
open OUT, ">:raw:encoding(UTF-16LE):crlf", $out or die "$out cannot be openned as OUT because $!";
select OUT;
print "\x{feff}";
print join "\t", qw(File Date Value Description Category Memo), "\n";
while () {
 if (/^$/) {
  # do nothing
 } elsif (/^Serial/) {
  # do nothing
 } elsif (not /,/) {
  chomp;
  $asset = $_;
 } else {
  chomp;
#  Serial,Date, Value, Balance,Description, Category, Memo
  my (undef, $date, $value, undef, $description, $category, $memo) = split /,/;
  next if $date !~ $today;
  next if $description and ($description =~ m|/$asset| or $description =~ m|$asset/|);
  print join "\t", $asset, $date, $value, $description, $category, $memo, "\n";
  $total += $value;
 }
}
print join "\t", '', 'Total', $total, '', '', '', '', "\n";
close OUT;

例によってアホみたいなプログラムでスミマセン。
実行してくださる酔狂な方は全角スペースをタブにしてください。
「Perlって何」という方はこの本をお読みください。



宣伝かよ!

ではポイントだけ解説する。
use Date::Calc qw(:all);

my $today = join "\/", Add_Delta_Days(Today(), (- shift));


Data::Calcは日付を計算するシンプルなモジュールであって、そのうち今日を返すTodayと、そこから指定日付前後を返すAdd_Delta_Daysを使っている。
Today()は今日の日付を(2012,11,18)のようなリストで返す。
最後の引数の- shiftは引数に数字が入っていると信じてそれをマイナスしている。

open IN, "<:encoding(Shift_JIS)", $in or die "$in cannot be openned as IN because $!";
open OUT, ">:raw:encoding(UTF-16LE):crlf", $out or die "$out cannot be openned as OUT because $!";

これは入力ファイルをShift_JISで解釈してUTF-16LEで出力している。
プログラム内部では文字コードはUTF-8になっている。
print OUT "\x{feff}";

これはBOMを出している。
もっとスマートな方法はないものだろうかね。
文字コードって何、BOMって何という方はこの本をお読みください。



だから宣伝かよ!

以下がメインのループである。注釈で説明する。
while () { # 入力ファイルを読みながら回るループ
 if (/^$/) { # 行頭即行末は空行なので
  # do nothing # 読み飛ばす(nextでも可)
 } elsif (/^Serial/) { # 先頭が「Serial」は見出しなので読み飛ばす
  # do nothing
 } elsif (not /,/) {  # 見出し以外でカンマがあれば「現金」などの見出し
  chomp;       # 改行を取り除く
  $asset = $_;    # $assetに取っておく
 } else { # ここまで生き残ったのは明細行
  chomp;
#  Serial,Date, Value, Balance,Description, Category, Memo
  my (undef, $date, $value, undef, $description, $category, $memo) = split /,/;
  next if $date !~ $today; # 日付に今日が含まれていないのは読み飛ばす
  next if $description and ($description =~ m|/$asset| or $description =~ m|$asset/|);
   # 説明に「現金/新生銀行」「新生銀行/現金」などと入っているのは資産間移動なので読み飛ばす
  print join "\t", $asset, $date, $value, $description, $category, $memo, "\n";
  $total += $value;
 }
}

こんな感じ。
雰囲気は分かるだろうか。

で、結果はkakeibo.txtというファイルになる。
CashFlowTXT
ここまでくればExcelに持っていくのはカンタンだ。

いや、もともとカンマ区切りのShift_JISファイルをExcelで読むぐらいカンタンだし、指定した日付の行のみを残す整形ぐらいExcel VBAでいくらでも出来るのかもしれないが、ぼくにはPerlがカンタンだったので上のようにしてみた。
自分のことだから、自分がやりやすいようにやりますよ。

Subscribe with livedoor Reader
Add to Google
RSS
このエントリーをはてなブックマークに追加