【入門編】【上級プロフェッショナル向け】DXF保存時の精度(小数点以下桁数)をシステム変数とVBAで最適化し容量を削減する – AutoCAD VBA解析バイブル

スポンサーリンク

こんにちは!AutoCAD VBAの世界へようこそ。
日々、膨大な図面データと格闘しているあなたなら、「DXFファイルを開いたら、容量がやたらと大きくてフリーズしそうになった…」なんて経験、一度や二度ではないはずです。

データ交換の標準フォーマットであるDXFですが、デフォルトのまま保存すると、「人間には到底認識できない小数点以下12桁の座標値」まで律儀に記録されてしまいます。これがファイル肥大化の元凶です。

今回は、プロの現場で即座に使える、「VBAでシステム変数を操り、DXFの精度を極限まで削ぎ落として軽量化する技術」を伝授します。ここをクリアすれば、単なる「マクロの記録が使えるレベル」から、AutoCADのエンジンを手のうちに入れた「真の自動化エンジニア」への扉が開きますよ。さあ、一緒に本質を学んでいきましょう!

—

なぜDXFの「精度(小数点以下桁数)」が問題になるのか?

AutoCADは内部で倍精度浮動小数点数(Double型)を使ってすべての座標や寸法を管理しています。これはCADとしては当然の設計ですが、他システム(CAMやGIS、Webブラウザ上のビューアなど)へデータを渡す際、この「過剰な精度」は百害あって一利なしです。

  • 通信の遅延: クラウドストレージやメールでのやり取りが重くなる。
  • メモリの圧迫: パースや読み込み時の処理コストが増大する。

そこで重要になるのが、「図面の用途に必要な最低限の精度(小数点以下〇桁)に丸めて保存する」というアプローチです。これをVBAで完全自動化します。

—

鍵を握るシステム変数:`AFLAGS` と `DWGCODEPAGE`…ではなく!

実は、DXF保存時の実数精度を直接制御するVBAの専用メソッド(`SaveAs` のオプションなど)は、AutoCADの標準オブジェクトモデルには用意されていません。

ここで登場するのが、AutoCADの根底を支えるシステム変数です。
DXF出力時の浮動小数点数の出力精度は、主に以下のシステム変数によってコントロールされます。

1. `LUNITS`(線分単位 形式): 単位の種類(小数, 建築, 工学など)
2. `LUPREC`(線分単位 精度): 小数点以下の表示桁数(0〜8)

「ななんだ、`LUPREC`を変えるだけか」と思いましたね?
甘い。それだけでは実務の現場で致命的なエラーを踏みます。なぜなら、システム変数を変更するということは、「元の図面のデータベースそのものを書き換えてしまうリスク」を伴うからです。

プロフェッショナルは、「処理の直前で安全に環境を退避させ、爆速でDXF出力を行い、何事もなかったかのように元の状態へ復元する」というライフサイクル管理をコードに組み込みます。

—

実践!超軽量DXF出力マクロの全コード

それでは、現場でそのままコピペして使える実践的なVBAコードを公開します。
このコードは、現在の図面を指定した精度(例:小数点以下2桁)に一時的に最適化し、軽量なDXFとして別名保存するプロシージャです。

Sub ExportOptimizedDXF()
Dim targetPath As String
Dim originalLuprec As Integer
Dim originalAtel As Integer

‘ エラーハンドリングの準備(異常終了時に環境が戻らないを防ぐ)
On Error GoTo ErrorHandler

‘ 1. 保存先のパスを設定(例: デスクトップの “optimized_drawing.dxf”)
targetPath = CreateObject(“WScript.Shell”).SpecialFolders(“Desktop”) & “\optimized_drawing.dxf”

‘ 2. 現在のシステム変数を退避(ここがプロの技!)
‘ LUPREC: 座標や寸法の小数点以下の桁数を保持する変数
originalLuprec = ThisDrawing.GetVariable(“LUPREC”)

‘ 3. 精度を意図的に落とす(例: 小数点以下「2桁」に絞る)
‘ ※製造業の厳密なミクロン単位の加工でなければ、大抵は2〜3桁で十分です
ThisDrawing.SetVariable “LUPREC”, 2

‘ 4. 画面更新をロックして実行速度を極限まで引き上げる
ThisDrawing.Application.ScreenUpdating = False

‘ 5. DXF形式で保存
‘ 引数: 保存パス, ファイルフォーマット (acR12DXF, ac2018DXF など)
‘ ※ここでは互換性が最も高い AutoCAD 2004 DXF (ac2004DXF) を例に取ります
ThisDrawing.SaveAs targetPath, ac2004DXF

‘ 6. 退避させていたシステム変数を元に戻す(環境の完全復元)
ThisDrawing.SetVariable “LUPREC”, originalLuprec

‘ 7. 画面更新を解除
ThisDrawing.Application.ScreenUpdating = True

MsgBox “軽量化DXFの出力が完了しました!” & vbCrLf & “保存先: ” & targetPath, vbInformation, “最適化完了”
Exit Sub

ErrorHandler:
‘ 万が一エラーが発生した場合でも、環境が破壊されないように必ず復元処理を通す
ThisDrawing.SetVariable “LUPREC”, originalLuprec
ThisDrawing.Application.ScreenUpdating = True
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical, “致命的なエラー”
End Sub

—

コードの深掘り:ここがエンジニアのこだわりポイント

初心者から一歩抜け出すために、上記のコードに散りばめられた「エンジニアの知見」を解説します。

① `On Error GoTo` によるトランザクション的思考

データベースを操作するプログラムで最も恐ろしいのは、途中でエラーが起きたときに「図面の精度が狂ったまま保存されてしまうこと」です。
上記のコードでは、エラーが発生しても必ず `ErrorHandler` ラベルにジャンプし、`originalLuprec`(元の精度)を復元するセーフティネットを張っています。これがプロのコードロジックです。

② `ScreenUpdating = False` によるパフォーマンス最適化

AutoCAD VBAにおいて、オブジェクトの操作やドキュメントの保存はグラフィック描画と密接に結びついています。保存の瞬間に画面描画をオフにすることで、わずかコンマ数秒の世界ですが、処理のっそり感を無くし、連続処理時のフリーズを防ぐことができます。

③ 最適なDXFバージョンの選択 (`ac2004DXF` など)

`SaveAs` メソッドの第二引数には、AutoCADのバージョンに応じた定数を指定できます。

  • `acR12DXF`: 最も古い形式ですが、データ構造が単純になるためファイルサイズが最小限になりやすい反面、一部のモダンな図形要素が消失します。
  • `ac2000DXF` / `ac2004DXF` / `ac2018DXF`: 近年のシステム連携であれば `ac2004DXF` あたりが、互換性とファイルサイズのバランスが最も優れています。

—

陥りやすい罠とトラブルシューティング

実際にこのコードを運用し始めると、いくつかの「罠」に直面することがあります。先輩からのアドバイスとして先回りしてお伝えしておきますね。

  • 罠1: 「あれ、寸法値が変わっちゃった!?」
  • 原因: `LUPREC` を下げたことで、図面上の寸法文字が「四捨五入」されて見た目が変わってしまうことがあります。
  • 対策: あくまで「保存用の別名ファイル(Export用)」としてこのマクロを走らせ、元の作業用DWGファイルはそのまま上書き保存しない(または閉じる際に保存しない)運用を徹底してください。
  • 罠2: 座標の丸め誤差(スナップ切れ)
  • 極端に精度を落としすぎると(例: `LUPREC = 0`)、隣接する線分の端点同士が微妙にズレて「隙間」が生まれることがあります。CADデータとして再利用するなら、最低でも `2`(小数点以下2桁)〜 `3` を死守ラインに設定しましょう。

—

おわりに:AutoCAD VBAの基本は「環境の支配」にある

お疲れ様でした!今回は単なるメソッドの呼び出しだけでなく、「システム変数の退避・変更・復元」という、AutoCADの裏側(データベース)をコントロールする技術に触れました。

ここをクリアしたあなたなら、単に画面をポチポチ操作するだけの自動化から、CADのライフサイクルそのものを手のうちに収めた「真の自動化エンジニア」としてのコードが書けるはずです。

現場の業務効率化に、ぜひこの軽量化テクニックを取り入れてみてください。「処理が劇的に速くなった!」と周囲を驚かせてやりましょう。
それでは、次回の応用講座でお会いしましょう!

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