【テクニカル・上級編】【実務中級者向け】図面保存時の「サムネイルプレビュー」をあえて非表示にする:ファイルサイズ削減と保存速度向上のためのVBA設定 – AutoCAD VBA解析バイブル

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

GUIの罠を排せ:THUMBSAVE制御によるDWG I/Oの極限最適化

エンジニアが「便利さ」という名の甘い罠に落ちたとき、システムのパフォーマンスは静かに、しかし確実に死へと向かう。

AutoCADにおける「サムネイルプレビュー」は、Windowsエクスプローラー上で図面の内容を視覚的に把握するための、ユーザーフレンドリーな機能だ。しかし、数千、数万の図面をネットワークストレージ(NAS/SAN)上で管理し、それをバッチ処理や自動化サーバーで回している実務の最前線において、この「親切心」は致命的なオーバーヘッドへと変貌する。

本稿では、システム変数`THUMBSAVE`を極限まで制御することで、DWGファイルのI/O負荷を最小化し、保存速度を劇的に向上させるためのアーキテクチャ的アプローチを詳解する。

1. 隠れたボトルネック:THUMBSAVEの正体

DWGファイル構造において、サムネイル画像はファイル末尾付近に埋め込まれるバイナリデータである。`THUMBSAVE`システム変数が`1`(デフォルト)に設定されている場合、`SAVE`コマンドを実行するたびに、AutoCADは現在のビューポートからビットマップを生成し、それをファイル構造内に書き込む。

一見、微々たる差に見えるだろう。しかし、以下の条件が重なったとき、その影響は指数関数的に増大する。

1. ネットワークレイテンシ: ファイルがローカルディスクではなく、SMB/NFS経由のネットワークストレージにある場合、追加のバイナリデータの転送はパケット数の増加を意味し、ネットワークのコンテンション(競合)を招く。
2. ファイルサイズの肥大化: 大規模な図面において、サムネイルが追加されるたびにファイルサイズが数MB単位で増加し続けるケースがある。これはストレージ容量を圧迫するだけでなく、バックアップや同期プロセスの負荷を増大させる。
3. バッチ処理の並列性: 数百の図面を自動処理する際、各プロセスがこの「不要な書き込み」を行うことで、ストレージのI/O待ち(I/O Wait)が発生し、全体の処理時間が大幅に遅延する。

我々が目指すべきは、「人間が見るための情報を、マシンが書くプロセスから切り離す」ことである。

2. 実装戦略:ステート管理を伴うセーフ・セーブ・パターン

単に`THUMBSAVE`を`0`に書き換えるだけでは、不完全な実装と言わざるを得ない。プロフェッショナルな自動化コードにおいては、「実行環境の整合性を維持すること」が絶対条件である。

つまり、処理中のみ設定を変更し、処理完了後には元のユーザー設定に確実に復元する「ステート管理」が必要不可欠となる。これを怠れば、自動化ツールを動かした後に、ユーザーが「エクスプローラーで図面が見えなくなった」とクレームを入れてくる事態を招く。

以下に、その極限のコード例を示す。

'==============================================================================
' Module: OptimizationModule
' Description: THUMBSAVEを制御し、I/O負荷を最小化した保存プロセスを実行する
'==============================================================================

Option Explicit

''' <summary>
''' サムネイル生成を無効化した状態で図面を高速保存する
''' </summary>
''' <param name="savePath">保存先のフルパス</param>
Public Sub OptimizedSave(ByVal savePath As String)
    Dim originalThumbsave As Integer
    Dim acadDoc As AcadDocument
    Set acadDoc = ThisDrawing

    On Error GoTo ErrorHandler

    ' 1. 現在のシステム変数の状態を退避(ステートの保存)
    originalThumbsave = acadDoc.GetVariable("THUMBSAVE")

    ' 2. 高速化のためのチューニング
    ' THUMBSAVE = 0 : サムネイルを保存しない。これにより書き込みデータ量を削減。
    acadDoc.SetVariable "THUMBSAVE", 0
    
    ' 必要に応じて他のシステム変数も調整(例: 画面更新の停止)
    ' acadDoc.SetVariable "REGENMODE", 0 

    Debug.Print "Optimization applied: THUMBSAVE set to 0"

    ' 3. 保存実行
    ' 注意: ネットワーク越しの保存時は、ファイルロックに注意が必要
    acadDoc.SaveAs savePath

    Debug.Print "Optimized save completed: " & savePath

CleanUp:
    ' 4. 環境の復元(ステートの復元)
    ' ユーザーの利便性を損なわないよう、必ず元の設定に戻す
    On Error Resume Next
    acadDoc.SetVariable "THUMBSAVE", originalThumbsave
    Debug.Print "Environment restored: THUMBSAVE set to " & originalThumbsave
    
    ' オブジェクトの明示的な解放(メモリリーク防止)
    Set acadDoc = Nothing
    Exit Sub

ErrorHandler:
    MsgBox "Critical Error during optimized save: " & Err.Description, vbCritical
    Resume CleanUp
End Sub

3. さらに高みへ:I/O同期とWindows APIによる確実な制御

ネットワークストレージへの保存において、VBAの`SaveAs`が完了した直後に次の処理(ファイルの移動や削除、または別のプロセスによる読み込み)に移ろうとすると、「ファイルが別のプロセスによって使用されています」というエラーに遭遇することがある。

これは、OSレベルでの「遅延書き込み(Delayed Write)」や、ネットワークプロトコルによるファイルハンドルの解放遅延が原因だ。シニアエンジニアであれば、単なるエラーハンドリングに留まらず、I/Oの完了を物理的に待機するロジックを組み込むべきである。

ここでは、`FileSystemObject`によるリトライロジック、あるいはWindows APIを用いたファイル属性の監視を検討する。

'==============================================================================
' Advanced Technique: I/O Synchronization
'==============================================================================

''' <summary>
''' ファイルが完全に解放され、書き込み可能になるまで待機する
''' </summary>
Private Sub WaitForFileRelease(ByVal filePath As String, ByVal timeoutSeconds As Integer)
    Dim fso As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    Dim startTime As Double
    startTime = Timer
    
    Do While Timer < startTime + timeoutSeconds
        On Error Resume Next
        ' ファイルを開こうとしてエラーが出なければ、ロックは解除されている
        Dim ts As Object
        Set ts = fso.OpenTextFile(filePath, 1) ' 読み取りモード
        If Err.Number = 0 Then
            ts.Close
            Exit Do
        End If
        On Error GoTo 0
        
        ' CPU負荷を抑えるための微小待機
        DoEvents
        Sleep 100 ' Windows APIのSleepを使用することを推奨
    Loop
End Sub

' ※ Sleep関数の宣言 (Standard Moduleの最上部に配置)
' Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)

4. アーキテクチャの結論

図面保存の最適化は、単なる「設定変更」ではない。それは、「アプリケーションの挙動を、インフラの特性に合わせて再設計する」というエンジニアリングそのものである。

  • ユーザー端末では、`THUMBSAVE = 1` を維持し、GUIの利便性を優先する。
  • 自動化サーバー・バッチ処理では、`THUMBSAVE = 0` を強制し、I/Oスループットを極限まで引き上げる。

この使い分けを、コードレベルでのステート管理によって実装すること。これこそが、レガシーなCAD環境をモダンなデータパイプラインへと昇華させる、我々プロフェッショナルの流儀である。

現場に立つ者は、常に「その1バイトが、ネットワークの向こう側でどのようなコストを支払っているか」を意識せよ。

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