2011/01/22

Google ドキュメントを活用する (家計簿編2)

Google ドキュメントを活用する (家計簿編1) で、簡単な家計簿のひな形を作りましたが、今回はちょっとした機能を追加します。前回は、ラジオボタンに残高という一見意味の無さそうなタイトルとラベルを用意しましたが、機能するように改造し、前回手動で入力していた数式の挿入の自動化を試みます。

Google ドキュメントのフォームは後でスクリプトから表示内容を直接変えることが出来ないようなのですが、一つだけこれを変更する簡単な手段があります。スプレッドシートの一行目を編集を変えることです。では早速、前回作った家計簿の一行目にある残高と書かれているセルに実際の残高の結果があるセルの値を代入してみましょう。表示例ではセルB3に残高の結果があるので、セルB1に=B3と書き込みます。


セルB1に値が反映されたことを確認したら、フォームを開いてみましょう。ラジオボタンのタイトルに金額がちゃんと反映されていますね?本来なら、残高という文字をタイトルにして、その下に金額を表示させたいところですが、ちょっとイマイチですがやりたいことは出来ているので大目にみましょう(だれか他にいい方法あったら教えて下さい)。


次に数式の挿入の自動化です。折角ですから、これらのスプレッドシートの操作を自動化したいと思いませんか?後でPCなどですスプレッドシートを直接編集するのは間違う可能性があるだけでなく億劫です。そこで登場するのが、無償で利用出来る Google Apps Script。Java Script に Google のスプレッドシートを扱う API を加えたものです。Excel の VBA に似ていますので、VBA の経験か Java Script の経験があれば取っ付きやすいと思います。このスクリプトを駆使して、自動化にトライします。

まずは、スクリプトエディタを開きます。これはスプレッドシートを開いている状態でメニューのツール->スクリプト->スクリプトエディタで開くことが出来ます。

このようなエディターが開きます。

とりあえず、サンプルコードを以下に書いておきますので、コピペしてひな形の関数 myFunction() を上書きしてしまいましょう。

// 定数定義
var BALANCE_COL = 2;  // 残高の列番号B
var IN_COL      = 3;  // 収入の列番号C
var EX_COL      = 4;  // 支出の列番号D
var IN_COL_SUM  = 7;  // 収入合計の列番号G
var EX_COL_SUM  = 8;  // 支出合計の列番号H

function updateCalculation() {
  // 左端のシートを今月の家計簿と定義する
  // 左端のシートのオブジェクトを取得する
  var s_latest = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];

  // 左端のシートでデータが書かれている最大の行数を取得する
  var maxRow = s_latest.getLastRow();

  // 支出の合計を計算したいので、その範囲を A1 形式の文字列にして準備する
  // 範囲は、支出列の入力したばかりの行と前回の支出合計欄
  var sumRngOutC = s_latest.getRange(maxRow,  EX_COL    ).getA1Notation();
  var sumRngOutL = s_latest.getRange(maxRow-1,EX_COL_SUM).getA1Notation();

  // 支出の縦合計の計算式を保管したいセルに先程の A1 形式を使っ埋め込む
  // 保管先のセルは入力したばかりの行の支出合計欄
  // 最初の行の場合は前回の結果が無いので今回の値を参照するだけ
  if (maxRow == 2) {
    s_latest.getRange(maxRow, EX_COL_SUM).setFormula('='+sumRngOutC);
  } else {
    s_latest.getRange(maxRow, EX_COL_SUM).setFormula('=SUM('+sumRngOutC+'+'+sumRngOutL+')');
  }
  
  // 収入の欄も同様に処理する
  var sumRngInC = s_latest.getRange(maxRow,  IN_COL    ).getA1Notation();
  var sumRngInL = s_latest.getRange(maxRow-1,IN_COL_SUM).getA1Notation();

  if (maxRow == 2) {
    s_latest.getRange(maxRow, IN_COL_SUM).setFormula('='+sumRngInC);
  } else {
    s_latest.getRange(maxRow, IN_COL_SUM).setFormula('=SUM('+sumRngInC+'+'+sumRngInL+')');
  }

  // 残高の計算のため、その元となる最後に入力した行の収入合計、支出合計、
  // 最後の行の残高の保管セルの位置を A1 形式の文字列で準備する
  var sumOut    = s_latest.getRange(maxRow, EX_COL_SUM).getA1Notation();
  var sumIn     = s_latest.getRange(maxRow, IN_COL_SUM ).getA1Notation();
  var refResult = s_latest.getRange(maxRow, BALANCE_COL ).getA1Notation();

  // 残高の計算式を埋め込む
  s_latest.getRange(maxRow, BALANCE_COL).setFormula('='+sumIn+'-'+sumOut);

  // 残高をフォームに表示する為、残高の計算結果の参照の式をセルにオーバーライド
  s_latest.getRange(1, BALANCE_COL).setFormula('='+refResult);
}​

こんな風にコピペします。関数の先頭に列の定義を書いていますので、使う際はあなたの環境に合わせて数字を変更して下さい。また列を示す数値 1, 2, 3 ... は A, B, C 列を意味します。




続いて適当な名前でスクリプトを保存します。

ではこのスクリプトを試してみましょう。既にスプレッドシートにデータがあるならば、最後の行と残高の一行目のセルが書き変わることを確認します。スクリプトエディタのプレイボタンをクリックするか、メニューの実行をクリックして見て下さい。スクリプトが実行されます。エラーが出た場合は修正してから再度実行して下さい。

ここまでで半自動化ができましたので、次に完全自動化を目指します。完全自動化には何かのきっかけでスクリプトが自動的に実行できればよいわけです。Google Apps Script にはきっかけを指定する機能があります(Event と呼ばれています)。Event を指定するには、スクリプトエディタのトリガーから Current script's triggers... (現在のスクリプトのトリガー)を選択します。

続いて No triggers set up. Click here to add one now.(トリガーがセットされていません。ここをクリックしてトリガーを追加します)をクリックします。

次に実行する関数を選ぶリストと、Event を指定するリストが現れます。Event は From spreadsheet で、On form submit を選択します。これは、フォームからデータを送信する度に指定の関数を実行するという意味になります。

Event の指定が終了したら、Save ボタンを押して保存します。以上で用意した関数が自動実行されるお膳立てが出来ました。早速フォームを開いて、適当な値を入れて収入、支出を別々に送信して下さい。正しくデータが更新されることが確認されれば以上で終了です。これで少し使い勝手がよくなりました。今回は以上になります。

最後にスプレッドシートの編集の注意点ですが、1行目は消さないこと。2行目以降は、セルの中身ではなく行単位で削除しないと新しく入力されたデータが詰めて挿入されません。消したい行番号を選択して、右ボタンを押し行を削除を選んで実行しましょう。


次回は、月ごとにデータを保存する機能を実装しようと思います。
では。

2011/01/20

Google ドキュメントを活用する (家計簿編1)


少ない小遣いのやりくりのため、以前 iPhone に有料の家計簿ソフトを入れたことがあったのですが、どうもしっくりこなくてすぐ止めてしまいました。最近は気分も新たに、Google ドキュメントのフォームを使って家計簿を作って活用しています。案外気に入ってます。すでに世の中には同様のことを試している人もいるようですが、Google Apps Script を加えてちょっとした味付けをした家計簿を作って行きたいと思います。

今回は、実用になる家計簿のひな形を作ります。
まずは Google ドキュメントを開いて、フォームを選択します。


フォームのひな形が表示されるので、家計簿らしく好みに編集します。ここで最初のポイントですが、最初のアイテムの形式はラジオボタンにして、ラジオボタンのラベルは残高にします。タイトルも残高にしておきます。後でこれが生かされるのですが、詳細は後ほど。

次に、収入、支出のアイテムを追加します。金額の入力になるので、形式はテキストにします。更に、何に支払ったか書き込めるように、適用のアイテムをテキスト形式で用意します。

続いて費目を追加します。費目の形式はテキストでもよいのですが、リストにした方が入力が楽でしょう(特に iPhone など携帯での使用を考えた場合)。追加修正はあとでいくらでもできますし、とりあえず思いついた物をリストにします。

これで基本のフォームが完成です。とりあえず、保存します。その後に、Google ドキュメントのアイテムリストから、このフォームが記録されているファイルを開きます。そして、一行目の開いているところに収入合計、支出合計の欄をシートに直接入力します。

次にスプレッドシートの設定を開いて、

タイムゾーンを自分の住んでいる地域(日本なら東京)に合わせます。設定を初めて開いた時に東京になっていても、設定を保存のボタンを押して下さい。これはフォームを入力する度に追加される、タイムスタンプの時間表示を合わせる為に必要です。これを実行しないとGoogle本社のある地域の時間がデフォルトになるようです(私が何度か試した限り)。

ではいよいよフォームを開いてテストしてみましょう。

最終的にフォームは以下のようになりました。デバッグ用に適当に収入、支出を入力します(数字は半角で)。

再びスプレッドシートに戻ると書き込んだ値が保存されていることが確認できます。日時も合っていますよね?合っていなければタイムゾーンを再設定して再度試して下さい。

以上で、家計簿として使えるフォームがひとまず完成です。ただ、折角用意した残高、収入/支出合計の欄を活用していませんので、計算式を入れましょう。以下は一例。すべての数式を表示させています。

数値表示にすると、

期待通りの演算結果です。今回までで、十分家計簿として使えます。iPhone 使いならフォームのURLを iPhone で開いてホーム画面に追加しましょう。

次回は Google App Script で、演算の自動アップデート機能を追加します。

2011/01/10

宇宙戦艦ヤマト、懐かしのゲーム

実写版が公開されて暫く経ちいろいろな評判を聞きますが。。

それはさておき、子供の頃好きでした。初めて見たのは小学一年まで居た厚木の頃の記憶なので1977年頃までに一作目をテレビで見ています。

そんなヤマトよ永遠にの下敷きなんかも持っていた小学生高学年の頃、お兄さんのいるませた友達のうちに遊びに行くと、バンダイの if シリーズというシミュレーション・ウォーゲームの宇宙戦艦ヤマトがあり、それにはまった挙げ句、自分でも購入してしまいました。友達と中学の頃までかなり遊びました。それが先日、実家の倉庫を漁った時にまだまだ十分遊べる状態で発見です。

箱の外観

箱の中身

ルールブックの背はぼろぼろで修復した跡がありますが、中身はちゃんと読めます。駒は確認していないけど、ほとんど揃っているでしょう。ゲーム盤はシンプルなヘックス状で、宇宙空間なので地形などはありません。ただただ宇宙が広がっているだけ。

これがヤマトの駒 (BS はバトルシップ)

よく使ったので若干擦れています。戦艦等の大型艦は二つのマスを占領します。

駒に書いてある数値の意味

基本攻撃力、防御力、移動力、旋回能力の数値を元に、ヘックス上のボードで駒を移動、攻撃を敵プレイヤーと交互に繰り返します。軍の種類としては、地球防衛軍、ガミラス帝国軍、白色彗星帝国軍、暗黒星団、ボラー連邦軍と多彩。完結編前、つまり宇宙戦艦ヤマトIII までを網羅しています。シナリオもヤマト発進から激戦!スカラゲック海峡星団まであったと思います。

ゲーム判定表

ゲームは、初心者向けの基本ゲームから大人向け?の応用上級ゲームの二つのルールが存在します。応用上級ゲームは確か士気があったりと面倒くさい。もちろん僕らは基本ゲームばかり。シナリオにはとらわれず、めいめい好きな軍を担当し、どちらかが全滅するまでというようなプレイをしていました。

ところで戦艦による攻撃は主砲だけでなく、波動砲、拡散波動砲、デスラー砲などなど特殊兵器もあります。ガミラス軍においては瞬間物質輸送機まで備えています。これがくせ者で、ある友人がガミラス軍を使った画期的な戦法を編み出し、ガミラス軍は常勝軍になってしまいました。
どんな戦法かというと、デスラー砲発射直前の艦を敵の目前かつ主砲が届かない範囲に瞬間物質輸送器で転送し、デスラー砲を放つという極悪な戦法です。
戦艦等の持つ主砲は一度に艦一つしか相手できず、かつ命中率、破壊力共に低いので効率が悪いのは想像通りですが、波動砲やデスラー砲は命中率、破壊力は抜群。しかも広範囲において敵を殲滅することが可能です。ただそんな波動砲やデスラー砲には発射に暫く時間がかかり、かつ身動きが出来ないという欠点があります。それを補ってしまう目から鱗の戦法です。
さすがにこれではゲームバランスが悪すぎるので、そんなルールおかしいじゃんということになって、バンダイまでわざわざ電話を掛けて確認したところ、出来ると言われてしまって。。まぁ、そこは適当にルールを決めて楽しんでいました。

また同時期に同じくバンダイの if シリーズである戦略戦術もずいぶんやり込みました。これはボード版の大戦略といったところで、仮想国の地上戦です。航空機もあったと思ったけど、支援の意味合いしかなかったはずです。他にもいくつかボードゲーム持っていたのだけど、なかなか時間と相手がいなくていまだにいくつか倉庫に眠ってます(バルジ大作戦や Harpoon とか)。最近はこういうボードゲームやらこれまた同時期に流行っていた D&D のようなボードゲームは無いんでしょうかねぇ。

そうそう、早く iPhone 版大戦略出して下さいね>システムソフトさん