WizHook考... VBA小ネタ:20190430

GWアドベントカレンダーの4日目ネタです。今日もブログからお伝えします。 今日の仕事はAccessCRM+請求系処理のツールを作っている案件のバグ取り、の予定でしたが機能の大幅変更になってしまいてんてこ舞いでした。 そんな状態なので、後日きちんとまとめますが、今日紹介するのはそのツールでも使用をしている、Microsoft Accessの2000から使うことができる非公開クラスのWizhookについて。

Wizhookの説明...は割愛しますね。

ちょっと長くなるので。

なんのために使うのか(使っているのか)

Accessのテーブル情報のデータエクスポートをするときに、任意の場所でSaveAsをしたい、という要望がありました。本来であればFileDialogを使いたいところです。

FileDialogの問題点1

しかし、FileDialogオブジェクトのヘルプには、

定数 msoFileDialogOpen および定数 msoFileDialogSaveAs は Access ではサポートされていません。

とあります*1。良心的に考えれば、そもそもAccessで管理しているデータをわざわざExcelCSVでエクスポートするなどというセキュリティリスクとなる機能を今後サポートすることはない、という意味なのでしょうが、ユーザーにとっては*2必要な機能ではあるので、サポートされないのは困ります。

FileDialogの問題点2

ライブラリの参照設定が必要になるんです。これ、正直言って問題なんです。Microsoft としてはOfficeの外部ライブラリとして多数のライブラリを提供しているし、使いたければ「参照設定」から追加してね、と言うスタンスです。私も今までもそうしてきたんですが、今回の案件では、2つの懸念材料がありました。

  • クライアント直案件ではなく、エンドユーザーまでの間に何社か入ってるっぽい。

  • エンドユーザーのPC熟練度が相当低く、その間の業者さんたちのフォローも期待しにくい。

VBAの参照設定」なんてよくある対応、と言いたいところですが、これを忘れて、例えば端末を購入したとか、オフィスの最新版インストールとか、それっぽっちの理由で「参照設定」のやり直しをしなければならないし、し忘れると「重篤なエラー」が発生するわけです。しかも伝言ゲームで。

だからできるだけ使いたくなかったのです。

回避方法1

「参照設定」の設定をエンドユーザーにさせることなく完結させる方法として考えられるのは、ADOの呼び出しなどで有効な、都度オブジェクトを呼び出すと言うやり方。

...
' なんかのSubなりFunctionなりの中でやっていると想定してね
Dim cn as Object   ' コネクション

set cn = CreateObject("ADODB.Connection)
cn.Open "hogehoge"
...

回避方法2

FileDialogは回避方法1のようなオブジェクトでの呼び出しがうまく使えません*3。ここでWizhookを使います。

...
' なんかのSubなりFunctionなりの中でやっていると想定してね
WizHook.key = 51488399
fileName = WizHook.GetFileName(0,"","","", strFilePath, "", strFilter, 0,0,0, False)
Docmd.TransferSpreadsheet acExport acSpreadsheetTypeExcel12Xml, tableName, fileName, True
WizHook.key = 0
...

「WizHook.GetFileName」メソッドの一番最後のフラグ(上の例ではFalseになっています)が、Falseの場合はSaveAs、Trueの場合はOpenFileという挙動になります。と言ってもまだSaveAsしか使ってないのですが。

今日はコレくらいで勘弁してください

我が家は祝日でもなんでもない、普通の火曜日ですので、そろそろ就寝の時間が近づいています。改元年越しですって? 睡眠中に改元をまたぐ予定ですがなにか。

明日のご予定は?

もう少しAccessをいじらないと。今日やり残したバグ取りが終わったら事務仕事が待っています。見積作成とかメール送信とか。  

*1:つまり、サポートされてはいないけど使うことができる、ということなのですが...。

*2:日本人のユーザーは特にそうですよね。なぜか最後はExcelに落ち着きたがる。

*3:ワタシだけなのかも、とは思っていますが