RubyでExcelのデータを読み込む
プログラミングの仕事をしていると「仕様書(内部向け)」「コード」「ドキュメント(外部向け)」をメンテナンスしなければならない場合がある。そして、3つを別々に管理するのが面倒なのは言うまでもない。
私も業務でそんな場面に出くわした。今回の仕事では外部向けのドキュメントをある程度きちんと書く必要が出てきたため、実装とドキュメントに差異が出るのは大変まずい、という事情もある。どうしたもんか…とtwitterでボヤいていたら、TLから’win32ole‘の推薦をいただいた。
推薦いただい記事は、「るびま」の最新号に掲載されている「VBA より便利で手軽 Excel 操作スクリプト言語「Ruby」へのお誘い (前編)」という記事。なんのことはない著者ご本人から推薦いただいた、というわけ。twitterは「すごい人が身近にいる」ということを再認識した次第である。
で、さっそく使ってみたところ、これが予想以上に便利。Excelにいろいろ書いたものをマスタ(兼内部向け仕様書)にしておいて、必要に応じて外部向けのドキュメント / テスト仕様書 / 実際のコードまでを出力することができる。メンテナンスの必要があるところを減らすという点で、ちゃんと仕込めば素晴らしいギミックになりそうな予感がする。
準備
環境
あらかじめWindows上でRubyが動くようにしておくこと。今回使った環境は以下の通り。
- Windows XP Pro SP3
- ruby 1.8.7 (2008-08-11 patchlevel 72) [i386-cygwin]
- Microsft Excel 2007 SP2
サンプル
アーカイブを展開してカレントを移動する。実行コマンドは以下のようになる。
% ruby process_xls.rb {action_name} {method_name}
action_nameがブックのファイル名、method_nameがシート名に対応する。詳細は後述。
内容
ブックの読み込み
ソース
process_xls.rb
→コマンドライン引数を受け取る
lib/xls_processor.rb
→ファイルの存在チェックをしてブックを読み込む
処理概要
コマンドラインの第一引数に[action_name]としてブック名を渡すと…
./excel/#{@action_name}.xlsx
を読み込む。
ワークシートを指定
ソース
lib/xls_processor.rb
→シート名でdispatch
処理概要
コマンドラインの第二引数として渡された[method_name]と同じシートをインスタンス変数に控え、渡されたメソッド名をそのまま呼び出して処理を行う。
ブック / シートに応じた処理
ソース
lib/xls_processor.rb
→アクション名で実際の処理をするライブラリを読み込む
lib/#{@action_name}.rb
→実際にブック / シートからデータを読み取り固有の処理を行う
処理概要
@@files に、method_nameをキーにしたhashを持つ。中身はarray。各要素は:srcと:dstのペアをキーにしたhash。日本語で書くと分かりにくいが、実際に使用しているXlsProcessor#saveを見ればやってることは把握できるのではないだろうか。method_nameごとに:srcをERBのソースとして読み込んで、:dstとして書きだしている。
@method_nameでinvokeしたメソッドの中身が実際のexcelシートからデータを読み出す処理部分。VBAとやってることはあまり変わらない。Excelの空きセルにマクロを挿入するとVBAのコードエディタが起動するので、そこで「Rows」などオブジェクト名を打ち込むとオブジェクトごとのメソッドやプロパティの候補が表示される。入力途中での補完はCtrl + Space。候補を確定した直後にF1を押すとヘルプが開く。このあたりの機能を使うと、どんなことができるかを探れる。
ERB
あんまりちゃんと使ったことがなかったのでググってみたら、やっぱり「るびま」の記事が一番ちゃんとしたドキュメントだった。すごいなるびま。
ソース
erb/*.erb
→excelから取得したデータを展開するテンプレート
lib/xls_processor.rb
→saveメソッドでerbを読み込み、目標ファイルに書き出す
で、処理完了。result/以下に目的のファイルができている。excelをベースにPHPのコード / htmlファイルが生成される、というわけだ。
まとめ
- Excelをマスタにして一元管理し、ドキュメント / コードの自動生成に挑戦してみる。
- win32oleを使うことで、VBAよりは慣れてるし楽しいRubyで書くことがでいる。
- テンプレートエンジンとしてERBを使うことで簡単に意図したフォーマットの結果を得ることができる。
サンプルコードは手元の環境で動作させているが、不具合などあればご指摘いただけると幸いである。
Links
http://homepage1.nifty.com/markey/ruby/win32ole/index.html
●Twitter / しは゛: それRubyでできるよ。最新号のるびま参照。RT @ …
https://twitter.com/bash0C7/status/4543500679
●Rubyist Magazine – VBA より便利で手軽 Excel 操作スクリプト言語「Ruby」へのお誘い (前編)
http://jp.rubyist.net/magazine/?0027-ExcellentRuby
http://jp.rubyist.net/magazine/