【Architecture】コンプライアンスの防波堤:教育版スタンプ汚染を阻止する「ガード機能」の設計思想
商用プロジェクトを預かるエンジニアにとって、最も恐ろしいのは「コードのバグ」ではない。「法的な汚染」だ。
教育版(Student Version)で作成されたDWGファイルが、知らず知らずのうちに商用プロジェクトの図面データに混入し、それが納品物にまで波及する。この「教育版スタンプ」の混入は、企業の信頼を失墜させ、最悪の場合、法的な係争に発展するリスクを孕んでいる。
自動化ツールを作成するエンジニアの使命は、単なる「作業の高速化」ではない。「不適切な操作を物理的に不可能にする、堅牢なガードレールの構築」である。
本稿では、AutoCAD VBAを用い、図面オープン時に教育版の痕跡を検知し、商用ファイルへの保存を強制的にブロックする、プロフェッショナル向けの検知・防御システムの設計と実装について解説する。
1. 探知の戦略:どこに「痕跡」は隠れているか
「教育版スタンプ」を検知しようとする際、初心者は「図面内のテキストを探す」といった、あまりにも脆弱な手法に陥る。しかし、プロフェッショナルはオブジェクトのメタデータ層に目を向ける。
AutoCADの教育版は、以下のいずれかの方法で、その属性をファイル内に刻印している。
1. SummaryInfo(要約情報): `Document.SummaryInfo` 内のタイトル、主題、キーワード、または「コメント」欄への文字列挿入。
2. XData(拡張データ): 特定のエンティティ(ブロック定義やレイヤー)に紐付けられた、非表示のアプリケーション固有データ。
3. Custom Properties(カスタムプロパティ): 図面内の辞書(Dictionary)オブジェクトに格納された、非表示の属性値。
我々が構築すべきは、単一のチェックではなく、これらを多層的にスキャンする「マルチレイヤー・スキャン・エンジン」である。
2. システム設計:イベント駆動型ガードのアーキテクチャ
単に「検知して警告を出す」だけでは不十分だ。ユーザーが警告を無視して保存できてしまっては、ガードとしての機能を果たしていない。
設計思想は以下の3ステップで行う。
1. Intercept (捕捉): `Document_Open` イベントで、ファイルが読み込まれた瞬間にスキャンを実行。
2. Flag (状態保持): 検知した場合、そのドキュメントのメモリ上に「汚染フラグ(IsContaminated)」を保持。
3. Block (遮断): `Document_BeforeSave` イベントでフラグを確認。フラグが立っていれば、`Cancel = True` を返し、保存処理そのものを物理的に無効化する。
3. プロダクションコード:堅牢な検知・防御実装
以下に、実務に耐えうる構造化されたコードを示す。このコードは、単なるスクリプトではなく、エラーハンドリングとパフォーマンスを考慮した「モジュール」として設計している。
実装場所:`ThisDrawing` モジュール
`ThisDrawing` モジュールは、開いている図面固有のイベントをハンドリングするために必要だ。
Option Explicit
' --- コンプライアンス制御用定数 ---
Private Const STAMP_KEYWORD As String = "Educational" ' 検知対象のキーワード
Private Const LOG_FILE_PATH As String = "C:\Logs\AutoCAD_Compliance_Guard.log" ' 監査ログ
' --- 内部状態管理 ---
Private mIsContaminated As Boolean ' 汚染フラグ
' ==============================================================================
' 1. 図面オープン時の検知プロセス
' ==============================================================================
Private Sub Document_Open()
On Error GoTo ErrorHandler
mIsContaminated = False
' ステップ1: SummaryInfoのスキャン (低コスト・高効率)
If CheckSummaryInfoContamination() Then
mIsContaminated = True
End If
' ステップ2: 必要に応じてXData等のディープスキャンを実行
' ※パフォーマンスを考慮し、重いスキャンはフラグが立っていない場合のみ、
' または特定の条件(商用フォルダ内など)でのみ実行するように設計すべき
If mIsContaminated Then
MsgBox "【警告】この図面には教育版の痕跡が検知されました。" & vbCrLf & _
"商用プロジェクトへの保存は禁止されています。", vbCritical, "コンプライアンス違反検知"
' ここでログ出力を行う(後述)
WriteComplianceLog "Contamination detected on Open: " & ThisDrawing.Name
End If
Exit Sub
ErrorHandler:
' 検知エラー自体が業務を止めてはならない。エラーはログに残し、処理を続行する。
WriteComplianceLog "Error in Document_Open: " & Err.Description
End Sub
' ==============================================================================
' 2. 保存直前のブロックプロセス
' ==============================================================================
Private Sub Document_BeforeSave(Cancel As Boolean)
On Error GoTo ErrorHandler
' 汚染フラグが立っている場合、保存を強制的にキャンセルする
If mIsContaminated Then
MsgBox "【保存拒否】教育版の痕跡が含まれるファイルは保存できません。" & vbCrLf & _
"汚染されたデータを商用環境に持ち込むことは禁じられています。", vbCritical, "セキュリティ・ブロック"
Cancel = True ' AutoCADの保存プロセスを中断
WriteComplianceLog "Save attempt blocked for contaminated file: " & ThisDrawing.Name
End If
Exit Sub
ErrorHandler:
WriteComplianceLog "Error in Document_BeforeSave: " & Err.Description
End Sub
' ==============================================================================
' 3. 検知ロジック(詳細実装)
' ==============================================================================
Private Function CheckSummaryInfoContamination() As Boolean
Dim info As SummaryInfo
Set info = ThisDrawing.SummaryInfo
' 要約情報の各フィールドをスキャン
' 判定ロジックはプロジェクトの要件に合わせてチューニングすること
If InStr(1, info.Title, STAMP_KEYWORD, vbTextCompare) > 0 Or _
InStr(1, info.Subject, STAMP_KEYWORD, vbTextCompare) > 0 Or _
InStr(1, info.Keywords, STAMP_KEYWORD, vbTextCompare) > 0 Or _
InStr(1, info.Comments, STAMP_KEYWORD, vbTextCompare) > 0 Then
CheckSummaryInfoContamination = True
Else
CheckSummaryInfoContamination = False
End If
End Function
' ==============================================================================
' 4. 監査ログ出力(トレーサビリティの確保)
' ==============================================================================
Private Sub WriteComplianceLog(msg As String)
On Error Resume Next ' ログ出力失敗でメイン処理を止めないための鉄則
Dim fso As Object
Dim ts As Object
Set fso = CreateObject("Scripting.FileSystemObject")
' ログファイルへの追記モードでの書き込み
Set ts = fso.OpenTextFile(LOG_FILE_PATH, 8, True) ' 8 = ForAppending
ts.WriteLine "[" & Now & "] " & msg
ts.Close
Set ts = Nothing
Set fso = Nothing
End Sub
4. プロフェッショナルとしての設計上の注意点
このコードを実務に投入する際、エンジニアが遵守すべき「極限の知見」が3点ある。
① パフォーマンスの重み(Latency Management)
`Document_Open` は、ユーザーが図面を開くたびに実行される。ここで数万個のエンティティに対して `XData` を全スキャンするような実装を書けば、CADの操作性は致命的に低下する。
「軽量なメタデータチェック(SummaryInfo)を先行させ、疑わしい場合のみ重い処理を行う」という、ショートサーキット(短絡評価)の設計を徹底せよ。
② エラーハンドリングの「沈黙」と「記録」
検知ロジック内でエラーが発生した場合、そのエラーでAutoCAD自体がクラッシュしたり、図面が開けなくなったりしては本末転倒だ。
`On Error Resume Next` を多用するのは素人だが、「エラーをログに記録しつつ、メインの業務フローには影響を与えない(Fail-safe)」設計はプロの仕事だ。
③ ログの整合性と監査(Audit Trail)
「なぜ保存できなかったのか」という問い合わせが必ず来る。その際、エンジニアが「たぶん教育版だからです」と答えるのはプロ失格だ。
`WriteComplianceLog` を通じて、「いつ、どのファイルで、どのような検知が行われたか」を客観的な証拠として残す仕組みを組み込むこと。これが、システムを「ツール」から「統制手段」へと昇華させる。
結びに代えて
自動化エンジニアの真価は、ユーザーが「できてしまうこと」を「できないようにする」設計能力に宿る。
このガード機能は、単なるプログラムではない。企業のコンプライアンスを守り、エンジニアのキャリアを守るための、デジタルな防護壁である。
設計に魂を込めろ。コードに責任を持て。
