title1
navigation bar3



[ 1 | 2 | 3 |4 |5 | 6 | 7 | 8 | 9 | 10 | 11-p1 | 11-p2 | 11-p3 | 12 ] [日経マック連載Index ]


連載[11-3] Visual Basicと対決〜システム構造編


《 何が困るのか、Access Basicで具体的に話そう 》
先生、ウンチクはこれくらいにして、実例を見せていただけませんか。開発環境がどうのこうので困る、なんて話は、実際にスクリプトを見ながらじゃないとピンときません。
先生
じゃぁデータベースのデータを集計してExcelに転送するなんてのはどうだい。
Windowsのデータベースは定番のAccess 2.0、マックではファイルメーカーProを使ってみよう。図5のようにデータベースには営業マンの売上データが入っている。営業マン別に合計を計算して、結果をExcelのセルに入れてみよう。Accessはリレーショナル型でファイルメーカーProはカード型なんて違いはあるけど、概要はつかめるだろう。
さて、まずWindowsから行こうか。
図5 データベースを集計してExcelに転送Windows上のAccessとExcel
Windows上のAccessとExcel
マック上のファイルメーカーProとExcel
マック上のファイルメーカーProとExcel
ExcelのVBAでAccessを自動操作してデータを集計させて結果を取りこめばいいわけですね。
先生
いや、先に述べたように、AccessはOLEオートメーションのクライアントにはなれるがサーバーになれない。
ってことは?
先生
VBAを使うってことは,Excelがクライアントになって、サーバーのAccessを操作するってことだろう。
これはできないんだ。従って、AccessのAccess BasicでExcelを操作するスクリプトを書くことになる(図6)。
図6 Access Basic
図6Access Basic
う〜ん、ややこしいですね。
先生
さっき私がこれでは困るって言ったわけを実感できたかい。Windowsでは、まだAppleScriptのようにアプリケーションから完全に独立した共通のスクリプト言語が出来上がってはいないって。
あぁ、そうでした。
先生
AppleScriptではスクリプト編集プログラムを使えばいい。ここからExcelやファイルメーカーProに対して、
「tell〜」という構文で呼びかける形だよね。両者のスクリプトは図7のようになる。
図7 データベースを集計して結果をExcelに貼り込むスクリプト
図7データベースを集計して結果をExcelに貼り込むスクリプト

*1 データベースの並べ替え

AppleScriptでは、ファイルメーカーProのデータ自体をソートする。
一方、Access Basicは、すでに日付によってソートするよう設定されたテーブルを変数(MyTb)に取ってきて、それに別のインデックスを与えてオブジェクトとして持つ。

*2 アプリケーションの起動

AppleScriptではアプリケーションの名前を指定してrunさせることもできるし、何かtellすると自動的に起動される。Access Basicでは、アプリケーションの実行ファイルのパスを指定して実行する。
そのアプリケーションがすでに起動していている時は、別にもう1つ起動させてしまう。

*3 代入文

Access Basicではまさに、Basicの構文である(A=Bと書くと、BがAに代入される)。AppleScriptでは、setを使う書き方と、copyを使う書き方がある。

*4 繰り返し

それぞれいくつかの形式の繰り返し構文がある。
Access Basicで使用している構文は、MoveNextでカレント・レコードを移動して最後(EOF)まで繰り返すという形。この方法はファイルメーカーProではできない。

*5 フィールドの型

ファイルメーカーProは文字としてしかデータを取り出せない。金額がカンマ桁区切りで表示されているので、合計計算のために生の数字に直すという面倒が生じる。

*6 データベースのフィールドへのアクセス

Access Basicのテーブル・オブジェクトにはカレント・レコードという考え方がある。「MyTb![営業担当者]」と指定して、「テーブルのカレント・レコードの営業担当者」という参照方法ができる。

*7 操作対象

AppleScriptはその性質上、スクリプトの中にいくつもの「tell〜end tell」構文があり、同じアプリケーションに対するtell構文が複数散在することも多い。その結果、どのアプリケーションに仕事をさせているのか分かりやすい。AccessBasicではアプリケーションではなく、OLEオブジェクトを操作対象とするので、どのアプリケーションを操作しているかという流れが初心者には把握しにくい。

*8 整数の扱い

AppleScriptではExcelに数値を渡す際になぜか32ビット整数が16ビット整数に強制変換されてしまう。仕方がないからStringへの変換で問題を回避。AccessBasicでは冒頭での適切な型を宣言(Dim)してあれば、こうした問題は起きない。

単に集計してセルにデータを入れるだけなのに、えらく面倒 ですね。
先生
本当はもっとはるかに簡単な方法もあるんだが、AppleScriptとOLEオートメーションの違いが分かるように、わざと面倒な方法を取ったんだ。データベースのレコードを1つひとつ調べて、担当者ごとに売上をExcelのセルに加算していく。
まぁ、スクリプトの内容を理解することより、構文やオブジェクトの扱い方などVBAの雰囲気を味わってくれたまえ。
TOP

《 自動操作の秘密は「CreateObject」という呪文 》
Access Basicでは、Excelって名前が出てくるのは最初にそれを起動する時と、

  Set Sheet = CreateObject("Excel.Sheet")

ってところだけですね。AppleScriptでは

  tell application "Microsort Excel"
   (Excelに対する命令)
  end tel


ってブロックが随所に出てきますけど。

先生
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にあり、ですね。

TOP

《 アクセスできるのはVBAオブジェクトではない 》
先生
そうだ。CreateObjectによってOLEサーバー(この場合はExcel)がほかのアプリケーションから利用できるようOLEオートメーション・システムに公開しているオブジェクトに、間接的にアクセスできる。これが、OLEオートメーションを利用するということなんだよ。
ExcelのSheetオブジェクトに対して行っている操作は、VBAなんでしょうか。
先生
いや、ExcelのVBAのコマンドをそのまま利用しているのでもないし、Accessの中にExcelを利用するための関数が用意されているわけでもないんだ。
何だか、わけが分かんないですよ。
先生
まぁ、そう言わないで聞きなさい。実は私も説明のしようがなくて困ってるんだから。OLEオートメーション・システムに公開されたExcelのオブジェクトはVBAのオブジェクトそのものではなく、何と言うか中間的なものだ。そのメソッドや属性は、ほかのアプリケーションから利用する場合には非常に分かりにくい。現状ではこれに関する参考資料がほとんどないんだ。具体的に言えば、Access BasicのヘルプにもExcelのVBAのヘルプにも、OLEオートメーション・システムに公開されているExcelのオブジェクトの一覧や、メソッド、プロパティーに関する説明は皆無に近い。分かるかな? だからAppleScriptが初めて登場した頃のように、ほとんど勘で書くしかない。
ひどいですよ先生、それは。
先生
それはマイクロソフトの天才どもに言ってやってくれ。
TOP

《 遅い、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を勝たせてくださいよ。
先生
勝ち負けとかの問題じゃないと思うけどなぁ。

TOP

AppleScript救急隊事務局(ASQs) info-asqs@fsight.co.jp

主催 株式会社フォーサイト   後援 アップルコンピュータ株式会社

(c)1996-2010 The ForeSight Inc. All rights reserved.Appleは、米国アップルコンピュータ社の登録商標です。
AppleScriptは、米国アップルコンピュータ社の商標です。
その他記載の会社名・製品名・ソフトウェア名は一般にその会社の登録商標または商標です。