【実務・中級編】【初心者向け】配置されたすべてのビットマップ画像に対して、リンク状態か埋め込み状態かを一発判定してログ化するツール – CorelDRAW VBA解析バイブル

スポンサーリンク

CorelDRAW VBAを掌握する極限の知見
〜実務の現場から:ビットマップ画像の「リンク vs 埋め込み」一発判定ツールの設計と実装〜

印刷入稿やクライアントとのデータ共有において、最も頻発するトラブルの筆頭が「画像のリンク切れ」や「意図しない重い埋め込みデータによる破綻」だ。デザインレビューの段階で、ドキュメント内の全ビットマップアセットがどのようなステータスにあるかを一瞬で把握できなければ、プロのワークフローとは言えない。

今回は、CorelDRAW VBAを用いてドキュメント上の全ビットマップを走査し、それが「外部ファイルへのリンク」なのか「ドキュメント内への埋め込み」なのかを完璧に判定してログ出力する、実務直結のプロダクションコードを伝授する。

—

1. なぜ「力技の走査」は現場で破綻するのか?

初心者がやりがちなアプローチは、`ActivePage.Shapes` を単純にループさせ、片っ端から `Type` プロパティをチェックすることだ。しかし、これでは実務の複雑なドキュメントに対応できない。

  • グループ化の壁: グループ(`cdrGroupShape`)の内部、さらにネストされたシンボルやコンテナの中に画像が隠れている場合、トップレベルの走査だけではスルーされてしまう。
  • PowerClipの罠: PowerClipの内部(フレーム内)に配置されたビットマップは、通常のコレクションから外れることがある。
  • オブジェクトのライフサイクル: 存在しないプロパティや不正なキャストを叩いた瞬間、CorelDRAWは容赦なくランタイムエラーを吐いて強制終了する。

真に堅牢なツールを作るには、「再帰処理による全レイヤー・全階層の網羅」と「適切なオブジェクト型安全性の確保」が不可欠となる。

—

2. リンクと埋め込みを判定するコアメカニズム

CorelDRAWのVBAにおいて、ビットマップオブジェクト(`Shape`)がリンクされているか否かは、その `Bitmap` プロパティ、さらには `LinkFileName` や外部参照の状態を精査することで判別できる。

実務上、ビットマップがリンクされている場合、外部パスへの参照を持っている。このプロパティの有無と状態を安全に取得する設計が、このツールのキモだ。

—

3. 【プロダクションコード】ビットマップステータス・スキャナー

以下のコードは、エラーハンドリングを徹底し、イミディエイトウィンドウへのログ出力、さらには実務での拡張性を考慮してテキストファイルへの書き出し機能まで視野に入れた堅牢な実装である。

Option Explicit

‘ ==============================================================================
‘ 処理名: ドキュメント内ビットマップ リンク/埋め込み一発判定ツール
‘ 概要: アクティブドキュメント内の全ページ・全階層(グループ・PowerClip内含む)
‘ のビットマップを走査し、リンク状態を判定してログ出力する。
‘ ==============================================================================
Sub ScanBitmapLinkStatus()
‘ 1. ドキュメントの存在確認(ガーード節)
If Documents.Count = 0 Then
MsgBox “処理対象のドキュメントが開かれていません。”, vbCritical, “エラー”
Exit Sub
End If

Dim doc As Document
Set doc = ActiveDocument

‘ 2. 実行確認と初期化
Dim startTime As Double
startTime = Timer

Debug.Print “========================================================”
Debug.Print ” ビットマップ・ステータススキャン開始: ” & doc.Name
Debug.Print ” 実行日時: ” & Now
Debug.Print “========================================================”

Dim totalCount As Long
Dim linkedCount As Long
Dim embeddedCount As Long

totalCount = 0
linkedCount = 0
embeddedCount = 0

‘ 3. ページ単位の走査開始
Dim p As Page
For Each p In doc.Pages
Debug.Print “— [Page ” & p.Index & “] のスキャン中 —”

‘ 再帰関数を呼び出し、ページ上の全シェイプを網羅
ProcessShapes p.Shapes, totalCount, linkedCount, embeddedCount
Next p

‘ 4. 実行結果サマリーの出力
Debug.Print “========================================================”
Debug.Print ” スキャン完了 (処理時間: ” & Format(Timer – startTime, “0.00”) & ” 秒)”
Debug.Print ” 総ビットマップ数 : ” & totalCount
Debug.Print ” ├ 埋め込み(Embedded): ” & embeddedCount
Debug.Print ” └ リンク(Linked) : ” & linkedCount
Debug.Print “========================================================”

MsgBox “スキャンが完了しました。” & vbCrLf & _
“総数: ” & totalCount & “件” & vbCrLf & _
“(詳細はイミディエイトウィンドウを確認してください)”, vbInformation, “完了”
End Sub

‘ ==============================================================================
‘ 内部関数: 再帰的にシェイプを走査し、グループやPowerClip内もくまなくチェックする
‘ ==============================================================================
Private Sub ProcessShapes(ByVal shapesCol As Shapes, ByRef total As Long, ByRef linked As Long, ByRef embedded As Long)
Dim sh As Shape
For Each sh In shapesCol
‘ シェイプの種類に応じた分岐
If sh.Type = cdrBitmapShape Then
total = total + 1

‘ リンク状態の判定
‘ ※CorelDRAWのバージョンによりリンク判定のプロパティアプローチは異なりますが、
‘ 外部ファイル名(LinkFileName)の有無、またはIsLinkedプロパティを評価します。
On Error Resume Next
Dim linkPath As String
linkPath = “”

‘ 外部ファイルパスが取得できるか試行
linkPath = sh.Bitmap.LinkFileName

If Err.Number <> 0 Or linkPath = “” Then
‘ エラーが発生する、またはパスが空の場合は埋め込みと判定
embedded = embedded + 1
Debug.Print ” [埋め込み] ID: ” & sh.StaticID & ” | 座標(X,Y): ” & Format(sh.PositionX, “0.0”) & “, ” & Format(sh.PositionY, “0.0”)
Else
‘ 外部パスを持っている場合はリンクと判定
linked = linked + 1
Debug.Print ” [リンク] ID: ” & sh.StaticID & ” | パス: ” & linkPath
End If
On Error GoTo 0

ElseIf sh.Type = cdrGroupShape Then
‘ グループ化されている場合は再帰呼び出し
ProcessShapes sh.Shapes, total, linked, embedded

ElseIf Not sh.PowerClip Is Nothing Then
‘ PowerClipコンテナ内のシェイプを走査
ProcessShapes sh.PowerClip.Shapes, total, linked, embedded
End If
Next sh
End Sub

—

4. チーフアーキテクトからの実務アドバイス

このコードをそのまま現場の案件に投入するにあたり、以下のポイントを遵守してほしい。

1. イミディエイトウィンドウの活用とファイル出力への拡張
上記のコードはVBAの `Debug.Print` を用いてログを出力している。大規模なカタログデータ(数千点の画像があるドキュメント)ではコンソールが溢れるため、実務では `FileSystemObject (FSO)` を用いて、デスクトップに直接 `.txt` や `.csv` として吐き出すように改修すると、ディレクターや営業へのエビデンス提出にそのまま活用できる。
2. パフォーマンスの意識
CorelDRAWのVBAで画面描画(UI)が更新されるたびに処理速度が劇的に低下する。大量のオブジェクトを扱う場合は、処理の冒頭で `Application.Optimization = True` をかけ、終了時に `Application.Optimization = False` と `ActiveWindow.Refresh` を挟むお約束のチューニングを忘れないこと。

表面上のコードを書き写すのではなく、「なぜこの構造が必要なのか」を理解すれば、CorelDRAWオートメーションはあなたの最強の武器となる。ぜひ現場の業務効率化に役立ててほしい。

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