ワークシートの削除 – ExcelVBAの散策とruby

2016/04/09

参考サイト:  Excel VBA 入門講座 ワークシートの削除


《目次》


1. 概要

 ワークシートの削除は、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 を返します。

目次に戻る


2. マクロを登録するスクリプト

 「概要」で述べてきた事柄を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

目次に戻る


3. win32oleのスクリプト

 前述のマクロと同じ処理を行う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

    

目次に戻る


4. exlapのスクリプト

 同じ処理を行うexlapのスクリプトを掲げます。

 exlapで独自に定義されている wb.delete_sheet(……) を用います。指定されたワークシート1枚を削除するメソッドです。

    

 1# encoding: Windows-31J
 2require "./exlap"
 3
 4File.delete("Book1.xls")  if test(?e, "Book1.xls")  # 既存のBook1.xlsを削除
 5Exlap.new("Book1.xls") do |wb|
 6    wb.delete_sheet(wb.ActiveSheet)
 7    wb.delete_sheet("Sheet3")
 8    ws = wb.ActiveSheet
 9    ws.Range("A1").Value = ws.Name
10    wb.save
11end

    

 wb.delete_sheet(……) は、引数としてワークシートオブジェクトを与えると、そのワークシートを削除します。

 wb.delete_sheet("Sheet3") のように、削除したいワークシートの名前を与えることもできます。

 delete_sheetは、削除処理の前後で DisplayAlerts を調整して、警告メッセージが出ないようにします。なので、DisplayAlerts に関する記述を書かなくても大丈夫です。

目次に戻る


5. 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の値を「一時的な待避と復元」で調整しています。


前のページ:ワークシートのコピー

次のページ:ワークシートのイベントプロシージャ

「ExcelVBAの散策とruby」トップページ