【テクニカル・上級編】Shape.Textのサニタイズと正規化:外部データ取り込み時の不要な制御文字(改行・TAB・異体字)を一括クレンジングするVBA – Visio VBA解析バイブル

スポンサーリンク

Visio VBAにおけるShape.Textのクレンジング:外部データ連携の隠れた落とし穴とAPIレベルでの解決策

長年、様々なエンタープライズシステム、特にレガシーなVBA資産と格闘してきた身から言わせてもらえば、Visio VBAにおける `Shape.Text` プロパティの扱いは、一見単純に見えて、実は多くの落とし穴を孕んでいます。特に、CSVやExcelといった外部データソースから図形テキストにデータを取り込む際、予期せぬ制御文字や異体字が混入し、図形が崩壊する光景は、もはや悪夢の部類です。

本稿では、単なる文字列置換では太刀打ちできない、Visio VBAにおける `Shape.Text` のサニタイズと正規化に焦点を当てます。Windows APIの活用、メモリ最適化、そしてレガシー環境との共存という、シニアエンジニアや社内システム管理者が直面するであろう、より高度な課題に対して、技術的深淵から光を当てていきます。

1. なぜ `Shape.Text` は「汚染」されるのか? – 外部データ取り込みの現実

CSVやExcelからVisio図形へテキストデータを流し込む際、データソース側の問題、あるいはデータ転送プロセスにおける問題で、以下のような「厄介者」が混入することがあります。

  • 制御文字:
  • 改行コード (`vbCrLf`, `vbLf`, `vbCr`)
  • タブ (`vbTab`)
  • NULL文字 (`Chr(0)`)
  • その他、表示されないUnicode制御文字 (例: Zero-Width Space, Soft Hyphenなど)
  • 異体字・互換文字:
  • 同じ意味でも複数のUnicode表現を持つ文字(例: 「﨑」と「㟄」)
  • 表示環境によって文字化けする可能性のある旧漢字、異体字
  • 余分な空白:
  • 文字列の前後に付加された全角・半角スペース

これらの「厄介者」が `Shape.Text` に含まれていると、Visio上での表示が崩れたり、後続の処理(テキスト抽出、条件判定など)で予期せぬエラーを引き起こしたりします。特に、長期間運用されるシステムや、複数の担当者によってメンテナンスされてきたシステムでは、その「汚染」度は無視できないレベルに達していることも少なくありません。

2. VBA標準機能の限界 – なぜ置換だけでは不十分なのか?

多くのエンジニアが最初に試みるのは、VBAの `Replace` 関数を使った置換処理でしょう。

Sub BasicTextSanitize()

Dim shp As Visio.Shape
Dim doc As Visio.Document
Dim page As Visio.Page

Set doc = Visio.ActiveDocument
Set page = doc.Pages.Item(1) ‘ アクティブページを想定

For Each shp In page.Shapes
If shp.Type = visTypeShape Or shp.Type = visTypeGroup Then ‘ 図形またはグループ内の図形を対象
Dim currentText As String
currentText = shp.Text

‘ よくある制御文字の置換
currentText = Replace(currentText, vbCrLf, vbCr) ‘ CRLF -> CR (Visioの改行はCRベース)
currentText = Replace(currentText, vbLf, vbCr) ‘ LF -> CR
currentText = Replace(currentText, vbTab, ” “) ‘ TAB -> スペース
currentText = Replace(currentText, Chr(0), “”) ‘ NULL文字の除去

‘ 前後の余分なスペース除去
currentText = Trim(currentText)

‘ 置換後のテキストをセット
If shp.Text <> currentText Then
shp.Text = currentText
End If
End If
Next shp

MsgBox “基本的なテキストクレンジングが完了しました。”, vbInformation

End Sub

このコードは、一般的な改行コードやタブの除去には有効です。しかし、以下のような問題点があります。

  • 未知の制御文字への対応: Unicodeには、目に見えない多数の制御文字が存在します。`Replace` 関数で全てを網羅するのは現実的ではありません。
  • 異体字・互換文字の正規化: これらは単なる「不要な文字」ではなく、意味を持つ文字です。単純な置換では、意図しない意味の変化を招く可能性があります。
  • パフォーマンス: 大量の図形に対して逐一 `Replace` を実行すると、特に複雑な図形や多数の図形が存在する場合、処理時間が無視できなくなります。
  • オブジェクトのライフサイクル管理: `shp.Text` の取得・設定を繰り返す際、Visioの内部的なオブジェクト管理によっては、一時的なオブジェクトがメモリ上に残り続ける可能性があります。

3. Windows APIによる制御文字の完全排除

未知の制御文字や、VBA標準機能では扱いにくい文字を確実に排除するためには、Windows APIの力を借りるのが最も確実な方法です。ここでは、`Char` 型の範囲で制御文字を判定し、除去するアプローチを示します。

‘=== 標準モジュールに記述 ===
Option Explicit

‘ Unicode制御文字の定義 (抜粋 – 必要に応じて追加)
‘ 参考: https://docs.microsoft.com/ja-jp/windows/win32/api/winnt/nf-winnt-is_control_character
‘ 実際にはUnicodeのU+0000からU+001F, U+007FからU+009Fなど、広範囲に及びます。
‘ ここではVBAで扱いやすいASCII範囲の制御文字を中心に定義します。
Public Const C0_CONTROLS_START As Integer = &H0
Public Const C0_CONTROLS_END As Integer = &H1F
Public Const DEL As Integer = &H7F
Public Const C1_CONTROLS_START As Integer = &H80
Public Const C1_CONTROLS_END As Integer = &H9F

‘ Windows API宣言
‘ IsCharControlW はUnicode文字かどうかを判定するが、ここではGetUnicodeCategory を使った方が汎用的
‘ Private Declare Function IsCharControlW Lib “user32” (ByVal c As Integer) As Long

‘ Unicodeカテゴリを取得するAPI (より汎用的)
Public Enum UCHAR_CATEGORY
U_UNASSIGNED = 0
U_UPPERCASE_LETTER = 1
U_LOWERCASE_LETTER = 2
U_TITLECASE_LETTER = 3
U_MODIFIER_LETTER = 4
U_OTHER_LETTER = 5
U_NONSPACING_MARK = 6
U_ENCLOSING_MARK = 7
U_SPACING_MARK = 8
U_DECIMAL_NUMBER = 9
U_LETTER_NUMBER = 10
U_OTHER_NUMBER = 11
U_PUNCTUATION_CONNECTOR = 12
U_PUNCTUATION_DASH = 13
U_PUNCTUATION_OPEN = 14
U_PUNCTUATION_CLOSE = 15
U_SYMBOL_OTHER = 16
U_PUNCTUATION_OTHER = 17
U_MARK_OTHER = 18
U_C1_CONTROL = 19 ‘ C1 制御文字 (U+0080-U+009F)
U_FORMATTING = 20 ‘ 書式設定文字 (例: ZWSP, RLM, LRM)
U_WHITESPACE = 21 ‘ 空白文字 (Space, Tab, LF, CR など)
U_OTHER_SYMBOL = 22
U_PRIVATE_USE = 23
U_SURROGATE = 24
U_HIGH_SURROGATE = 25
U_HIGH_NOT_A_NUMBER = 26
U_LOW_SURROGATE = 27
U_LOW_NOT_A_NUMBER = 28
U_CAT_MAX
End Enum

‘ GetUnicodeCategoryW の宣言 (Windows Vista以降で利用可能)
‘ Older systems might require alternative methods or libraries.
If VBA7 Then ‘ 64-bit or 32-bit Office 2010+
Private Declare PtrSafe Function GetUnicodeCategoryW Lib “normaliz.dll” ( _
ByVal Char As Integer, _
ByVal Flags As Long) As Long
Else ‘ 32-bit Office 2007 or older
Private Declare Function GetUnicodeCategoryW Lib “normaliz.dll” ( _
ByVal Char As Integer, _
ByVal Flags As Long) As Long
End If

‘======= Visio VBA サブルーチン (標準モジュールに配置) =======

Sub SanitizeShapeTextWithApi()

Dim shp As Visio.Shape
Dim doc As Visio.Document
Dim page As Visio.Page
Dim cleanedText As String
Dim i As Integer
Dim charCode As Integer

On Error GoTo ErrorHandler

Set doc = Visio.ActiveDocument
If doc Is Nothing Then
MsgBox “アクティブなVisioドキュメントがありません。”, vbExclamation
Exit Sub
End If

‘ — パフォーマンス向上のための設定 —
‘ AutoSave を無効化
‘ doc.Application.ShowChanges = False ‘ 変更履歴を非表示にする場合
doc.Application.AlertResponse = visAlertResponseDiscard ‘ ダイアログの自動応答
doc.Application.DeferRecalc = True ‘ 再計算を遅延

‘ — ページを選択 —
‘ 特定のページを指定するか、アクティブページを使用
If doc.Pages.Count = 0 Then
MsgBox “ドキュメントにページがありません。”, vbExclamation
Exit Sub
End If
Set page = doc.Pages.Item(1) ‘ 例: 最初のページ

‘ — 図形をループ —
For Each shp In page.Shapes
‘ テキストを持つ図形のみを対象とする (グループは再帰的に処理するか、別途対応)
If shp.Type = visTypeShape And shp.TextExists Then
Dim originalText As String
originalText = shp.Text

‘ APIを使用してクレンジング
cleanedText = CleanStringByApi(originalText)

‘ テキストが変更された場合のみ更新
If originalText <> cleanedText Then
‘ オブジェクトの明示的解放を意識する (Textプロパティは値型ではないため)
‘ shp.Text = “” ‘ 一度クリアしてから設定すると、まれに安定することがある
shp.Text = cleanedText
‘ Call ClearObject(shp) ‘ 必要に応じて、より詳細な解放処理
End If
End If
Next shp

‘ — 後処理 —
doc.Application.DeferRecalc = False ‘ 再計算を有効化
doc.Application.AlertResponse = visAlertResponseDefault ‘ ダイアログ応答を元に戻す
‘ doc.Application.ShowChanges = True ‘ 変更履歴表示を元に戻す場合

MsgBox “APIによるテキストクレンジングが完了しました。”, vbInformation

Exit Sub

ErrorHandler:
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical
‘ エラー発生時も後処理を実行
If Not doc Is Nothing Then
doc.Application.DeferRecalc = False
doc.Application.AlertResponse = visAlertResponseDefault
End If

End Sub

‘ 文字列から制御文字をAPIで除去する関数
Public Function CleanStringByApi(ByVal inputString As String) As String

Dim cleanedChars() As Integer ‘ Integers for Unicode code points
Dim charCount As Integer
Dim i As Integer
Dim charCode As Integer
Dim unicodeCategory As UCHAR_CATEGORY

If Len(inputString) = 0 Then
CleanStringByApi = “”
Exit Function
End If

‘ 制御文字を格納するための配列を初期化
ReDim cleanedChars(0 To Len(inputString) – 1)
charCount = 0

‘ 各文字をループ
For i = 1 To Len(inputString)
‘ VBAのMid関数は文字列を返すため、Unicodeコードポイントを取得
‘ ChrW関数はIntegerを引数に取るが、Unicodeコードポイントを直接渡す
charCode = AscW(Mid$(inputString, i, 1))

‘ Unicodeカテゴリを取得 (normaliz.dllを使用)
‘ Flags = 0 はデフォルト設定
unicodeCategory = GetUnicodeCategoryW(charCode, 0)

‘ 保持する文字の条件:
‘ – 制御文字 (U_C1_CONTROL, U_FORMATTING) でない
‘ – 空白文字 (U_WHITESPACE) で、かつVBA標準でTrimされる範囲の文字 (CR, LF, TAB, Space) である
‘ (より厳密には、U_WHITESPACE の中でも、表示可能なスペース (U+0020) のみ残す、などの制御も可能)
Select Case unicodeCategory
Case U_WHITESPACE
‘ CR (0x0D), LF (0x0A), TAB (0x09), Space (0x20) は残す
‘ それ以外の空白文字 (例: No-Break Space U+00A0) は除去するか、必要に応じて処理
If charCode = vbCr Or charCode = vbLf Or charCode = vbTab Or charCode = Asc(” “) Then
‘ 標準的な空白文字は保持
cleanedChars(charCount) = charCode
charCount = charCount + 1
‘ Else
‘ 表示可能なスペース以外は除去 (例: No-Break Space U+00A0)
‘ 必要に応じてここに処理を追加
End If
Case Else
‘ 制御文字 (U_C1_CONTROL, U_FORMATTING) 以外は保持
‘ (U_WHITESPACE は上記で別途処理済み)
If unicodeCategory <> U_C1_CONTROL And unicodeCategory <> U_FORMATTING Then
cleanedChars(charCount) = charCode
charCount = charCount + 1
‘ Else
‘ 制御文字は除去
End If
End Select
Next i

‘ 文字列を再構築
If charCount > 0 Then
‘ 配列を実際のサイズにリサイズ
ReDim Preserve cleanedChars(0 To charCount – 1)
‘ Integer配列から文字列へ変換
CleanStringByApi = ArrayToWideString(cleanedChars)
Else
CleanStringByApi = “”
End If

‘ — 最終的な整形 (Trim, 余分なスペース除去) —
‘ VBAのTrim関数はASCII範囲のスペースのみを対象とする
‘ Unicodeのスペースを考慮する場合は、上記API処理でFilterするか、別途関数を作成
CleanStringByApi = Application.WorksheetFunction.Trim(CleanStringByApi) ‘ ExcelのTrimを使用すると全角スペースも除去できる場合がある
‘ 余分な連続スペースを1つにまとめる
CleanStringByApi = Replace(CleanStringByApi, ” “, ” “)
Do While InStr(CleanStringByApi, ” “) > 0
CleanStringByApi = Replace(CleanStringByApi, ” “, ” “)
Loop

End Function

‘ Helper function to convert an array of Integers (Unicode code points) to a Wide String
‘ Needed because VBA doesn’t have a direct way to convert Integer array to String
Private Function ArrayToWideString(ByVal intArray() As Integer) As String
Dim result As String
Dim i As Long
Dim numChars As Long

numChars = UBound(intArray) – LBound(intArray) + 1
If numChars <= 0 Then ArrayToWideString = "" Exit Function End If ' Pre-allocate string if possible (VBA string handling is tricky) ' For very large strings, this might need chunking. result = String$(numChars, Chr$(0)) ' Initialize with null characters #If VBA7 Then ' 64-bit or 32-bit Office 2010+ Declare PtrSafe Function RtlMoveMemory Lib "kernel32" ( _ Destination As Any, Source As Any, ByVal Length As Long) As Long #Else ' 32-bit Office 2007 or older Declare Function RtlMoveMemory Lib "kernel32" ( _ Destination As Any, Source As Any, ByVal Length As Long) As Long #End If ' Use RtlMoveMemory for efficient memory copying RtlMoveMemory ByVal StrPtr(result), ByVal VarPtr(intArray(LBound(intArray))), numChars 2 ' Each Integer is 2 bytes ' Remove any trailing null characters that might have been copied result = Left$(result, numChars) ArrayToWideString = result End Function ' オブジェクト解放の補助 (明示的な解放が難しい場合) ' Sub ClearObject(ByRef obj As Object) ' Dim temp As Variant ' temp = obj ' Set obj = Nothing ' End Sub 解説:

  • `GetUnicodeCategoryW` API: `normaliz.dll` に含まれるこのAPIは、指定されたUnicode文字のカテゴリ(制御文字、空白、レターなど)を返します。これにより、VBAの `IsControl` では捉えきれない広範な制御文字を判定できます。
  • `CleanStringByApi` 関数:
  • 入力文字列を1文字ずつUnicodeコードポイントに変換します。
  • `GetUnicodeCategoryW` でカテゴリを取得します。
  • 保持すべき文字(表示可能な文字、標準的な空白、VBAで扱われる制御文字など)のみを配列 `cleanedChars` に格納します。
  • `ArrayToWideString` ヘルパー関数を用いて、Integer配列を効率的にStringに変換します。
  • 最後に、VBAの `Trim` や `Replace` を使って、前後のスペースや連続するスペースを整理します。
  • `SanitizeShapeTextWithApi` サブルーチン:
  • Visioの `Application.DeferRecalc = True` を使用して、図形変更時の描画更新を一時停止し、パフォーマンスを向上させます。
  • `Application.AlertResponse = visAlertResponseDiscard` は、処理中に表示される可能性のあるダイアログ(例:「変更を保存しますか?」)を自動的に無視します。
  • 図形をループし、`CleanStringByApi` 関数で整形します。
  • 変更があった場合のみ `shp.Text` を更新することで、不要な処理を削減します。
  • 処理完了後に `DeferRecalc = False` で描画更新を再開します。

4. 異体字・互換文字の正規化:さらに高度な課題

異体字や互換文字(例: 「﨑」と「㟄」)の正規化は、単なる制御文字の除去よりも複雑です。これらは「誤字」ではなく、異なる表現を持つ「正しい文字」であるため、単純な削除は意味を損ないます。

正規化の目的は、一般的に以下のいずれかになります。

1. 統一的な表現への変換: 例えば、全ての「﨑」を「崎」に統一する、など。
2. 表示可能な標準文字への変換: 一部の異体字は、特定のフォントや環境でしか正しく表示されません。これらを、より一般的な文字に変換します。

これらを実現するには、通常、Unicode正規化フォーム (Normalization Form) を利用します。Windows APIには `NormalizeString` という関数が存在しますが、VBAから直接呼び出すのは容易ではありません。

現実的なVBAでのアプローチ:

  • VBScriptの利用: VBScriptには `StrConv` 関数があり、一部の正規化(例: `vbUnicode` での互換文字の正規化)が可能です。PowerShellスクリプトを `Shell` 関数で呼び出すことも考えられます。
  • VB.NET / C# の利用: .NET Framework (.NET Core / .NET 5+ も同様) には、強力な文字列正規化機能 (`System.String.Normalize`) が標準で備わっています。Visio VBAからCOM経由でこれらの .NET ライブラリを呼び出す、あるいは、.NETで処理した結果をVisio VBAに返す、というシステム連携が最も堅牢です。
  • カスタムマッピング: 特定の異体字のみを対象とする場合は、VBAの辞書オブジェクト (`Scripting.Dictionary`) を使って、手動でマッピングテーブルを作成し、置換処理を行うことも可能です。

VB.NET を利用した正規化の例 (概念):

.net
‘ VB.NET コード例 (Visio VBAからCOM経由で呼び出すことを想定)
Imports System
Imports System.Text

Public Class TextNormalizer

Public Function NormalizeText(ByVal inputText As String, Optional ByVal normalizationForm As String = “NFC”) As String
If String.IsNullOrEmpty(inputText) Then
Return String.Empty
End If

Dim form As Text’NormalizationForm
Select Case normalizationForm.ToUpper()
Case “NFC”
form = Text’NormalizationForm.FormC
Case “NFKC”
form = Text’NormalizationForm.FormKC
Case “NFD”
form = Text’NormalizationForm.FormD
Case “NFKD”
form = Text’NormalizationForm.FormKD
Case Else
Throw New ArgumentException(“Invalid normalization form specified. Use NFC, NFKC, NFD, or NFKD.”)
End Select

Return inputText.Normalize(form)
End Function

‘ 異体字のカスタム置換例
Public Function ReplaceVariantChars(ByVal inputText As String) As String
Dim tempText As String = inputText

‘ 例: 「﨑」を「崎」に置換
tempText = tempText.Replace(“﨑”, “崎”)
‘ 例: 「髙」を「高」に置換
tempText = tempText.Replace(“髙”, “高”)
‘ … 必要に応じて追加

Return tempText
End Function

End Class

このVB.NETクラスをCOM公開し、Visio VBAから `CreateObject` でインスタンス化して利用します。

‘ Visio VBA から VB.NET クラスを呼び出す例
Sub NormalizeShapeTextWithDotNet()

Dim shp As Visio.Shape
Dim doc As Visio.Document
Dim page As Visio.Page
Dim originalText As String
Dim normalizedText As String

On Error GoTo ErrorHandler

Set doc = Visio.ActiveDocument
Set page = doc.Pages.Item(1) ‘ アクティブページ

‘ COMオブジェクトとしてVB.NETクラスをインスタンス化
‘ プロジェクト設定で「Microsoft .NET Framework 4.x Type Library」への参照が必要な場合あり
‘ または、RegAsm.exe でCOM登録されたDLLを CreateObject で呼び出す
Dim normalizer As Object
On Error Resume Next
Set normalizer = CreateObject(“YourDotNetProject.TextNormalizer”) ‘ プロジェクト名とクラス名を指定
On Error GoTo ErrorHandler
If normalizer Is Nothing Then
MsgBox “VB.NETのTextNormalizerオブジェクトの作成に失敗しました。” & vbCrLf & _
“COM登録または参照設定を確認してください。”, vbCritical
Exit Sub
End If

‘ パフォーマンス向上のための設定
doc.Application.DeferRecalc = True

For Each shp In page.Shapes
If shp.Type = visTypeShape And shp.TextExists Then
originalText = shp.Text

‘ — APIによる制御文字除去 (必要であれば) —
Dim cleanedApiText As String
cleanedApiText = CleanStringByApi(originalText) ‘ 上記のAPI関数を使用

‘ — .NETによる正規化 (NFKC推奨:互換文字を意味的に近い標準文字に変換) —
normalizedText = normalizer.NormalizeText(cleanedApiText, “NFKC”)

‘ — カスタム置換 (必要であれば) —
normalizedText = normalizer.ReplaceVariantChars(normalizedText)

‘ — VBA標準のTrim処理 —
normalizedText = Application.WorksheetFunction.Trim(normalizedText) ‘ 全角スペースも考慮
Do While InStr(normalizedText, ” “) > 0
normalizedText = Replace(normalizedText, ” “, ” “)
Loop

If originalText <> normalizedText Then
shp.Text = normalizedText
End If
End If
Next shp

doc.Application.DeferRecalc = False
MsgBox “.NET連携によるテキスト正規化が完了しました。”, vbInformation

Exit Sub

ErrorHandler:
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical
If Not doc Is Nothing Then
doc.Application.DeferRecalc = False
End If
If Not normalizer Is Nothing Then Set normalizer = Nothing

End Sub

5. メモリ最適化とレガシー環境での保守

  • オブジェクトの明示的解放: VBAでは、COMオブジェクトの解放は自動で行われることが多いですが、大量のオブジェクトを扱う場合や、複雑な参照関係がある場合は、意図しないメモリリークが発生する可能性があります。`Set obj = Nothing` による明示的な解放は、基本ですが重要です。ただし、`Shape` オブジェクト自体はVisioのドキュメントオブジェクトモデルの一部であり、`Shape.Text` プロパティへのアクセスもVisioの内部処理に依存するため、VBAレベルでの「解放」は限定的です。重要なのは、不要になった `Shape` オブジェクトへの参照を速やかに解除することです。
  • `DeferRecalc` の活用: 前述の通り、図形への変更を繰り返す際に `DeferRecalc` を `True` に設定し、処理の最後に `False` に戻すことで、描画更新のオーバーヘッドを大幅に削減できます。
  • `ScreenUpdating` の無効化: `Application.ScreenUpdating = False` も同様に画面描画を抑制しますが、`DeferRecalc` の方がVisioにおいてはより直接的に描画処理に影響するため、効果が高いことが多いです。
  • レガシー環境の保守:
  • OS/Officeバージョンの依存性: `GetUnicodeCategoryW` は比較的最近のWindows APIですが、古いOS (Windows XPなど) では利用できない可能性があります。その場合、代替手段 (例: COMオブジェクトとして登録されたサードパーティライブラリ、あるいはVBScript等へのフォールバック) を検討する必要があります。
  • APIの可用性: .NET Frameworkのバージョン依存性も考慮が必要です。古い環境では .NET Framework がインストールされていない、あるいは古いバージョンしか存在しない場合があります。
  • コードの可読性と保守性: レガシーコードの保守においては、コードの可読性と、将来の変更に対する柔軟性が重要です。コメントを適切に記述し、モジュール化を徹底することが、長期的な資産保全につながります。

6. システム間連携の極限:パフォーマンスと堅牢性の両立

Visio VBA単体での限界を超える場合、他のシステムとの連携が不可欠になります。

  • PowerShell: Windows標準のスクリプト言語であり、.NET Frameworkの機能にもアクセスできます。COMオブジェクトの操作も得意とするため、Visio VBAとPowerShellを連携させることで、より高度なテキスト処理やファイル操作が可能になります。
  • VB.NET / C#: 高度な処理ロジックや、複雑なデータ構造の操作が必要な場合に最適です。COMインターフェイスを公開することで、Visio VBAから容易に呼び出せるように設計します。
  • データベース連携: 外部データを直接データベースから取得し、Visio図形に反映させる場合、データベース側のデータクレンジング処理を強化する、あるいは、ETLツールなどを活用して、Visioに渡す前にデータを整形しておく、というアプローチも有効です。

重要なのは、「Visio VBAでどこまでやるべきか」という線引きです。複雑すぎる処理や、Visioのパフォーマンスを著しく低下させるような処理は、外部の専門的なツールや言語に委譲するのが賢明な判断です。

まとめ

`Shape.Text` のサニタイズと正規化は、外部データ連携における見過ごされがちな、しかし非常に重要な課題です。VBA標準機能だけでは限界があり、Windows APIや、場合によっては.NETのようなより高度な技術を組み合わせることで、その真価を発揮します。

パフォーマンス、メモリ管理、そしてレガシー環境との互換性を考慮した設計は、単に動くコードを書くだけでなく、長期的に運用され、信頼されるシステムを構築するための礎となります。本稿で解説したAPIレベルでのアプローチやシステム連携の知見が、皆さんのVisio VBA開発、ひいてはシステム全体の品質向上に貢献できれば幸いです。

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