こんにちは!CorelDRAW VBAの世界へようこそ。
マクロの記録ボタンを押して形だけのコードを生成する日々は、もう卒業しましょう。今回は、業務自動化の現場で「おっ、やるな」と一目置かれる、一歩進んだテクニックをお届けします。
テーマは「Windows APIを活用したCorelDRAWのウィンドウ完全非表示化による超高速バックグラウンド変換」です。
「大量のCDRファイルをPDFやIllustrator形式に変換したいけれど、画面がパチパチ切り替わって遅いし、見栄えも悪い……」そんな悩みを抱えたことはありませんか?
今回は、GUIの描画オーバーヘッドを極限まで削ぎ落とし、裏側でマッハのように処理を完結させるヘッドレスエンジンの作り方を、優しく、そしてディープに解説していきます。ここをクリアすれば、あなたのVBAスキルは確実にプロの領域に到達しますよ!
—
なぜ、通常のVBA制御では遅いのか?
通常、VBAから別アプリケーションを操作する場合、`Application.Visible = False` といったプロパティを使いたくなりますよね。しかし、CorelDRAWのCOMオブジェクトをそのまま起動すると、瞬間的にウィンドウが画面に現れたり、タスクバーがチラついたりします。
ウィンドウが画面に描画される(=GUIスレッドが稼働する)ということは、OSに対して「ピクセルを描画しろ」という無駄な命令を出し続けている状態です。これが数千ファイルのバッチ処理ともなると、処理時間の何割をも無駄な描画コストが食いつぶしてしまいます。
そこで登場するのが Windows API です。
OSの深部(User32.dll)に直接働きかけ、CorelDRAWが生成したウィンドウハンドル(hWnd)を捕獲し、「そもそも画面に存在させない(非表示)」に指定してしまうのです。
—
秘伝のコード:完全非表示・超高速バッチ変換エンジン
百聞は一見にしかず。まずは、開発現場でそのままコピペして使える実用的なコードをお見せします。
今回は、指定したフォルダ内のCorelDRAW(.cdr)ファイルを、CorelDRAWの画面を表示することなく、一瞬でPDFに変換するVBAモジュールです。
Option Explicit
‘ ==============================================================================
‘ Windows API の宣言(User32.dllからウィンドウ制御の関数をインポート)
‘ ==============================================================================
If VBA7 Then
‘ 64bit環境用
Private Declare PtrSafe Function ShowWindow Lib “user32” (ByVal hwnd As LongPtr, ByVal nCmdShow As Long) As Long
Else
‘ 32bit環境用
Private Declare Function ShowWindow Lib “user32” (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
End If
‘ ShowWindow用の定数
Private Const SW_HIDE As Long = 0 ‘ ウィンドウを完全に隠す
Private Const SW_SHOW As Long = 5 ‘ ウィンドウを表示する
Sub HeadlessConverterPro()
Dim cdrApp As CorelDRAW.Application
Dim doc As CorelDRAW.Document
Dim sourceFolder As String
Dim targetFolder As String
Dim fileName As String
Dim startTime As Double
Dim fileCount As Long
startTime = Timer
fileCount = 0
‘ 処理元と保存先のパス(環境に合わせて書き換えてください)
sourceFolder = “C:\Data\CDR_Input\”
targetFolder = “C:\Data\PDF_Output\”
‘ フォルダの存在チェック(簡易)
If Dir(sourceFolder, vbDirectory) = “” Then
MsgBox “入力フォルダが見つかりません。”, vbCritical
Exit Sub
End If
‘ ==========================================================================
‘ 1. ヘッドレスモードでのCorelDRAW起動
‘ ==========================================================================
On Error GoTo ErrorHandler
Set cdrApp = New CorelDRAW.Application
‘ 【超重要】CorelDRAW自体の画面描画と警告を完全停止し、極限までスピードアップ
cdrApp.Optimization = True
cdrApp.EventsEnabled = False
cdrApp.Interactive = False
‘ ==========================================================================
‘ 2. Windows APIによるウィンドウの完全隠蔽(非表示化)
‘ ==========================================================================
‘ CorelDRAWのメインウィンドウハンドルを取得し、強制的に非表示(SW_HIDE)にする
On Error Resume Next
Dim appHwnd As LongPtr
appHwnd = cdrApp.FrameWindow.Handle
If appHwnd <> 0 Then
ShowWindow appHwnd, SW_HIDE
End If
On Error GoTo ErrorHandler
‘ ==========================================================================
‘ 3. 高速バッチ変換ループ
‘ ==========================================================================
fileName = Dir(sourceFolder & “.cdr”)
Do While fileName <> “”
‘ ファイルを開く(UIを表示させないためにウィンドウ非表示で開く設定)
Set doc = cdrApp.OpenDocument(sourceFolder & fileName)
‘ PDFパブリッシュ設定(必要に応じてカスタマイズ)
Dim pdfPath As String
pdfPath = targetFolder & Left(fileName, Len(fileName) – 4) & “.pdf”
‘ アクティブドキュメントをPDFとしてパブリッシュ
doc.PublishToPDF pdfPath
‘ メモリリークを防ぐため、速やかにドキュメントを閉じる
doc.Close
Set doc = Nothing
fileCount = fileCount + 1
fileName = Dir() ‘ 次のファイルへ
Loop
‘ ==========================================================================
‘ 4. 終了処理とクリーンアップ
‘ ==========================================================================
‘ 設定を元に戻す
cdrApp.Interactive = True
cdrApp.EventsEnabled = True
cdrApp.Optimization = False
‘ アプリケーションの終了
cdrApp.Quit
Set cdrApp = Nothing
MsgBox “変換完了!処理ファイル数: ” & fileCount & “件” & vbCrLf & _
“実行時間: ” & Format(Timer – startTime, “0.00”) & ” 秒”, vbInformation, “ヘッドレス変換成功”
Exit Sub
ErrorHandler:
‘ エラー発生時もCorelDRAWのプロセスがゾンビ化しないように必ず復元処理を入れる
If Not cdrApp Is Nothing Then
cdrApp.Interactive = True
cdrApp.EventsEnabled = True
cdrApp.Optimization = False
cdrApp.Quit
Set cdrApp = Nothing
End If
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical, “致命的なエラー”
End Sub
—
コードのキモ:ここがプロの技術!
1. `ShowWindow appHwnd, SW_HIDE` の魔術
CorelDRAWのCOMオブジェクトは起動時にどうしても初期ウィンドウを作ってしまいますが、取得したウィンドウハンドル(`FrameWindow.Handle`)に対して即座に `SW_HIDE` を送ることで、ユーザーの目に触れる前に画面から消し去ります。これにより、描画コストがほぼゼロになります。
2. 三種の神器:`Optimization`, `EventsEnabled`, `Interactive`
- `cdrApp.Optimization = True`:画面の再描画を完全にストップします。
- `cdrApp.EventsEnabled = False`:不要なイベントマクロの暴走を防ぎます。
- `cdrApp.Interactive = False`:ユーザーからのマウス・キーボード入力を受け付けなくし、バックグラウンド処理に特化させます。
この3つをセットで使うのが、CorelDRAW VBA高速化の「絶対正義」です。
3. 安全なエラーハンドリング(ゾンビプロセスの防止)
VBAで外部アプリケーションを操作するときに一番怖いのが、エラーで途中で止まった際にメモリ上にCorelDRAWのプロセス(タスク)が幽霊のように残り続ける「ゾンビプロセス」です。エラーハンドラ(`ErrorHandler`)を必ず設置し、例外時にも確実に `Quit` を叩く構造にしています。
—
陥りやすい罠とエンジニアの知見
ここで、現場でやりがちな「失敗パターン」をシェアしておきます。
- 罠1: 64bit版OfficeでのAPI宣言ミス
最近の環境はほとんどが64bit版Excel/Accessです。古いネットの記事にあるような `Declare Function` をそのまま使うと、Excelごと強制終了(クラッシュ)します。必ず `#If VBA7 Then` を使って、`PtrSafe` と `LongPtr` を用いた環境分岐を記述してください。(上記のコードはすでに64bit完全対応済みです!)
- 罠2: `doc.Close` のし忘れによるメモリリーク
ループ内でドキュメントを開きまくると、OSのメモリがじわじわと圧迫され、後半になるにつれて極端に処理が遅くなります。処理が終わったドキュメントは、必ずその場で `doc.Close` を呼び、`Set doc = Nothing` で参照を焼き払うのが鉄則です。
—
まとめ
いかがでしたでしょうか?
今回はWindows APIをVBAから華麗に操り、CorelDRAWを完全に裏方として働かせる「ヘッドレス変換エンジン」をご紹介しました。
「画面が見えないと不安……」と思われるかもしれませんが、一度この爆速の処理スピードと、作業中もPCの画面が邪魔されない快適さを知ってしまったら、もう元のGUI表示ありの処理には戻れなくなるはずです。
ここをクリアできれば、あなたのCorelDRAW VBAのスキルは、単なる「マクロの延長」から、確固たる「業務システム開発」の領域にステップアップしています。ぜひ日々の業務に組み込んで、周囲をあっと言わせる自動化を実現してくださいね!
