【実務・中級編】【中級者向け】複数に分散しているテキストフレームを読順(左から右、上から下)の座標アルゴリズムに従って自動的に結合・再構築し、長文編集を容易にするスクリプト – CorelDRAW VBA解析バイブル

スポンサーリンク

CorelDRAW VBA:バラバラのテキストフレームを「正しい読順」で結合する極限のアルゴリズム

CADや古のDTPデータからインポートした瞬間に絶望したことはないか? 数百ものテキストフレームが断片化し、読み順もバラバラ。これを手作業で整列させるのは、もはや「拷問」に近い。

今回は、CorelDRAWのオブジェクトモデルを深く理解したエンジニアが、「座標ベースのソート」によるテキスト統合アルゴリズムを授ける。単に結合するだけではない。実務で耐えうる堅牢性と、拡張性を考慮した設計だ。

—

1. なぜ単純なループではいけないのか?

多くの初学者は、`ActivePage.Shapes` をそのままループさせて結合しようとする。だが、これは罠だ。
CorelDRAWの内部構造において、オブジェクトのインデックスは「作成順(または重なり順)」に依存しており、「視覚的な読順」とは一切無関係である。

業務自動化において重要なのは、以下の2点だ。
1. 空間インデックスの構築: 座標(Y軸→X軸)に基づいた再マッピング。
2. メモリ管理: 大量オブジェクトの処理中にVBAをクラッシュさせないための、適切な参照解放と最適化。

—

2. 実装:読順判定アルゴリズム

以下のコードは、選択された複数のテキストフレームを「上から順、かつ同じ行なら左から順」にソートし、結合する。

Option Explicit

‘ ———————————————————
‘ 目的: 選択されたテキストフレームを読順(上→下、左→右)で結合
‘ ———————————————————
Public Sub RebuildTextFramesSequentially()
Dim s As Shape, sr As ShapeRange
Dim i As Long, j As Long
Dim tempShape As Shape
Dim combinedText As String

‘ 選択範囲がない場合のガード節
If ActiveSelection.Shapes.Count < 2 Then MsgBox "結合対象のテキストフレームを2つ以上選択してください。" Exit Sub End If ' 1. ShapeRangeを配列に展開して座標ソート ' 本来はクイックソートを実装すべきだが、簡易的にバブルソートで解説 ' ※数百個超える場合はコレクションとクイックソートを推奨 Dim shapes() As Shape ReDim shapes(1 To ActiveSelection.Shapes.Count) For i = 1 To ActiveSelection.Shapes.Count Set shapes(i) = ActiveSelection.Shapes(i) Next i ' 座標ソートアルゴリズム ' Y座標が大きい順、同じならX座標が小さい順 For i = 1 To UBound(shapes) - 1 For j = i + 1 To UBound(shapes) If (shapes(i).Top < shapes(j).Top) Or _ (Abs(shapes(i).Top - shapes(j).Top) < 0.1 And shapes(i).Left > shapes(j).Left) Then
Set tempShape = shapes(i)
Set shapes(i) = shapes(j)
Set shapes(j) = tempShape
End If
Next j
Next i

‘ 2. テキストの抽出と統合
combinedText = “”
For i = 1 To UBound(shapes)
If shapes(i).Type = cdrTextShape Then
combinedText = combinedText & shapes(i).Text.Story & vbCrLf
‘ 不要になったフレームを削除(バックアップを取る場合はコメントアウト)
shapes(i).Delete
End If
Next i

‘ 3. 新規フレームの生成
Dim newText As Shape
Set newText = ActiveLayer.CreateParagraphText(0, 0, 100, 100, combinedText)

MsgBox “結合完了。全” & UBound(shapes) & “オブジェクトを統合しました。”
End Sub

—

3. プロダクション環境での「極限の知見」

座標の「ゆらぎ」を許容せよ

CADデータは完璧な水平・垂直ではないことが多い。`shapes(i).Top` を直接比較すると、0.001mmの差で順序が逆転する。
比較処理には必ず `Abs(A – B) < 許容値` という「浮動小数点比較」のイディオムを組み込むこと。これがバグを生まないエンジニアの矜持だ。

Undo/Redoの重要性

本スクリプトでは `shapes(i).Delete` を行っている。業務で運用する場合、予期せぬ事故を防ぐため、処理全体を `Optimization` で囲み、最後に `Undo` が1回で済むように設計する。

‘ 処理の高速化とUndoの最適化
Application.Optimization = True
‘ … 処理本体 …
Application.Optimization = False
ActiveWindow.Refresh

データベース連携のヒント

もしこのスクリプトを「多言語翻訳ワークフロー」の一部に組み込むなら、テキストを結合する際に、各フレームの元座標をCSVやJSONとして外部出力しておくことを強く勧める。翻訳後に再配置(リフロー)が必要になった際、この「座標マップ」が神のような威力を発揮するからだ。

—

最後に:自動化の真髄

「コピペで動くコード」を作るのは簡単だ。しかし、真のエンジニアは「このコードが数年後、別のデータソースで実行された時にどう振る舞うか」を想像する。

今回提供した座標ソートアルゴリズムは、UI上の並びを論理構造へ変換する極めて強力な武器になるはずだ。CorelDRAWのAPIは古いが、その分、安定している。限界まで使い倒し、繰り返される単純作業を過去のものにしてほしい。

健闘を祈る。

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