プロが教える店舗&オフィスのセキュリティ対策術

VBAの質問です。
20年前に作られたファイルの更新をしたいです。
ファイルの場所およびファイル名を取得する箇所で、該当のボタンを押すとファイル選択のエクスプローラーが起動するはずなのですが、パソコンを入れ替えたら何も起きなくなってしまいました。
(エラーも出ません)

コードの該当箇所はここだと思うのですが、どこかを書き換えれば動くようになるでしょうか。

なお、一般公開してはまずい情報は含まれていないと判断してアップロード致しましたが、万一含まれていましたらご指摘下さい。質問を取り消します。

Private Sub CommandButton2_Click()
Dim tOpenFileName As OpenFileName
With tOpenFileName
'構造体のサイズを設定
.lStructSize = LenB(tOpenFileName)
'親ウィンドウのハンドルを指定
'.hwndOwner = Me.hWnd
'アプリケーションのインスタンスのハンドルを指定
'.hInstance = App.hInstance '不要の時 0&
'ファイルパターンを設定(複数指定する場合は続いて記入)
.lpstrFilter = "Excelファイル(*.XLS)" & vbNullChar & "*.XLS"

'優先的に表示させるフィルタのインデックス
.nFilterIndex = 1
'ファイル名の内容を初期化
.lpstrFile = String$(256, Chr$(0)) ' "*.txt" & String$(256, Chr$(0))
'同バイト数
.nMaxFile = 256
'ファイル名を受取るバッファの設定(Nullで埋めておく)
.lpstrFileTitle = String$(256, Chr$(0))
'同バイト数
.nMaxFileTitle = 256
'デフォルトのフォルダ名の設定
.lpstrInitialDir = "C:\"
'ダイアログのキャプション名
.lpstrTitle = "ファイルを開く"
'flagsの動作の設定
.flags = OFN_EXPLORER Or OFN_PATHMUSTEXIST _
Or OFN_FILEMUSTEXIST Or OFN_HIDEREADONLY
End With
'ダイアログの表示
If GetOpenFileName(tOpenFileName) = 0 Then
'キャンセルボタンを押した場合(クローズ・エラーも)
strFileName = ""
Exit Sub
Else
'開くボタンを押した場合(ファイル名を取得)
Sheet5.Cells(7, "M") = Left$(tOpenFileName.lpstrFile, InStr(tOpenFileName.lpstrFile, vbNullChar) - 1)
Sheet5.Cells(7, "N") = Left$(tOpenFileName.lpstrFileTitle, InStr(tOpenFileName.lpstrFileTitle, vbNullChar) - 1)

End If

End Sub

質問者からの補足コメント

  • #4さんのご回答のお礼の補足です。

    「動かなくなってしまった古いVBAを動くよ」の補足画像1
    No.6の回答に寄せられた補足コメントです。 補足日時:2022/09/20 16:14
  • #4さんのご回答に対応してみたら、エラーメッセージがでました。

      補足日時:2022/09/20 16:16
  • メッセージボックスを表示させて、処理の流れを確認しましたところ

    If GetOpenFileName(tOpenFileName) = 0
    の項でThenに行ってしまい、ファイル名が取得されず処理が終わってしまっていることがわかりました。

      補足日時:2022/09/21 10:27
  • パソコンはWindows10・32bit → Windows 11 Pro・64bit への切り替えです。
    エクセルのバージョンにつきましては2013~2021(Windows10・64bit)で確認をして、いずれの場合も動作しておりません。

      補足日時:2022/09/21 16:38

A 回答 (8件)

こんにちは


取り合えず既存コードをおいといて
#6にある参考サイトのGetOpenFileName 部分を
新規モジュールに丸っとコピペして

Function呼び出し用のプロシージャ・・例
Sub test()
MsgBox GetMyFile("ファイルを開く")
End Sub
を追加・・・

testを実行するとダイアログが生成されます
ファイルを選ぶと情報がMsgboxで返り、キャンセルですと空のstringが返るはずです

OpenFileはWithで括ることも出来るでしょう
各パラメータを確認変更して使用できるようであれば、置き換えて使用することも出来ると思います

API シート関数、シートメソッド、シートオブジェクトは
バージョン変更などで仕様が変わる事があります
この際、改修し易い(理解度や情報が多くある)メソッドやロジックに変えてしまうのが良いと思います。
    • good
    • 0

こんばんは



横からですが・・・

APIの宣言を後出しなさったりしている様子から想像するところ、失礼ながら、質問者様はVBAをあまりご存じないのではないかとの印象を受けました。

ご提示のコードにこだわる理由がわかりませんけれど、ざっと見たところダイアログで指定ファイルのパス(ファイル名かな?)を取得するだけのもののように思われます。
であるなら、わざわざ回りくどい方法をとらなくても、普通の方法で取得すれば簡潔になるのではないでしょうか?
既に、No5様が具体例をご提示済みですが、そちらを利用すれば済む話ではないかと思いますけれど・・
    • good
    • 1

>という記述がありましたので、下記に書き換えてみました。


APIに問題がある場合

Private Type  必要個所が使われているかは不明ですが、書き換える必要があるかも知れません

VBA7の場合
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

参考:https://jkp-ads.com/articles/apideclarations.asp
この回答への補足あり
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
下記の記述がありました。
★がついている所が、ご回答の内容と書いてあることが違うようです。

'動作条件を設定するOPENFILENAME構造体(P158)
Public Type OPENFILENAME
lStructSize As Long '構造体のサイズ
hwndOwner As Long '親ウィンドウのハンドル★
hInstance As Long 'モジュールのインスタンスハンドル★
lpstrFilter As String 'VBのファイルパターン
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 Long 'フックプロシージャに渡すデータ★
lpfnHook As Long 'フックプロシージャOFNHookprocへのポインタ★
lpTemplateName As String 'テンプレートリソース名
End Type

お礼日時:2022/09/21 13:20

#2です。

ごめんなさい
>'.hInstance = App.hInstance
コメントブロックにされていましたね・・#2は忘れてください

>グレイアウトしたままなのですが
コンパイルは出来ているかと・・実行時自動でされるので気にしなくて良いと思います

GetOpenFileName Lib・・
なんか・・他の処理で使っているかもですが
Shell "EXPLORER.EXE /select とか
Application.GetOpenFilename メソッド で代用出来ないかな?

GetOpenFilenameの例 ファイル名のみ

Sub ExcelFile()
Dim openFilePath As String
openFilePath = Application.GetOpenFilename _
("Excel ファイル,*.xls*", , "エクセルファイルを選んで下さい", MultiSelect:=False)
If openFilePath <> "" Then Sheet5.Cells(7, "M") = Dir(openFilePath)
End Sub

複数選択が必要の場合、(MultiSelect:=True)
Application.GetOpenFilenameをVariantで受けて
配列で複数ファイル情報を取得します
この時のキャンセル対応
If IsEmpty(openFilePath) Then


windows APIについてはうる覚えで調べられる環境にないので とりあえず
    • good
    • 0

Microsoft Scripting Runtime とかオンにしてみたら動かないでしょうか、当てずっぽうですが。

    • good
    • 0
この回答へのお礼

ありがとうございます。
#2さんのお礼に書いた内容を元に戻し、オンにしてみたら補足画像のエラーメッセージが出ました。

お礼日時:2022/09/20 16:06

Cドライブ以外があればそれを、なければ任意のフォルダを作成し『Cドライブ直下を指定するのをやめる』なんて事はないかな。


初級レベルなジジィですし。

パソコンを入れ替えたってなら『環境をどう変えたのか(Excelのバージョンも変わったのか)』を書かれては?
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
パソコンはWindows10・32bit → Windows 11 Pro・64bit への切り替えです。
エクセルのバージョンにつきましては2013~2021(Windows10・64bit)で確認をして、いずれの場合も動作しておりません。

お礼日時:2022/09/21 16:37

こんにちは


コンパイルは出来ているのでしょうか?
API、Type部分など点検してみては・・32bit-->64bit

Excelを64bitに変えているのなら・・
ぱっと見 .hInstance を(.Hinstanceプロパティを指しているのなら)
.hinstancePtrにしてLongPtr 型に変更するとかでしょうか・・・

他にも多分あると思いますが・・この情報だけでは、分かりませんね

エラーが出ない・・・エラー対策などがあるものと思いますので、
すべて外してデバッグしながら進めるかですかね・・・
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。

恥ずかしながらエクセルVBAでコンパイルが必要だとは知りませんでした…
メニューの デバッグ>コンパイル を選んでしばらく経ちますが、何も起きま せん。
「コンパイル」のメニューもグレイアウトしたままなのですが、このまま待って いて大丈夫なのでしょうか。

'ファイル選択ダイアログボックスを表示する(P157)
Declare PtrSafe Function GetOpenFileName Lib "comdlg32.dll" (pOpenfilename As OpenFileName) As Long

という記述がありましたので、下記に書き換えてみました。
しかし、まだ動きません。

Declare PtrSafe Function GetOpenFileName Lib "comdlg32.dll" Alias "GetOpenFileNameA" (pOpenfilename As OpenFileName) As Long

お礼日時:2022/09/20 15:40

参照設定じゃないでしょうか。

    • good
    • 1
この回答へのお礼

ご回答ありがとうございます。

すみません、参照設定について知識がないのですが、ツール>参照設定 の参照 設定でしょうか?

お礼日時:2022/09/20 15:39

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング