以下のような Excel VBA なマクロプログラムを書く。やりたいことは「新しいブックを作って、そのブックにマクロがあるブックにあるシートを一枚コピー」したい。
Sub AddWorkbookWithCopyWorkSheet() Dim newBook As Workbook Set newBook = Workbooks.Add ' 新しい Book の生成と参照 ' 自分のシートを新しいBookにコピー ThisWorkbook.Sheets(1).Copy newBook.Sheets(1) End Sub
ところがこのマクロ、特定の条件が成立するとエラーとなり、以下のダイアログが表示されてしまいます。
その条件は以下。
- マクロがある側(コピー元)が xlsx,xlsm のような office2007 形式で保存されている。
- デフォルトの「ファイルの保存形式」が「Excel 97-2003 ブック (*.xls)」になっている
この条件が両方成立するとき、Workbooks.Add をしたとき、xls形式(65535行/256列) で新規 Workbook が生成されます。その後、xls 形式の book に xlsm (1048576行/16384列) のシートをコピーしようとしたため、当該エラーが発生します。
この問題が面倒くさいのは、従来 xls のマクロを xlsm に改名して保存するとエラーになってしまうこと。ユーザーは保存形式を変えただけでマクロが動かなくなってしまいためパニックに陥ります。
もう一点面倒くさいのは Workbooks.Add がデフォルトの保存形式の設定によって、生成されるワークブックが異なる点。せめて Workbooks.Add の時に xls 形式か xlsx 形式か指定できればいいのだけれど、その指定はできないことです。
---------
デフォルトの保存形式 xls で、マクロがある book が xlsm の場合に、新規で作成するワークブックを xls ベースでなく xlsx ベースにするための対策案は以下の2つ。
- デフォルトの保存形式を xlsx にしてから Workbook.Add を実行する。
Application.DefaultSaveFormat = xlOpenXMLWorkbook Dim newBook As Workbook Set newBook = Workbooks.Add
わりと単純な実装です。
ですが、Excel のアプリケーション設定(=デフォルトの保存形式)を触ることになります。このため、使用後は忘れずに設定を元に戻す必要があります。 - コピーするシートを持つ Workbook(xlsm) でまずシートを追加し、そのシートを新規 Workbook として移動させる方法
Dim newSheet As Worksheet Set newSheet = Sheets.Add ' 自分に新しい Sheet を生成 newSheet.Move ' 新しい Book を生成 (Sheet を移動) Dim newBook As Workbook Set newBook = Workbooks.Item(Workbooks.Count) ' 新しい Book への参照
この方法の場合、アプリケーション設定は触らないので、DefaultSaveFormat を操作するよりは安全です。加えて、生成される新規のワークブックは、マクロ側のワークブックの形式と同じになるので Excel 2003 でも動くはず。
欠点としては、コードを一目でみただけでは何を目的としたコードなのかわからないこと。なのでコメントなどで注釈を入れておくなどの配慮が必要です。
---------
ただ、今回の命題 (マクロのある Workbook にあるシートを、新しい Workbook にコピーしたい) の場合は、上記の様に Workbooks.Add 的なことをするまでもなく、以下のコード一発で解決します(汗
ThisWorkbook.Sheets("コピー元シート").Copy ' 新しい Book を生成 (Sheet を Copy) Dim newBook As Workbook Set newBook = Workbooks.Item(Workbooks.Count) ' 新しい Book への参照