またまた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を付与することからも当たらずも遠からずと思っています。)