資料の更新時や、データを再利用する際に「シート上の説明図やグラフは全部消したいけど、操作用のボタンは残しておきたい…」そんな場面はありませんか?
手作業で一つずつ図形を選んで削除するのは大変ですが、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
プロパティを調べています。.Type
がmsoFormControl
(フォームコントロールの定数)でない場合 (Not
) に、.Delete
メソッドでその図形を削除します。
補足:他の種類のシェイプも判定できる
.Type
プロパティを使えば、フォームコントロール以外にも様々な種類のオブジェクトを判定できます。
msoChart
: グラフmsoPicture
: 図、写真msoGroup
: グループ化された図形msoAutoShape
: オートシェイプmsoActiveXControl
: ActiveX コントロール
これらを組み合わせれば、「グラフと画像だけを削除する」といった、より細かい制御も可能です。
まとめ
今回は、VBAでフォームコントロール以外の図形を一括削除する方法を解説しました。
- コレクションから項目を削除する際は、後ろから逆順にループする (
For i = .Count To 1 Step -1
)のが安全な定石。 - 図形の種類は
.Type
プロパティで判定でき、フォームコントロールはmsoFormControl
という定数で表される。 - データを削除するようなマクロには、実行前の確認メッセージ (
MsgBox
) を必ず入れるようにしましょう。
このテクニックは、シートの初期化や定型レポートの整形など、様々な場面で役立ちます。ぜひ、安全な書き方をマスターしてください。