- ベストアンサー
処理速度が万行の重複検出コードが応答なしになる問題の解決方法
- 8万列のデータに対して重複検出コードを実行すると応答なしになる問題の解決方法を教えてください。
- ExcelのVBAコードで、データの重複を検出し、重複があれば隣に印を付ける処理をしていますが、処理速度が遅くなってしまいます。
- 処理速度を向上させるためにはどのような記述をすれば良いですか?
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは CountIfも遅いですし、一個一個セルにアクセスするのも遅い原因かと思います。 Sub test() Dim i As Long Dim v As Variant Dim d As Object Set d = CreateObject("Scripting.Dictionary") With Range("X1", Range("X" & Rows.Count).End(xlUp)) .Offset(, 1).ClearContents v = .Resize(, 2) For i = 1 To UBound(v, 1) If d.Exists(v(i, 1)) Then d(v(i, 1)) = d(v(i, 1)) + 1 Else d.Add v(i, 1), 1 End If Next For i = 1 To UBound(v, 1) v(i, 2) = IIf(d(v(i, 1)) > 1, "●", "") Next .Resize(, 2) = v End With End Sub
その他の回答 (2)
- imogasi
- ベストアンサー率27% (4737/17069)
先日、OKWAVEの質問に、重複をマークする、という質問があり、私は http://okwave.jp/qa/q9197965.html?f=mail_thanks のNo2で「ソート法」というのを紹介しました。 本件でその方法をテストデータで具体的にやってみた。 === Sub test01() '乱数で8万元数値データ作成 A列 For i = 1 To 80000 Cells(i, "A") = Int(Rnd() * 1000000#) Next i End Sub '----- Sub test02() '元データに連番を振る B列 For i = 1 To 80000 Cells(i, "B") = i Next End Sub '--- Sub test03() '---A列でソート Worksheets("Sheet1").Range("A1:B80000").Sort Key1:=Range("A1"), Order1:=xlAscending '--同じ値の行のC列にマークを付ける For i = 2 To 80000 If Cells(i - 1, "A") = Cells(i, "A") Then Cells(i, "C") = "○" End If Next i '--当初データの順に復元 Worksheets("Sheet1").Range("A1:C80000").Sort Key1:=Range("B1"), Order1:=xlAscending End Sub ==== 時間は、Test01、Test02、Test03それぞれ1-2秒で終わった。 Test02はTest01のコードの終りに含めることができる。 ーーー >下記のコードを実行すると応答なしとなってしまいます が今のパソコンで、手に負えない量のものかどうか、調べたかったのでやってみた。 以上の実験から、データ数が8万で、多すぎてじかんがかかるということはないと思う。 何か処理ロジックかコードにエラーがあると思う。 == ソート法 昔(パソコン普及の時代の前)から、ソート法は、オフラインバッチ処理で、処理ロジックで重用されたもので、メーカーが作る、ユティリティソフトのソートのロジック(やその処理スピード)などもソフトメーカーが力を注ぎ、MSでも完成されたものになっていると思う。
- SI299792
- ベストアンサー率47% (774/1619)
countif は遅いです。一つ一つ比較していますから。 =80000*80000で6400000000回比較をすることになります。 セルに直接数式を書き込んでも同じでした。 データを並べ替え、上下だけ比較して、元に戻す。私のパソコンで試したら、7秒でできました。 Sub Macro2() ' Dim iy As Long Dim iye As Long ' Aplication.ScreenUpdating = False ' iye = Range("X" & Rows.Count).End(xlUp) [Y:Y].ClearContents ' For iy = 1 To iye Cells(iy, "W") = iy Next iy ' [W:Y].Sort Key1:=[X1] ' For iy = 2 To iye If Cells(iy - 1, "X") = Cells(iy, "X") Then Cells(iy - 1, "Y") = "●" Cells(iy, "Y") = "●" End If Next iy ' [W:Y].Sort Key1:=[W1] [W:W].ClearContents ' End Sub ' ただし、Wをワークエリアに使っているのでWは消えます。 もしWが使えないなら、別シートにコピーしてから、処理をするしかないですね。