【テクニカル・上級編】【中級者向け】複数に分散しているテキストフレームを読順(左から右、上から下)に従って自動結合・再構築するスクリプト – CorelDRAW VBA解析バイブル

スポンサーリンク

混沌としたベクターデータの浄化:CorelDRAW VBAによる「テキスト断片」の完全統合術

CAD図面からのDXFインポート、あるいはPDF変換を経たデータ。それらがもたらす悪夢は常に同じだ。本来は一連の文章であるはずのテキストが、改行やフォント属性の差異によって数千個の「断片化されたオブジェクト」へと解体されている。

この惨状を前に、手作業で統合を試みるのはエンジニアのすることではない。我々はCorelDRAWの内部構造を掌握し、メモリを制御し、アルゴリズムによって秩序を取り戻す。

今回は、座標ソートに基づき、バラバラのテキストフレームを論理的な読順で再構築する「データ浄化スクリプト」の極意を伝授する。

—

1. 空間認識とソートアルゴリズムの罠

テキストの読順(左から右、上から下)を決定するには、単なる座標比較では不十分だ。特にCADデータは、微妙なY座標のズレが隣接行の判定を狂わせる。

ここで重要なのは、「許容範囲(Tolerance)」を設けた二段階ソートである。

1. 第一階層: Y座標でグループ化(一定の誤差内は同一行とみなす)
2. 第二階層: 各グループ内でX座標順にソート

このロジックを実装することで、見た目上の自然な読順を抽出可能になる。

—

2. 実装:テキスト統合の極致

以下に、メモリ効率と実行速度を意識した、プロダクションコードの骨子を示す。

‘ 伝説的なデータ浄化スクリプト: 選択中のテキストを読順に統合する
Sub ConsolidateTextFrames()
Dim s As Shape, sr As ShapeRange
Dim i As Long, j As Long
Dim textArray() As Shape
Dim combinedText As String

‘ 最適化: 画面更新を停止し、処理速度を向上させる
Optimization = True
EventsEnabled = False

Set sr = ActiveSelectionRange
If sr.Count < 2 Then Exit Sub ' 1. オブジェクトを配列に格納(コレクションより配列が高速) ReDim textArray(1 To sr.Count) For i = 1 To sr.Count Set textArray(i) = sr(i) Next i ' 2. 座標によるバブルソート(※小規模なら十分。数千個ならクイックソートへ換装せよ) ' 実務上の極意: Y座標の許容誤差(行とみなす範囲)を適宜設定 Dim temp As Shape For i = 1 To UBound(textArray) - 1 For j = i + 1 To UBound(textArray) ' 上から下、左から右への並び替え If (textArray(i).TopY < textArray(j).TopY - 0.1) Or _ (Abs(textArray(i).TopY - textArray(j).TopY) < 0.1 And textArray(i).LeftX > textArray(j).LeftX) Then
Set temp = textArray(i)
Set textArray(i) = textArray(j)
Set textArray(j) = temp
End If
Next j
Next i

‘ 3. テキスト抽出と結合
For i = 1 To UBound(textArray)
combinedText = combinedText & textArray(i).Text.Story.Text & vbCrLf
‘ 不要になった断片を削除
textArray(i).Delete
Next i

‘ 4. 新規テキストフレームの生成
Dim shp As Shape
Set shp = ActiveLayer.CreateParagraphText(0, 0, 10, 10, combinedText)

‘ 5. メモリ解放の徹底
Set sr = Nothing
Optimization = False
EventsEnabled = True
ActiveWindow.Refresh
End Sub

—

3. シニアエンジニアが押さえるべき「メモリと安定性」の知見

1. `Optimization` と `EventsEnabled` の真実

CorelDRAWのVBAにおいて、この2つのフラグを操作しないのは素人である。特に `Optimization = True` は、描画の再計算を抑制し、処理時間を1/100以下に短縮する。これを忘れると、数千個のオブジェクト削除のたびにGPUが悲鳴を上げ、最悪の場合はハングアップする。

2. オブジェクトの明示的破棄

VBAのガベージコレクションを信用してはならない。特に `ShapeRange` や `Text` オブジェクトは、スコープを抜けてもメモリ上に残滓を残すことが多い。`Set obj = Nothing` をループの最後で行う癖をつけること。これは大規模なCADデータ処理におけるメモリリークを防ぐ唯一の防波堤だ。

3. Windows APIによる拡張

もし、数万個規模のオブジェクトを扱う必要があるなら、標準のVBAソートでは限界が来る。その場合は、`kernel32.dll` の `RtlMoveMemory` を呼び出し、メモリポインタを直接操作してソートアルゴリズムをC言語並みの速度で実装する道もある。しかし、それは「最後の手段」だ。保守性を考慮すれば、まずは上記のようなアルゴリズムの最適化で勝負すべきである。

—

結びに:技術は「道具」であれ

自動化とは単なる省力化ではない。「人間の認知能力を超えたデータ処理を、エラーなく完遂させること」だ。

今回のスクリプトをテンプレートとして、貴殿の現場にある「負の遺産」を整理してほしい。コードは語る。書いた者の技術水準を、そして、その者がどれだけ「システム」というものを敬愛しているかを。

健闘を祈る。

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