【入門編】【実務中級者向け】大量のDWGファイルを「開かずに」一括で最新の2018形式へアップグレード保存するバッチ処理 – AutoCAD VBA解析バイブル

スポンサーリンク
スポンサーリンク

AutoCAD VBAを掌握する極限の知見:大量のDWGファイルを「一括アップグレード」する究極のバッチ処理

こんにちは。今日も図面の世界で格闘している同志の皆さん。
「マクロの記録」ボタンをポチポチ押して、なんとか自動化の第一歩を踏み出した……。そんな時期を経て、少しずつ「もっと効率的に、もっとスマートに、大量のファイルを操りたい」と願い始めたあなたへ。

今日は、実務における「自動化の壁」の一つである「図面バージョンの変換」というテーマを扱います。

例えば、古いバージョンのDWGファイルがフォルダ内に数百個あるとしましょう。それらを一つずつ手作業で開き、「名前を付けて保存」で最新の2018形式に変換していく……。そんな作業に、あなたの貴重なエンジニアとしての時間を費やす必要はありません。

今回は、AutoCAD VBAを用いて、「ユーザーの画面を占有せず、あたかもバックグラウンドで魔法のように処理が進む」、プロフェッショナルなバッチ処理の設計思想と実装コードを伝授します。

1. なぜ「ただのループ」では失敗するのか?

多くの初学者が最初に書くコードは、単純な `For Each` ループです。
「フォルダ内のファイルを探す」→「開く」→「保存する」→「閉じる」。
論理的には完璧に見えますが、実務(現場)ではこのコードは高確率で「AutoCADのフリーズ」または「メモリ不足による強制終了」を引き起こします。

なぜでしょうか? 理由は、「オブジェクトのライフサイクル」を理解していないからです。

陥りやすい3つの罠

1. メモリの蓄積(メモリリーク):
図面を開いた後、適切に「Close」メソッドを呼び出し、そのオブジェクトをメモリから解放(Nothingを代入)しないと、AutoCADは開いた図面の残骸をメモリに抱え込み続け、次第に動作が重くなり、最終的にクラッシュします。
2. UI(ユーザーインターフェース)の占有:
`Documents.Open` を実行すると、通常は画面がパカパカと切り替わり、ユーザーは作業ができなくなります。これを「バックグラウンド実行感」を持たせるように制御するのがプロの技です。
3. エラーハンドリングの欠如:
途中で一つでも「読み取り専用」のファイルや「破損した」ファイルが混ざっていたら? ループが止まってしまい、それまでの作業が水の泡になります。

これらをクリアして初めて、あなたは「マクロ使い」から「自動化エンジニア」へと昇格できるのです。

2. 魂のコード:最新形式への一括変換エンジン

それでは、実戦でそのまま使えるコードを見ていきましょう。
このコードは、`FileSystemObject` を使ってファイルを制御し、エラーが発生しても止まらずに次のファイルへ進む「堅牢な設計」になっています。

Option Explicit

' ==============================================================================
' 目的: 指定フォルダ内の全てのDWGファイルを最新の2018形式(AC1032)へ一括変換する
' 設計思想: オブジェクトの確実な解放と、エラー発生時のスキップ処理による堅牢性の確保
' ==============================================================================

Sub BatchUpgradeDWGTo2018()
    Dim fso As Object
    Dim targetFolder As Object
    Dim fileItem As Object
    Dim dwgDoc As AcadDocument
    Dim folderPath As String
    Dim fileCount As Integer
    Dim successCount As Integer
    Dim errorCount As Integer

    ' --- 設定エリア ---
    ' 処理したい図面が入っているフォルダのパスを指定してください
    folderPath = "C:\Users\YourName\Desktop\TestDWG\" 
    ' ------------------

    ' FileSystemObjectの生成(ファイル操作のプロフェッショナルツール)
    Set fso = CreateObject("Scripting.FileSystemObject")

    ' フォルダの存在確認
    If Not fso.FolderExists(folderPath) Then
        MsgBox "指定されたフォルダが見つかりません: " & folderPath, vbCritical
        Exit Sub
    End If

    Set targetFolder = fso.GetFolder(folderPath)
    
    ' 画面更新の抑制(ユーザーへの視覚的負荷を軽減)
    ' ※AutoCAD VBAでは完全に隠すことは難しいが、処理速度に寄与する
    Application.Visible = True ' 動作確認のためTrueにしていますが、プロは状況に応じて制御します
    
    fileCount = 0
    successCount = 0
    errorCount = 0

    Debug.Print "--- バッチ処理開始 ---"

    ' フォルダ内の全ファイルをループ
    For Each fileItem In targetFolder.Files
        ' 拡張子が .dwg かどうかを判定 (大文字小文字を区別しない)
        If LCase(fso.GetExtensionName(fileItem.Path)) = "dwg" Then
            
            fileCount = fileCount + 1
            Debug.Print "処理中 [" & fileCount & "]: " & fileItem.Name

            ' エラーハンドリング開始
            On Error Resume Next
            
            ' 1. 図面を開く
            Set dwgDoc = Documents.Open(fileItem.Path)
            
            If Err.Number <> 0 Then
                Debug.Print "  [Error] 開けませんでした: " & Err.Description
                errorCount = errorCount + 1
                Err.Clear
            Else
                ' 2. 最新の2018形式で保存 (ac2018DWG = 2018形式)
                ' SaveAsの引数は、AutoCADのバージョンによって定数が異なります。
                ' ここでは、最も汎用的な「名前を付けて保存」のロジックを適用。
                
                ' 注意: dwgDoc.SaveAs は、新しいファイル形式を指定する必要があります。
                ' 2018形式への変換を行うための定数指定
                ' ※AutoCADのバージョンにより定数名が異なる場合があるため、
                ' 直接ファイルパスを指定して保存する手法が最も安全です。
                
                dwgDoc.SaveAs fileItem.Path ' 現在のパスで上書き保存(形式はAutoCADの設定に依存)
                
                ' もし特定のバージョンを強制したい場合は、
                ' SaveAs の引数にファイル形式の定数を渡します。
                ' 例: dwgDoc.SaveAs fileItem.Path, ac2018DWG 
                
                If Err.Number <> 0 Then
                    Debug.Print "  [Error] 保存に失敗しました: " & Err.Description
                    errorCount = errorCount + 1
                    Err.Clear
                Else
                    successCount = successCount + 1
                    Debug.Print "  [Success] 完了"
                End If

                ' 3. 重要:オブジェクトを閉じて、メモリを解放する
                dwgDoc.Close acDocumentCloseSaveNo ' すでにSaveAsしているので、保存せずに閉じる
                Set dwgDoc = Nothing
            End If
            
            On Error GoTo 0 ' エラーハンドリングをリセット
        End If
    Next fileItem

    ' --- 終了処理 ---
    Set targetFolder = Nothing
    Set fso = Nothing

    MsgBox "処理が完了しました!" & vbCrLf & _
           "総ファイル数: " & fileCount & vbCrLf & _
           "成功: " & successCount & vbCrLf & _
           "失敗: " & errorCount, vbInformation, "実行結果"

    Debug.Print "--- バッチ処理終了 ---"
End Sub

3. プロの視点:コードを解剖する

このコードが、なぜ単なる「記録」と違うのか。その核心を解説します。

① FileSystemObject (FSO) の採用

`Dir` 関数ではなく `FileSystemObject` を使っています。これは、ファイル名だけでなく「フォルダの存在確認」「拡張子の判定」「ファイル属性の取得」を極めて高い信頼性で行うためです。実務レベルの自動化では、ファイル操作の正確性が命です。

② `On Error Resume Next` の戦略的配置

ここが重要です。エラーが発生した瞬間にマクロが止まってしまうと、100個中1個のファイルが原因で、残り99個の処理が止まってしまいます。
私は、「エラーが起きても、それを記録して次のファイルへ進む」という設計にしています。これが「止まらないシステム」の基本です。

③ オブジェクトの完全な破棄

`Set dwgDoc = Nothing`。
これを忘れることは、エンジニアとして致命的なミスです。図面オブジェクトをメモリから明示的に解放することで、大量のファイル処理を行っても、AutoCADが重くなったり落ちたりすることを防いでいます。

4. 実務で陥りやすい「落とし穴」と回避策

このコードを運用するにあたって、以下の点に注意してください。

  • ファイルが「読み取り専用」の場合:

サーバー上の図面を直接処理しようとすると、書き込み権限がなくエラーになります。事前にローカルフォルダにコピーしてから実行するのが、最もスマートで安全なワークフローです。

  • AutoCADの「ダイアログボックス」:

AutoCADの設定で「保存時にダイアログを表示する」設定になっていると、マクロがダイアログで止まってしまいます。実行前に `FILEDIA` システム変数を `0` に設定する処理をコードに加えると、より完璧になります。

  • ObjectDBX という「真の裏技」:

もしあなたが「画面を一切動かさず、もっと高速に処理したい」と願うなら、次に学ぶべきは ObjectDBX という技術です。これは図面を「開かずに」メモリ上だけで操作するAPIです。VBAでも利用可能ですが、少しだけ難易度が上がります。今回の `Documents.Open` は、そのための第一歩です。

最後に:自動化のその先へ

ここまで読んでくれたあなたは、もう単なる「マクロの利用者」ではありません。
「どうすればシステムが安定して動くか?」「どうすればユーザーにストレスを与えないか?」を考えられる、設計者(アーキテクト)の思考を持ち始めています。

プログラミングは、単に命令を並べることではありません。「例外(エラー)をいかにコントロールするか」。これこそが、プロフェッショナルの境界線です。

このコードをベースに、自分なりの改良を加えてみてください。
「もし、変換した後にログファイルを出力したらどうなるだろう?」
「もし、特定のレイヤーがある図面だけを抽出したら?」

その好奇心こそが、あなたを伝説のエンジニアへと導くのです。
応援していますよ。さあ、コードを書き始めましょう!

タイトルとURLをコピーしました