もう Excel VBA ネイティブな人たちの間では、何年も前に話題になったであろう今更な話(笑)。
お客さんに送ってもらった Excel シートで「コンパイルエラー:このプロジェクトのコードjは、64 ビット システムで使用するために更新する必要があります。Declare ステートメントの確認及び更新を行い、次に Declare ステートメントに PtrSafe 属性を設定してください。」のエラーメッセージが表示される。
セルの編集をすると実行される VBA マクロがあり、それがエラーになっているようだ。
引っかかっているのは、メッセージにあるように
Private Declare Function SHBrowseForFolder Lib "SHELL32" (lpbi As BROWSEINFO) As LongPrivate Declare Function SHGetPathFromIDListLong Lib "SHELL32" Alias "SHGetPathFromIDList" (ByVal pIDL&, ByVal lpStr$) As LongPrivate Declare Function GetForegroundWindow Lib "USER32" () As Long
この部分。
メッセージに書かれているように、PtrSafe オプションを追加してやるだけでいい。
Private Declare PtrSafe Function SHBrowseForFolder Lib "SHELL32" (lpbi As BROWSEINFO) As LongPrivate Declare PtrSafe Function SHGetPathFromIDListLong Lib "SHELL32" Alias "SHGetPathFromIDList" (ByVal pIDL&, ByVal lpStr$) As LongPrivate Declare PtrSafe Function GetForegroundWindow Lib "USER32" () As Long
これでエラーは出なくなる。
Declare ステートメントで Dynamic Link Library(DLLファイル)内の外部プロシージャへの参照を宣言するのだが、64bit版の VBA では必ず PtrSafe を付けないといけないらしい。「この外部プロシージャが 64bit版 Office で実行しても安全よ」ということを表明するだけのオプションだと聞いたことがあるが、本当なのか、どうなのか?(笑)
まあ、64bit版で動かして安全なのかどうなのかは・・・知らんけど(^^;;;
指定せんと動かんからな。あとで、「あんたが『安全』だと表明して PtrSafe オプション設定したんでしょ!」とか言われたら困るけどな(^^;
ちなみに、この Excel シートを 64bit版でも 32bit版でも参照するのであれば、
#If VBA7 And Win64 ThenPrivate Declare PtrSafe Function SHBrowseForFolder Lib "SHELL32" (lpbi As BROWSEINFO) As LongPrivate Declare PtrSafe Function SHGetPathFromIDListLong Lib "SHELL32" Alias "SHGetPathFromIDList" (ByVal pIDL&, ByVal lpStr$) As LongPrivate Declare PtrSafe Function GetForegroundWindow Lib "USER32" () As Long#ElsePrivate Declare Function SHBrowseForFolder Lib "SHELL32" (lpbi As BROWSEINFO) As LongPrivate Declare Function SHGetPathFromIDListLong Lib "SHELL32" Alias "SHGetPathFromIDList" (ByVal pIDL&, ByVal lpStr$) As LongPrivate Declare Function GetForegroundWindow Lib "USER32" () As Long#End If
このように条件付きコンパイルをしてやる必要がある。
今回は俺のPC+Office(64bit環境)でしか使わないので、PtrSafe をべた書きで追加しただけということ。