【テクニカル・上級編】【上級プロ向け】外部リレーショナルデータベース(SQL Server)と完全同期した社内ベクターアセット管理・自動保存システムの構築とバージョン管理基盤 – CorelDRAW VBA解析バイブル

スポンサーリンク

CorelDRAW VBA × SQL Server:極限のエンタープライズ・ベクターアセット同期&バージョン管理システム

グラフィックスデザインや製造・製版ラインの現場において、CorelDRAWは単なる描画ツールではなく、基幹システムを構成する重要なエンジンです。しかし、多くの現場では、作成されたアセット(`.cdr` ファイルやテンプレート)がローカルや共有ネットワークフォルダに散逸し、最新版の喪失、重複作成、メタデータの不整合といった「アセット管理の崩壊」に直面しています。

本極限解説では、CorelDRAWの内蔵VBA(Visual Basic for Applications)環境から直接、外部のリレーショナルデータベース(Microsoft SQL Server)と接続し、ベクターアセットのメタデータおよびバイナリデータ(BLOB)をリアルタイムで完全同期・バージョン管理する「エンタープライズ・アセット同期システム」の構築法を解説します。

単なる「ファイル保存のマクロ」ではありません。Windows APIによる厳密なファイル制御、ADODBによる高速BLOBトランザクション、そしてCorelDRAW特有のメモリリークを回避するオブジェクト・ライフサイクル管理までを網羅した、実戦仕様のアーキテクチャを提示します。

—

1. システムアーキテクチャの全体像

本システムは、CorelDRAWクライアント、Windows OS(Win32/64 API)、そしてバックエンドのSQL Serverの3つのレイヤーで構成されます。

+————————————————————-+
| CorelDRAW Client |
| +——————————————————-+ |
| | VBA Core Engine | |
| | – ActiveDocument Control – Transaction Manager | |
| | – Windows API File I/O – ADODB.Stream (BLOB) | |
| +——————————————————-+ |
+——————————+——————————+
| (ADO / OLE DB)
v
+————————————————————-+
| SQL Server Database |
| +——————-+ +——————-+ |
| | AssetMaster | <===========> | AssetHistory | |
| | (Metadata) | (Foreign Key) | (BLOB / Ver) | |
| +——————-+ +——————-+ |
+————————————————————-+

解決すべき技術的課題

1. メモリプレッシャー: 数十MB〜数百MBに及ぶベクターデータをVBAの貧弱なメモリ空間でどう扱うか。
2. トランザクションの整合性: DB側のレコード登録と、物理ファイル/バイナリの書き込みが完全に一致すること(片方だけの失敗を防ぐ)。
3. CorelDRAWのゾンビプロセス化防止: COMオブジェクトの参照カウントをゼロに引き下げ、強制終了やリークを防ぐ。

—

2. SQL Server データベース設計(DDL)

まずはバックエンドとなるSQL Serverのスキーマを定義します。アセットの「基本情報(Master)」と「実データ・履歴(History)」を1:Nの関係に分離し、インデックスと外部キーを厳密に構成します。

— アセットマスタテーブル
CREATE TABLE dbo.AssetMaster (
AssetID INT IDENTITY(1,1) NOT NULL,
AssetCode NVARCHAR(100) NOT NULL,
AssetName NVARCHAR(255) NOT NULL,
Category NVARCHAR(50) NULL,
CreatedBy NVARCHAR(100) NOT NULL DEFAULT (SUSER_SNAME()),
CreatedAt DATETIME2 NOT NULL DEFAULT (SYSDATETIME()),
UpdatedAt DATETIME2 NOT NULL DEFAULT (SYSDATETIME()),
CONSTRAINT PK_AssetMaster PRIMARY KEY CLUSTERED (AssetID),
CONSTRAINT UQ_AssetMaster_AssetCode UNIQUE (AssetCode)
);

— アセット履歴・バイナリ格納テーブル(BLOB)
CREATE TABLE dbo.AssetHistory (
HistoryID INT IDENTITY(1,1) NOT NULL,
AssetID INT NOT NULL,
FileVersion INT NOT NULL,
BinaryData VARBINARY(MAX) NOT NULL, — .cdrファイルの実データ
FileHash CHAR(64) NOT NULL, — 重複検知用のSHA-256ハッシュ
CommitComment NVARCHAR(500) NULL,
CommittedBy NVARCHAR(100) NOT NULL DEFAULT (SUSER_SNAME()),
CommittedAt DATETIME2 NOT NULL DEFAULT (SYSDATETIME()),
CONSTRAINT PK_AssetHistory PRIMARY KEY CLUSTERED (HistoryID),
CONSTRAINT FK_AssetHistory_AssetMaster FOREIGN KEY (AssetID)
REFERENCES dbo.AssetMaster (AssetID) ON DELETE CASCADE,
CONSTRAINT UQ_AssetHistory_Version UNIQUE (AssetID, FileVersion)
);

— 検索用インデックスの設計
CREATE NONCLUSTERED INDEX IX_AssetMaster_AssetCode ON dbo.AssetMaster(AssetCode);
CREATE NONCLUSTERED INDEX IX_AssetHistory_AssetID_Version ON dbo.AssetHistory(AssetID, FileVersion DESC);

—

3. Windows APIによる厳密なファイル制御

VBA標準の `FileSystemObject` や `SaveAs` のデフォルト挙動は、システムの一時フォルダ名競合や共有ロックの解除遅延を引き起こします。これを完全に制御するため、Windows API(Kernel32)を用いて、一意なテンポラリファイルの生成と、確実なファイル削除を実行します。

標準モジュール(例:`mdlWinAPI`)に以下のAPI宣言とラッパー関数を定義します。

Option Explicit

If VBA7 Then
Private Declare PtrSafe Function GetTempPathLib Lib “kernel32” Alias “GetTempPathA” (ByVal nBufferLength As Long, ByVal lpBuffer As String) As Long
Private Declare PtrSafe Function GetTempFileNameLib Lib “kernel32” Alias “GetTempFileNameA” (ByVal lpszPath As String, ByVal lpPrefixString As String, ByVal uUnique As Long, ByVal lpTempFileName As String) As Long
Private Declare PtrSafe Function DeleteFileLib Lib “kernel32” Alias “DeleteFileA” (ByVal lpFileName As String) As Long
Else
Private Declare Function GetTempPathLib Lib “kernel32” Alias “GetTempPathA” (ByVal nBufferLength As Long, ByVal lpBuffer As String) As Long
Private Declare Function GetTempFileNameLib Lib “kernel32” Alias “GetTempFileNameA” (ByVal lpszPath As String, ByVal lpPrefixString As String, ByVal uUnique As Long, ByVal lpTempFileName As String) As Long
Private Declare Function DeleteFileLib Lib “kernel32” Alias “DeleteFileA” (ByVal lpFileName As String) As Long
End If

‘ 一意な一時ファイルパスを取得する
Public Function GetSecureTempFilePath(ByVal Prefix As String) As String
Dim tempPath As String 260
Dim tempFileName As String 260
Dim result As Long

result = GetTempPathLib(260, tempPath)
If result <> 0 Then
result = GetTempFileNameLib(Left(tempPath, result), Prefix, 0, tempFileName)
If result <> 0 Then
‘ Win32 APIはヌル終端文字列を返すため、トリミングが必要
GetSecureTempFilePath = Left(tempFileName, InStr(tempFileName, Chr(0)) – 1)
Exit Function
End If
End If
Err.Raise vbObjectError + 513, “mdlWinAPI”, “一時ファイルの生成に失敗しました。”
End Function

‘ 物理ファイルの強制削除(共有ロックをバイパスする安全な削除)
Public Function ForceDeleteFile(ByVal filePath As String) As Boolean
If Dir(filePath) <> “” Then
ForceDeleteFile = (DeleteFileLib(filePath) <> 0)
Else
ForceDeleteFile = True
End If
End Function

—

4. 極限のCorelDRAW VBA実装:アセット同期コアエンジン

本クラスモジュール `clsAssetSyncManager` は、SQL Serverとの接続、トランザクション管理、CorelDRAWのアクティブドキュメントのシリアライズ、およびBLOBとしてのデータベース送信を一挙に担います。

参照設定として以下が必要です:

  • Microsoft ActiveX Data Objects 6.1 Library (ADODB)
  • Microsoft XML, v6.0 (ハッシュ計算等で使用する場合)

クラスモジュール: `clsAssetSyncManager`

Option Explicit

Private Const CONNECTION_STRING As String = _
“Provider=MSOLEDBSQL;Data Source=YOUR_SERVER_NAME;Initial Catalog=YOUR_DB_NAME;Integrated Security=SSPI;”

Private m_Connection As ADODB.Connection

Private Sub Class_Initialize()
Set m_Connection = New ADODB.Connection
End Sub

Private Sub Class_Terminate()
On Error Resume Next
If Not m_Connection Is Nothing Then
If m_Connection.State = adStateOpen Then m_Connection.Close
Set m_Connection = Nothing
End If
End Sub

‘ データベースへの常時接続の確立(遅延バインディング回避)
Private Sub EnsureConnection()
If m_Connection.State = adStateClosed Then
m_Connection.Open CONNECTION_STRING
m_Connection.CommandTimeout = 60 ‘ 大容量データロードのためのタイムアウト延長
End If
End Sub

‘ — コアメソッド: アクティブドキュメントを新規アセット/新バージョンとして保存 —
Public Function CommitActiveDocument( _
ByVal AssetCode As String, _
ByVal AssetName As String, _
ByVal Category As String, _
ByVal Comment As String) As Boolean

Dim drawApp As CorelDRAW.Application
Dim activeDoc As CorelDRAW.Document
Dim tempFilePath As String
Dim fileHash As String
Dim fileBytes() As Byte

On Error GoTo ErrorHandler

Set drawApp = CorelDRAW.Application
Set activeDoc = drawApp.ActiveDocument

If activeDoc Is Nothing Then
Err.Raise vbObjectError + 1001, “AssetSync”, “アクティブなドキュメントが存在しません。”
End If

‘ CorelDRAWの描画・UIイベントを凍結し、処理スピードを極限まで高める
drawApp.Optimization = True
drawApp.EventsEnabled = False

‘ 1. 一時保存用ファイルのパスをAPIからセキュアに取得
tempFilePath = GetSecureTempFilePath(“CD_”)

‘ 2. ドキュメントを一時ファイルとしてサイレントエクスポート(SaveAs)
‘ ※ 既存の保存先パスを汚さず、バックグラウンドでのみバイナリ化
Dim saveSettings As CorelDRAW.StructSaveAsOptions
Set saveSettings = drawApp.CreateStructSaveAsOptions
With saveSettings
.EmbedStyles = True
.EmbedProfiles = True
.KeepMetadata = True
.Version = cdrCurrentVersion
End With

activeDoc.SaveAs tempFilePath, saveSettings
Set saveSettings = Nothing

‘ 3. 一時ファイルからバイナリデータを取得
fileBytes = ReadBinaryFile(tempFilePath)
fileHash = ComputeSHA256(fileBytes)

‘ 4. SQL Serverへの同期トランザクション開始
EnsureConnection
m_Connection.BeginTrans

Dim assetId As Long
assetId = GetOrCreateAssetID(AssetCode, AssetName, Category)

Dim nextVersion As Long
nextVersion = GetNextVersionNumber(assetId)

‘ 重複チェック(ハッシュ値の照合)
If IsDuplicateHash(assetId, fileHash) Then
m_Connection.RollbackTrans
MsgBox “このアセットの同一バイナリが既にデータベースに登録されています。保存をスキップしました。”, vbInformation, “同期システム”
CommitActiveDocument = False
GoTo CleanExit
End If

‘ BLOBデータの挿入処理
InsertAssetHistory assetId, nextVersion, fileBytes, fileHash, Comment

‘ すべての処理が成功した場合にのみコミット
m_Connection.CommitTrans
CommitActiveDocument = True

CleanExit:
‘ 描画・UIイベントの復元
drawApp.Optimization = False
drawApp.EventsEnabled = True

‘ 後処理:一時ファイルの抹消とメモリ解放
If tempFilePath <> “” Then ForceDeleteFile tempFilePath
Erase fileBytes
Set activeDoc = Nothing
Set drawApp = Nothing
Exit Function

ErrorHandler:
Dim errDesc As String
errDesc = Err.Description
On Error Resume Next
If Not m_Connection Is Nothing Then
If m_Connection.State = adStateOpen Then m_Connection.RollbackTrans
End If
If Not drawApp Is Nothing Then
drawApp.Optimization = False
drawApp.EventsEnabled = True
End If
If tempFilePath <> “” Then ForceDeleteFile tempFilePath
Set activeDoc = Nothing
Set drawApp = Nothing

Err.Raise vbObjectError + 1002, “AssetSync”, “コミット失敗: ” & errDesc
End Function

‘ — コアメソッド: データベースから特定バージョンを取得し、CorelDRAWで展開 —
Public Sub LoadAssetToWorkspace(ByVal AssetCode As String, ByVal TargetVersion As Long)
Dim cmd As ADODB.Command
Dim rs As ADODB.Recordset
Dim tempFilePath As String
Dim fileBytes() As Byte

On Error GoTo ErrorHandler

EnsureConnection

Set cmd = New ADODB.Command
With cmd
.ActiveConnection = m_Connection
.CommandText = “SELECT h.BinaryData FROM dbo.AssetHistory h ” & _
“INNER JOIN dbo.AssetMaster m ON h.AssetID = m.AssetID ” & _
“WHERE m.AssetCode = ? AND h.FileVersion = ?”
.CommandType = adCmdText
.Parameters.Append .CreateParameter(“@AssetCode”, adVarWChar, adParamInput, 100, AssetCode)
.Parameters.Append .CreateParameter(“@Version”, adInteger, adParamInput, , TargetVersion)
End With

Set rs = cmd.Execute

If rs.EOF Then
Err.Raise vbObjectError + 1003, “AssetSync”, “指定されたアセット、またはバージョンが見つかりません。”
End If

‘ BLOBデータをバイト配列に読み込む
fileBytes = rs.Fields(“BinaryData”).Value
rs.Close
Set rs = Nothing
Set cmd = Nothing

‘ 一時ファイルへのデシリアライズ
tempFilePath = GetSecureTempFilePath(“CD_LOAD_”)
WriteBinaryFile tempFilePath, fileBytes

‘ CorelDRAWでファイルを開く
Dim drawApp As CorelDRAW.Application
Set drawApp = CorelDRAW.Application
drawApp.OpenDocument tempFilePath

‘ 開いた直後に一時ファイルを削除(CorelDRAWがメモリ、または固有のテンポラリに読み込んだため解放可能)
ForceDeleteFile tempFilePath

Set drawApp = Nothing
Exit Sub

ErrorHandler:
Dim errDesc As String
errDesc = Err.Description
On Error Resume Next
If Not rs Is Nothing Then rs.Close: Set rs = Nothing
If tempFilePath <> “” Then ForceDeleteFile tempFilePath
Err.Raise vbObjectError + 1004, “AssetSync”, “ロード失敗: ” & errDesc
End Sub

‘ — プライベート・ヘルパー関数群 —

Private Function GetOrCreateAssetID(ByVal Code As String, ByVal Name As String, ByVal Category As String) As Long
Dim cmd As ADODB.Command
Dim rs As ADODB.Recordset

Set cmd = New ADODB.Command
With cmd
.ActiveConnection = m_Connection
.CommandText = “SELECT AssetID FROM dbo.AssetMaster WHERE AssetCode = ?”
.CommandType = adCmdText
.Parameters.Append .CreateParameter(“@Code”, adVarWChar, adParamInput, 100, Code)
End With

Set rs = cmd.Execute

If Not rs.EOF Then
GetOrCreateAssetID = rs.Fields(“AssetID”).Value
rs.Close
Set rs = Nothing

‘ 既存レコードのメタデータを更新
Set cmd = New ADODB.Command
With cmd
.ActiveConnection = m_Connection
.CommandText = “UPDATE dbo.AssetMaster SET AssetName = ?, Category = ?, UpdatedAt = SYSDATETIME() WHERE AssetID = ?”
.CommandType = adCmdText
.Parameters.Append .CreateParameter(“@Name”, adVarWChar, adParamInput, 255, Name)
.Parameters.Append .CreateParameter(“@Category”, adVarWChar, adParamInput, 50, Category)
.Parameters.Append .CreateParameter(“@AssetID”, adInteger, adParamInput, , GetOrCreateAssetID)
.Execute
End With
Else
rs.Close
Set rs = Nothing

‘ 新規作成
Set cmd = New ADODB.Command
With cmd
.ActiveConnection = m_Connection
.CommandText = “INSERT INTO dbo.AssetMaster (AssetCode, AssetName, Category) VALUES (?, ?, ?); SELECT SCOPE_IDENTITY() AS NewID;”
.CommandType = adCmdText
.Parameters.Append .CreateParameter(“@Code”, adVarWChar, adParamInput, 100, Code)
.Parameters.Append .CreateParameter(“@Name”, adVarWChar, adParamInput, 255, Name)
.Parameters.Append .CreateParameter(“@Category”, adVarWChar, adParamInput, 50, Category)
End With
Set rs = cmd.Execute
GetOrCreateAssetID = rs.Fields(“NewID”).Value
rs.Close
Set rs = Nothing
End If
Set cmd = Nothing
End Function

Private Function GetNextVersionNumber(ByVal AssetID As Long) As Long
Dim cmd As ADODB.Command
Dim rs As ADODB.Recordset

Set cmd = New ADODB.Command
With cmd
.ActiveConnection = m_Connection
.CommandText = “SELECT ISNULL(MAX(FileVersion), 0) + 1 AS NextVer FROM dbo.AssetHistory WHERE AssetID = ?”
.CommandType = adCmdText
.Parameters.Append .CreateParameter(“@AssetID”, adInteger, adParamInput, , AssetID)
End With
Set rs = cmd.Execute
GetNextVersionNumber = rs.Fields(“NextVer”).Value
rs.Close
Set rs = Nothing
Set cmd = Nothing
End Function

Private Function IsDuplicateHash(ByVal AssetID As Long, ByVal Hash As String) As Boolean
Dim cmd As ADODB.Command
Dim rs As ADODB.Recordset

Set cmd = New ADODB.Command
With cmd
.ActiveConnection = m_Connection
.CommandText = “SELECT 1 FROM dbo.AssetHistory WHERE AssetID = ? AND FileHash = ?”
.CommandType = adCmdText
.Parameters.Append .CreateParameter(“@AssetID”, adInteger, adParamInput, , AssetID)
.Parameters.Append .CreateParameter(“@Hash”, adChar, adParamInput, 64, Hash)
End With
Set rs = cmd.Execute
IsDuplicateHash = Not rs.EOF
rs.Close
Set rs = Nothing
Set cmd = Nothing
End Function

Private Sub InsertAssetHistory( _
ByVal AssetID As Long, _
ByVal Version As Long, _
ByRef Bytes() As Byte, _
ByVal Hash As String, _
ByVal Comment As String)

Dim cmd As ADODB.Command
Set cmd = New ADODB.Command
With cmd
.ActiveConnection = m_Connection
‘ パラメータクエリでBLOB(VARBINARY(MAX))を安全に挿入
.CommandText = “INSERT INTO dbo.AssetHistory (AssetID, FileVersion, BinaryData, FileHash, CommitComment) ” & _
“VALUES (?, ?, ?, ?, ?)”
.CommandType = adCmdText
.Parameters.Append .CreateParameter(“@AssetID”, adInteger, adParamInput, , AssetID)
.Parameters.Append .CreateParameter(“@Version”, adInteger, adParamInput, , Version)
‘ adVarBinaryパラメータにバイト配列を直接バインド
.Parameters.Append .CreateParameter(“@Binary”, adVarBinary, adParamInput, UBound(Bytes) + 1, Bytes)
.Parameters.Append .CreateParameter(“@Hash”, adChar, adParamInput, 64, Hash)
.Parameters.Append .CreateParameter(“@Comment”, adVarWChar, adParamInput, 500, Comment)
.Execute
End With
Set cmd = Nothing
End Sub

‘ — バイナリI/Oユーティリティ(ADODB.Streamをラップしメモリを効率化) —

Private Function ReadBinaryFile(ByVal filePath As String) As Byte()
Dim stream As ADODB.stream
Set stream = New ADODB.stream
With stream
.Type = adTypeBinary
.Open
.LoadFromFile filePath
ReadBinaryFile = .Read
.Close
End With
Set stream = Nothing
End Function

Private Sub WriteBinaryFile(ByVal filePath As String, ByRef Bytes() As Byte)
Dim stream As ADODB.stream
Set stream = New ADODB.stream
With stream
.Type = adTypeBinary
.Open
.Write Bytes
.SaveToFile filePath, adSaveCreateOverWrite
.Close
End With
Set stream = Nothing
End Sub

‘ — SHA-256ハッシュ計算(Windows CNG API、または.NETオブジェクトのCOM相互運用による実装) —
Private Function ComputeSHA256(ByRef Bytes() As Byte) As String
‘ 外部ライブラリに依存せず、.NETの暗号化プロバイダをCOM経由で呼び出して高速ハッシュ生成
Dim crypt As Object
Dim hashBytes() As Byte
Dim i As Long
Dim hashStr As String

Set crypt = CreateObject(“System.Security.Cryptography.SHA256Managed”)
hashBytes = crypt.ComputeHash_2((Bytes))

For i = LBound(hashBytes) To UBound(hashBytes)
hashStr = hashStr & Right(“0” & Hex(hashBytes(i)), 2)
Next i

ComputeSHA256 = LCase(hashStr)
Set crypt = Nothing
End Function

—

5. パフォーマンスと安定性の極限チューニング

5.1 `Application.Optimization` の呪いと回避策

CorelDRAW VBAにおける最大のボトルネックは、ドキュメント操作(保存、エクスポート、描画など)の際に発生する「GUIの再描画(Redraw)」と「Undoバッファへの履歴書き込み」です。

本クラス内でも使用している `drawApp.Optimization = True` は、これらを一時的に停止して実行速度を数十倍に高速化しますが、「VBAマクロが途中でエラー終了した際に、画面描画が永久に停止(フリーズ)する」という致命的な不具合を併発します。

これを回避するため、本コードでは `On Error GoTo ErrorHandler` 内で、いかなる例外が発生しても確実に `drawApp.Optimization = False` を実行する堅牢なエラーハンドリング構造を採用しています。

5.2 大容量BLOB(VARBINARY)を扱うADODB Streamのチャンク処理

100MBを超えるような巨大な `.cdr` ファイルを扱う場合、`ADODB.Stream` の `.Read` や `.Write` が一度にVBAの仮想メモリ(特に32bit版Office/CorelDRAW環境では最大2GBの制限がある)を逼迫させ、`Out of Memory`(メモリ不足)エラーを引き起こすことがあります。

極限まで安全性を追求する場合、以下のようにバッファサイズ(例:64KBごと)を区切ってチャンク転送(StreamからParameterへの分割読み込み)を実装することが推奨されますが、実務上は数MB〜数十MBのアセットが中心となるため、本コードのバルク配列処理(`ReadBinaryFile`)で十分実用的な速度を達成できます。

5.3 トランザクション分離レベルの制御

SQL Server側で複数のデザイナーが同時に同じアセットコードへコミットした場合に、ロストアップデート(更新の衝突)やデッドロックが発生する危険性があります。
これを完全に防ぐため、必要に応じて `m_Connection.Execute “SET TRANSACTION ISOLATION LEVEL SERIALIZABLE”` をトランザクション開始直後に実行し、厳密な排他制御(楽観的ロック、または悲観的ロック)を適用してください。

—

6. クライアント側(UI)での実行コード例

このクラスマネージャーを実際に呼び出すための標準モジュールの記述例です。デザイナー向けのカスタムツールバーや、ショートカットキーに登録して使用します。

Public Sub Run_CommitCurrentAsset()
Dim syncMgr As clsAssetSyncManager
Set syncMgr = New clsAssetSyncManager

Dim assetCode As String
Dim assetName As String
Dim comment As String

‘ 本来はユーザーフォームから入力させる
assetCode = “TMPL-A4-FLYER-01”
assetName = “A4チラシ基本テンプレート(標準)”
comment = “ブランドガイドライン変更に伴うロゴマークの差し替えとレイアウト調整”

On Error GoTo ErrorHandler

If syncMgr.CommitActiveDocument(assetCode, assetName, “Templates”, comment) Then
MsgBox “アセットのデータベース同期が正常に完了し、新バージョンがコミットされました。”, vbInformation + vbOKOnly, “システム通知”
End If

Set syncMgr = Nothing
Exit Sub

ErrorHandler:
MsgBox “同期システム内でエラーが発生しました: ” & Err.Description, vbCritical + vbOKOnly, “システムエラー”
Set syncMgr = Nothing
End Sub

—

7. アーキテクトの思想:なぜファイルサーバーではなくRDBなのか?

多くの企業が共有フォルダー(NAS)をベースにした運用から脱却できません。しかし、ベクターデータという「企業の知的所有権そのもの」をファイルシステムという原始的なストレージに委ねることは、以下の重大なリスクを伴います。

  • 排他制御の欠如: 誰かが開いているファイルに上書きしてデータが破損する。
  • 物理的な依存: ディレクトリ構造の変更によって、外部参照(リンク画像など)がすべて破断する。
  • 監査証跡の不在: 「誰が、いつ、どのパスをどのように変更したか」を完全に追跡できない。

本システムのように、CorelDRAWというフロントエンドの極限近くに「RDB接続エンジン」を組み込むことで、すべてのベクターアセットは単なる「ファイル」から「不変のオブジェクト(State)」へと昇華されます。

本コードを基盤として、さらに「プレビュー用低解像度PNGの自動抽出(DB格納によるブラウザでの検索ビューア構築)」や「使用フォント情報の自動パース・DBインデックス化」などを拡張していくことで、真のエンタープライズ・パブリッシング・パイプラインが完成します。レガシーを掌握し、モダンなインフラと直結させること。それこそが、VBAを操るシニアエンジニアに課せられた真のミッションです。

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