nak435さんの回答のとおり、ExcelとAutoCADのApplicationが提供している機能の違いによるものが原因だと思われます。
そのため、対策としてはWindows APIのGetOpenFileName
などを使うか、既存のオブジェクト(=ActiveX)の機能を使うか、というところです。
しかし、私の知っている範囲では、既存のオブジェクトでファイル選択ダイアログの機能を提供しているものはOfficeぐらいしかありません。
Office自体は外部からの操作も可能なため、裏でOfficeを開いてダイアログだけ使う、といったことも可能ですが、ホスト(今回でいうとAutoCAD)の裏にダイアログが回り込んでしまう可能性があるなど、注意が必要です。
以下は、Officeのダイアログを使うサンプルコードです。
ShowFileOpenDialogByOffice
がダイアログ表示処理の本体です。
Sub Sample()
Dim csvFiles() As String
csvFiles = ShowFileOpenDialogByOffice(True)
Dim countOfFiles As Long
countOfFiles = UBound(csvFiles) - LBound(csvFiles) + 1
If countOfFiles = 0 Then
MsgBox "csv ファイルを選んでください。"
Exit Sub
Else
MsgBox countOfFiles & " ファイル選択されました。" & vbLf & VBA.Strings.Join(csvFiles, vbLf)
End If
End Sub
Public Function ShowFileOpenDialogByOffice( _
Optional ByVal inMultiSelect As Boolean _
) As String() '0 To ~
'MS Office 以外の VBA 環境用に、ファイル選択ダイアログを表示するサンプル。
'以下の点で注意が必要。
'・ダイアログの左上のアイコンが Office のものになる
'・ダイアログが VBA のホストアプリの裏に移動してしまうことがある
'・表示に少し時間がかかる
240328
'適当な Office を裏で起動する。
'Excel/Word/PowerPoint/Access/Publisher 何でもいいが、
'・マイナーのため使っている人が少なく影響が出にくい
'・1ファイル1インスタンスのため、雑に扱っても勝手に終了してくれることが多い
'の面から Publisher を使用している。
'何を使うかは実際の環境に合わせて調整してください。
'PowerPoint は一つのインスタンスで全部のファイルを管理しているので注意が必要です。
Dim appAnyOffice As Object
Set appAnyOffice = VBA.Interaction.CreateObject("Publisher.Application")
'Office = Microsoft Office 16.0 Object Library の参照設定が必要です。
'Const msoFileDialogOpen = 1 を別途定義すれば As Object などでも動くはず。
Dim fd As Office.FileDialog
Set fd = appAnyOffice.FileDialog(msoFileDialogOpen)
fd.Filters.Clear
fd.Filters.Add "csvファイル(*.csv)", "*.csv"
'最初に表示する場所を指定(暫定)。
fd.InitialFileName = VBA.Interaction.Environ$("USERPROFILE")
fd.AllowMultiSelect = inMultiSelect
If fd.Show() = 0 Then
'キャンセルされた場合 0 To -1 の String 配列を返す。
Let ShowFileOpenDialogByOffice = VBA.Strings.Split(VBA.Constants.vbNullString)
Exit Function
End If
With fd.SelectedItems
Dim buf() As String
ReDim buf(0 To .Count - 1)
Dim i As Long
For i = 1 To .Count
buf(i - 1) = .Item(i)
Next i
End With
Let ShowFileOpenDialogByOffice = buf
End Function
参考として、Windows APIを使う場合はGetOpenFileNameA
(末尾がA)を使っている実装の場合、ファイルパスとして一部の文字(俗に言う環境依存文字)が使えないという制限があるため注意が必要です。