2014/09/07

Excel2013マクロの注意箇所

 またまたExcel2013ネタです。ほんっとSDI関係問題ありすぎです。ちょっと息切れしているので日々更新していきます。

シートコピー後のActiveSheetは保証されない

 コピー元ブックのシートをコピー先ブックにコピーした場合、Excel2010まででは、ActiveSheetがコピー先ブックのコピー先シートの内容になっていましたが、なんとExcel2013からは保証されないようです。  コピー元シートの場合もコピー先シートの場合もあるような動作結果になりました。
Workbooks("コピー元ブック").Activate
Workbooks("コピー元ブック").Sheets(1).Copy Before _
 := Workbooks("コピー先ブック").Sheets(1)
MsgBox "ActiveSheet = " & ActiveSheet.Parent.Name & " " & ActiveSheet.Name
 メッセージボックスの内容は、場合によってコピー元ブックになりますし、場合によってはコピー先ブックになります。
 シートコピー後のActiveSheetを処理する場合は次のように書き直す必要があるようです。
Workbooks("コピー元ブック").Activate
Workbooks("コピー元ブック").Sheets(1).Copy Before _
 := Workbooks("コピー先ブック").Sheets(1)
' beforeの場合は、コピー先シートに指定したシート番号と同じ、afterの場合は+1
Workbooks("コピー先ブック").Sheets(1) ほげほげ

Workbooks.Openで必ずウィンドウが表示される

 Excel2013からはSDIになった関係から、最小化表示されたExcelマクロシートからのWorkbooks.Openでも必ずExcelウィンドウが表示されるようになります。
   Workbooks.Open "エクセルファイル"
 これを回避する場合は、CreateObjectでExcel.Applicationオブジェクトを取得しオートメーション配下で実行する必要があります。
   Dim eap As Excel.Application
   Set eap = CreateObject("Excel.Application")
   eap.Workbooks.Open "エクセルファイル"
 開いたエクセルファイル上のAuto_Openマクロを実行する場合は以下のように行います。
   Dim eap As Excel.Application
   Dim wb  As WokrkBook
   Set eap = CreateObject("Excel.Application")
   Set wb = eap.Workbooks.Open ("エクセルファイル")
   wb.RunAutoMacros xlAutoOpen
 これらの手法を使用すれば、非表示状態で処理できますのでExcel2010までと同じような感覚で使えます。
 注意!! 非表示状態でExcelを制御すると、セルSelect,Selection.copyを多用するマクロなどでオーバーフローエラーが発生することが確認出来ました。
 これを改善するには、最小化表示をしたほうが良いようです。

Excel2013でWorkbooks.Openを最小化表示するには

 次のようにすれば、Workbooks.Openしたシートを最小化できました。
  Dim saveWb As Workbook
  Application.Visible = False  '一旦非表示
  Set saveWb = Workbooks.Open FileName:= "ワークブック"  ' ← ワークブックを開く
  Application.WindowState = xlMinimized ' ← Application.WindowStateはアクティブブックが対象になる。
  saveWb.Activate
  Application.Visible = True '再表示
 非表示でのExcelマクロは少々問題が出ることがあるので、こちらを使用したほうが良いかもしれません。

セルSelect,Selection.Copyはやめよう

 セルのコピーを行う場合、マクロ録音をすると次のようなコードが生成されますが、これを多用すると、なんとオーバーフローエラーが発生するケースがありました。エラー発生後はExcelが制御不能になり、プロセスが残留します。
Range("A1").Select
Selection.Copy
 なんとこのようなコードの不具合はDoEventsを追加することで解決します。
DoEvents
Range("A1").Select
DoEvents
Selection.Copy
 おそらく内部にイベントバッファなるものがあり、イベント発生と実施を処理しているのだと想像しますが、このバッファがあふれたとのエラーなのではないかと推測します。(DoEventsを付与することからも当たらずも遠からずと思っています。)

0 コメント:

コメントを投稿