LoginSignup
you_0421
@you_0421

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

AutoCADのVBA でファイルダイアログを表示できない

AutoCADVBAにてファイルダイアログからパスを取得したい。

AutoCADVBAにてファイルダイアログからパスを取得したい

AutoCADの自動化をする際、事前に作成したcsvを読み込みたいのですが、表題の通りファイルダイアログを表示できません。

エクセルのVBA は少しさわっていたので、それと同じように書いてみた(下記のコード)のですがダメでした。

Application.GetOpenFilename

CADのVBA記事が少なく、調べきれていないのですが、ご存じの方がいらっしゃいましたらご教示願います。

0

2Answer

AutoCADを使っていないので、実際に確認することができませんが、
ネットで見る限り、Excelで使うVBAと同じだと考えて よさそうです。

「ダメでした」とは、具体的にどうなったのでしょうか?
エラーダイアログが出てきた、実行時エラーになった、とか・・・。
その時のスクショを貼ってもらうといいと思います。

AutoCADのバージョンに対応した、VBAモジュールのインストールは必要です。

↓20年前の情報ですが

1

Comments

  1. @you_0421

    Questioner

    スクリーンショット 2024-03-27 152646.png

    ご回答ありがとうございます。
    情報・言葉足らずな質問で申し訳ありません。

    VBAのモジュールを再インストールして、同じようにエクセルでは動作を確認している添付のコードを実行しましたが、エラーが出てしまいます。
    ※このエラーは投稿時のものと同じ

  2. Excelの場合は、ApplicationがExcelですが、
    AutoCADの場合は、ApplicationはAutoCADになりますね。
    そこには、GetOpenFilenameが無いということですね。恐らく。
    Applicationと入力して続いて、.(ピリオド)を入力すると、使えるプロパティやメソッドがリストで現れますか? そこにGetOpenFilenameが無いと思われます。

    ↓ WidnwosAPIを使った例が見つかりました。

    探せば、ActiveXを使った、もう少し簡単な方法もあるはずです。

  3. @you_0421

    Questioner

    ご返信ありがとうございます。
    CADにダイアログ表示のコマンドがないこと、理解しました。
    WidnwosAPIでの表示に挑戦してみようと思います。
    ありがとうございました。

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)を使っている実装の場合、ファイルパスとして一部の文字(俗に言う環境依存文字)が使えないという制限があるため注意が必要です。

0

Comments

  1. @you_0421

    Questioner

    ご回答ありがとうございます。
    早速、サンプルコードコピーペーストでテストしたのですが、以下のコード*で囲んだ部分でコンパイルエラー:ユーザ定義型は定義されていませんと出てきてしまいました。
    参照設定というのは、ツール>参照設定Microsoft Word 16.0 Object Libralyのチェックボックスにチェックを入れるという認識であっていますか。
    ※Publisherがなかったので、とりあえずwordでテストしたいと思っています。
    ※Publisherの部分はWordに書き換えています。

    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
    
  2. WordではなくOffice(Microsoft Office 16.0 Object Library)の参照設定をしてください。
    使用してる機能がWordやExcel固有では無く、Office共通の機能のため、Office共通ライブラリを参照する必要があります。

    また、前後のコメントにも簡単に記載していますが、以下の箇所を、

        'Office = Microsoft Office 16.0 Object Library の参照設定が必要です。
        'Const msoFileDialogOpen = 1 を別途定義すれば As Object などでも動くはず。
        Dim fd As Office.FileDialog
        Set fd = appAnyOffice.FileDialog(msoFileDialogOpen)
    

    次のように変更すれば、参照設定は不要になります。

        'Office = Microsoft Office 16.0 Object Library の参照設定が必要です。
        Const msoFileDialogOpen = 1 'を別途定義すれば As Object などでも動くはず。
        Dim fd As Object 'As Office.FileDialog
        Set fd = appAnyOffice.FileDialog(msoFileDialogOpen)
    

    ダイアログの細かい動作を変更したい場合は、参照設定がある状態の方が変更はしやすいはずです。

Your answer might help someone💌