【実務・中級編】【中級者向け】印刷入稿前の最終関門!全テキストオブジェクトの強制カーブ変換(アウトライン化)と未処理文字の自動検出アラート – CorelDRAW VBA解析バイブル

スポンサーリンク

【CorelDRAW VBA極限解説】印刷入稿前の最終関門!全テキストの完全アウトライン化と未処理文字自動スキャナーの構築

印刷入稿直前のデータチェックほど、エンジニアにとって神経を使う瞬間はない。
「文字化け」「フォントの埋め込みミス」「RIP処理時のフォント置き換え事故」。これらは、どれだけ熟練したオペレーターであっても、ヒューマンエラーの温床となり得る。

特にCorelDRAW環境において、クライアントから支給された雑多なネイティブデータをそのままPDFやPostScriptへ書き出すのは、ロシアンスーレットを回すようなものだ。
「すべてのテキストオブジェクトを、例外なく確実にカーブ(アウトライン)へ変換する。そして、もし変換漏れやロックされたレイヤーのテキストがあれば、即座に検知してアラートを上げる」。

この業務を完全に自動化し、人間の目によるチェックコストをゼロにするためのプロダクションコードと、CorelDRAW VBAの深部を突くアーキテクチャをここに伝授しよう。

—

1. なぜ「単純なループ処理」では実務で破綻するのか?

CorelDRAW VBAでテキストをカーブに変換する際、多くの初中級者が陥る罠がある。
「`ActiveDocument.Pages`を回して、すべてのシェイプを走査し、`ConvertToCurves`メソッドを叩けばいい」——そう考えて書かれたコードは、実務の巨大なドキュメントの前では必ず沈黙する。

実務データを襲う3つの「死角」

1. グループ化・コンポーネント化の壁
テキストは単一のレイヤーに裸で存在しているとは限らない。グループ(`ShapeRange`)のネストの奥底や、シンボルのマスター内、さらにはブレンドやコンターといった効果の途中にあるテキストは、単純な`ActivePage.Shapes`のループでは捕捉できない。
2. ロックおよび非表示レイヤーの存在
印刷不可に設定されているレイヤーや、誤操作防止でロックされたレイヤー内のテキストを無理やり触ろうとすると、VBAは容赦なくランタイムエラーを吐いて停止する。
3. テキストオブジェクトのライフサイクル
`ConvertToCurves`を実行した瞬間、元の`Shape`オブジェクトの参照は破棄され、新しく生成された複数の`Curve`オブジェクト(またはそれらを内包するグループ)が返される。これを理解していないと、ループのインデックスが狂い、メモリリークや無限ループ、あるいは処理落ちを引き起こす。

我々は、これらすべての例外とハードウェアの制約をねじ伏せる「再帰的走査(Recursive Traversal)とエラーバリア」を備えた設計を構築しなければならない。

—

2. 堅牢性(ロバストネス)を極めたアーキテクチャ設計

今回紹介するコードは、単に文字をアウトライン化するだけではない。以下の3つのフェーズを厳密に実行する。

  • Phase 1: 事前スキャンとロック解除(またはスキップ判定)

処理対象外となるロックされたレイヤーを検出し、安全に処理をバイパスまたは一時解除する。

  • Phase 2: 深層再帰による完全捕捉

ネストされたグループ構造をくまなく探し出し、すべての`cdrTextShape`を網羅する。

  • Phase 3: 未処理文字の事後検証(セーフティネット)

処理完了後、ドキュメント内に「まだテキストシェイプが残っていないか」を強制スキャンし、残存していれば即座に処理を中断してアラートを鳴らす。

—

3. プロダクションコード:全自動テキスト・アウトライン&チェッカー

以下のコードをCorelDRAWのVBAエディタ(`Alt + F11`)に貼り付け、実行してほしい。実務の現場でそのまま組み込めるよう、徹底的なコメントと例外処理を施してある。

‘ ==============================================================================
‘ Module: 印刷入稿前・全テキスト強制アウトライン化&未処理チェッカー
‘ Architecture: Recursive Shape Traversal & Post-Validation Engine
‘ ==============================================================================
Option Explicit

Public Sub ExecuteProductionPreflight()
Dim startTime As Double
startTime = Timer

‘ 1. ドキュメントの存在チェック
If Documents.Count = 0 Then
MsgBox “処理対象となるドキュメントが開かれていません。”, vbCritical, “プリフライトエラー”
Exit Sub
End If

Dim targetDoc As Document
Set targetDoc = ActiveDocument

‘ トランザクション的処理のため、画面描画を停止してパフォーマンスを極限まで引き上げる
targetDoc.BeginCommandGroup “Production Text Outline & Check”
EventsEnabled = False
ScreenRefresh = False

On Error GoTo ErrorHandler

Dim convertedCount As Long
convertedCount = 0

‘ 2. ページ全体の走査とアウトライン化の実行
Dim p As Page
For Each p In targetDoc.Pages
‘ ページ単位でアクティブ化(一部の古いCorelDRAWエンジン対策)
p.Activate

‘ ページ内の全シェイプを再帰的に走査してアウトライン化
ProcessShapesRecursively p.Shapes, convertedCount
Next p

‘ 3. 事後検証:まだテキストオブジェクトが残っていないか強制スキャン
Dim residualTextCount As Long
residualTextCount = CountRemainingTexts(targetDoc)

‘ 4. 結果判定とコミット
targetDoc.EndCommandGroup
ScreenRefresh = True
EventsEnabled = True

If residualTextCount > 0 Then
‘ 未処理文字が存在する場合は強制ロールバック(変更破棄)せず、アラートを上げる
MsgBox “【警告】入稿違反のテキストが検出されました!” & vbCrLf & _
“未処理のテキストオブジェクトが ” & residualTextCount & ” 件残っています。” & vbCrLf & _
“ロックされたレイヤーや特殊効果内の文字を確認してください。”, _
vbCritical, “プリフライト強制中断”
Else
Dim elapsedTime As Double
elapsedTime = Timer – startTime
MsgBox “プリフライトチェック完了。” & vbCrLf & _
“すべてのテキストオブジェクト (” & convertedCount & ” 件) のアウトライン化に成功しました。” & vbCrLf & _
“処理時間: ” & Format(elapsedTime, “0.00”) & ” 秒”, _
vbInformation, “入稿準備完了”
End If

Exit Sub

ErrorHandler:
‘ 異常終了時のクリーンアップ
ScreenRefresh = True
EventsEnabled = True
targetDoc.EndCommandGroup
MsgBox “予期せぬエラーが発生しました。” & vbCrLf & _
“Error # ” & Err.Number & “: ” & Err.Description, _
vbCritical, “致命的エラー”
End Sub

‘ ——————————————————————————
‘ Sub: ProcessShapesRecursively (再帰的シェイプ走査とアウトライン変換)
‘ ——————————————————————————
Private Sub ProcessShapesRecursively(ByVal shapesCol As Shapes, ByRef counter As Long)
Dim sh As Shape
Dim i As Long

‘ コレクションのインデックス破壊を防ぐため、後ろからループを回す(逆順走査の鉄則)
For i = shapesCol.Count To 1 Step -1
Set sh = shapesCol(i)

‘ ロックされているシェイプや非表示レイヤーのものはスキップ(必要に応じてロック解除処理を追加)
If Not sh.Locked Then
‘ グループまたはブレンド等のコンテナシェイプの場合
If sh.Type = cdrGroupShape Then
ProcessShapesRecursively sh.Shapes, counter

‘ パワードライブやシンボル、アートメディア等の複合オブジェクトの考慮
ElseIf sh.HasShapes Then
ProcessShapesRecursively sh.Shapes, counter

‘ テキストオブジェクトである場合の処理
ElseIf sh.Type = cdrTextShape Then
‘ テキストをカーブに変換
Dim convertedSh As Shape
Set convertedSh = sh.ConvertToCurves()
counter = counter + 1
End If
End If
Next i
End Sub

‘ ——————————————————————————
‘ Function: CountRemainingTexts (残存テキストスキャナー)
‘ ——————————————————————————
Private Function CountRemainingTexts(ByVal doc As Document) As Long
Dim count As Long
count = 0

Dim p As Page
For Each p In doc.Pages
count = count + CountTextsInShapes(p.Shapes)
Next p

CountRemainingTexts = count
End Function

‘ ——————————————————————————
‘ Function: CountTextsInShapes (再帰的テキストカウンター)
‘ ——————————————————————————
Private Function CountTextsInShapes(ByVal shapesCol As Shapes) As Long
Dim count As Long
count = 0

Dim sh As Shape
Dim i As Long
For i = 1 To shapesCol.Count
Set sh = shapesCol(i)

If sh.Type = cdrTextShape Then
count = count + 1
ElseIf sh.HasShapes Or sh.Type = cdrGroupShape Then
count = count + CountTextsInShapes(sh.Shapes)
End If
Next i

CountTextsInShapes = count
End Function

—

4. コードの深層解説:プロが仕込んだ3つの技術的要件

このコードが「なぜ現場でバグを起こさないのか」、その技術的背景を解説する。

① 逆順ループ(`Step -1`)の徹底

VBAでコレクション(`Shapes`など)の要素を削除したり、別のオブジェクトに変化(`ConvertToCurves`など)させたりする場合、先頭からループを回すとインデックスがズレて致命的なメモリアクセス違反(または要素の飛ばし)が発生する。
常に後ろから前へ(`Count`から`1`へ)ループを回すのが、ベクターグラフィックス操作における絶対的な大原則だ。

② 画面描画の遮断(`ScreenRefresh = False`)による劇的な速度向上

CorelDRAWは、VBAからシェイプが1つ変更されるたびに、UIのプレビュー画面を再描画しようとする。これが数千個におよぶオブジェクトに対して行われると、処理が数分単位で遅くなる。
処理の冒頭で `ScreenRefresh = False` と `EventsEnabled = False` を宣言し、処理終了時に必ず復元させることで、処理速度を最大で 10倍以上 に跳ね上げることができる。

③ 妥協なき事後検証(Post-Validation)

「エラーが出なかったから大丈夫」という性善説をエンジニアリングの世界手では採用してはならない。
コードの後半に組み込まれた `CountRemainingTexts` 関数は、すべての処理が終わった後に、ドキュメントの隅々まで「テキストシェイプがまだ残っていないか」を改めて冷徹にスキャンする。
もしロックされたレイヤーのせいで変換漏れがあれば、ここで確実に検知され、誤って文字化けしたまま印刷所へデータが飛ぶ悲劇を物理的に阻止する。

—

5. 実運用における拡張とアドバイス

このスクリプトを社内のプリフライトワークフローに組み込む際は、以下の拡張を検討してほしい。

  • ログ出力機能の追加: どのレイヤーにどのテキストが残っていたかをテキストファイル(CSV等)に吐き出すようにすれば、デザイナーへの修正指示が極めてスムーズになる。
  • PDFエクスポートの自動化: すべてのチェックが正常終了(`residualTextCount = 0`)した直後に、そのまま印刷用PDF/X-1a形式でのエクスポート処理をチェーンさせることで、ワンクリック完全自動入稿パイプラインが完成する。

手作業によるチェックからオペレーターを解放し、コードで絶対的な品質を担保すること。それこそが、我々エンジニアが目指すべきCorelDRAW自動化の真髄である。

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