• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:条件に合った行を削除するマクロについて)

条件に合った行の削除マクロの効率的な方法

このQ&Aのポイント
  • 条件に合った行を削除するマクロの効率的な方法はどうすればいいでしょうか?
  • 後ろから探索して1行ずつ削除する方法が一般的ですが、Unionでセルの範囲を結合してから一度に削除する方法も考えられます。
  • しかし、Union結合を使用した方法は遅くなってしまいます。なぜUnion結合が遅いのでしょうか?効率的なマクロを作成するためには後ろから探索する方法が適しているかもしれません。

質問者が選んだベストアンサー

  • ベストアンサー
  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.5

#2です。 行を削除するのはいずれにしても遅いと思うので、抽出する方法を追加で試してみました。 xl2010(32bit), WinXP SP3, 昔のCeleron 2.4GHzの環境です。 データは#2と同じで、1万行の内、半分程度を削除する条件です。 ○下から、行削除 平均17秒程度 ○セル範囲→配列→別配列に抽出→セル範囲に丸ごと代入 平均1.9秒程度 ○フィルタオプションで別シート抽出 0.6秒程度 ・フィルタオプションは意外に速く、見直しました。(抽出条件の複雑さにもよると思いますが) ・xl2010はxl2003までに比べて重たいイメージでしたが、行削除に何倍もかかるという訳ではありませんでした。 以上、ご参考まで。

iori16
質問者

お礼

回答遅くなりましたすみません。 なるほど、フィルタオプションですか。 エクセルの既存の機能を使った方が速いんですね。 他の方もいろいろ案を出してくださったのですが、実際に速度まで測って検討してくださったmitarashiさんをベストアンサーにさせていただきます ありがとうございました

その他の回答 (4)

  • 30246kiku
  • ベストアンサー率73% (370/504)
回答No.4

解決されていましたらスルーしてください。 速い遅いはわかりませんが、以下ではどうでしょうか 作業用に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 は不慣れなため、具体的説明は無理かも・・・・ (まずは、ヘルプを参照ください)

iori16
質問者

お礼

回答ありがとうございます。 返答が遅くなりまして申し訳ありません。 教えていただいた方法試して見ます。

  • Siegrune
  • ベストアンサー率35% (316/895)
回答No.3

試された結果の通り、 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 と処理速度が違ったかも。 (ただ、少数の行の処理ではわからないと思います。)

iori16
質問者

お礼

回答ありがとうございます。 返答が遅くなりまして申し訳ありません。 教えていただいた方法試して見ます。

  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.2

徒然なるままにやってみました いずれも Application.ScreenUpdating = False Application.Calculation = xlCalculationManual を入れてあります。今回のケースでは後者は0.数秒くらいしか効きませんでしたが。 xl2000,WinXP SP3,初代Pentium4 3Gの環境です。 A,B,C列が数文字の文字列で、D列が3桁の乱数。乱数が500より大きい行を削除する事例です。 10000行に合わせました。 1.普通に下から行(行全体)を削除する 11秒台 2.条件に合うセル範囲を一旦Unionして丸ごと削除する 50数秒台 (範囲内だけ消しても、行全体を消しても大差無し) と、ご指摘の通りUnionする方が数倍遅かったです。条件分岐等でRangeを操作する回数が増えるので、遅くなるのかもしれません。試しにUnionしたセルを丸ごと消すところをコメントアウトして実行すると40数秒かかりましたので、行を消すのにかかる時間は、1,2共に同じ位で、Unionする部分に時間がかかる分だけ遅くなると言えそうです。 ご自分のコードの要所にGetTickCountを入れて確認されれば良いと思います。 速くしたければ、一旦配列に収納して、上記の例では500未満のデータだけ別シートに書き出す方法をとれば数分の1~十分の一位の時間で処理可能でした。(redimとかしないで、同一サイズの配列に条件に合うデータを移し、丸ごと別シートに貼り付ける単純なコードです)ニーズに合うかどうかは分かりませんが、ご参考まで。

iori16
質問者

お礼

Unionはどうも、結合する数が膨大になっていくにつれて遅くなっていくような気がしました。 一概に早いマクロって理論道理にいかないものですね・・・ 早いマクロ作るにはなかなか苦労します。 1万件もあるファイルが6ファイルもあるので、なるべく早いマクロを試してみようと思います。 配列のアイデアありがとうございます 作業シートを使うと早くなりそうですね

  • nao-y
  • ベストアンサー率58% (111/190)
回答No.1

後者は Application.ScreenUpdating = False を入れているから早いのでは?

iori16
質問者

補足

前者にApplication.ScreenUpdating = Falseを入れても変わりませんでした。 ちなみに前者Unionの方は2~3分かかるのに対し、後者は数秒しかかかりません。 また、union結合を使って、1行おきにセル範囲を結合していくマクロを作成した場合でも、同じくらい時間がかかる為、ボトルネックはUnion結合にあると考えます