2014/12/22

12/22/2014
 ExcelVBAでページ設定を行うPageSetupオブジェクトですが、プロパティー設定毎にプリンタと通信を行うらしく、非常に時間がかかります。
 例えば以下のコード、なんと4秒かかったりします。(プリンタドライバと接続方法により異なるようです。)
With Application.PageSetup
     .LeftMargin = Application.InchesToPoints(0.17)
     .RightMargin = Application.InchesToPoints(0.17)
     .TopMargin = Application.InchesToPoints(0.62)
     .BottomMargin = Application.InchesToPoints(0.48)
     .HeaderMargin = Application.InchesToPoints(0.17)
End With
 ExcelVBAのPageSetupの遅さは結構有名な話で、以前からExcel4Macroを代用する高速化方法が知られています。
 Excel4Macroを利用すると以下のような表記となり、1行で記述できることからかなりの高速化が見込めます。
ExecuteExcel4Macro "Page.Setup(....)"
 ただし、Excel4Macroは少々クセがあり、指定パラメータによっては無視されるパラメータがあったります。
 筆者もかなりいじめられました。
 Excel2010よりPrintCommunicationプロパティーが追加(プリンタとの通信フラグ)されExcel4Macroよりこちらの高速化が推奨されているのは知っていたのですが、どうもこちらもクセがあるので少々敬遠していたのですが、今回色々調べてみたのでメモを記載しておきます。
 PrintCommunicationプロパティーはFalseを設定するとPageSetupへの設定がすべてキャッシュされ、Trueを設定すると一気に設定がコミットされます。
 一つにまとめることで、オーバーヘッドが激減するでしょうから、かなりの高速化が見込めるのはわかります。
 しかし、クセがあるのです。以下のコードは最終行で1004エラーが発生します。
With ActiveSheet.PageSetup
   .Parent.Application.PrintCommunication = False
   .FitToPagesWide = 1
   .FitToPagesTall = False
   .zoom = False
   .Parent.Application.PrintCommunication = True
With
 海外でも困っている方多いようです。
 何故かわからなかったので、同期上の問題かとDoEventsなどを追加しても効果なく、こまっていたのですが、なんと次のように順番を変更すると正常に動作します。
With ActiveSheet.PageSetup
   .Parent.Application.PrintCommunication = False
   .zoom = False
   .FitToPagesWide = 1
   .FitToPagesTall = False
   .Parent.Application.PrintCommunication = True
With
 どうも関連するプロパティーについて設定順番があるようなのです。順番についてはどこにも記載事項がないので、これは実験してみるしか無いように思います。
 今回エラー回避策がわかったので一例として公開してみますが、類似の状況を経験された方、参考にしてみてください。

0 コメント:

コメントを投稿