戻る


他の多くのAPI同様、見ただけで酸っぱいものが込み上げてきそうな文字の羅列です。
Private Declare Function GetOpenFileName Lib "comdlg32.dll" Alias "GetOpenFileNameA" (pOpenFileName As OPENFILENAME) As Long
Private Type OPENFILENAME
    lStructSize As Long
    hwndOwner As Long
    hInstance As Long
    lpstrFilter As String
    lpstrCustomFilter As Long
    nMaxCustrFilter As Long
    nFilterIndex As Long
    lpstrFile As String
    nMaxFile As Long
    lpstrFileTitle As String
    nMaxFileTitle As Long
    lpstrInitialDir As String
    lpstrTitle As String
    Flags As Long
    nFileOffset As Integer
    nFileExtension As Integer
    lpstrDefExt As String
    lCustrData As Long
    lpfnHook As Long
    lpTemplateName As Long
End Type
他に定数なんかもたくさんあったりするんですが、個人的にはそんなもの使う気になれないんで、ずっと下のほうに隔離しておくとして、
とりあえず上のFunction宣言1個と、Type宣言1個、APIでファイル選択ダイアログ出したいならこれだけは必須。

で、たとえば
    Dim MyStrFile As String
    Dim MyRtn As Long
    Dim MyOFN As OPENFILENAME

    '↓この3つだけ書けばとりあえずは動くんじゃなかろうか
    MyOFN.lStructSize = Len(MyOFN)
    MyOFN.lpstrFile = String(256, Chr(0))
    MyOFN.nMaxFile = 256
    '↑    
    
    MyOFN.lpstrTitle = "どうでもいいけど何か選べ"
    MyOFN.lpstrInitialDir = "C:\"
    MyOFN.lCustrData = 0
    MyOFN.lpfnHook = 0
    '・・・・・・このあたりは省略しても問題なさそう
    
    MyRtn = GetOpenFileName(MyOFN)
    If MyRtn = 0 Then
        MyStrFile = ""
    Else
        MyStrFile = MyOFN.lpstrFile
    End If
↑程度のことを書いておけばいいと思います。

ひとつ、重要かもしれないこと。

ここで得られた文字列 MyStrFile は、場合によっては、このまま使うとかなり困ったことが起こります。
見かけは何てこともないファイルパス文字列なんですけどね。
256文字あるんです。
ついでに256ってのもたとえばの数で、上のコードの書き方によっては400にも500にもなります。

なに言ってるかわかりませんよね。

たとえば "C:\test.txt"

これでも256文字です。
256文字のうちの「見える部分」が "C:\test.txt" で、残りが全部 Chr(0) で埋まってるみたいなんです。

MyStrFile = Left(MyStrFile, Len(MyStrFile) - 1)
右端の1文字を削れと命令しても、返ってくる値は "C:\test.txt" です。

MyStrFile = Left(MyStrFile, Len(MyStrFile) - 10)
右端10文字を削れと命令しても、返ってくる値は "C:\test.txt" です。

ファイル操作だったらこの不思議な文字列のままでも差し支えはありません。
CreateObject("Scripting.FileSystemObject").FileExists(MyStrFile)
で、有無を問えば、たしかにそういうファイルは存在するという答が返ってきます。

この MyStrFile の文字列をデータベースのテーブルに保存しようとして
DbCnn.Execute ("INSERT INTO tbl1 ( fld0 ) SELECT '" & MyStrile & "' AS S1")
なんてことをやると、予想外のエラーを吐かれます。
何でこんな簡単なクエリでコケるんだと、悩みに悩んだ末、GetOpenFileNameで得られる文字列の不思議な性質にようやく気づいたのでした。

この文字列は、得られたらそのまま使おうとしないで、
MyStrFile = Replace(MyStrFile, Chr(0), "")
とか
MyStrFile = Left(MyStrFile, InStr(MyStrFile, Chr(0)) - 1)
とかいうような処理を施して、見かけと実体を一致させておいたほうがいいです。


あと、Dim MyOFN As OPENFILENAME で、
この MyOPF.・・・の属性については、埋めたい人はもっといっぱい埋めてもいいですよ。
    MyOFN.hwndOwner = Me.Hwnd 'Accessだとハンドルは簡単に取れるけど、Excelはけっこう面倒(やり方はカメラ操作のページを参考に)
    MyOFN.hInstance = 0
    MyOFN.lpstrFilter = "全てのファイル (*.*)" & String(1, Chr(0)) & "*.*" & String(2, Chr(0))
    MyOFN.nFilterIndex = 1
    MyOFN.lpstrFileTitle = String(256, Chr(0))
    MyOFN.nMaxFileTitle = 256
    MyOFN.Flags = OFN_EXPLORER Or OFN_PATHMUSTEXIST _
      Or OFN_FILEMUSTEXIST Or OFN_HIDEREADONLY 'この定数使うなら、宣言忘れずに
な具合ですけど、いいかげん勘弁してくれって感じでしょ。
まあ好きにやってください。

以下、定数です。
たぶんFragsのところで使うんだと思います。
どうでもいいです。

Const OFN_ALLOWMULTISELECT = &H200 '複数のファイルを選択可能に
Const OFN_CREATEPROMPT = &H2000 'ファイルが存在しなかった場合、新規作成するかどうか確認
Const OFN_EXPLORER = &H80000 'エクスプローラ形式のダイアログを使用
Const OFN_FILEMUSTEXIST = &H1000 '存在しないファイル名を入力不可に
Const OFN_HIDEREADONLY = &H4 '「読み取り専用」チェックボックスを非表示
Const OFN_NODEREFERENCELINKS = &H100000
Const OFN_NONETWORKBUTTON = &H20000 'ネットワークコンピュータを非表示に
Const OFN_NOREADONLYRETURN = &H8000
Const OFN_NOVALIDATE = &H100
Const OFN_OVERWRITEPROMPT = &H2 'ファイルが存在していた場合、上書きするかどうか確認
Const OFN_PATHMUSTEXIST = &H800 '有効なパス名のみを入力可能に
Const OFN_READONLY = &H1 '「読み取り専用」チェックボックスをオンに
Const OFN_SHOWHELP = &H10 '「ヘルプ」ボタンの表示
Const OFN_NOCHANGEDIR = &H8 'カレントディレクトリをダイアログのカレントディレクトリにする(???)
Const OFN_EXTENSIONDIFFERENT = &H400 '拡張子がデフォルトの拡張子と異なる場合に設定されるフラグ(???もはや何を言っているのかわからない)
VBAでカメラを動かすページに行く