概要

今回は、Access 2000 以降で [ファイルを開く] ダイアログを表示する方法です。

.....あっ、今アナタ、こう思いましたね?

[ファイルを開く] ダイアログ? FAQ だね、FAQ。

Access 2000 には [ファイルを開く] ダイアログを表示する機能は無いんだから。

アレでしょ、Developer 版に付属しているコモンダイアログ コントロールを使うか、Excel 経由で GetOpenFileName メソッドを呼び出すか、さもなくば Windows API を使うっていう。

あ、それとも Access 2002 から追加された新機能の FileDialog メソッドを使う方法かな?

でもそれだと Access 2000 では使えないから、やっぱり最初の 3 つの方法でしょ。

そんなの他のサイトにもたくさん載ってるし、毎週どこかの掲示板に上がってくる定番ネタじゃん。

さては YU-TANG のヤツ、サイト立ち上げ時に「極力他サイトとバッティングしないように配慮するつもりです」なーんて言っといて、さすがに 2 年もやってるとネタ枯れかぁ?

ハーッ、ハッハッハッ!

ーーーいッ!!!

まったくルノアールのココアみたいに甘いやっちゃ、ペッペッ!

# いま「古っ」と言ったアナタも古いですね。

「Access 2000 には [ファイルを開く] ダイアログを表示する機能は無い」という常識迷信にすぎません。

Access 2000 に [ファイルを開く] ダイアログを表示する機能は有るのです。

詳細

論より証拠、下記を標準モジュールに貼り付けてみてください。

' GetFileName をテストします。
Function TestGetFileName()
    Const ENABLE_WIZHOOK = 51488399
    Const DISABLE_WIZHOOK = 0
    Dim strFile   As String
    Dim intResult As Integer
    WizHook.Key = ENABLE_WIZHOOK    ' WizHook 有効化
    intResult = WizHook.GetFileName( _
                    0, "", "", "", strFile, "", _
                    "すべてのファイル (*.*)|*.*", _
                    0, 0, 0,True _
                    )
    WizHook.Key = DISABLE_WIZHOOK    ' WizHook 無効化
    TestGetFileName = strFile
End Function

続いてイミディエイトウィンドウに次のように入力して【Enter】してみましょう。

?TestGetFileName

次のようなダイアログが表示されるはずです。

GetOpenFileName Dialog

Test.txt を選んで <開く> を押すと、イミディエイトウィンドウには次のように表示されます。

C:\Documents and Settings\YU-TANG\My Documents\Test.txt

上の画面は Windows XP で実行した場合(ただしクラシックモード^^;)なので、他バージョンの OS ではダイアログのスタイルが異なるかもしれませんが、ともかく Access 2000 の組み込み機能の中にファイル選択ダイアログの呼び出し機能が存在することは、これでお分かりいただけるでしょう。

コード中の WizHook というのはウィザード/ビルダ支援用の隠しオブジェクトで、この WizHook のメソッドの 1 つとして GetFileName メソッドが存在しているのです。

GetFileName メソッドの構文は次の通りです。

Function GetFileName(hwndOwner As Long, AppName As String, DlgTitle As String, OpenTitle As String, File As String, InitialDir As String, Filter As String, FilterIndex As Long, View As Long, flags As Long, fOpen As Boolean) As Long

引数については下の表を参照してください。

GetFileName メソッドの引数
引数データ型説明
hwndOwnerLong ダイアログのオーナーとなるオブジェクトのハンドルを渡します。
AppNameString 実行アプリケーションの名前を指定します。
DlgTitleString ダイアログのウィンドウタイトルに表示する文字列を指定します。省略時は既定のタイトル(「ファイルを開く」あるいは「名前を付けて保存」)が表示されます。
OpenTitleString 実行用コマンドボタンの標題に当たる文字列を指定します。省略時は既定の標題(「開く」あるいは「保存」)が表示されます。
FileString 入出力用引数です。パスを渡すと、ダイアログの [ファイル名] 欄にそのファイル名がセットされます。またユーザーが選択したファイルのフルパスが格納されます。
InitialDirString ダイアログの初期表示ディレクトリを指定します。省略時はカレントディレクトリが表示されます。
FilterString [ファイルの種類] リストボックスに設定する一覧を指定します。形式は「表示用文字列 1|拡張子 1|表示用文字列 2|拡張子 2|...」の繰り返しになります。区切り記号「|」は Chr$(0) あるいは定数 vbNullChar でも構いませんが、VB では「|」を使った方が簡単でしょう。
なお表示用文字列の中の拡張子を括る括弧を誤って全角文字で指定すると、実行されません。初心者はよくハマるので、注意してください。
FilterIndexLong 初期表示時に [ファイルの種類] リストボックスの何行目を既定で選択するかをインデックス番号で指定します。先頭行は 0 から開始します。
ViewLong ファイル一覧の表示スタイルを指定します。
0=詳細、1=プレビュー、2=プロパティ、3=一覧、4=縮小表示、5=アイコン、8=並べて表示、です。ただし 4 以降は Windows XP SP3 + Access 2003 SP3 で確認しています。OS 依存の可能性があるため、どの環境でも有効かどうかは不明です。
なお View 引数は単独では機能せず、flags 引数に &H40 を指定して初めて有効になります。
flagsLong ダイアログの動作を指定するオプション値をビットフラグで指定します。これは Win32 API で使用される OPENFILENAME 構造体の Flags と微妙に異なります。現時点で判明しているオプションについては、後述します。
fOpenBoolean ダイアログの種別を指定します。True を設定すると [ファイルを開く] になり、False を指定すると [名前を付けて保存] になります。

戻り値は、ファイルが正常に選択された場合は 0 に、ユーザーによってキャンセルされたりエラーが発生した場合は 0 以外になります。

現状のままでは、引数を省略できません。

不要な引数を省略できるように、ラッピングすることにしましょう。

以下のコードを標準モジュールに貼り付けてください。

仕様を少し変更し、選択されたパスを返すことにしています。

キャンセルされた場合は、実際には GetFileName の戻り値が 0 以外(Windows XP 上での確認では -302)になることをもって判定するのが正規の方法ですが、今回は戻り値を無視して、パスに空文字列が返ればキャンセルとみなして簡略化しています。

また引数 View, flags. fOpen に関しては利便性を考慮して列挙定数として定義しています。

必要であれば改変してください。

では使用例を見てみましょう。

以下は引数を特に指定しない、もっとも簡単な例です。

Sub SimpleTest()
    Dim strFile As String
    strFile = wh_GetFileName()
    If strFile = vbNullString Then strFile = "キャンセルされました。"
    MsgBox strFile
End Sub

引数をいろいろ指定してみた場合は、たとえば次のようになります。

Sub AdvansedTest()
    Const DLG_TITLE = "社員の顔写真を出力"
    Const OPEN_TITLE = "準備OK"
    Const INITIAL_DIR = "X:\総務\ライブラリ\社員\写真"
    Const FILTER_ = "ビットマップ (*.bmp;*.dib)|*.bmp;*.dib" _
            & "|JPEG (*.JPG;*.JPEG;*.JPE;*.JFIF)" _
            & "|*.JPG;*.JPEG;*.JPE;*.JFIF" _
            & "|PNG (*.PNG)|*.PNG"
    Const FILTER_INDEX = 2   ' 3 行目を既定で選択する。
    Dim strFile As String
    ' 保存先ファイル名を取得します。
    strFile = wh_GetFileName(, ,  _
                DLG_TITLE, OPEN_TITLE, , INITIAL_DIR, FILTER_, _
                FILTER_INDEX, , gfnFlagsOverWritePrompt, _
                gfnFOpenSaveAs)
    If strFile = vbNullString Then strFile = "キャンセルされました。"
    MsgBox strFile
End Sub

実行結果は以下の通りです。

GetSaveFileName Dialog

引数 flags を指定すると、さらに細かくダイアログの挙動を指定することが出来ます。

flags 列挙定数一覧
列挙定数ファイルを開く名前を付けて保存
gfnFlagsOverWritePrompt無効です。読み取り専用ファイルの選択を不可にし、既存のファイルと同名の場合は上書きを確認します。
gfnFlagsSetCurDir選択時のディレクトリをカレントに設定します。
gfnFlagsAllowMultiSelect【Ctrl】キーや【Shift】キーによる複数ファイルの選択を許可します。戻り値はタブ区切りで連結された複数ファイルのパスになります。複数ファイルの選択自体は可能ですが、目的上、戻り値は選択された先頭ファイルのパスだけになります。通常は指定しません。
gfnFlagsSelectFolderフォルダを選択します。無効です。
gfnFlagsEnableViewView 引数を有効にします。

上記の表はあくまで判明している範囲の一覧であり、他にもオプションが存在している可能性があります。

以下で、実例を見ていきましょう。

以下は引数 flags に定数 gfnFlagsOverWritePrompt を指定する例です。

MsgBox wh_GetFileName(flags:=gfnFlagsOverWritePrompt, fOpen:=gfnFOpenSaveAs)

この定数は [名前を付けて保存] ダイアログでのみ有効になります。[ファイルを開く] ダイアログでは、無視されます。

既存のファイルに上書きをしようとした場合は、次のような確認ダイアログが表示されます。

gfnFlagsOverWritePrompt

読み取り専用のファイルに上書きをしようとした場合は、次のようなダイアログが表示されて選択を完了できません。

gfnFlagsOverWritePrompt

以下は引数 flags に定数 gfnFlagsSetCurDir を指定する例です。

MsgBox wh_GetFileName(flags:=gfnFlagsSetCurDir)

この定数を指定しない場合は、ファイル選択時のディレクトリがカレントになりません。つまり一度フォルダを延々たどって深い階層でファイルを保存なり開くなりした後でも、再度ファイルを開くか保存する際にはまた同じフォルダを探す必要があります。

定数 GFN_SETCURDIR を指定すると、1 度開いたフォルダが次回の初期ディレクトリになります。

以下は引数 flags に定数 gfnFlagsAllowMultiSelect を指定する例です。

MsgBox wh_GetFileName(flags:=gfnFlagsAllowMultiSelect)

この定数を指定すると【Ctrl】キーや【Shift】キーによる複数ファイルの選択が可能になります。

gfnFlagsAllowMultiSelect

戻り値はタブ区切りで連結された複数ファイルのパスになります。

従って、次のようなコードで簡単に配列に格納して列挙することができます。

Dim ret, i
ret = Split(wh_GetFileName(flags:=GFN_ALLOWMULTISELECT), vbTab)
For Each i In ret
    Debug.Print i
Next

結果イメージは以下の通りです。

イミディエイト

以下は引数 flags に定数 gfnFlagsSelectFolder を指定する例です。

MsgBox wh_GetFileName(DlgTitle:="フォルダを選択", _
                      flags:=gfnFlagsSelectFolder)

この定数は [ファイルを開く] ダイアログでのみ有効になります。[名前を付けて保存] ダイアログでは、無視されます。

この定数を指定するとフォルダの選択のみが可能になります。

gfnFlagsSelectFolder

引数 flags に定数 gfnFlagsEnableView を指定すると、View 引数の指定が有効になります。

この指定を行なわない場合は、前回の表示オプションに準ずるスタイルでダイアログが開きます。

ではこの辺で、複数のオプションを組み合わせた例を 1 つ。

以下は、次の条件でダイアログを呼び出すコードの入力例です。

Input with Intelli SENS.

VBE のインテリセンス機能によって、列挙定数をプルダウンリストから選べるようになっていることを確認できます。

複数のオプションを組み合わせる場合は、オプションフラグを Or 演算子か + 演算子で演算します。

どちらでも結果は同じですが、個人的にはビットフラグであることを意識させてくれる Or 演算子の方を好んで使っています。

なお老婆心ながら付け加えておきますが、この関数はパスを返すだけで、実際にはファイルを開いたり保存したりはしません。その実装は、開発者側の責任になります。

謝辞

WizHook のキーについては、Skrol 29 氏の UtterAccess Discussion Forums への投稿を参考にさせていただきました。

末尾ながら、お礼申し上げます。

Thanks Mr.Skrol 29! Your post makes this topic be it.

なお WizHook は非公開クラスですので、建前としては動作保証は一切致しません。

、ウィザードが利用している関数が動作しないわけが有りません。

ガンガン利用して楽をしましょう。

関連情報

WizHook クラスには他にも多数のメソッドが有ります。

興味のある方は下記を参考にしながら、探検してみるとよいでしょう。

Access y VBA -> WizHook (スペイン語)

ACCESS WizHook - [ハムスターの巣] (日本語)

Picasoのぴー: WizHookクラス (日本語)

ushimitsudoki.com - Viewing Microsoft Access WizHook Reference (英語)

Team-Moeller.de - Downloads (ドイツ語)

※ 実際に動く MDB のデモあり

更新履歴