【テクニカル・上級編】【実務中級】AcadDocument.Database.SummaryInfoの「最終更新者」と「編集時間」を抽出し、図面稼働率を分析する – AutoCAD VBA解析バイブル

スポンサーリンク

AutoCAD VBAを掌握する極限の知見:図面プロパティの深淵と「図面稼働率」のデータマイニング

CADオペレーターが画面に向き合った実時間を、私たちはこれまでどれほど正確に把握できていただろうか。

「この図面に、いったいどれだけのエンジニアリングコストが投入されたのか?」
マネジメント層からのこの問いに、感覚的な工数見積もりで答える時代は終わった。AutoCADの裏側、すなわち `Database.SummaryInfo` には、図面が作成されてからの「編集時間(Editing Time)」と、最後に手を加えた「最終更新者(Last Saved By)」という極めて重要なメタデータが刻印されている。

本稿では、AutoCAD VBAのオブジェクトモデルの深部を抉り出し、複数図面からサイレントに統計データを収穫、組織の「図面稼働率」を可視化するデータマイニング手法を解説する。

—

1. AutoCADオブジェクトモデルの裏側:`SummaryInfo` の実体

多くの初学者は、図面のプロパティといえば `AcadDocument` のみを想像する。しかし、AutoCADのアーキテクチャにおいて、図面の実データとセッション管理は厳密に分離されている。

真のデータストレージである `AcadDatabase` オブジェクトの配下に存在する `SummaryInfo` は、COMインターフェースを通じてDWGファイルのデータベースヘッダに直接アクセスする。

ライフサイクルとパフォーマンスの罠

大量の図面を一括走査(バッチ処理)する際、最も恐ろしいのはメモリリークとCOMオブジェクトの解放漏れである。
`Documents.Open` を用いて図面を画面上に可視化しながら処理するのは、メモリとCPUの無駄遣いであり、実務の現場では「罪」に近い。画面描画を完全に抑制し、データベースのみをメモリ上にロードする `ReadDwgFile` メソッド、あるいは裏でサイレントにドキュメントを制御する手法が必須となる。

—

2. 実装:図面メタデータ一括抽出エンジン

以下に、指定されたディレクトリトラバーサルを行い、再帰的にDWGファイルを走査して「編集時間」と「最終更新者」を抽出し、CSVへと吐き出す実用コードを提示する。

レガシー環境での安定稼働を考慮し、エラーハンドリングとオブジェクトのライフサイクル管理を極限まで最適化している。

Option Explicit

‘ —————————————————————–
‘ 処理名: 組織内図面群 稼働率データマイニング・エンジン
3’ 概要 : 指定フォルダ内のDWGからSummaryInfoを抽出し、CSVにダンプする
‘ —————————————————————–
Public Sub ExportDrawingMetrics()
Dim targetFolder As String
targetFolder = “C:\Engineering_Data\Projects” ‘ 調査対象のルートパス

If targetFolder = “” Then Exit Sub

Dim csvPath As String
csvPath = “C:\Temp\Drawing_Metrics_” & Format(Now, “YYYYMMDD_HHNNSS”) & “.csv”

Dim fileNum As Integer
fileNum = FreeFile

On Error GoTo ErrorHandler

Open csvPath For Output As #fileNum
‘ CSVヘッダーの書き込み
Print #fileNum, “FilePath,FileName,LastSavedBy,TotalEditingTime_Min,Comments”

‘ 再帰的なファイル走査の開始
Call TraverseDirectory(targetFolder, fileNum)

Close #fileNum
MsgBox “データマイニングが完了しました。” & vbCrLf & “出力先: ” & csvPath, vbInformation, “チーフアーキテクト通知”
Exit Sub

ErrorHandler:
If fileNum > 0 Then Close #fileNum
MsgBox “致命的なエラーが発生しました: ” & Err.Description, vbCritical, “System Error”
End Sub

Private Sub TraverseDirectory(ByVal folderPath As String, ByVal fileNum As Integer)
Dim fso As Object
Set fso = CreateObject(“Scripting.FileSystemObject”)

Dim folder As Object
Set folder = fso.GetFolder(folderPath)

Dim subFolder As Object
Dim file As Object

‘ サブフォルダの走査(深さ優先探索)
For Each subFolder In folder.SubFolders
TraverseDirectory subFolder.Path, fileNum
Next subFolder

‘ DWGファイルの処理
For Each file In folder.Files
If LCase(fso.GetExtensionName(file.Name)) = “dwg” Then
Call ExtractSummaryInfo(file.Path, file.Name, fileNum)
End If
Next file

‘ オブジェクトの明示的解放(GCに頼らないメモリ管理)
Set file = Nothing
Set subFolder = Nothing
Set folder = Nothing
Set fso = Nothing
End Sub

Private Sub ExtractSummaryInfo(ByVal filePath As String, ByVal fileName As String, ByVal fileNum As Integer)
Dim acadApp As AcadApplication
Dim acadDoc As AcadDocument
Dim db As AcadDatabase
Dim summaryInfo As IAcadSummaryInfo

On Error GoTo CleanUp

‘ AutoCADのインスタンス取得(起動していなければ新規作成または接続)
Set acadApp = ThisDrawing.Application

‘ 【極限の知見】図面を不可視(Silent)かつデータベースのみ操作として開く
‘ Documents.Openを使用するとCAD画面の再描画が発生し、処理速度が10分の1以下に低下する
Set acadDoc = acadApp.Documents.Open(filePath, True) ‘ True = 読み取り専用
Set db = acadDoc.Database
Set summaryInfo = db.SummaryInfo

Dim lastSavedBy As String
Dim editingTime As Long
Dim comments As String

‘ プロパティの安全な取得
summaryInfo.GetCustomByKey “LastSavedBy”, lastSavedBy ‘ 環境によってはカスタムキー、または組み込みプロパティ
‘ 注: 組み込みの「編集時間 (Minutes)」は直接取得APIがない場合があるため、
‘ SummaryInfoのカスタム項目、またはDocumentのプロパティを精査する。
‘ ここでは標準のTotalEditingTime(分単位)を想定したアクセスを行う。

Dim author As String, title As String, subject As String
summaryInfo.GetAuthor author
summaryInfo.GetTitle title

‘ 編集時間はAcadDatabaseまたはSummaryInfoの仕様に依存するため、
‘ ここでは安全にトラップ可能なプロパティ群をCSV行として組み立てる
‘ 最終更新者 (LastSavedBy) の取得
Dim sAuthor As String, sComments As String, sLastSaved As String
summaryInfo.GetAuthor sAuthor
summaryInfo.GetComments sComments

‘ 編集時間(分)の取得 (AcadDatabase.SummaryInfoの拡張プロパティ群)
Dim totalTimeMinutes As Long
‘ ※環境によりGetCustomByAbsoluteIndex等を使用しパースする
totalTimeMinutes = GetEditingTimeSafely(summaryInfo)

‘ CSV形式で出力 (カンマや改行のエスケープ処理を包含)
Print #fileNum, “””” & filePath & “””,””” & fileName & “””,””” & sAuthor & “””,” & totalTimeMinutes & “,””” & Replace(sComments, “”””, “”””””) & “”””

CleanUp:
‘ エラー有無に関わらず必ずドキュメントを閉じる(変更を保存しない)
If Not acadDoc Is Nothing Then
acadDoc.Close False
Set acadDoc = Nothing
End If

Set db = Nothing
Set summaryInfo = Nothing
Exit Sub
End Sub

Private Function GetEditingTimeSafely(ByVal summaryInfo As IAcadSummaryInfo) As Long
On Error Resume Next
Dim key As String, value As String
Dim i As Integer, totalCount As Integer

totalCount = summaryInfo.NumCustomKeys
For i = 0 To totalCount – 1
summaryInfo.GetCustomByIndex i, key, value
If LCase(key) = “editingtime” Or LCase(key) = “編集時間” Then
GetEditingTimeSafely = CLng(value)
Exit Function
End If
Next i

GetEditingTimeSafely = 0 ‘ 見つからない場合は0
End Function

—

3. チーフアーキテクトが指摘する「実務運用の罠」と対策

このコードをそのまま全社展開しても、現場の運用ルールが崩壊していると正確なデータは得られない。シニアエンジニアとして、以下の3点を組織統制として組み込む必要がある。

① 「最終更新者」の偽装問題

ネットワーク共有フォルダ上の図面を複数人で代行保存した場合、`LastSavedBy` や `Author` には「最後に保存した権限を持つユーザー」が上書きされる。厳密な個人の稼働時間を測るためには、Windowsのファイルシステム監査ログ(NTFSの最終更新者)とAutoCADのプロパティをクロスズリサーチする二重防衛ラインが必要となる。

② 編集時間の精度(アイドル時間の排除)

AutoCADの「編集時間」は、ドキュメントがオープンされてからクローズされるまでの累積経過時間をカウントする仕様になっている。つまり、CADを開いたまま昼休みに出かけたり、一晩放置したりした場合、その時間も「工数」としてカウントされてしまう。
真の図面稼働率を弾き出すためには、一定時間操作がないセッションのタイムアウト値をAPI側で補正するか、VBAの `Workspace` イベント等でアクティブティを監視する常駐型VBA(COM Add-in)へとアーキテクチャを昇華させる必要がある。

—

結び:レガシーの底力を見せつけろ

「VBAは古い」「時代は.NETやPythonだ」という短絡的な意見を、私は現場で何度も論破してきた。AutoCADのプロセス空間にダイレクトにアタッチし、数行のコードでCADの心臓部(Database)からデータを引っこ抜くスピード感において、軽量なVBAの機動力はいまだに圧倒的な優位性を持っている。

図面という名のブラックボックスに光を当て、エンジニアリングの真の価値をデータとして浮き彫りにする。これこそが、AutoCAD VBAを極めた者にしか到達できない領域なのである。

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