マクロありブック(xlsm)をマクロなしブック(xlsx)として保存する


マクロを使って、何かのデータを作成したとしましょう。そのブックを、取引先など第三者に渡すとき「これ、データだけでいいんだよなぁ~マクロは渡したくないんだよなぁ~」ってことありませんか?ありますよね。その「マクロ入りブック(xlsm)」を「マクロなしブック(xlsx)」として保存し直す作業を、もし手動でやっているのなら、いっそのこと、そこもマクロで自動化してしまいましょう。こういうファイル操作って、思いのほか面倒くさいですからね。

実は超簡単

既存ブックから、マクロつまり「VBAのコード部分」を除去するって考えたら大変なんですけど、でもこれ、実は簡単にできるんです。その「マクロ入りブック(xlsm)」を「マクロなしブック(xlsx)」形式で保存してやればいいんです。マクロが含まれているブックを xlsx 形式で保存しようとすると次の確認が表示されますよね。

ここで[はい]ボタンをクリックして、強引に xlsx 形式で保存すれば、自動的にマクロは除去されます。したがって、次のコードだけでOKです。

Sub Macro1()
    ActiveWorkbook.SaveAs "C:\Work\Data.xlsx", xlOpenXMLWorkbook
End Sub

"C:\Work\Data.xlsx"は、新しく「マクロなしブック」として保存するファイル名です。適時変えてください。ポイントは最後の「xlOpenXMLWorkbook」です。これは「ファイルの形式は"マクロなしブック(xlsx)"で保存してください」という指定です。「xlOpenXMLWorkbook」は定数なんですけど、これ、ちょっと長くないですか?Excel 2007以降の、拡張子が"xlsx"や"xlsm"になったファイルって"Open XML"と呼ばれる形式です。その形式のブック(Workbook)なのですから、まぁ意味としては分かるんですけど、酔っ払ってるときなどに、パッと思い浮かばないこともあります。実はこの定数「xlOpenXMLWorkbook」って、実体は「51」です。私はそれを覚えているので、いつもは次のように「51」と書いちゃいます。

Sub Macro1()
    ActiveWorkbook.SaveAs "C:\Work\Data.xlsx", 51
End Sub

ちなみに「マクロ入りブック(xlsm)」として保存するときには、定数「xlOpenXMLWorkbookMacroEnabled」を指定するんですが、これなんかシラフのときでも打ち間違えます。こちらの定数も実体は「52」です。なので「xlsx → 51, xlsm → 52」って覚えてます。

さて、マクロ入りブックを上記のコードで保存しようとすると、やはり先の確認画面が表示されます。この確認画面を表示しないで保存するには、Application.DisplayAlerts に False を指定してやります。

Sub Macro1()
    Application.DisplayAlerts = False
    ActiveWorkbook.SaveAs "C:\Work\Data.xlsx", 51
    Application.DisplayAlerts = True
End Sub

Application.DisplayAlerts って、よく「ワークシートを削除する」ときに表示される確認画面を抑止するときに使われますが、こんなときにも便利です。

ボタンも削除したい

みなさん、マクロを実行するときってどうしてますか?VBAが分からないExcelのビギナーに「VBEを開いて[F5]を押してください」ってのは無理ゲーです。多くの場合、ワークシート上にボタンなどを配置して、そのボタンをクリックすることでマクロが実行できるようにすることが一般的です。これなら、ビギナーでも扱えますからね。でも、先の方法で「マクロなしブック(xlsx)」として保存しても、ワークシート上のボタンは残ったままです。これは、いただけません。ボタンには「クリックされたとき、どのマクロを実行するか」という情報が記録されていますので、クリックすると「マクロがありません」みたいなエラーになります。ここはひとつ、ボタンも削除しちゃいましょう。

マクロを登録するボタンなどのように「セルに依存しないで、ワークシート上で自由に配置できるものなど」のことを、総称してShapeオブジェクトと呼びます。もし「ワークシート上にボタン(Shapeオブジェクト)が1つしか存在しない」のでしたら、次のように簡単です。

Sub Macro1()
    Application.DisplayAlerts = False
    ActiveSheet.Shapes(1).Delete
    ActiveWorkbook.SaveAs "C:\Work\Data.xlsx", 51
    Application.DisplayAlerts = True
End Sub

Shapes(1) というのは「ワークシート上で 1番目 に配置された Shapeオブジェクト」という意味です。上記のように「ワークシート上にあるShapeオブジェクトは、マクロを実行するためのボタン1つしか存在しない」のでしたら Shapes(1) でもいいのですが、"思いもよらないもの"が実は Shape オブジェクトだったりします。ちょっと、さまざまな Shape オブジェクトをご紹介しましょう。

[挿入]タブの[図]グループから挿入できるものは、すべて Shape オブジェクトです。ほかにもあります。

グラフもShape オブジェクトですし、テキストボックスも Shape オブジェクトです。ほとんど知られていないのが、入力規則のリストを設定したときに表示される▼ボタンも Shape オブジェクトですし、セルに挿入されたコメント枠も Shape オブジェクトです。

要するに言いたいことは、その削除しようとしている「マクロを実行するためのボタン」は、本当に「1番目に挿入された Shape オブジェクトですか?」ということです。どうです?こう言われると心配になりませんか?

「はいっ!間違いありません!(キリッ」と断言できるのでしたら、Shapes(1) でもOKですが、ちょっとでも自信がなかったら、ボタンを Shapes(1) のように番号で指定するのではなく、名前で指定した方が安全です。マクロを実行するためによく使われるボタンは、標準で「ボタン 1」「ボタン 2」という名前が設定されます。ボタンの名前は、ボタンを選択したとき「名前ボックス」に表示されます。

Sub Macro1()
    Application.DisplayAlerts = False
    ActiveSheet.Shapes("ボタン 1").Delete
    ActiveWorkbook.SaveAs "C:\Work\Data.xlsx", 51
    Application.DisplayAlerts = True
End Sub

ちょっと余談です。ボタンなどの Shapeオブジェクトには、昔から不思議な特徴があります。たとえば、ワークシートに新しいボタンをひとつ挿入したとします。

ややこしくなるので、ボタンに表示する文字列(Captionプロパティ)は「Click Me」に編集しました。さて、このボタンの名前は「名前ボックス」に表示されている"ボタン 1"です。したがって、このボタンは Shapes("ボタン 1") で特定できます。では、このボタンの名前を、Nameプロパティで調べてみましょう。

Sub Macro2()
    MsgBox ActiveSheet.Shapes("ボタン 1").Name
End Sub

Nameプロパティは"Button 1"となっています。もちろん、Shapes("Button 1") でもこのボタンを特定可能です。ってことは、ボタンには名前が2つあるのかと。ローカルウィンドウで調べてみました。

どこを探しても"ボタン 1"という値は見つかりません。Nameプロパティは"Button 1"です。この状態では、Shapes("ボタン 1") と Shapes("Button 1") は、どちらでも指定可能です。では、ボタンの名前を「名前ボックス」で変更してみます。

先と同じコードで、Nameプロパティを調べると、

Nameプロパティも変更されています。この状態ではもう、Shapes("Button 1") は使えません。エラーになります。指定できるのは、Shapes("実行ボタン") だけです。「名前ボックス」に表示される文字列と、Nameプロパティが連動しているのは分かります。だったらなぜ、挿入した直後の初期状態では、

  • 名前ボックス → ボタン 1
  • Nameプロパティ → Button 1

となっていて、しかも両方名前として指定できるってのが解せません。じゃ、このとき「名前ボックス」に表示される"ボタン 1"って何なのでしょう。たぶん、英語圏ではどちらも"Button 1"なので違和感がないのでしょうね。大昔から疑問に感じているのですが、まぁ、それほど大きな話ではありませんので、ずっとモヤモヤしたままやってます。たぶんですけど、ネットに公開されているコードなどでも、Shapes("ボタン 1") と Shapes("Button 1")が混在していると思いますが、こうした理由なので、あまり気にしないでください。