2012-01-04 17 views
2

私は3つの列を含むリストを持っています。最初の列には名前があり、他の2つの列には番号があります。マクロは、最初の名前(A1)を取得し、列Aを検索して別のオカレンスを探します。検索とマクロの高速化

それが見つかると、行全体が削除されます。次に、A2に移動して同じことを行います。それは約500のエントリのためのokを働かせるが、3000のエントリを使用することはそれをかなり遅くする。このコードをスピードアップする方法はありますか?

Sub Button1_DeleteRow() 

Dim i As Integer 
Dim j As Integer  
Dim Value As Variant 
Dim toCompare As Variant 

For i = 1 To 3000  
    Value = Cells(i, 1) 
    For j = (i + 1) To 3000 
     toCompare = Cells(j, 1) 
     If (StrComp(Value, toCompare, vbTextCompare) = 0) Then 
      Rows(j).EntireRow.Delete 
     End If 
     Next j 
Next i 

End Sub 

答えて

4

あなたはxl07/10を実行している場合、あなたはRemove Duplicatesを持つ単一の行でこれを行うことができます。あなたは03を実行している場合、オートフィルタでのソリューションは、最も効率的になります(古いバージョンである場合、私はこれを提供することができます)

重複

  1. 手動

    • 選択を削除列A
    • データ....重複を削除する
    • 展開選択
    • Excelを実行している場合、brettdjの答え@補うため
  2. コード

    ActiveSheet.Range("$A$1:$A$3000").EntireRow.RemoveDuplicates Columns:=1, Header:=xlNo

before only A after

+2

+1素晴らしいです! –

+0

ありがとう、素晴らしい答え。マクロがなぜそんなに長い時間を取っているのかをお聞かせください。どうすればスピードアップできますか? – Ali

+1

@Aliあなたの現在のコードを意味しますか?そうであれば3000 =(3000/2)-1500 = 4498500のループを実行しています。範囲ループは本質的に遅いa)速度を上げるには、コード開始時にScreenUpdatingとCalculationをオフにしてください(そしてコード終了時に戻る)b)行を削除する場合は、行をスキップしないように上から下を削除する必要がありますあなたのコードは2つ連続しています)。 – brettdj

3

に重複を見つけるためにのみ、列Aを選択します2003年、あなたはこれを行うことができます

Range("A1:A11").AdvancedFilter Action:=xlFilterInPlace, Unique:=True 

注:次のようAdvancedFilterを歌うAdvancedFilterはあなたの範囲(この例ではA列)の最初の行は、列ヘッダを含み、フィルタリングにその行が含まれないことを前提としています。この手動で行うには

:データ>フィルタ>高度なフィルタを... Bretts技術を使用>ユニークな記録だけ

2

は良い答えです:それはそう長くはかからない理由についての質問に答えるために:
- あなたのマクロは、400万以上の細胞から1つずつ価値を得ています。これは非常に遅いです。
- マクロでスクリーン更新と自動計算がオフになっているとは限りません。行が削除されるたびに画面が更新され、Excelが再計算されます。これらのスイッチを切っていないと、非常に遅いです。
このコードは、その後のコメントに反応して単一のパスで、それは些細な重複を識別して削除する


になるだろう、列Aのデータをソート

Option Explicit 
Sub Button1_DeleteRow() 
Dim i As Long 
Dim j As Long 
Dim vArr As Variant 
Dim iComp As Long 
Dim Deletes(1 To 3000) As Boolean 
Application.ScreenUpdating = False 
iComp = Application.Calculation 
Application.Calculation = xlCalculationManual 
vArr = Range("a1:A3000") 
For i = 1 To 3000 
    For j = (i + 1) To 3000 
     If (StrComp(vArr(i, 1), vArr(j, 1), vbTextCompare) = 0) Then 
      Deletes(j) = True 
     End If 
     Next j 
Next i 
For j = 3000 To 1 Step -1 
If Deletes(j) Then Rows(j).EntireRow.Delete 
Next j 
Application.ScreenUpdating = True 
Application.Calculation = iComp 
End Sub 
0

速く多くのことを実行する必要があります以下では、並べ替えが便利なテクニックである理由について説明します。

列Aを順番に並べ替えると、列Aの隣接する項目を比較するだけで重複除去が行われます。重複行を見つけて削除するか、後で削除するためにフラグを立てることができます。

リストを並べ替えるだけで(並べ替え、組み込みが非常に速い傾向があります)、リストを削除して4498500の代わりに1回処理するだけで、プロセスは実際には面倒ではありません/あなたが行くようにフラグを立てる(あなたがフラグを立てるために行くなら、明らかに後続のクリーンアップパスが必要です)。

リストの順序を変更する場合は、追加の列(たとえば列D)を追加し、D2に値2(つまり行番号のみ)を追加します。後ですべての行に番号が付けられます。並べ替えと削除/フラグ設定の後、元の注文を復元することは列Dを並べ替えるだけで済み、削除することができます。

私はいくつかの操作や重複を実行する必要がある場合は、このメソッドを使用します。つまり、列Aに重複値がありますが、列BとCの値は意味があります(たとえば、列Aの特定の値に関連するすべてのエントリからこれらの値を合計することができます)。しかし、多くの場合、同じ結果を得るためにSQLを使用する方が簡単でしょう。

+0

なぜですか?リストをソートすると、極端な方法(3000個のエントリの手作業による検出がやや面倒である)以外に、ダプを取り除くことができなくなります。さらに、シートレイアウトを変更します。 – brettdj

+0

@brettdjあなたのコメントに答えるために私の答えを編集しました。 – barrowc

関連する問題