こんにちは!CorelDRAW VBAの奥深い世界へようこそ。
マクロの記録ボタンを押して図形を描くだけの自動化から一歩抜け出し、「真のプロフェッショナルなシステム」を構築したいあなたへ。
今回は、CorelDRAW VBAの限界を突破する極限のテクニック「Windows APIを活用したウィンドウ完全非表示化(Invisible Mode)とバックグラウンド一括変換」を授けましょう。
「数千件のCDRファイルを別フォーマットに変換したいけれど、画面がパチパチ切り替わって遅いし、見ていて目が疲れる……」
そんな悩みを抱えたことはありませんか?
ここをクリアすれば、CorelDRAWが裏画面で猛烈なスピード働き、数千のファイルを一網打尽にする「影のエンジン」へと生まれ変わります。さあ、一緒にその領域へと踏み込みましょう!
—
なぜ「ウィンドウ非表示」が必要なのか?(本質的な課題)
通常、CorelDRAWのVBA(あるいは外部からのCOM操作)でファイルを開いて保存し直すコードを書くと、どうしてもあの見慣れたメインウィンドウが画面に表示され、ドキュメントのタブが開閉するアニメーションが実行されます。
人間にとっては親切なUIですが、プログラムの処理速度においては「百害あって一利なし」です。
画面の描画(GDI/DirectXによるピクセル計算)には膨大なCPUパワーとメモリのオーバーヘッドが消費されます。さらに、フォーカスが奪われるため、変換処理が走っている間は他の仕事ができません。
これを解決するのが、「起動直後にWindows APIでCorelDRAWのウィンドウハンドルを隠し、完全に裏(バックグラウンド)で処理を完結させる」というプロの技です。
—
3つのステップで実装する「Invisible Engine」
今回は、CorelDRAWのVBAエディタから直接実行し、指定フォルダ内の膨大なCDRファイルをPDFやJPEGに爆速変換するスクリプトを構築します。
ステップ1:Windows APIの宣言とウィンドウ制御の仕組み
Windowsのウィンドウはすべて「ウィンドウハンドル(HWND)」という一意のIDを持っています。CorelDRAWのメインウィンドウのHWNDを特定し、OSのAPIである `ShowWindow` 関数を使って非表示(SW_HIDE = 0)に指定します。
ステップ2:画面更新の完全停止番兵(Application.Optimization)
ウィンドウを隠すだけでなく、CorelDRAW自体の描画エンジンも完全にストップさせます。
`Application.Optimization = True` を宣言することで、オブジェクトの生成・削除に伴う画面再描画がすべてバイパスされ、メモリ上で純粋なベクター演算だけが行われるようになります。
ステップ3:エラー耐性の高い一括変換ループ
数千件のファイルを処理する際、1つの壊れたファイルでマクロ全体がクラッシュするのは絶対に避けなければなりません。`On Error Resume Next` と適切なエラーハンドリングを組み合わせ、不屈のバッチ処理を実現します。
—
実装コード:バックグラウンド一括変換モジュール
以下のコードを、CorelDRAWのVBAモジュール(Standard Module)にそのまま貼り付けてください。
Option Explicit
‘ ==============================================================================
‘ Windows APIの宣言(CorelDRAWのウィンドウを完全に隠すために使用)
‘ ==============================================================================
If VBA7 Then
‘ 64bit版Office/CorelDRAW用
Declare PtrSafe Function FindWindow Lib “user32” Alias “FindWindowA” (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
Declare PtrSafe Function ShowWindow Lib “user32” (ByVal hwnd As LongPtr, ByVal nCmdShow As Long) As Long
Private m_AppHwnd As LongPtr
Else
‘ 32bit版用
Declare Function FindWindow Lib “user32” Alias “FindWindowA” (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Declare Function ShowWindow Lib “user32” (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
Private m_AppHwnd As Long
End If
Const SW_HIDE As Long = 0
Const SW_SHOW As Long = 5
Sub BackgroundBatchConverter()
Dim sourceFolder As String
Dim targetFolder As String
Dim fileName As String
Dim doc As Document
Dim counter As Long
‘ 変換元と変換先のパスを設定してください(環境に合わせて変更)
sourceFolder = “C:\CDR_Source\”
targetFolder = “C:\CDR_Output\”
‘ フォルダの存在確認(簡易チェック)
If Dir(sourceFolder, vbDirectory) = “” Then
MsgBox “変換元のフォルダが存在しません: ” & sourceFolder, vbCritical
Exit Sub
End If
If Dir(targetFolder, vbDirectory) = “” Then MkDir targetFolder
‘ ==========================================================================
‘ 【極限最適化フェーズ 1】 CorelDRAWのウィンドウを完全に非表示にする
‘ ==========================================================================
On Error Resume Next
m_AppHwnd = FindWindow(“CorelDRAW”, vbNullString)
If m_AppHwnd <> 0 Then
‘ 画面からウィンドウを消去(タスクバーからも一時的に消えます)
ShowWindow m_AppHwnd, SW_HIDE
End If
On Error GoTo 0
‘ ==========================================================================
‘ 【極限最適化フェーズ 2】 描画の完全停止と警告ダイアログの抑制
‘ ==========================================================================
With Application
.Optimization = True ‘ 画面描画やイベント通知を停止して高速化
.EventsEnabled = False ‘ ユーザー操作による割り込みを禁止
.Interactive = False ‘ マウスやキーボードからの入力を無効化
End With
counter = 0
fileName = Dir(sourceFolder & “.cdr”)
‘ 処理開始時刻の記録
Dim startTime As Double
startTime = Timer
‘ ==========================================================================
‘ 【メインループ】 黙々とバックグラウンドでファイルを変換し続ける
‘ ==========================================================================
Do While fileName <> “”
On Error GoTo ErrorHandler ‘ 破損ファイル対策
‘ ウィンドウを表示させずにファイルを開く(OpenDocumentExを活用)
‘ ※バックグラウンド処理では極力UIを伴うメソッドを避けます
Set doc = Application.OpenDocument(sourceFolder & fileName)
If Not doc Is Nothing Then
Dim baseName As String
baseName = Left(fileName, InStrRev(fileName, “.”) – 1)
‘ 例としてPDF形式でパブリッシュ(書き出し)
‘ 必要に応じて .Export や .SaveAs に書き換えてください
Dim pdfParams As StructPDFExportSettings
Set pdfParams = New StructPDFExportSettings
‘ ここでPDFのプリセット等を細かく調整可能
doc.PublishToPDF targetFolder & baseName & “.pdf”
‘ ドキュメントを保存せずに閉じる(メモリリーク防止の鉄則)
doc.Close
Set doc = Nothing
counter = counter + 1
End If
NextFile:
fileName = Dir() ‘ 次のファイルへ
Loop
CleanUp:
‘ ==========================================================================
‘ 【後処理フェーズ】 環境を元の状態に美しく復元する
‘ ==========================================================================
With Application
.Interactive = True
.EventsEnabled = True
.Optimization = False
End With
‘ 非表示にしたCorelDRAWウィンドウを再度表示させる
If m_AppHwnd <> 0 Then
ShowWindow m_AppHwnd, SW_SHOW
End If
‘ 完了報告
MsgBox “バックグラウンド変換が完了しました!” & vbCrLf & _
“処理件数: ” & counter & “件” & vbCrLf & _
“所要時間: ” & Format(Timer – startTime, “0.00”) & “秒”, vbInformation, “チーフアーキテクトからの報告”
Exit Sub
ErrorHandler:
‘ 万が一、特定のファイルが破損していて開けなくても、処理を止めずに次へ進む
If Not doc Is Nothing Then
doc.Close
Set doc = Nothing
End If
Resume Next
End Sub
—
開発現場で絶対にハマる「陥りやすい罠」と回避策
このレベルのコードを扱う際、初心者が必ず直面する「3つの罠」があります。プロとしてこれらを事前に回避しましょう。
1. メモリリーク(Memory Leak)の悪夢
数千件のループを回す際、`Set doc = Nothing` や `doc.Close` を怠ると、開いたドキュメントのオブジェクトがメモリ上に残り続け、やがてCorelDRAWがメモリ不足(Out of Memory)で強制終了します。
> 対策: ループの1回ごとに必ずドキュメントを完全に閉じ、変数を解放する癖をつけましょう。
2. ウィンドウを戻し忘れてプロセスがゾンビ化する
もしコードの途中で致命的なエラーが発生し、`CleanUp:` ラベルを通らずにマクロが中断した場合、CorelDRAWのウィンドウが非表示のまま(プロセスだけがタスクマネージャーに残る状態)になってしまいます。
> 対策: デバッグ中は `ShowWindow m_AppHwnd, SW_SHOW` をイミディエイトウィンドウから手動実行できるように覚えておきましょう。本番運用では `On Error GoTo CleanUp` を確実に記述します。
3. モーダルダイアログによるハングアップ
「リンクされた画像が見つかりません」「フォントがありません」といった警告ダイアログがファイルを開く時にポップアップすることがあります。ウィンドウを非表示にしているため、このダイアログはユーザーに見えず、プログラムは永遠に応答待ち(フリーズ状態)になります。
> 対策: あらかじめ `Application.Optimization = True` や各種プロパティで警告を抑制するか、ファイル側のプレフライト(事前チェック)を万全にしておく必要があります。
—
ここをクリアすれば、CorelDRAW VBAの基本はバッチリですよ
お疲れ様でした!Windows APIの呼び出しや、CorelDRAWの描画エンジンの裏側を制御するテクニックは、一見すると難しく感じたかもしれません。
しかし、この「画面を隠し、描画を止め、裏で淡々と仕事をさせる」というアーキテクチャを理解してしまえば、もはやあなたにとってCorelDRAW VBAで自動化できないものはありません。社内の誰もが何時間もかけて手作業でやっているフォーマット変換を、コーヒーを一杯飲んでいる間に裏で静かに完遂してしまう――そんなエンジニアとしての醍醐味を、ぜひあなたの現場で存分に発揮してください。
あなたの自動化ライフが、最高にエキサイティングなものになりますように!
