連載[11-3] Visual Basicと対決〜システム構造編
|
《 何が困るのか、Access
Basicで具体的に話そう 》
|
|||||||||||||||||
|
」
|
先生、ウンチクはこれくらいにして、実例を見せていただけませんか。開発環境がどうのこうので困る、なんて話は、実際にスクリプトを見ながらじゃないとピンときません。 | ||||||||||||||||
|
先生
|
じゃぁデータベースのデータを集計してExcelに転送するなんてのはどうだい。 Windowsのデータベースは定番のAccess 2.0、マックではファイルメーカーProを使ってみよう。図5のようにデータベースには営業マンの売上データが入っている。営業マン別に合計を計算して、結果をExcelのセルに入れてみよう。Accessはリレーショナル型でファイルメーカーProはカード型なんて違いはあるけど、概要はつかめるだろう。 さて、まずWindowsから行こうか。 |
||||||||||||||||
|
図5 データベースを集計してExcelに転送Windows上のAccessとExcel
![]() |
|||||||||||||||||
|
マック上のファイルメーカーProとExcel
|
|||||||||||||||||
|
」
|
ExcelのVBAでAccessを自動操作してデータを集計させて結果を取りこめばいいわけですね。 | ||||||||||||||||
|
先生
|
いや、先に述べたように、AccessはOLEオートメーションのクライアントにはなれるがサーバーになれない。 | ||||||||||||||||
|
」
|
ってことは? | ||||||||||||||||
|
先生
|
VBAを使うってことは,Excelがクライアントになって、サーバーのAccessを操作するってことだろう。 これはできないんだ。従って、AccessのAccess BasicでExcelを操作するスクリプトを書くことになる(図6)。 |
||||||||||||||||
|
図6 Access Basic
![]() |
|||||||||||||||||
|
」
|
う〜ん、ややこしいですね。 | ||||||||||||||||
|
先生
|
さっき私がこれでは困るって言ったわけを実感できたかい。Windowsでは、まだAppleScriptのようにアプリケーションから完全に独立した共通のスクリプト言語が出来上がってはいないって。 | ||||||||||||||||
|
」
|
あぁ、そうでした。 | ||||||||||||||||
|
先生
|
AppleScriptではスクリプト編集プログラムを使えばいい。ここからExcelやファイルメーカーProに対して、 「tell〜」という構文で呼びかける形だよね。両者のスクリプトは図7のようになる。 |
||||||||||||||||
|
図7 データベースを集計して結果をExcelに貼り込むスクリプト
![]()
|
|||||||||||||||||
|
」
|
単に集計してセルにデータを入れるだけなのに、えらく面倒 ですね。 | ||||||||||||||||
|
先生
|
本当はもっとはるかに簡単な方法もあるんだが、AppleScriptとOLEオートメーションの違いが分かるように、わざと面倒な方法を取ったんだ。データベースのレコードを1つひとつ調べて、担当者ごとに売上をExcelのセルに加算していく。 まぁ、スクリプトの内容を理解することより、構文やオブジェクトの扱い方などVBAの雰囲気を味わってくれたまえ。 |
||||||||||||||||
|
《 自動操作の秘密は「CreateObject」という呪文
》
|
|
|
」
|
Access Basicでは、Excelって名前が出てくるのは最初にそれを起動する時と、
Set Sheet = CreateObject("Excel.Sheet") ってところだけですね。AppleScriptでは tell application "Microsort Excel" |
|
先生
|
Access Basicでは,オブジェクトに対してメソッド(命令)や属性を記述する形を取るんだ。Access BasicやExcelのVBAでは、スクリプトで操作する対象をすべて「オブジェクト」と呼んでいる。Excelのシートやブック、Accessのテーブル、ボタンなどはすべてオブジェクトだ。命令はすべてこれらオブジェクトに対して行われることになる。 |
|
」
|
でも、どこでExcelに命令しているのか、すごく分かりにくいんですけど。 |
|
先生
|
それはAccess自身のオブジェクトもExcelのオブジェクトも透過的に扱っているからだ。
Set Sheet = CreateObject("Excel.Sheet") でExcelのSheetオブジェクトが変数「Sheet」に入る。その後は、 Sheet.×× って書くだけで、ExcelのSheetオブジェクトの操作ができるんだ。
|
|
」
|
前回、
CreateObject("Word.Basic") って命令がありましたが、これはWordのオブジェクトを得ていたわけですね。 |
|
先生
|
そうそう。この場合はSheetじゃなくてBasicってオブジェクトだけどね。 |
|
」
|
う〜ん、でも分かりにくい。 |
|
先生
|
アプリケーションの名前を指定するAppleScriptの方が確かに初心者には分かりやすいかも知れないね。でもオブジェクト指向プログラミングに慣れた開発者の中には、あらゆるオブジェクトを透過的に扱える方がプログラムを書きやすいって人もいるはずだ。先にOLEオートメーションはプロっぽいって言ったのはそういうこともあるね。 |
|
」
|
まぁ、とにかく、アプリケーション自動化の呪文はCreateObjectにあり、ですね。 |
|
《 アクセスできるのはVBAオブジェクトではない
》
|
|
|
先生
|
そうだ。CreateObjectによってOLEサーバー(この場合はExcel)がほかのアプリケーションから利用できるようOLEオートメーション・システムに公開しているオブジェクトに、間接的にアクセスできる。これが、OLEオートメーションを利用するということなんだよ。 |
|
」
|
ExcelのSheetオブジェクトに対して行っている操作は、VBAなんでしょうか。 |
|
先生
|
いや、ExcelのVBAのコマンドをそのまま利用しているのでもないし、Accessの中にExcelを利用するための関数が用意されているわけでもないんだ。 |
|
」
|
何だか、わけが分かんないですよ。 |
|
先生
|
まぁ、そう言わないで聞きなさい。実は私も説明のしようがなくて困ってるんだから。OLEオートメーション・システムに公開されたExcelのオブジェクトはVBAのオブジェクトそのものではなく、何と言うか中間的なものだ。そのメソッドや属性は、ほかのアプリケーションから利用する場合には非常に分かりにくい。現状ではこれに関する参考資料がほとんどないんだ。具体的に言えば、Access BasicのヘルプにもExcelのVBAのヘルプにも、OLEオートメーション・システムに公開されているExcelのオブジェクトの一覧や、メソッド、プロパティーに関する説明は皆無に近い。分かるかな? だからAppleScriptが初めて登場した頃のように、ほとんど勘で書くしかない。 |
|
」
|
ひどいですよ先生、それは。 |
|
先生
|
それはマイクロソフトの天才どもに言ってやってくれ。 |
|
《 遅い、AppleScriptが弱点を暴露
》
|
|
|
」
|
実際に実行すると、AppleScriptは随分遅いですね。 |
|
先生
|
いくつも理由があるんだ。まず余計な処理がいろいろあることだな。スクリプト編集プログラムでExcelのセルに数値を入れる時、なぜか数値が3万2767までしか表せない16ビット整数型に強制変換されてしまうんだ。仕方がないから整数値をわざわざ文字列に変換してからExcelに渡している。Access BasicやVBAには16ビット整数のInteger型のほかに32ビット整数のLong型があって、きちんと宣言(Dim)しておけばこうしたトラブルは起きないんだがね。 |
|
」
|
要するに、意外なところでトラブルに会い、それを迂回するために余計な手間がかかっていると。 |
|
先生
|
まぁ、とにかくこれも遅くなる理由の一つだ。それからこれはデータベース側の問題だが、Accessの場合は「通貨型」という設定でデータを持つことが可能で、それをそのまま数値に変換して計算し、Excelに貼り付ることができる。だがファイルメーカーは通貨としてデータを持つと、計算する時に「\」や「,」が読み込まれてエラーになってしまう。そこで、AppleScript側ではカンマ区切りを生の数値に戻す余計な作業をしている。 |
|
」
|
意外とAppleScriptも脆さがあるんですね。 |
|
先生
|
そりゃそうさ、人間の考えることなんて、所詮、思惑通りには行かないものなのさ。 |
|
」
|
それだけは理解できます、先生。 |
|
先生
|
話を続けると、Accessは、データを保持した「テーブル」とそれを表示している「フォーム」、そしてテーブルのデータにアクセスするために作成した「MyTb」などのオブジェクトはそれぞれ別なものだ。それらがすべて一体となったファイルメーカーとは,操作の記述や計算速度が変わってくるのは仕方がない。 |
|
」
|
ほかにも遅い原因はあるんですか。 |
|
先生
|
もちろん。例えば、ファイルメーカーProで計算を行う時は、テーブルに実際に保存されているデータを直接ソートして、そこからいちいち調べて持ってくる。一方のAccess
Basicでは、テーブルの実体とは別の,Access Basic用の仮想的なテーブルとでも言おうかな,そんなオブジェクトに対して操作を行う。仮想的なテーブル・オブジェクトは実体とは別のインデックスを与えてソートすることもできる。
MyTb.Index = "営業担当者" ってのがそうだ。 |
|
」
|
何だかチンプンカンプンです。 |
|
先生
|
テーブルのエイリアスみたいなもんが作れるってことさ。これはAccess Basicでテーブルを処理する目的の専用オブジェクトだから、実体を操作するファイルメーカーProより高速に実行されるんだ。 |
|
」
|
するとAppleScriptは場合によったら非常に処理速度の遅いツールだってことですか? |
|
先生
|
いや、そんなことはない。別の書き方もあるんだが、そうするとVBAとのスクリプティングの比較が分かりにくくなるんだな。今回はAppleScriptに我慢してもらって、書き方をVBAに合わせたので処理が遅くなった、ってことだな。 |
|
」
|
分かりました。でも先生、次回はかなり具体的なプロジェクトでのお話だっていうことでしたから、今度はAppleScriptを勝たせてくださいよ。 |
|
先生
|
勝ち負けとかの問題じゃないと思うけどなぁ。 |
AppleScript救急隊事務局(ASQs) info-asqs@fsight.co.jp