Accessのデータベースファイルを64bit版のofficeで開いた際、32bit版で使用できていた機能(ファイル取り込みの際に「参照」等のボタンを押すとウインドウが開く)を使えるようにしたいです


今回の件について、同様の質問が既にあります。

GetOpenFileName 開かない - Access(アクセス) 締切済み| 【OKWAVE】
https://okwave.jp/qa/q9720064.html

上記のQ&Aについての解決策について、お力添えをいただきたいです。
自分も同じ悩みに直面しておりますので、上記質問の答えが出れば、解決できるような気がします。

32bitの時は、GetOpenFileNameメソッドが使われているときに、取り込みたいファイルを指定するためのウインドウが開いておりました。
上記Q&Aにおける「lngRet = GetOpenFileName(pOpenFileName)」の箇所です。
自分が携わっているシステムのコードも、全く同じく「lngRet = GetOpenFileName(pOpenFileName)」のところでウインドウが開いているのをステップインで実行して確認したのですが、62bitの環境では、全くの無反応でウインドウが開かないです。

回答の条件
  • 1人20回まで
  • 登録:
  • 終了:2020/05/25 15:27:20
id:moon-fondu

どうすれば64bitでも開けられるのかと考えまして…

Office TANAKA - ファイルの操作[名前を指定してブックを開く]
http://officetanaka.net/seminar/seminar8.htm

を参考にしました。
上記Q&Aにもあります、

pOpenFileName.lpstrFilter = "CSVファイル (*.xlsx)" & String(1, vbNullChar) & "*.xlsx" & String(2, vbNullChar)

という箇所が、自分が携わっていたシステムにもありましたので。
ここを、

pOpenFileName.lpstrFilter = ""Microsoft Excelブック,*.csv?"

と、変えてみたのですが。
全くの無反応なのは変わらず…「String(1, vbNullChar) & "*.xlsx" & String(2, vbNullChar)」が、ウインドウを開くために何か関係している気がしたのですが。
また、 https://www.ilovex.co.jp/blog/system/i/systemdevelopment/winapi32bit64bit.html (WinAPIの32bitと64bit | システム開発 | システム開発ブログ)の記事を参考にしまして、
Private Declare PtrSafe Function GetOpenFileName Lib "comdlg32.dll" Alias "GetOpenFileNameA" (pOpenfilename As OPENFILENAME) As Long
という記述を入れ、構造体の宣言の部分も、

hwndOwner As LongPtr
hInstance As LongPtr
lCustData As LongPtr
lpfnHook As LongPtr

と、4箇所をLongPtrに変換したり、nMaxCustrFilter→nMaxCustFilter に修正もしたのですが…。全くウインドウが開いてくれず、困っております。
お力添えいただけますと幸いです。
よろしくお願い致します。

ベストアンサー

id:forest318 No.2

回答回数106ベストアンサー獲得回数24

ポイント700pt

 
https://hatena19.com/use-win-api-with-office-64bit-or-32bit-vba/
 
WindowsAPI をOffice64bit版または32bit版のVBAで使うには
Officeの32bit版のVBAでWindowsAPIを使用していたコードが、
Officeを64bit版に変更すると
コンパイルエラーになり使えないということが発生します。
64bit版に対応させるためには、
WindowsAPIのDeclareステートメントの宣言を書き換える必要があります
とのことです。
 
http://officevba.info/filedialog/
https://detail-infomation.com/vba-getopenfilename-method/
https://mam-mam.net/mytech/show.php?cd=14
 
参考になさってください。
 
 
 

id:moon-fondu

ありがとうございます、ウインドウ、開くことができました!forest318さんが紹介してくださった、「WindowsAPI をOffice64bit版または32bit版のVBAで使うには | hatena chips」https://hatena19.com/use-win-api-with-office-64bit-or-32bit-vba/ の記事で紹介されておりました、どの引数をLongPtr型に変更するかについても把握できる、MSサイトにある64bit対応のAPI宣言が網羅されているリンク、これが決め手でした。

https://hatena19.com/Office2010Win32API_PtrSafe/Win32API_PtrSafe.TXT
にあります、GetOpenFileNameメソッドのAPI宣言?に関する箇所というよりは。
Type OPENFILENAME~以下の部分、構造体の方でした。
こちら、32bit版で動かしていたときは、

'#if (_WIN32_WINNT >= 0x0500)
pvReserved As LongPtr
dwReserved As Long
FlagsEx As Long
'#endif // (_WIN32_WINNT >= 0x0500)

の記述がなかったんです。でもこれらの記述を加えたら、64bitのofficeでも動かすことができまして、選択ダイアログが出てくれましたー。

本当に助かりました。ありがとうございましたm(__)m

2020/05/21 16:18:34

その他の回答1件)

id:kaitesukkiri No.1

回答回数2ベストアンサー獲得回数1

ポイント500pt

参考にしているサイトで構造体の定義が違いますね。
aは、「lpstrCustomFilter As Long」
bは、「lpstrCustomFilter As String」

aの定義を使用していて「ofn.lpstrCustomFilter = 0」はOKだけど、
bの定義を使用していて「ofn.lpstrCustomFilter = 0」だと、GetOpenFileNameAPIがスルーされます。
bの定義を使用しているなら、
ofn.lpstrCustomFilter = String(512,vbNullChar)
ofn.nMaxCustFilter = Len(ofn.lpstrCustomFilter)
などにすれば動くのでは。

そのあたりをチェックしてもダメなようなら、一番シンプルなコードでテストしてみては?
新規のmdb(accdb)に標準モジュールを1つ作ってベーシックなコードでテスト。
例えば、次のようなコードを張り付けて、イミディエイトウインドウに 「? GetOpenFileName」と入力してリターンがあるかとか。 私の環境では問題なく動作しました。

Private Declare PtrSafe Function GetOpenFileName Lib "comdlg32.dll" Alias "GetOpenFileNameA" (pOpenFileName As OPENFILENAME) As Long
Private Type OPENFILENAME
lStructSize As Long
hwndOwner As LongPtr
hInstance As LongPtr
lpstrFilter As String
lpstrCustomFilter As String
nMaxCustFilter 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
lCustData As LongPtr
lpfnHook As LongPtr
lpTemplateName As String
End Type

Private Const OFN_EXPLORER = &H80000

Public Function GetFileName() As String

Dim ofn As OPENFILENAME
Dim lngRet As Long

With ofn
.hwndOwner = Application.hWndAccessApp
.hInstance = 0
.lpstrFilter = "全てのファイル (*.*)" & String(1, vbNullChar) & "*.*" & String(2, vbNullChar)
.lpstrCustomFilter = String(512, vbNullChar)
.nMaxCustFilter = Len(.lpstrCustomFilter)
.nFilterIndex = 1
.lpstrFile = String(512, vbNullChar)
.nMaxFile = 512
.lpstrFileTitle = String(512, vbNullChar)
.nMaxFileTitle = 512
.lpstrInitialDir = String(1, vbNullChar)
.lpstrTitle = String(1, vbNullChar)
.nFileOffset = 0
.nFileExtension = 0
.lpstrDefExt = String(1, vbNullChar)
.lCustData = 0
.lpfnHook = 0
.lpTemplateName = 0
.Flags = OFN_EXPLORER
.lStructSize = Len(ofn)

lngRet = GetOpenFileName(ofn)

GetFileName = Left(.lpstrFile, InStr(.lpstrFile, vbNullChar) - 1)
End With

End Function

他1件のコメントを見る
id:kaitesukkiri

あー、昨日の私の書き込み間違ってますね。
イミディエイトウインドウからコ-ルするのは、GetOpenFileNameではなくGetFileNameですね。

それでもだめならなにか環境の問題でしょうね。当方はWin10、Office2013しかも持ってないのでそれ以外の環境での確認はできません。

2020/05/20 19:28:18
id:moon-fondu

lpstrInitialDirが、forest318さんが紹介してくださった「Accessでファイル選択ダイアログを使うには」https://mam-mam.net/mytech/show.php?cd=14 の記事で、パスを指定していたので、これが原因かな?と思いましたが。
結果的に別のところが原因でした。
何とか解決できたので、よかったです。ありがとうございました。

2020/05/21 16:08:32
id:forest318 No.2

回答回数106ベストアンサー獲得回数24ここでベストアンサー

ポイント700pt

 
https://hatena19.com/use-win-api-with-office-64bit-or-32bit-vba/
 
WindowsAPI をOffice64bit版または32bit版のVBAで使うには
Officeの32bit版のVBAでWindowsAPIを使用していたコードが、
Officeを64bit版に変更すると
コンパイルエラーになり使えないということが発生します。
64bit版に対応させるためには、
WindowsAPIのDeclareステートメントの宣言を書き換える必要があります
とのことです。
 
http://officevba.info/filedialog/
https://detail-infomation.com/vba-getopenfilename-method/
https://mam-mam.net/mytech/show.php?cd=14
 
参考になさってください。
 
 
 

id:moon-fondu

ありがとうございます、ウインドウ、開くことができました!forest318さんが紹介してくださった、「WindowsAPI をOffice64bit版または32bit版のVBAで使うには | hatena chips」https://hatena19.com/use-win-api-with-office-64bit-or-32bit-vba/ の記事で紹介されておりました、どの引数をLongPtr型に変更するかについても把握できる、MSサイトにある64bit対応のAPI宣言が網羅されているリンク、これが決め手でした。

https://hatena19.com/Office2010Win32API_PtrSafe/Win32API_PtrSafe.TXT
にあります、GetOpenFileNameメソッドのAPI宣言?に関する箇所というよりは。
Type OPENFILENAME~以下の部分、構造体の方でした。
こちら、32bit版で動かしていたときは、

'#if (_WIN32_WINNT >= 0x0500)
pvReserved As LongPtr
dwReserved As Long
FlagsEx As Long
'#endif // (_WIN32_WINNT >= 0x0500)

の記述がなかったんです。でもこれらの記述を加えたら、64bitのofficeでも動かすことができまして、選択ダイアログが出てくれましたー。

本当に助かりました。ありがとうございましたm(__)m

2020/05/21 16:18:34
  • id:moon-fondu
    すみませんリンクガうまく貼れていない部分がありましたので、貼り直します。
    https://www.ilovex.co.jp/blog/system/i/systemdevelopment/winapi32bit64bit.html

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません