【入門編】【上級】AutoCAD 202x系での「読み取り専用」図面を強制的に別名保存して編集ロックを解除 – AutoCAD VBA解析バイブル

スポンサーリンク

こんにちは!AutoCADの自動化ロードを歩む皆さん、日々の業務効率化お疲れ様です。優しく、そして時にはディープに、VBAの深淵をご案内する先輩エンジニアです。

実務でAutoCADのマクロを作っていると、必ずと言っていいほどぶつかる「壁」があります。それが「誰かが図面を開いていて、読み取り専用になっているから自動処理が止まってしまった!」という問題です。

共有サーバー上の図面を一括処理したいのに、誰かの離席のせいでマクロがエラーを吐いて止まる……。切ないですよね。

そこで今回は、AutoCAD 202x系にも完全対応した、「読み取り専用」図面を一時ファイル(テンポラリ)として別名保存(SaveAs)し、編集ロックをスマートに解除して処理を続行する高度なワークフローを解説します。

「難しそう……」と思うかもしれませんが、大丈夫。AutoCADのオブジェクトモデルが持つ「ある特有の振る舞い」を理解すれば、驚くほどエレガントに解決できます。「ここをクリアすれば、AutoCAD VBAの基本と応用はバッチリマスターできますよ!」という核心の技術を、一歩ずつ丁寧に紐解いていきましょう。

1. なぜ「読み取り専用」は厄介なのか?その裏に潜むファイルロックの仕組み

まず、AutoCADが図面を開くときの挙動を整理しましょう。

AutoCADで `project-A.dwg` を開くと、同じフォルダ内に `.dwl` および `.dwl2` という隠しファイル(ドキュメントロックファイル)が生成されます。これが「いま誰かがこの図面を編集していますよ」という印です。

この状態で別の人がその図面を開くと、AutoCADは自動的に「読み取り専用(ReadOnly)」として図面を開きます。

読み取り専用図面に対するVBAの限界

読み取り専用の図面(`AcadDocument`)に対して、VBAから以下のような操作を行おうとすると、無情にもエラーが発生します。

  • `ThisDrawing.Save`(上書き保存) → 「図面は書き込み禁止です」エラー
  • 図面内のオブジェクトの変更(画層の追加、文字の書き換えなど) → メモリ上では変更できても、最終的に保存できない

「じゃあ、一度閉じて、別の場所にコピーしてから開き直せばいいのでは?」と思うかもしれません。しかし、VBAを実行している「その図面自体」を閉じてしまうと、実行中のVBAマクロ自体も一緒に強制終了してしまうという致命的な罠があります。

ここで、AutoCADのオブジェクトライフサイクルを知り尽くしたプロならではの「コペルニクス的転回」が必要になります。

2. 魔法の解決策:`SaveAs` による「アクティブドキュメントのすり替え」

AutoCAD VBAにおける最高にエレガントな解決策。それは、「開いている読み取り専用図面を、その場でテンポラリパス(一時フォルダ)へ `SaveAs`(別名保存)する」という方法です。

実は、AutoCADには以下のような素晴らしい仕様があります。

> 【超重要仕様】
> アクティブな図面を `SaveAs` すると、AutoCADは「現在開いているドキュメントの正体を、保存先の新しいファイルへとシームレスに切り替える」
> そして、一時フォルダに保存された新しいファイルは、他人にロックされていないため、その瞬間に「読み取り専用」状態が解除され、自由に編集・保存が可能になる。

図解すると、以下のような美しい流れになります。

[ステップ 1: 読み取り専用で開く]
└─ 対象ファイル: server/project-A.dwg (ReadOnly = True)

[ステップ 2: VBAが読み取り専用を検知]

[ステップ 3: テンポラリフォルダへ SaveAs]
└─ 一時ファイル: C:/Temp/temp_xyz.dwg として保存
│ ★この瞬間、アクティブ図面の正体が temp_xyz.dwg に変化!
│ ★ReadOnly が False (編集可能) に自動昇格!

[ステップ 4: 自由に変更・保存・データ抽出]
└─ 編集ロックに邪魔されることなく、すべてのVBA自動処理が完遂する

この方法なら、マクロの実行スレッドを維持したまま、安全にロックを解除して処理を続けることができます。

3. 【実戦コード】読み取り専用を強制解除して処理を続行するVBAマクロ

それでは、実際のソースコードを見てみましょう。コピー&ペーストしてそのまま使えるように、実戦的なエラーハンドリングと、Windowsの一時フォルダ(テンポラリパス)を安全に取得するロジックを組み込んでいます。

Option Explicit

‘ Windows APIを使用してテンポラリパス(一時フォルダ)のパスを取得する関数
If VBA7 Then
Private Declare PtrSafe Function GetTempPath Lib “kernel32” Alias “GetTempPathA” ( _
ByVal nBufferLength As Long, ByVal lpBuffer As String) As Long
Else
Private Declare Function GetTempPath Lib “kernel32” Alias “GetTempPathA” ( _
ByVal nBufferLength As Long, ByVal lpBuffer As String) As Long
End If

Sub ForceUnlockAndProcess()
Dim doc As AcadDocument
Set doc = ThisDrawing ‘ 現在アクティブな図面を取得

Dim originalPath As String
originalPath = doc.FullName

MsgBox “現在の図面: ” & doc.Name & vbCrLf & _
“読み取り専用状態: ” & doc.ReadOnly, vbInformation, “処理開始”

‘ —- Step 1: 読み取り専用(ReadOnly)かどうかの判定 —-
If doc.ReadOnly Then
MsgBox “この図面は読み取り専用です。編集ロックを解除するため、テンポラリ領域へ退避します。”, vbInformation, “ロック検知”

‘ —- Step 2: テンポラリファイルのフルパスを生成 —-
Dim tempFolder As String
tempFolder = GetWindowsTempFolder()

‘ ユニークな一時ファイル名を生成(例: Temp_20231024_123045.dwg)
Dim tempFileName As String
tempFileName = “Temp_” & Format(Now, “yyyymmdd_hhmmss”) & “.dwg”

Dim tempFullPath As String
tempFullPath = tempFolder & tempFileName

‘ —- Step 3: SaveAsを実行して「編集可能状態」へ昇格させる —-
On Error GoTo Err_SaveAs

‘ ac2018_dwg 形式(AutoCAD 2018〜202x系共通の標準保存形式)で保存
‘ ※お使いのバージョンに合わせて適宜変更してください
doc.SaveAs tempFullPath, ac2018_dwg

On Error GoTo 0

‘ —- Step 4: 昇格成功の確認 —-
‘ この時点で、docはテンポラリファイルを指しており、ReadOnlyはFalseになっています
MsgBox “テンポラリへ退避完了!” & vbCrLf & _
“現在の図面パス: ” & doc.FullName & vbCrLf & _
“現在の読み取り専用状態: ” & doc.ReadOnly, vbInformation, “ロック解除成功”

Else
MsgBox “この図面は既に編集可能です。退避処理をスキップします。”, vbInformation, “通常処理”
End If

‘ —- Step 5: 本来やりたかった自動編集処理をここに記述 —-
‘ 例として、モデル空間に簡単な円を描画して保存してみます
On Error GoTo Err_Process

Dim circleObj As AcadCircle
Dim centerPoint(0 To 2) As Double
Dim radius As Double

centerPoint(0) = 0#: centerPoint(1) = 0#: centerPoint(2) = 0#
radius = 100#

‘ 円を追加(読み取り専用のままだと、最終的に保存できないが、今は保存可能!)
Set circleObj = doc.ModelSpace.AddCircle(centerPoint, radius)
circleObj.Update

‘ 編集した内容をテンポラリファイルに保存
doc.Save

MsgBox “図面の自動編集と一時保存が完了しました!” & vbCrLf & _
“保存先: ” & doc.FullName, vbInformation, “処理完了”

Exit Sub

‘ —- エラーハンドリング部 —-
Err_SaveAs:
MsgBox “テンポラリファイルへの保存に失敗しました。” & vbCrLf & _
“エラー内容: ” & Err.Description, vbCritical, “SaveAsエラー”
Exit Sub

Err_Process:
MsgBox “図面の編集処理中にエラーが発生しました。” & vbCrLf & _
“エラー内容: ” & Err.Description, vbCritical, “実行エラー”
Exit Sub
End Sub

‘ Windowsの一時フォルダパスを安全に取得するヘルパー関数
Private Function GetWindowsTempFolder() As String
Dim tempPath As String
Dim bufferSize As Long
Dim result As Long

bufferSize = 260
tempPath = String(bufferSize, Chr(0))
result = GetTempPath(bufferSize, tempPath)

If result > 0 Then
GetWindowsTempFolder = Left(tempPath, result)
Else
‘ 万が一APIが失敗した場合は、環境変数から取得を試みる
GetWindowsTempFolder = Environ(“TEMP”) & “\”
End If
End Function

4. コードの深層解説:プロがこだわる3つのポイント

このコードには、ただ「動くだけ」ではない、実務の過酷な環境に耐えるための設計思想が込められています。先輩として、特に注目してほしいポイントを3つ解説しますね。

① `ThisDrawing.SaveAs` の「DWGバージョン」指定

コード内で `ac2018_dwg` という定数を指定しています。
AutoCAD 2018から最新の202x系までは、図面形式(DWGバージョン)が「2018形式」で共通化されています。VBAで `SaveAs` を行う際は、この保存形式を明示的に指定しないと、古いバージョン形式で保存されてデータが一部欠落したり、予期せぬ保存エラーが発生したりする原因になります。

② Windows APIによる安全なテンポラリパスの取得

一時ファイルの保存先を `C:\Temp` などとハードコーディング(直接記述)するのは厳禁です。ユーザーのPC環境によっては、そのフォルダが存在せず、マクロが途中でクラッシュしてしまいます。
Windows APIの `GetTempPath` を呼び出すことで、どのようなPC環境であっても、そのユーザーが確実に書き込み権限を持っている一時フォルダのパスを安全に取得しています。

③ 実行スレッドの維持

前述の通り、このアプローチの最大のメリットは、「現在のドキュメントを一度も閉じずに、その場で編集可能ドキュメントへと変身させている」点です。
もし「現在の図面を閉じて、新しく開く」というコードを書いてしまうと、その時点でVBAの実行エンジン自体が停止してしまい、その後の処理が走りません。オブジェクトのライフサイクルを理解しているからこそできる、スマートな回避策です。

5. 次のステップ:さらに業務を自動化するために

「読み取り専用の壁」を突破したあなた。これで、共有サーバー上の図面を巡回して、情報を書き換えたりPDFを書き出したりする「全自動バッチ処理マクロ」を作るための最大の難所をクリアしました!

今回のテクニックを応用すれば、以下のような強力なツールも作成可能です。

1. 図面情報の全自動回収ツール
誰かが編集中であっても、お構いなしにテンポラリに退避して図面内のタイトルブロック(属性文字)を読み込み、Excelへ書き出す。
2. バッチPDF出力マクロ
「読み取り専用」の図面であっても、一時的にローカルに保存して図面内のレイアウトを最新状態に更新し、PDFとして一括パブリッシュする。

「マクロの記録」から一歩踏み出し、AutoCADのオブジェクトモデル(`AcadApplication` や `AcadDocument`)を直接手なずけることができるようになると、あなたの開発効率は劇的に向上します。

もしコードを試してみて「うまく動いた!」「ここが少し分からない」といったことがあれば、ぜひ周りのエンジニア仲間とも議論してみてくださいね。

一歩一歩、本質を理解しながら進めば、AutoCAD VBAはあなたの最強の武器になります。これからも一緒に頑張っていきましょう!

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