【入門編】【上級】外部DB(SQL Server)の接続文字列をAcadDocumentの拡張ディクショナリに暗号化して保存 – AutoCAD VBA解析バイブル

スポンサーリンク

こんにちは!AutoCAD VBAの海原を航海する開発者の皆さん、調子はイカガですか?
「マクロの記録」ボタンを押して図形を描くだけの自動化は、もう卒業しましたよね。

今回は、AutoCAD VBAの真骨頂である「オブジェクトモデルの深層」と、現場で即戦力となる「セキュアな外部データ連携」のテクニックを伝授します。

テーマはずばり、「SQL Serverの接続文字列を、図面ファイル(AcadDocument)の拡張ディクショナリに暗号化して安全に保存する」というもの。

「図面にパスワードや接続情報をそのまま書くなんて、セキュリティ事故の元だ!」
「かといって、外部INIファイルに頼ると、図面を別の人に渡したときにリンクが切れてしまう……」

そんな現場の悩みを一発で解決する、プロのアーキテクトが使う極上の知見をシェアしましょう。ここをクリアすれば、あなたのAutoCAD VBAスキルは間違いなく一段上のステージに到達しますよ!

1. なぜ「拡張ディクショナリ (Extension Dictionary)」なのか?

AutoCADの図面(`.dwg`)には、図形や画層だけでなく、図面そのものにデータを隠し持つ仕組みが用意されています。それが `ExtensionDictionary`(拡張ディクショナリ)です。

データベースとしての図面の強み

  • 図面ファイルと運命を共にする: 図面をメールで送ったり、クラウドで共有したりしても、設定が消えません。「あ、接続定義のファイル(ini)を送り忘れた!」という凡ミスを防げます。
  • 外部から見えにくい: 通常の画層や文字データとは異なり、図面ビューポート上には一切描画されません。

しかし、そのまま平文(プレーンテキスト)で接続文字列を入れたのでは、メモ帳などでバイナリを覗かれたときに丸見えになってしまいます。そこで今回は、簡易的な暗号化(XORシフトまたはBase64等)を施して格納するアプローチを取ります。

2. 全体設計と今回のミッション

今回の実装の流れはこうです:

1. 暗号化・復号化ロジック: 接続文字列をそのまま保存せず、簡単な難読化(暗号化)をかける関数を用意する。
2. 拡張ディクショナリの取得/作成: 現在開いている `AcadDocument` から独自のディクショナリ(例: `MyCompanyDBConfig`)を取り出す。存在しない場合は新規作成する。
3. XRecord(拡張レコード)への書き込み: ディクショナリの中にデータを格納するためのコンテナである `XRecord` を作成し、そこに暗号化文字列を書き込む。
4. 読み出しテスト: 保存したデータを正しく取り出し、復号化して元の接続文字列に戻せるか確認する。

3. 実装コード(コピペで使える実践VBA)

以下のコードをAutoCADのVBAエディタ(Alt + F11)の標準モジュールに貼り付けてください。

Option Explicit

‘ 独自のキー名(ディクショナリおよびXRecordの名前)
Const DICT_NAME As String = “EnterpriseDBConfig”
Const XREC_KEY As String = “ConnectionSettings”

” ===================================================================
” メイン処理1:SQL Serverの接続文字列を暗号化して図面に保存する
” ===================================================================
Public Sub SaveSecureConnectionString()
Dim connStr As String
‘ サンプルの接続文字列(実際の環境に合わせて変更してください)
connStr = “Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;”

On Error GoTo ErrorHandler

‘ 1. 文字列を暗号化(今回はシンプルかつ安全な難読化の例)
Dim encryptedStr As String
encryptedStr = SimpleEncryptDecrypt(connStr)

‘ 2. アクティブドキュメントの拡張ディクショナリを取得、なければ作成
Dim acadDoc As AcadDocument
Set acadDoc = ThisDrawing

Dim extDict As AcadDictionary
Set extDict = GetOrCreateExtensionDictionary(acadDoc)

‘ 3. 既存のXRecordがあれば削除(上書きのため)
On Error Resume Next
extDict.Remove XREC_KEY
On Error GoTo ErrorHandler

‘ 4. XRecordを作成してデータを格納
Dim xRec As AcadXRecord
Set xRec = extDict.AddXRecord(XREC_KEY)

‘ XRecordにはグループコードの配列でデータを渡す必要がある
Dim dataType(0) As Integer
Dim dataValue(0) As Variant

dataType(0) = 1 ‘ グループコード 1: 文字列データ
dataValue(0) = encryptedStr

xRec.SetXRecordData dataType, dataValue

MsgBox “データベース接続文字列を図面にセキュアに保存しました!”, vbInformation, “成功”
Exit Sub

ErrorHandler:
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical, “異常終了”
End Sub

” ===================================================================
” メイン処理2:図面から暗号化された文字列を読み出し、復号化する
” ===================================================================
Public Sub LoadSecureConnectionString()
On Error GoTo ErrorHandler

Dim acadDoc As AcadDocument
Set acadDoc = ThisDrawing

Dim extDict As AcadDictionary
‘ 拡張ディクショナリが存在するかチェックして取得
On Error Resume Next
Set extDict = acadDoc.ExtensionDictionary
On Error GoTo ErrorHandler

If extDict Is Nothing Then
MsgBox “この図面には接続情報が保存されていません。”, vbExclamation, “データなし”
Exit Sub
End If

‘ XRecordの存在チェック
Dim xRec As AcadXRecord
On Error Resume Next
Set xRec = extDict.Item(XREC_KEY)
On Error GoTo ErrorHandler

If xRec Is Nothing Then
MsgBox “指定された接続設定レコードが見つかりません。”, vbExclamation, “データなし”
Exit Sub
End If

‘ XRecordからデータを取り出す
Dim dataType As Variant
Dim dataValue As Variant
xRec.GetXRecordData dataType, dataValue

Dim encryptedStr As String
encryptedStr = dataValue(0)

‘ 復号化
Dim decryptedStr As String
decryptedStr = SimpleEncryptDecrypt(encryptedStr)

‘ 結果表示(実務ではここにADOの接続処理などを記述します)
MsgBox “【復号化された接続文字列】” & vbCrLf & decryptedStr, vbInformation, “読み込み成功”
Exit Sub

ErrorHandler:
MsgBox “読み込み中にエラーが発生しました: ” & Err.Description, vbCritical, “エラー”
End Sub

” ===================================================================
” ヘルパー関数:拡張ディクショナリを取得、なければ追加する
” ===================================================================
Private Function GetOrCreateExtensionDictionary(doc As AcadDocument) As AcadDictionary
Dim extDict As AcadDictionary

On Error Resume Next
Set extDict = doc.ExtensionDictionary
On Error GoTo 0

‘ まだ拡張ディクショナリが存在しない場合は自動生成されるが、
‘ オブジェクトモデルの仕様により、通常ドキュメントには標準で持っている。
If extDict Is Nothing Then
‘ 万が一取得できない場合のフォールバック
Set GetOrCreateExtensionDictionary = doc.Dictionaries.Add(DICT_NAME)
Else
Set GetOrCreateExtensionDictionary = extDict
End If
End Function

” ===================================================================
” ユーティリティ:簡易暗号化・復号化関数(XORシフトの応用)
” ===================================================================
Private Function SimpleEncryptDecrypt(ByVal text As String) As String
Dim i As Long
Dim result As String
Dim key As Integer

key = 123 ‘ 独自の暗号化キー(任意の整数)
result = “”

For i = 1 To Len(text)
‘ 文字コードを取得してキーでXOR演算(暗号化と復号化が同じロジックで可能)
result = result & Chr(Asc(Mid(text, i, 1)) Xor key)
Next i

SimpleEncryptDecrypt = result
End Function

4. コードの解説と「プロのツボ」

1. `AcadDocument.ExtensionDictionary` の重み

AutoCADの図面オブジェクト(`AcadDocument`)は、通常の図形(LineやCircleなど)とは異なり、アプリケーションセッションの中で常にメモリの根幹に居座る重いオブジェクトです。
ここにデータを紐付けることで、図面が開かれている間はいつでも高速に設定値をロードすることができます。

2. XRecord(拡張レコード)のグループコード

AutoCADのデータベース構造(DXF仕様)を引き継ぐVBAにおいて、`AcadXRecord` は最強のコンテナです。
データを格納する際に `dataType`(データ型を表す整数コード)と `dataValue`(実際の値の配列)をセットで渡す必要があります。

  • `dataType(0) = 1` は「文字列(String)」を意味します。
  • 複数のパラメータ(タイムアウト時間やフラグなど)を保存したい場合は、配列のサイズを `0` から `1, 2…` と拡張していけば、一つのXRecordに複数のデータを詰め込むことができます。

3. セキュリティに関するプロの注意点

今回のサンプルコードで使用している `SimpleEncryptDecrypt` 関数は、あくまで「丸見えの平文を防ぐ(難読化)」ためのものです。
VBAのコード自体やアルゴリズムをリバースエンジニアリングされれば解読は可能です。
「絶対に破られたくない極秘のパスワード」を扱う場合は、Windowsの資格情報マネージャー(Credential Manager)や、外部の安全な暗号化API(AES等)を組み込む設計を検討してください。しかし、社内ニッチなDB接続情報の隠蔽としては、これだけでも十分に実用的なセキュリティレベルに達します。

まとめ

いかがでしたでしょうか?
今回は、ただ図形を動かすだけのマクロから一歩進んで、「図面ファイル自体をデータベースのコンテナとして賢く扱う」という上級テクニックをご紹介しました。

  • 図面ファイルにデータを内包させることで、配布ミスや設定漏れを防ぐ。
  • 拡張ディクショナリとXRecordを使いこなし、スマートにデータを永続化する。
  • 一工夫加えて、セキュリティ面への配慮も忘れない。

ここをクリアしたあなたなら、現場で「おっ、こいつデキるな」と言われる自動化システムを構築できるはずです。
ぜひ、あなたの開発プロジェクトに取り入れてみてくださいね。それでは、次のオートカッドの海でお会いしましょう!

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