こんにちは
今、現在、とある条件にあった行を削除するマクロ作っているのですが、
インターネットを調べてみると後ろから探索して、1行ずつ消していくのがいいと書いてありました。
まぁ、その理屈はわかるんですが、それなら
「Unionでセルの範囲を結合してから、最後に一度に消してしまった方が速いのでは」
(消す作業が1度だけで済むから)
と思い試してみたんですが、実際試したところ・・・
ものすごく遅かったです。
(ちなみに、1万件のデータで削除した行数は6000ほどでした)
何故Union結合だと遅いのでしょうか?
速いマクロを作成するには、やはり後ろから探索して、1行ずつ消していくしかないのでしょうか?
以下は試したマクロです。
(test が unionで試したマクロ、test2が後ろから1行ずつ削除したマクロ)
Option Explicit
Public Sub test()
Dim r As Range
Dim r1 As Range
'Cells.Replace "-", " "
For Each r In Range("A2", Range("A65536").End(xlUp))
If r = r.Offset(1, 0) And r.Offset(0, 1) < r.Offset(1, 1) Then
If r1 Is Nothing Then
Set r1 = r
Else
Set r1 = Union(r1, r)
End If
End If
Next
r1.EntireRow.Delete
' r1.Select
End Sub
Public Sub test2()
Dim r As Range
Dim r1 As Range
Dim i As Integer
'Cells.Replace "-", " "
Application.ScreenUpdating = False
For i = Range("A65536").End(xlUp).Row To 1 Step -1
If Cells(i, 1) = Cells(i + 1, 1) And Cells(i, 2) < Cells(i + 1, 2) Then
Cells(i, 1).EntireRow.Delete
End If
Next
Application.ScreenUpdating = True
End Sub
解決されていましたらスルーしてください。
速い遅いはわかりませんが、以下ではどうでしょうか
作業用にK列を使ってます。
都合悪ければ、With .Offset(, 10) 部分を変更してください。
Sub Sample()
On Error Resume Next
With Range("A2", Cells(Rows.Count, 1).End(xlUp))
With .Offset(, 10)
.Formula = "=IF(AND(A2=A3,B2<B3),1,"""")"
.Value = .Value
.SpecialCells(xlCellTypeConstants, 1).EntireRow.Delete
.ClearContents
End With
End With
End Sub
試される時には、戻せる状態で行ってください。
なお、上記は以下を参考にしていました。
VBAのことを教えてください
http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1486329244
EntireRow を Union する方法もあるようです。
※ Excel VBA は不慣れなため、具体的説明は無理かも・・・・
(まずは、ヘルプを参照ください)
試された結果の通り、
Unionした結果に対して行を追加するのは遅かったと思うので、
複数の行の選択を1回でして、削除をすると別に遅くはないのでは?
Public Sub test3()
Dim r As Range
Dim r1 As Range
dim wkstr as String
wkstr = ""
For Each r In Range("A2", Range("A65536").End(xlUp))
If r = r.Offset(1, 0) And r.Offset(0, 1) < r.Offset(1, 1) Then
If wkstr = "" Then
wkstr = trim(cstr(r.row)) & ":" & trim(cstr(r.row))
Else
wkstr = wkstr & "," & trim(cstr(r.row)) & ":" & trim(cstr(r.row))
End If
End If
Next
range(wkstr).Delete
' r1.Select
End Sub
といった感じででも試してみられては。
(未検証)
・・・Cells(i, 1).EntireRow.Delete と rows(i).delete と処理速度が違ったかも。
(ただ、少数の行の処理ではわからないと思います。)
お礼
回答遅くなりましたすみません。 なるほど、フィルタオプションですか。 エクセルの既存の機能を使った方が速いんですね。 他の方もいろいろ案を出してくださったのですが、実際に速度まで測って検討してくださったmitarashiさんをベストアンサーにさせていただきます ありがとうございました