• ベストアンサー

エクセルのマクロで重複データーを削除する

Sub Sample() Dim i As Long With Range("B:B") For i = .CurrentRegion.Rows.Count To 1 Step -1 If .Offset(i, 0) = .Offset(i - 1, 0) Then .Offset(i, 0).EntireRow.Delete Next i End With End Sub 上記のマクロを実行するとエラーがでますが、どこを直せばわかりません。 一つのブックのシート全体のB列の重複データーを削除したいのですが、教えて頂けないでしょうか?

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

  • ベストアンサー
  • onlyrom
  • ベストアンサー率59% (228/384)
回答No.9

またまたまた登場、onlyromです。   >一つのブックのシート全体に適応させたい これは2つの意味に取れますが。。。。 ●例えば、各シートのB列を県名と仮定する (1)ブック全体をひとつのシートとみなしてのダブり削除    シート1、2、3のB列に”東京”があったら    シート1の”東京”を残し、シート2,3の”東京”を削除する (2)ブック全体の各シート内でのダブり削除    シート1、2、3のB列に”東京”があっても    各シート内ではダブっていないので、削除しない     たぶん(1)だと思いますが99%同じコードなので2つともアップ (1)ブック全体をひとつのシートとみなした場合 '------------------------------------------------- Sub TestBook()  Dim R As Long  Dim LastRow As Long  Dim Sht As Worksheet  Dim myDic  Set myDic = CreateObject("Scripting.Dictionary") For Each Sht In ActiveWorkbook.Worksheets   LastRow = Sht.Cells(Rows.Count, "A").End(xlUp).Row   For R = LastRow To 2 Step -1     If myDic.exists(Sht.Cells(R, "B").Value) Then       Sht.Rows(R).Delete xlShiftUp     Else       myDic.Add Sht.Cells(R, "B").Value, ""     End If   Next R Next Sht End Sub '------------------------------------------------------- (2)各シート内でのダブり削除 '------------------------------------------------------- Sub TestSheet()  Dim R As Long  Dim LastRow As Long  Dim Sht As Worksheet  Dim myDic  Set myDic = CreateObject("Scripting.Dictionary") For Each Sht In ActiveWorkbook.Worksheets   LastRow = Sht.Cells(Rows.Count, "A").End(xlUp).Row   For R = LastRow To 2 Step -1     If myDic.exists(Sht.Cells(R, "B").Value) Then       Sht.Rows(R).Delete xlShiftUp     Else       myDic.Add Sht.Cells(R, "B").Value, ""     End If   Next R   myDic.RemoveAll  '●ここだけが違う Next Sht End Sub '------------------------------------------------------- 2つのコードで違いは、●印のmyDic.RemoveAllがあるかないかだけです。 また、上記のようにDictionaryオブジェクトを使うと、B列のデータは、ソートされてなくてもOKです。 新しいブックに簡単なテストデータを作成し試してください。 以上。  

goo0607
質問者

補足

ありがとうございます。 私の説明不足ですいません、回答は2のほうでした。 試しましたら正確に動きました、二つのコードの違いが >myDic.RemoveAllがあるかないかだけです。 だけとは最初見てもわからなかったのでまだまだ勉強が足りません、 今回非常に勉強になりました、ありがとうございました。

すると、全ての回答が全文表示されます。

その他の回答 (8)

  • onlyrom
  • ベストアンサー率59% (228/384)
回答No.8

またまた登場、回答5、onlyromです。 >下記のサンプルを試すとエラーがでました。 いやはや、申し訳ありませぬ。 With ステートばかりに目がいってました。 >For i = Range("A1").CurrentRegion.Rows.Count To 1 Step -1 これでは最終行から1行目までになり、iが1になったときエラーが出ますので、 次のように最終行から2行目まで回すようにしなければいけませんね。 ●の部分。 For i = Range("A1").CurrentRegion.Rows.Count To ●2● Step -1 '--------------------------------------------------- Sub Sample() Dim i As Long For i = Range("A1").CurrentRegion.Rows.Count To 2 Step -1 If Cells(i, "B").Value = Cells(i - 1, "B").Value Then Cells(i, "B").EntireRow.Delete End If Next i End Sub '---------------------------------------------------- それから、 >サンプルに複数のシートを対応させると試しに書いてみました この意味が分かりません。。。文章もちょと怪しいし。。(^^;;;  

goo0607
質問者

補足

ご丁寧にありがとうございました。 >それから、 >サンプルに複数のシートを対応させると試しに書いてみました ↓ 書いて頂いたサンプルコードは一つのシートだけの対応でしたので、 一つのブックのシート全体に適応させたいというのが最終目標でして 試しに書いてみましたがエラーになりどうしていいものかまいっているしだいです。

すると、全ての回答が全文表示されます。
  • don9don9
  • ベストアンサー率47% (299/624)
回答No.7

エラーの原因は他の回答にありますので省略します。 http://officetanaka.net/excel/vba/tips/tips14.htm 上記サイトの「Sample02」のコードを参考に Sub Sample() Dim i As Long With Range("B1") For i = .CurrentRegion.Rows.Count To 1 Step -1 If .Offset(i, 0) = .Offset(i - 1, 0) Then .Offset(i, 0).EntireRow.Delete Next i End With End Sub とすればよいとは思いますが この場合、B列がソートされている必要がありますので 少し変更して Sub Sample() Dim i, j As Long With Range("B:B") For i = 1 To .CurrentRegion.Rows.Count Step 1 With Range("B" & i) If .Value = "" Then Exit For For j = .CurrentRegion.Rows.Count To 1 Step -1 If .Offset(j, 0) = .Value Then .Offset(j, 0).EntireRow.Delete Next j End With Next i End With End Sub とすれば、B列のデータが順不同で入っていても重複分を削除できます。 但し当然ですが前者のコードより処理は遅くなりますので注意下さい。 何万行も処理しようとするとフリーズするかもしれません。 (未確認です)

goo0607
質問者

補足

ありがとうございました。上記のソース確認いたしました。 あとはブックのシート全体に反映させるだけですね・・・・

すると、全ての回答が全文表示されます。
  • n-jun
  • ベストアンサー率33% (959/2873)
回答No.6

#2です。 >A列もC列もデーターはありますが、B列に重複があれば、重複しているデーターを一つ残して >(A列とC列のデーターは保存)行ごと削除です。 もしかするとB列の重複しているデータを1個だけ表示して、あとは空白にすると 言う事ではないのでしょうか?   A B C 1 111 aaa zzz 2 222 aaa yyy 3 333 aaa xxx とあったら   A B C 1 111 aaa zzz 2 222   yyy 3 333   xxx とか? 違っていたらスル~して下さい。

すると、全ての回答が全文表示されます。
  • onlyrom
  • ベストアンサー率59% (228/384)
回答No.5

回答4にもありますが、原因は、With Range("B:B") です。 例えば、i=50 を考えてみましょう .Offset(50,0)  → Range("B:B").Offset(50,0)  → Range("B1:B65536").Offset(50,0) こうなりますので、行だけ考えると シートの最終行65536行に50行プラスした行を指定したことになりエラー 更に今後のためにいうと、 仮に、上記でエラーの出ない許容範囲、仮に、Range("B1:B10")だとしても With Range("B1:B10)   IF .Offset(50,0) = .offset(49,0) then このように複数のセルの値を比較することはできません。 ここでもエラーでます。   '--------------------------------------------------- Sub Sample()  Dim i As Long  For i = Range("A1").CurrentRegion.Rows.Count To 1 Step -1    If Cells(i,"B").value = Cells(i-1, "B").Value Then      Cells(i, "B").EntireRow.Delete    End If  Next i End Sub '-------------------------------------------------   

goo0607
質問者

補足

丁寧なご説明ありがとうございます。 下記のサンプルを試すとエラーがでました。 サンプルに複数のシートを対応させると試しに書いてみましたが エラーでした・・・難しいですね・・・ Sub Sample()  Dim i As Long  For i = Range("A1").CurrentRegion.Rows.Count To 1 Step -1    If Cells(i,"B").value = Cells(i-1, "B").Value Then      Cells(i, "B").EntireRow.Delete    End If  Next i End Sub

すると、全ての回答が全文表示されます。
  • web2525
  • ベストアンサー率42% (1219/2850)
回答No.4

With Range("B:B")に対して .Offset(i, 0)と指定している部分がまずいのだと思います。

すると、全ての回答が全文表示されます。
  • hallo-2007
  • ベストアンサー率41% (888/2115)
回答No.3

ご希望の動きになるかわかりませんが、 For i = .CurrentRegion.Rows.Count To 2 Step -1 If .Cells(i, 2) = .Cells(i - 1, 2) Then .Cells(i, 2).EntireRow.Delete Next i エラーの訂正なら、といったことでしょうか。

すると、全ての回答が全文表示されます。
  • n-jun
  • ベストアンサー率33% (959/2873)
回答No.2

B列が重複している”行”を削除するというのは、A列やC列以降にはデータがないのでしょうか? ようはB列の重複を消す場合に、他の列が削除に関連するかどうかですけど。 しない(B列のみデータがある)ならフィルタオプションでしょうか。 http://www.eurus.dti.ne.jp/~yoneyama/Excel/filter3.htm#tyusyutu とか。

goo0607
質問者

補足

A列もC列もデーターはありますが、B列に重複があれば、重複しているデーターを一つ残して(A列とC列のデーターは保存)行ごと削除です。

すると、全ての回答が全文表示されます。
  • marbin
  • ベストアンサー率27% (636/2290)
回答No.1

直接の回答ではないですが。 フィルタオプションの設定を使う Dictionaryを使って重複無し配列を作成 などの方法で重複なしリストを作成できます。

すると、全ての回答が全文表示されます。

関連するQ&A