Excel2003形式から2007マクロ有効形式へのコンバート時のWorkbook.SaveAsの挙動... VBA小ネタ:20190429

GWアドベントカレンダーの3日目ネタです。ブログ形式でお送りします。 今日の仕事はExcel97-2003形式で作成されたマクロを検証しつつ2007以降形式(マクロ有効ファイル)へのコンバート、という仕事でした*1

引っかかった点

タイトルの通りですが、よくあるパターンで、ExcelのシートやUserFormのボタンを押すと、新しくExcelのシートを生成して名前を付けて保存させるという流れがあります。こういうとき、Excelのマクロは1行で指示ができるので大変便利なのです。

ActiveWorkbook.SaveAs

こんなコマンドでいいわけです。これは昔から*2使えるコマンドなのですが、今回コンバートでこのコードに少し手を加えなければエラーが発生するという事態に遭遇しました。

エラーの詳細とコード

「よくあるパターン」ではあったのですが今回のケース、実は出力するExcelシートにはマクロが仕込まれているので、「ファイル名.xlsm」とファイル保存ダイアログに書いて保存ボタンを押す、という動きになるのですが、なぜか保存したはずのファイルのタイトルバーは保存後のファイル名になっておらず、しかもその後に「- 保存に失敗しました」とか表示されています。ちなみにこのファイルをもう一度閉じると、新規保存扱いになるので普通に保存ができるようになるのですが。

もとのコードはこれ。

ActiveWorkbook SaveAs FileName:=fileName
' シートを新しいブックにコピペして、新しいブックをアクティベートしてからこれ。

まぁ「なんの変哲もない」という表現がよく似合う、ありがちな書き方。なのですが。

エラー回避方法

原因なのですが、SaveAsの引数に問題がありました。問題があった、というべきか、引数の省略されている箇所でデフォルト値としてとっている値を使ってはいけない、というのが原因でした。SaveAsはいくつか(正確に言うと12個)の引数を与えることができ、かつ全部省略可能、という、なかなか「簡単な*3」メソッドです。具体的にはこのページを参照ください。

docs.microsoft.com

問題になるのはFileFormatパラメータ。説明をそのまま抜き出します。

ファイルを保存するときに使用するファイル形式を指定します。 有効な選択肢の一覧については、 XlFileFormat 列挙を参照してください。 既存のファイルの場合、既定の形式は、最後に指定したファイル形式です。新しいファイルの場合、既定値は、使用されている Excel のバージョンの形式です。

ちなみにxlFileFormatのリストはこれ。

docs.microsoft.com

さて。省略するとデフォルト値(既定値)が採用される、ということになると、Excelのデフォルト値は(2007以降であれば)「XMLブック(拡張子: *.xlsx)」になります。どうやら拡張子を明示してファイル名を書いて保存をするとエラーになるようです。ちなみに拡張子を書かずにファイルを保存するとどうなるか。拡張子なしのファイルが保存されます*4。 どうやらFileFormatパラメータの明示が必要になりそうです。やれやれ*5

ActiveWorkbook SaveAs FileName:=fileName, FileFormat:=xlOpenXMLWorkbookMacroEnabled
または
ActiveWorkbook SaveAs FileName:=fileName, FileFormat:=52

これでファイルを保存するとマクロ有効ファイルとして保存されます。ただし、ファイル名に拡張子を付けなければ拡張子なしのファイルが保存されてしまいます。

ミッションコンプリート?

ユーザビリティから考えると拡張子は自動で保存させたいよなぁ...。もちろん実際には、自動というか、強引な手法を使って拡張子を記入しなくても適切な拡張子を付与して保存をさせています。こんな感じで。

ActiveWorkbook SaveAs FileName:=fileName & "xlsm", FileFormat:=xlOpenXMLWorkbookMacroEnabled
' スマートじゃないなぁ、と思いながら。

もうひとつネタがありますがこれはレギュラーのブログネタにとっておきます。

明日のご予定は?

多分別のVBA案件ですかね。今度はAccessです。書くことがあるかどうかはわからないですがなにか小ネタを探しておきますね。

*1:今日はこれでほぼ1日費やしています。

*2:と言ってもExcelの最初期からあったかどうかは知らないです。

*3:プログラム文脈に沿って引数を自動判別してくれるというのは大変便利ではありますが...。

*4:しかもこのファイルはxlsx以外の拡張子を後付しても開けません。

*5:Excel2003→2007への変更で、「拡張子が変わった」ことはよく言われることですが、拡張子が複数存在することについてはわりと忘れ去られている気がします。