0の行を消す方法
Excelで表形式のデータを作成する際に、一部のセルの値が0であることがあります。
0に意味がある場合もあって消してはいけない場合が多いとは思いますが、不要で消したい場合もあります。ここでは0のセルがある行を削除するマクロを紹介します。
なお、マクロを使わなくてもテーブル機能やフィルター機能を使えば、表示から0を除外することができます。
また、Excelのデータをテキストエディタに貼り付けて正規表現で「^.*0.*\r\n」(行の先頭から改行文字までのどこかに0がある場合)を空文字に置換するとその行が削除されます。
事前設定
以下のマクロではDictionaryクラスを利用しています。事前に参照設定が必要です。
VBA画面のツールメニュー→参照設定を選び、参照設定ダイアログで「Microsoft Scripting Runtime」にチェックを付けます。
コードの書き方は以下のようになります。
1 2 |
Dim dic As Dictionary Set dic = New Dictionary |
なお、1行で書いても構いません。
1 |
Dim dic As New Dictionary |
厳密には1行で書かない方がいいのですが、普通に利用する分では問題は発生しませんので1行でも構いません。以下のマクロも1行で書いています。
このことについての詳細は「VBAでクラス変数の宣言とNewを1行で書いてよいか」をご参照ください。
選択セル範囲に0がある行を削除するマクロ
以下のマクロは選択したセル範囲の中に値が0のセルがあると、その行を削除します。
セルの選択範囲は複数行、複数列を選択することが可能です。その場合、セル選択範囲であるSelectionをループ処理する場合、範囲の一番左上から一番右下に向かって1セルずつ処理されます。これはVBAの仕様です。
この選択範囲が左上から右下に向かって処理されることの詳細については「VBAのSelectionのセルの格納順序」をご参照ください。
以下のマクロではそのSelectionの特性を考慮した上で、選択範囲のセルを1つずつ0かどうかチェックしています。0であれば削除対象行配列「ar」に格納しています。
なお、セルの値が0かどうかですが、何も入力されていないセルの場合もRange.Valueプロパティでは0と判定されてしまうため、空セルの場合は0と見なさないようにしています。
Dictionaryの用途ですが、削除対象行配列「ar」に既に0のセルの行を登録済みかどうかの判定に利用しています。
セル選択範囲を全てチェックして0が設定されている行が判明したら、それを格納している削除対象行配列「ar」を終端から先頭に向かってループして処理します。終端から先頭に向かうのには理由があります。
それは、先頭から行削除をすると、次に処理する行番号が変わってしまうためです。例えば、1行目と3行目を削除したい場合、1行目を先に削除してしまうと次に削除する行は元々3行目だったのに1行目が無くなったことで2行目に移動してしまいます。行位置が1減ったことを考慮するような処理を入れれば配列の先頭からループしてもいいのですが、わざわざその処理を入れなくても後ろから先頭に向かって処理すれば、元の行位置で削除できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
Sub del0Row() Dim r As Range '// セル Dim dic As New Dictionary '// 削除対象行リスト Dim ar() As Long '// 削除対象行配列 ReDim ar(0) '// 選択範囲を1セルずつループ For Each r In Selection '// 値か文字列が0の場合(空セルを選択した場合は0と見なさないようにする) If (r.Value = 0 Or r.Text = "0") And (r.Value <> "") Then '// 削除対象行リストに未登録の場合 If dic.Exists(r.Row) = False Then '// 0の行を保持 Call dic.Add(r.Row, r.Row) '// 配列に追加 ReDim Preserve ar(UBound(ar) + 1) ar(UBound(ar) - 1) = r.Row End If End If Next '// 0のセルがある場合は不要な最終端の要素を削除する(最終端に0があるため削除する) If ar(0) <> 0 Then ReDim Preserve ar(UBound(ar) - 1) End If Dim i As Long '// ループカウンタ '// 下から上に向かって0がある行をループ For i = UBound(ar) To 0 Step -1 '// 行削除 Call Rows(ar(i)).Delete(Shift:=xlUp) Next End Sub |
実行結果
元(5~10行目を選択して上のマクロを実行。7行目と10行目に0がある)
実行後(10行目、7行目の順に削除される)