【Excel VBA】フォームコントロール(ボタンなど)を除くすべての図形を一括削除する方法

資料の更新時や、データを再利用する際に「シート上の説明図やグラフは全部消したいけど、操作用のボタンは残しておきたい…」そんな場面はありませんか?

手作業で一つずつ図形を選んで削除するのは大変ですが、VBAを使えば、フォームコントロールだけを賢く見分けて、それ以外の図形(オートシェイプ、グラフ、画像など)を瞬時に一括削除できます。今回はその方法と、安全に実行するための重要な注意点を解説します。


目次

注意点:ループで項目を削除する際の「落とし穴」

シート上の全図形を処理するにはループを使いますが、単純なFor Eachループでコレクションの項目を削除しようとすると、問題が起こることがあります。

' これは危険な例!
' For Each myShp In ActiveSheet.Shapes
'     If Not myShp.Type = msoFormControl Then
'         myShp.Delete
'     End If
' Next

これは、ループの途中で要素を削除すると、コレクションの数やインデックスがずれてしまい、一部の図形がスキップされて削除されないことがあるためです。トランプの山からカードを抜きながら、上から順番に数えていくと数え間違いが起こるのに似ています。


正しい実装:後ろからループして安全に削除する

コレクションの項目を安全に削除するための鉄則は、後ろから逆順にループすることです。後ろから処理すれば、項目を削除しても、まだチェックしていない前方の項目のインデックスはずれないため、すべての項目を確実にチェックできます。

For i = コレクションの数 To 1 Step -1 という書き方をします。


実践コード:フォームコントロール以外の全シェイプを削除

事前準備

マクロを試すために、シート上に様々なオブジェクトを配置しておきましょう。

  • 四角形や矢印などの図形
  • グラフ画像
  • そして最も重要な、フォームコントロールのボタン(「開発」タブ > 「挿入」 > 「フォーム コントロール」から追加)

VBAコード例

以下のコードは、削除という危険な操作の前に確認メッセージを表示し、安全な逆順ループでフォームコントロール以外の全シェイプを削除する、より実践的なサンプルです。

Sub DeleteAllShapesExceptFormControls()

    Dim i As Long
    Dim targetSheet As Worksheet
    
    ' 操作対象のシートを設定
    Set targetSheet = ActiveSheet
    
    ' 重要な処理の前に、必ずユーザーに確認する
    If MsgBox("「" & targetSheet.Name & "」シート上のフォームコントロール以外の図形をすべて削除します。" & _
              vbCrLf & "この操作は元に戻せません。よろしいですか?", _
              vbQuestion + vbYesNo, "最終確認") = vbNo Then
        MsgBox "処理を中断しました。", vbInformation
        Exit Sub
    End If
    
    ' ■ 後ろから逆順にループして、安全に項目を削除する
    For i = targetSheet.Shapes.Count To 1 Step -1
    
        ' シェイプの種類が「フォームコントロール」でなければ削除
        If Not targetSheet.Shapes(i).Type = msoFormControl Then
            targetSheet.Shapes(i).Delete
        End If
        
    Next i
    
    MsgBox "クリーンアップが完了しました。", vbInformation

End Sub

コードの解説

  • If MsgBox(...) = vbNo Then ... MsgBoxを使って、これから行う処理の内容をユーザーに伝え、実行するかどうかの選択肢(はい/いいえ)を提示しています。vbNo(いいえ)が選択された場合は、Exit Subでマクロを安全に中断します。データを削除するマクロでは、このような確認処理は必須です。
  • For i = targetSheet.Shapes.Count To 1 Step -1 シート上の図形の総数(.Shapes.Count)から1まで、Step -1でカウントダウンしながらループします。これが安全な逆順ループです。
  • If Not targetSheet.Shapes(i).Type = msoFormControl Then ... Shapes(i)でi番目の図形を取得し、その.Typeプロパティを調べています。.TypemsoFormControl(フォームコントロールの定数)でない場合 (Not) に、.Deleteメソッドでその図形を削除します。

補足:他の種類のシェイプも判定できる

.Typeプロパティを使えば、フォームコントロール以外にも様々な種類のオブジェクトを判定できます。

  • msoChart: グラフ
  • msoPicture: 図、写真
  • msoGroup: グループ化された図形
  • msoAutoShape: オートシェイプ
  • msoActiveXControl: ActiveX コントロール

これらを組み合わせれば、「グラフと画像だけを削除する」といった、より細かい制御も可能です。


まとめ

今回は、VBAでフォームコントロール以外の図形を一括削除する方法を解説しました。

  • コレクションから項目を削除する際は、後ろから逆順にループする (For i = .Count To 1 Step -1)のが安全な定石。
  • 図形の種類は .Typeプロパティで判定でき、フォームコントロールは msoFormControl という定数で表される。
  • データを削除するようなマクロには、実行前の確認メッセージ (MsgBox) を必ず入れるようにしましょう。

このテクニックは、シートの初期化や定型レポートの整形など、様々な場面で役立ちます。ぜひ、安全な書き方をマスターしてください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次