行の挿入と削除

中級VBA

はじめに

 行の挿入には Insert メソッドを使い、行の削除には、Delete メソッドを使います。
 これらのメソッドは、実行後に行数が変化するため繰り返して使う場合は注意が必要です。
 殆どの場合、繰返しを逆順で行う事で上手くいきます。
 
  Insert メソッドについては、Copyした行を貼り付けるために使用する事もできます。

行の挿入 Insert

 行を挿入する Insert メソッドは以下のように使います。
 Rowsを使った方法と、Range().EntireRowを使う方法があります。
 Rowsでは行数を指定します。3 を “3” のように文字列で指定してもOKです。
 Range().EntireRowでは、Rangeの指すセルの属する行が対象となります。

Sub RowsInsertTest1()
    Rows(3).Insert
End Sub

Sub RowsInsertTest2()
    Range("A3").EntireRow.Insert
End Sub

 両方とも同じ結果になります。上のように3行目に空白行が挿入されて、3行目以降が4行目以降にシフトする形になります。
 指定した行が空白となり、それ以降はズレると覚えておきましょう。

複数行の挿入

 一度に複数の行を挿入するには、以下のように書きます。
 3行目~5行目に空白行を挿入します。
 この場合、Rowsの引数は、“3:5” のように文字列で指定します。

Sub RowsInsertTest3()
    Rows("3:5").Insert
End Sub

Sub RowsInsertTest4()
    Range("A3:A5").EntireRow.Insert    
End Sub

 こちらも指定した行が空白となり、それ以降はズレます。

コピーした行を挿入する

 行をコピーした後に、 Insert メソッドを使うとコピーした行が挿入されます。
 最後の、 Application.CutCopyMode = False はコピーモードを解除しています。

Sub RowsInsertTest5()
    Rows(3).Copy
    Rows(3).Insert
    Application.CutCopyMode = False   'コピーモード解除
End Sub

 このプログラムでは、3行目をコピーして3行目に挿入しています。
 コピー元の3行目は、4行目になります。(赤枠)

 以下のように書いても同じ結果が得られます。

Sub RowsInsertTest5a()
    Rows(3).Copy
    Rows(4).Insert
    Application.CutCopyMode = False   'コピーモード解除
End Sub

 結果は同じですが、こちらは、コピー元の3行目は3行目に残り、4行目にコピーした行を挿入しています。

一行おきに行を挿入

 一行おきに行の挿入を行う際は、行を挿入した時の挙動を考慮する必要があります。
 以下は上手くいかなかった例です。

'【失敗例】
Sub RowsInsertTest6()
    Dim i As Long
    For i = 2 To 6
        Rows(i).Insert
    Next i
End Sub

 この例では、追加された行が常に挿入先の行に指定されてしまうため上手くいきません。
 以下のように書けばうまくいきます。

'挿入行(r)は、2,4,6,8,10 を取れば良い。
Sub RowsInsertTest6a()
    Dim i As Long, r As Long
    r = 2
    For i = 2 To 6
        Rows(r).Insert
        r = r + 2
    Next i
End Sub

 上の例では、挿入行を別に指定しています。
 ただ、Forループを逆順にしてやれば簡単に書く事ができ、こちらの方が一般的に良く用いられます。

Sub RowsInsertTest7()
    Dim i As Long
    For i = 6 To 2 Step -1
        Rows(i).Insert
    Next i
End Sub

 繰り返し処理を逆順にする事で、行の位置が変化しても、これから挿入される位置とは無関係になるため上手くいきます。

行の削除 Delete

 行の削除は、Delete メソッドを使います。
 使い方は、Insert メソッドとほぼ同じです。
 Rowsの行数指定は、3 を “3” のように文字列で指定してもOKです。

Sub RowsDeleteTest1()
    Rows(3).Delete
End Sub

Sub RowsDeleteTest1()
    Range("A3").EntireRow.Delete
End Sub

 行の削除の場合、指定した行が削除されそれ以降の行が繰り上がります。

複数行の削除

 一度に複数の行を削除するには、以下のように書きます。
 3行目~5行目に空白行を削除します。
 この場合、Rowsの引数は、“3:5” のように文字列で指定します。

Sub RowsDeleteTest3()
    Rows("3:5").Delete
End Sub

Sub RowsDeleteTest4()
    Range("A3:A5").EntireRow.Delete
End Sub

一行おきに行を削除

 RowsInsertTest7()で行を挿入した例を使って、一行おきに行を削除をしてみましょう。
 以下のように書く事で一応上手くいきます。

Sub RowsDeleteTest5()
    Dim i As Long
    For i = 2 To 6
        Rows(i).Delete
    Next i
End Sub

 ただし、実際に削除する行がイメージしにくいのが欠点です。
 こちらも逆順にする事で削除する行の位置がイメージしやすくなります。

Sub RowsDeleteTest6()
    Dim i As Long
    For i = 10 To 2 Step -2
        Rows(i).Delete
    Next i
End Sub

検索結果で行を削除する

 検索にヒットした行を削除したい場合は、繰り返し処理は逆順にした方が良いでしょう。
 以下のような表があった時に品名が 「リンゴ」 の行を削除するには以下のように書きます。

Sub DeleteItem()
    Dim i As Long
    For i = 7 To 2 Step -1
        If Cells(i, "B") = "リンゴ" Then
            Rows(i).Delete
        End If
    Next i
End Sub

 これを、逆順にしない場合、上手くいかない場合が出てきます。
 表のように 「リンゴ」 が2行続けて出てきた場合、うまく削除されません。

 データの並びによってうまくいく場合と、うまく行かない場合がありますので注意してください。

まとめ

 Insert や Delete メソッドでは、繰り返し処理を行うと指し示す行が変化してしまいますので注意が必要です。
 殆どの場合、繰り返し処理を逆順にすればうまく行くでしょう。

 
 挿入や削除の対象がイメージしやすいようにプログラムを書く事が大事で、そうする事で後々の変更などもスムーズに移行できるようになります。

タイトルとURLをコピーしました