VBA

2004年10月07日 木曜日

Excel VBAは究極の「変数 = 箱」モデル

某MLに書いた内容ですが、僕が遭遇したExcelVBA的なものの発想法について。
ExcelVBAでのプログラミングでは、8月8日の日記福盛さんの日記で触れられているように、「VBAでエクセルのマクロを作る初心者がですね、変数の代わりにセルを使うんですよ」と言うような、matz日記で話題になった究極の「変数 = 箱モデル」に相当するようなコードを書く人が結構多い。
つまり、「ExcelVBAは普通のVBと違って、「手動で」かつ「視覚的に」変数領域を割り当 てられる、2次元でアドレス指定するポインタを持つBASICである。」と言い換えても良さそうですし、暴論を言えば、「一流のExcelVBA使いは1次元のポインタしかないCのポインタなど目をつぶって使えないとならない訳だ(暴論)。分からないなどと言わせぬ!」ということになる。まぁ実際に一流の(分かった気になって、有頂天になって、ナニか勘違いしている人_のことを言う)ExcelVBA使いのみなさんはこういうポインタに相当するものには名前をつけたりしなくて「全部直接セル参照」という神業をするので、構造化言語とかOOPとかにジャブ付けの頭しか持ち得ない僕なんかから見るとある意味「すげーっ!」(絶対そうなりたくない)と思ったり、頭の中がどうなっているのかかち割って見てみたいなんて思っている_3流のへっぽこVBA使い_なので、せめて妥協点として、Rangeオブジェ クトに名前をつけてアクセスしたくなっちゃいます。
1次元のRange領域を作ってやれば普通のポインタと同じような感覚(アドレス指定はCellsプロパティで2次元指定できるけど)ですかね。領域の割り当ては自分でやらないと駄目ですが… まぁ_ご利用は計画的に

たとえば「1から10までの話を求めたい」と言う例題を考える。和を求めたいRangeオブジェクトを渡すと「Rangeの和を求めるワークシート関数を文字列として返す関数」なんてものをつくってやれば、少し楽ができそうし、応用もあるのは手を付けてはいけないと思いますねえかな? まぁ実際にこつこつアルゴリズムを書くのではなく、計算などはすでにあるExcelのワークシート関数にしまえと言うことになります。(まぁ_手抜き_とも言う) 和を求めるくらいだとあまりありがたみが出ないが、同じ手間でRangeの最大・最小とか2個のRangeオブジェクトを関数に渡して最小自乗法とかさくっと出来ちゃったりするので、まぁ楽チンですね。(実際は統計関係の計算をするときはExcelのバグを知り尽くしてないと危ないですが。まぁ統計をちゃんとしたい時はExcelは使っちゃいけません。ちゃんと統計ソフトを使いましょう。)
ということでコード例。(基本的にVBでプログラムを書くときは型宣言を必須にしましょう。そうでないと全部Variantになったりしますから。あとDim文の使い方も意図しない型宣言になったりしますので注意しましょう。)

2004年09月16日 木曜日

今日は1日中Wordで文書書き

期末も近いのでたらたら報告書書き。ということで、しばらく使ってなかったWordの使い方などを再構成中。まぁWordはシステマティックに使っていたので、何年も使っていなくても人が知らない機能はサクサク出てくるんですが、メニューの配置がだいぶん変わっていてかなり手間取る。僕が使い込んでいたのはWord1.2とWord6.0までで、そのあとは文書書きはLaTeX。会社に入ってからはExcelで文書書きを強制されていたので会社ではExcel、家ではテキストしか用事がないからEmacsで編集というスタイルに落ち着いているわけだが…
数時間格闘して、とりあえず図表番号の付け方、クロスリファレンスの張り方を思い出す。あとはがんがん書くだけだ。ただある程度書いて報告書形式のスタイルを適用しようと思ったら… 全然インストールされてないじゃん! せめて基本的なスタイル集・オブジェクト編集ツール(数式エディタとかExcelの何個かのアドイン)・VBAのヘルプがインストールされていないと、まるでお仕事にならないんですけど!
まぁUnix系な人やWordを全然使いこなしていない人には、MS-WordがEmacsの次に好きな文書書きツールであるって言うと、_気でも狂ったんじゃないの?_とか言われそうだが、使い勝手の良いアウトライン・エディタって、身近にあるのはEmacsとWordしかない。まぁ僕は基本的にはアウトラインモードで項目をメモ状に書いて、前後関係を考えて、おおざっぱな文書構造を書き連ねて、詳細な段落を書くという非常にトップダウンな文章の書き方をするので、アウトラインエディタが必要なんです。

2004年08月08日 日曜日

Lightweight Language Weekend 2日目

2日目の前半は最近はやりのblogな話題。僕は基本的に興味がないのだが一応お勉強のため… 大きなblogサイト(Livedoor Blog)やはてなダイアリーなど)の方が来ていたので、個人的には「(政府や各種圧力団体などから圧力がかかりそうな)非常にまずい記事の削除要請があった場合にどのように考えるかの立ち位置」を効きたかったのだが、LLには関係ないし、契約で乗り切れる話かもしれないし、あまりにダークなんで聞けなかった。聞いておけば良かったかな? LLの最も巨大な応用先であることは認めるが、blogだけでこんなに時間を取るんだったら他の話が聞きたかった。
Lightning Talkは詳細はあまり覚えてない。(なんせ半分くらいBitKeeperと話をしていたので。) 平内さんの「木のマッチ」では、Schemeを使用した木構造のデータに対して正規表現みたいなパターンマッチをする話。さくっとXML VallidatorがかけるあたりがSchemeのマクロらしい。久井さんの「Gauche-glによる、3次元図形言語」では、Gauche-GLとストリーム(SICP Chap3の後半)を使ったアニメーションによるプレゼンでGaucheではこんなこともできるのかと言うこともあってこれまた面白かった。
高橋さんの「日本Rubyの会設立」の話は要点とをついたインパクトのあるプレゼンで、こうあるべきかと思ったり… 早川さんの「LL侍」は最初は照れが見えたが、吹っ切れたあとはかなり面白かった。(もう一段切れが欲しかったかな。)

2004年01月11日 日曜日

GNUの20年

ずいぶん前の話になるが、昨年はrmsがGNU Projectへの呼びかけ(翻訳,後の「GNU宣言」の元になる文書だと思う)から20年目の年だったそうな。昨年の9月末の話なので何をいまさらという話であるが、1月5日のNewsforgeにrms自身による「The Free Software Community After 20 Years: With great but incomplete success, what now?」という記事(和訳)が掲載されていたので、読んでみて思い出したかのように日記の記事にすることにした。
ソフトウェアにそれなりに踏み込んでつきあうようになると誰でもそうであると思うが、GNUの成果物の恩恵に預かっていることに気づかされることが多い。僕の場合は今年で11年目になると思う。最初の出会いはテキスト処理をするために使い始めたawkであるが、MS-DOSで使っていたので当然GNU版のawkであるgawk(の日本語版jgawk)だったように思う。当時書くのもめんどくさいテキストファイルのフィルタ処理がこんな簡単な言語でできるもんだと感動して使った記憶がある。(その後、awkの使いこなしでは師匠に絶対勝てねえと思ってperlを使うようになりawkを忘れ、今はテキストの処理の需要があまりないのでなんにもやってないが。)
その後、数値計算でCでプログラムを書く機会が多かった(Fortran嫌いなんで)ので、MS-DOSでMS QuickCを使っていた。Cを始めた頃はこの処理系でよかったが、当時積分計算をすることが結構多くて処理速度を稼ぐために最適化をかけたいことがよくあった。ただMS-Cのような処理系は_学生時代には絶対買えないお値段の処理系_(今も買えませんが)で、とても手を出せる状態にはなかった。またMS-DOSの制約以上の大きなメモリ空間を計算上必要としていたこと(こっちの方がより重大だった)ため、どうしてもMSのツールじゃ駄目だった。そんなときに大学のFTPサーバを覗いていて発見したのが、GNUのCコンパイラGCCのMS-DOS版であるdjgppでした。DOS-Extenderという妙な環境で動く何ともしれないコンパイラだったが、結構長い間愛用していた。
その後のLinuxの登場によりMS-DOSという妙な環境ではなく、何の制約もないUnix互換環境でGCCを使えるようになったので、ソースファイルごとLinuxの環境に移行してしまい、それ以来何かツールを作る環境はLinuxの上でやってきているし、こんな素晴らしいものはないと言うことでLinuxや*BSDの普及活動に時間があったら手間を惜しまず関わっている。まぁ最近はC/C++でプログラムを書くこともなくなったので、すっかり一利用者になってしまったけども。(お仕事上のVBAは除く。あれは選べない環境なので。)
最近の風潮ではGNUのGPLによる配付の縛りがきつすぎて、_GPL嫌い_な人を結構見かけるが、近年のオープンソースムーブメントのよりどころは_Linusによるバザール的開発手法の発明_とESRによる精緻な再定義によるものだとかんがえられる。しかし実際にはそれ以前の_rmsのFree Softwareの運動が基礎として存在_しており、GNU嫌いな人も_アンチテーゼとしての存在としてのGNU_なしには語れない訳だから、すべてに対して影響を及ぼしていると考えて良いと思う。改めて凄いことだと言わざる得ない。
さて、最初のrms自身の記事にもどるが、ちょっと過激なところはあると思うが大いに刺激を感じる記事かと思う。たしかに僕自身も特許やら企業秘密の中に生活している人なので、特許や企業秘密に依存するソフトウェアがどうしてもclosedでものでproprietaryな物にならざる得ないのは理解できるので、「Non-free software carries with it an antisocial system that prohibits cooperation and community.」は、ちょっと言いすぎだろうと思うが、先鋭的な意見を述べて戦い続けなければならない立場を考えると、確かにそう言い切ってしまわねばならないのだと思う。
さらに読んでいくと、

2003年10月27日 月曜日

.NETの呼び声

最近、VBAでのプログラムにほとほと嫌気がさしてきたのであるが、お仕事関係ではMicrosoft WindowsというかMicrosoft Officeの呪縛を逃れることは出来ない。それ故プログラム環境としてVisual Basic for Application(VBA)を使うことになるのであるが、不満は多いので使っていてなんだかだめだめだなぁと思うことを列挙してみよう。

  • _必ずExcelやWord文書の付録_みたいなものになる。文書を開くときに何となく厭な気分になる。(回避法はあるけれど。)
  • 当然コードの_履歴管理をするのが大変_。(何が楽しくてVisual Source Safeを使わねばならないのか。頼むからCVSSubversionを使わせてくださいな。)
  • 正規表現が使えない。(がーん。 かなり不便。)
  • 正規表現を差し引いてもテキスト処理がいまいち。(変形CVSなテキストを読むのがもう大変。)
  • しょっちゅう関数の名前がだぶる。(名前空間をサポートしてくださいよ。僕のボキャブラリが寂しいだけ?)
  • 使えるデータ型が_恐ろしいくらい貧弱_。(未だに基本な型と構造体と配列くらいしかなく、ハッシュやリストのような現代的な言語でサポートされているデータ型は_当然ない_。)
  • クラスは作れるが、継承は出来ない。(勘違いしている人は多いけれど継承はOOPの必須事項ではない。)
  • スレッドって何だっけ?
    という具合で、結構痛いところが満載なのである。そこまで使い込んでいるんだったらVisual Source Safeというか、OfficeのDeveloper Editionを買えばいいじゃんと言う意見もあろうが、僕はお仕事のためにわざわざOffice Developer版を買うほど酔狂な人間ではありません。 ちなみに家のPCにはOfficeをインストールしてません。家に帰って_Excelのアイコンを見るのも厭です_。ということで、会社で買ってくれないものを使う気にはならんのです。
    かといって、Windows Scriptの上で動く現代的なスクリプト言語であるActivePerlActiveRubyは、_デフォルトでインストールされない_ということもあって、プログラムを使ってもらうという前提の開発では、管理が発生するためにメインの言語として選べない。(ExcelはどのPCでもバージョンは同じであることを前提に出来るが、PerlやRubyのバージョンなどの管理は職場で誰がするの?)
    ひょっとしたらVBA自身は、Office2003でVB.netのような言語の現代化が行われるのではないかと多少期待したのだけど、VBA自身はVBA 6.3から6.4にアップデートで余り変化はないみたい。(がっかり。 まぁ無論会社ではOffice2000までしか使ったら駄目ということになっているので、Office2003は使えないのだが。)
    という状況で、なんだか良い解法は無いなぁと思っていたのだが、先日のTCP/IP勉強会で、PostgreSQL方面の高橋さんより、「そういう話なら、.NETが良いよ。」という話を聞いたので、早速試すことにした。
    よく.NETのページを眺めていると、.NET Framework SDKには、コマンドライン版のC++とC#とVBのコンパイラが付属してくるのね! てっきり、C#やVB.netで遊ぶにはVisual Studio .NETを買わねばならないのかと思っていたのであるが、僕が組むプログラムの規模ではVisual Studioには手を出さなくてよさそう。
    ダウンロード・インストールをしている間にWebをさまよえば、_フリーの統合環境は転がっている_もので、Javaの開発環境から進化して、C++やC#やPerlやRubyやXMLなどの編集が行えるJavaで書かれているEclipse(エクリプス)や、C#の開発環境に特化しつつVBの開発環境にも使えそうなC#で書かれているSharpDevelop(SharpDevelop-JP)といったオープンソースな環境が出回っているので、なんだか簡便な開発環境が整いそうである。
    今日はつらつら.NETのドキュメントとC#やVBのサンプルソースを眺めているわけだが、眺めているだけでも上記の問題は解決しそうである。例えば順に並べるとこんな感じ。
  • ソースコードは_ただのテキストファイルになる_(当然)
  • 当然コードの管理にCVSSubversionを使える。
  • Microsoft .NET Framework ではPerl5のような正規表現がサポートされている。
  • テキスト処理はようわからんが、コンソールアプリを書けるからたぶん大丈夫でしょう。(調査中)
  • 名前空間をサポートしている。(僕のボキャブラリが寂しくても_安心だ_。)
  • コレクションクラスが_充実している_。(ハッシュもリストも_当然ありますよ_。)
  • VBでも継承ができるようになった。(VB7からは継承が出来るようになりました。)
  • スレッドを考慮したプログラムも当然書ける。
    という具合。ガベージコレクションもしてくれるのですか。メモリ管理関係も結構楽になるのかしら… しばらく眺めて勉強してみることにするが、MSと仲良く付き合うには、_過度の期待はしない_ことと_仕様はどうせすぐに変わるもの_と思って、_適当に勉強すること_と言うのが重用である。どうせ勉強しても長く持たないバッドノウハウだらけになるに決まっているのだから。
    今日の日記はリンクをいっぱい付けてみた。疲れたなぁ。

2003年08月26日 火曜日

給料日

今月から給与カット無しの給料に戻ります。考え方によっては労せず給与アップになるんでしょうが、それは間違った見方をしています。 でも元に戻ってもこんなものか… がっくし… 頑張る気力はとうに吹き飛びました。やる気を出すために火を付けてくださいなと言っても、会社がなくなるくらいの勢いで火を付けてくれないと、もうだめっす。

だめだめプログラミング

他の人が作った何個かのプログラムを寄せ集めて、使いやすいように僕が1つにまとめたプログラムがあるのだが、ここ3年程度、想定したものを定型通りに使う分にはほとんど問題なく、想定していない希な使い方をすると、予想外の妙な動作をするという何とも知れない状態なので、久しぶりに中身を見てみることにした。
すると、そこには私が書いた部分も含めて_だめだめなプログラミングの典型_とも言える跡がいっぱい残っていた。VBAだととかくこういうプログラムになりがちという典型であるのだが、とりあえず僕がブラックボックスとして使っていた部分に問題があることまでデバッガで突き詰めた。しかし何度デバッガでトレースしても_実に動作が読めない_。何をしようとしているのかまるで分からないのである。自戒を込めて、かいつまんで原因をあげるとこんなところか。
一つ一つの関数・プロシジャが長い。
全体の見通しが付かないくらい長大。まぁ処理上しょうがない部分はあるし、気が付くと自分もこういう関数やプロシジャを書く場合が多いので、人のことは言えない。 ただし僕の場合は長くなっても単機能なものにまとめるようにしている。
長いプロシジャが線形に続く
メインのプロシジャから、関数A, 関数B, …を呼び出すのではなく、A関数の処理が終わったらB関数を呼び出し、B関数の処理が終わったらC関数を呼び出す。最終的に最後に呼んだ関数で処理が終わる。(実際には僕がくっつけたときに元の関数に戻るようにはしたのだが…)
GOTO文の嵐
条件分岐の際にGOTO文を乱発する。デバッガで追いかけても処理がどうなっているのか追い切れない。当然意図しない2重処理をしているのかも知れない。(少なくともソースからはどういう処理をしているか読み解けない。)
Global変数の多用とLocal変数との名前の衝突
安易にGlobal変数を用いたので、変数スコープの関係で意図しない値が入っている(入っていない)場合が多い。(今回のプログラムの場合、Loopの終点判定がかなり怪しい。)
Doc/Viewが分離されていない
Doc/Viewが分離されていないから、アルゴリズムが表示周りの雑多な処理に埋没してさらに理解不能となっている。
ブラックボックスな部分をリファクタリングしようにも、全体に影響が出そうなので手が出せなさそう。こまったものだ。最初にこの不具合に遭遇したときも同じ結論だったが、結合前のプログラムまで遡って、駄目な部分は捨てて、すべて再設計というのが望ましいと言う結果だ。構造化プログラミングの教科書に書いてありそうな事ばかりなのだが、なかなか実践できないものなのね。(実践すべく頑張らねば。)

2003年08月06日 水曜日

今日のVBAとの闘い

前回のVBAとの闘いでは、Cで言うところのsscanf()みたいな関数がないので、テキストファイルからの入力は不便じゃのうという話だった。普通のExcelのユーザ(VBAを使いこなしている人はすでに_普通の人ではないと言う意見はあるが_)は、CSVなファイルもExcelで開いてから、VBA側でセルを参照して値を取り出すのかな? 僕はそういうデータ構造を考えないプログラムを書く趣味を持ち合わせていません。
今回の闘いは、まともにCollection系のライブラリが欲しいという話。ちょっと考えてみると、文字列をKey、構造体をValueとするHashを使えれば、一発でおしまいという話だったのだが、VBAやVBっていまいちCollection系のデータ構造がまるでないので、いかんせんいろいろと貧弱すぎだなぁと思うのよね。結局配列で非常に安直な実装にしたのだが、どうにかならんもんかね。VBプログラマはデータ構造なんて考えてプログラムをしないのかねぇ。で、あらかたプログラムを書いた後に、

2003年08月05日 火曜日

プログラムを書く時って…

自分だけで使うプログラムを書く時は適当に書き始めるのだが、僕の場合、お仕事でプログラムを書く時は最初の1行目を書き始めるまでの時間が異様に長い。今後の保守性だとか、環境の持続性だとかに縛られるので。MSさんがもうちょっと後先考えてくれれば良いんですけれど。ころころ変わりすぎて、MSのツールを投げ捨てたいんだけど…
VBAはこれまでさんざん書いてきたけれど、個人的にはかゆいところに手が届かないので悩ましいのであるが、さらにExcelやWordの文書の中に入っちゃうので、ソースの履歴管理に問題があるので、あまり使いたくないのです。ただIDEはMS-Cのころからこんな感じなので、それなりに使い慣れているせいか、悩ましい存在だったりする。(オブジェクトのメソッドやらプロパティを打ち込むのもめんどくさいので、あれだけ補完入力が効いてくれると便利なので。)
ということで、今日はこれから書くプログラムのデータ構造を決めるのに結構な時間を要し、とりあえず基礎の部分を作って1日おしまい。スロースタータなんですねぇ。
ちなみにMSのツールを捨てられないのは、よけいなインストール作業を繰り返すことになるからなのね。少なくともExcelはどのPCにもインストールされているので、これになかなか勝てないのです。

2003年07月16日 水曜日

GNU R

まじめな統計計算を滅多にしないので、Excelで十分かと思っていたが、ずいぶん前から直らないバグが結構あり、場合によって_Fatal_なので、Excelでの統計計算にあきれていた。かといって、proprietaryな統計計算パッケージ(たとえばSとかS Plusとか)は非常に高価で入手不可能であるため、Excelを我慢してうまく使い続けてきたが、GNUのSとも言うべきRの日本語化が結構な勢いで進んできたので、これはしたりと思ったわけである。Rって何?と言う人もいると思うので、以下にR Projectのページに載っている説明文を載っけてみる。

2002年10月24日 木曜日

言語の勉強のためにインタプリタを書く?

うーむ、最近Raccの勉強中。Rubyを勉強するためにRaccでインタプリタを書いてみようと言うことで、いろいろ遊んでいる。今のところはRaccの256本に掲載されているBASICもどきな言語を学びつつ、もっと別の文法を持つインタプリタを書いて遊んでみたいなぁ。(BNF記法実に深い…)
いずれにしてもそろそろ正規表現をまともに取り組まないとならないなぁ。

VBAでプログラム書き

ここ3年ほど保守している仕事に使っているExcel VBAのマクロなのであるが、当初の開発目標をおおむねクリアできたような気がする。やはり自分が使うツールの改良は楽しいし、自分が作ってきた種々のツールのコードをライブラリの共通化による統合が行えるとなかなか快絶な喜びだ。唯一悲しいのはVBAであると言うところか。VBAがやっぱり好きになれないと言うところとCVSでコードの管理とかできないじゃんと言うところが悲しい。
VBA周りで考えていきたいのは、_VBAからActiveScriptRubyのオブジェクトとやりとりできないものか_と言うことと、上記のマクロのclassライブラリ化かなぁ。Rubyを使えればテキストデータのパースをRubyにやらせて、Excel出力をVBAなんて事ができそうだし、後者はコードをOOP風に整理しておきたいんだよなぁと思うのだ。どうなんだろう。気が向いたら調べていこう。