2016/04/09
参考サイト: Excel VBA 入門講座 ワークシートの削除
ワークシートの削除は、Deleteメソッドで行います。
ActiveSheet.Delete
とすればアクティブシートが削除されます。
Worksheets("Sheet3").Delete
とすれば Sheet3 が削除されます。
ただし、削除前に次ぎのような警告メッセージが出ます。
選択したシートに、データが存在する可能性があります。データを完全に削除するには、[削除]をクリックしてください。
メッセージと一緒に [削除], [キャンセル] の二つのボタンが出て、[削除]をクリックすると、そこで初めてワークシートの削除が実行されます。
この警告メッセージを出さずに、直ちに削除が行われるようにするには、下のようにして警告メッセージの出力を抑制します。
Application.DisplayAlerts = False
ActiveSheet.Delete
Application.DisplayAlerts = True
DisplayAlertsプロパティにFalseをセットすると警告メッセージの出力が抑制され、Trueをセットすれば再び警告メッセージが出るようになります。
それから、あまり遭遇しないかもしれませんが、ワークブックにワークシートが1枚しかない状態で、そのワークシートを削除しようとするとエラーメッセージが出ます。ワークブックには、少なくとも1枚のワークシートが所属していなければならないためです。
この時のメッセージは、警告メッセージではなくエラーメッセージです。なので、DisplayAlertsプロパティをFalseにしていてもエラーメッセージは出ます。
このエラーに遭遇しないようにするには、Worksheets.Count でワークシートの枚数をみて、それが2以上であるとの条件の下で ActiveSheet.Delete
などと実行してやればいいことになります。
ちょっと先走りですが、エラーを回避するためのコードを掲げてみます。条件分岐のIf文を用います。
If Worksheets.Count >= 2 Then
Application.DisplayAlerts = False
ActiveSheet.Delete
Application.DisplayAlerts = True
End If
上のコードだと、ワークシートが残り1枚の時に何もしません。ユーザーからすれば「削除しようとしてもできない」と戸惑うかもしれません。Else文を追加して、「残り1枚なので削除できません」といったメッセージを出す方が新設でしょうか。
Deleteメソッドの戻り値は True, False のどちらかです。削除に成功した時は True を返します。
「概要」で述べてきた事柄をVBAマクロとして登録するためのスクリプトを掲げます。
これまでと同様に、マクロには Control + j
というショートカットキーを割り当てます。
アクティブシートを削除し、次に Sheet3 を削除します。
最後に、アクティブシートのA1セルにそのワークシート名を書き込みます。
1# encoding: Windows-31J 2require "./exlap" 3 4macro_str = <<'EOS' 5Sub Macro1() 6 Application.DisplayAlerts = False 7 ActiveSheet.Delete 8 Worksheets("Sheet3").Delete 9 Application.DisplayAlerts = True 10 Range("A1").Value = ActiveSheet.Name 11End Sub 12EOS 13 14macro_name = "Macro1" 15File.delete("Book1.xls") if test(?e, "Book1.xls") # 既存のBook1.xlsを削除 16Exlap.new("Book1.xls") do |wb| 17 wb.macro_add(macro_str) 18 wb.Application.MacroOptions("Macro"=>macro_name, "ShortcutKey"=>"j") 19 wb.save 20end
前述のマクロと同じ処理を行うwin32oleのスクリプトは下のようになります。
1# encoding: Windows-31J 2require "win32ole" 3 4def fullpath(filename) 5 fso = WIN32OLE.new("Scripting.FileSystemObject") 6 return fso.GetAbsolutePathName(filename) 7end 8 9File.delete("Book1.xls") if test(?e, "Book1.xls") # 既存のBook1.xlsを削除 10app = WIN32OLE.new("Excel.Application") 11wb = app.Workbooks.Add() 12app.DisplayAlerts = false 13wb.ActiveSheet.Delete 14wb.Worksheets("Sheet3").Delete 15app.DisplayAlerts = true 16ws = wb.ActiveSheet 17ws.Range("A1").Value = ws.Name 18wb.SaveAs(fullpath("Book1"), -4143) 19app.Quit
同じ処理を行うexlapのスクリプトを掲げます。
exlapで独自に定義されている wb.delete_sheet(……)
を用います。指定されたワークシート1枚を削除するメソッドです。
wb.delete_sheet(……)
は、引数としてワークシートオブジェクトを与えると、そのワークシートを削除します。
wb.delete_sheet("Sheet3")
のように、削除したいワークシートの名前を与えることもできます。
delete_sheetは、削除処理の前後で DisplayAlerts を調整して、警告メッセージが出ないようにします。なので、DisplayAlerts に関する記述を書かなくても大丈夫です。
これまでのサンプルでは、警告メッセージが出ないようにするため、DisplayAlertsプロパティにFalseをセットしました。そして、ワークシートを削除後、今度は True をセットしました。
しかし、厳密にいうと、その処理は妥当ではありません。
もしマクロ記述の別の箇所で、DisplayAlertsを意図してFalseにしていたとしたらどうでしょうか。それを単純にTrueにしてしまうと、意図に反することになります。
そうしたトラブルを避けるには、DisplayAlertsの値を一時的に変数に保存し、ワークシートの削除が済んだところでDisplayAlertsの値を元の値に復元します。こうした「一時的な待避と復元」は、プログラミングではしばしば必要になります。
当シリーズでは、まだ変数について触れられていないので先走りですが、参考まで「一時的な待避と復元」の例を書いてみます。
Sub Macro1()
Dim DVal As Boolean
DVal = Application.DisplayAlerts
Application.DisplayAlerts = False
ActiveSheet.Delete
Application.DisplayAlerts = DVal
End Sub
DisplayAlertsの値を変数 DVal に待避しています。
この変数の型は Boolean です。これは、True, False に対応する型です。
もし文字を代入するなら String、整数値を代入するなら Integer とか Long にします。
VBAでは変数を使う前にその型を宣言します。rubyとかperlなどのスクリプト系プログラミング言語では宣言なしで変数をつかえるので、それに慣れていると面倒ですが、間違った変数の使い方をしてしまった時にデバッグしやすくなるといったメリットがあります。
なお、exlapの wb.delete_sheet(……)
は、DisplayAlertsの値を「一時的な待避と復元」で調整しています。