• ベストアンサー

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

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

  • エクセル 重複する行の削除に加算処理を追加したい

    データの例と、現在使用しているマクロの内容は以下のようになっております。重複行を消すマクロです。EXCEL2003です。 ◇データ例◇ 名前 点数 田中 20 田中 10 鈴木 10 佐藤 10 佐藤 20 佐藤 20 ◇現在のマクロ◇ Sub sakujo() Dim i As long With Range("A2") 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 A2以下を一つ一つ見て行き、重複していれば削除します。 元データはソートされており、途中にスペースなどは存在しません。 これを、重複する行を消したときに、件数を加算する仕様にしたいです。 上記の例ですと、最終的に 田中 30 鈴木 10 佐藤 50 となるようにしたいです。 よろしくお願いします。

  • 特定の文字を含まないセルの行を削除するには

    いつもお世話になっております。 特定の文字列(下記では"0610")を含まないセルの行を削除するプログラムを組むにはどのようにしたどのようにしたらよいのでしょうか。 以下のようなプログラムを組んでみました。 Sub test() Dim i As Long With Range("C1") For i = .CurrentRegion.Rows.Count To 1 Step -1 If .Offset(i, 0) <> "0610*" Then .Offset(i,0).EntireRow.Delete Next i End With End Sub しかしこれでは先頭行を残し全ての行が削除されてしまいます。 IF文の"<>"がうまくないのだと思いますが、Like演算子の反対のようなものはありませんでしょうか。ご教授いただければ幸いです。 *ちなみに上のプログラムは'06年10月以外のデータは削除するために作ったものです。

  • A B C

    A B C コード 商品 単価 1 チョコレート 100 2 キャンディー 50 3 ガム 80 4 スナック菓子 150 5 乳製品 170 上記表の下にデータを追加していきたいのですが、その際重複データの入力及びコピーもできないようにしたいと思います。 Private Sub CommandButton1_Click() Dim endrow As Long Dim i As Integer endrow = Range("商品").Columns(1).CurrentRegion.Rows.Count Range("商品").Rows(endrow + 1).Columns(1).Value = TextBox1.Value Range("商品").Rows(endrow + 1).Columns(2).Value = TextBox2.Value Range("商品").Rows(endrow + 1).Columns(3).Value = TextBox3.Value TextBox1.Value = Clear TextBox2.Value = Clear TextBox3.Value = Clear With Range("A2") 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 すぐ上の行と同じ場合には入力ができませんが、それ以外での重複している場合の入力を回避する為の改善箇所をご教示の程お願い致します。(コードが同じで入力不可)

  • エクセルで型番ごとにワークシートをマクロで作る方法

    昨日に質問させて頂いたものですが、下記のマクロを教えて頂いたのですが 新しく生成された型番のワークシートが抜けていたり、最後まで型番が生成されない状態です。 なにか間違っていたら直して頂ける方お願いします。 Sub macro4()  Dim h As Range  Dim w As Worksheet  Dim i As Long, e As Long  Application.ScreenUpdating = False  Application.CutCopyMode = False ’準備  Set w = ActiveSheet  w.Range("4:4").Insert shift:=xlShiftDown  e = Range("B65536").End(xlUp).Offset(1).Row  Range("B4").Select ’複写  Do   ActiveSheet.Copy after:=ActiveSheet   Selection.EntireRow.Delete shift:=xlShiftUp  Loop Until ActiveCell.Offset(1) = "" ’片付け  For i = ActiveSheet.Index To w.Index + 1 Step -1  With Worksheets(i)  .Range(.Range("B4").Offset(1), .Cells(e, "B")).EntireRow.Delete shift:=xlShiftUp  End With  Next i  w.Rows(4).Delete  Application.ScreenUpdating = True End Sub http://okwave.jp/qa/q7081084.html

  • #N/Aの文字を削除するには

    お世話になっております。 #N/Aの文字を含む行を削除するため以下のようなマクロ(Excel)を組みました。 Dim i As Long With Range("C1") For i = .CurrentRegion.Rows.Count To 1 Step -1 If .Offset(i, 2) = "#N/A" Then .Offset(i, 5).EntireRow.Delete Next i End With 当然かもしれませんが、IF文の ".offset(i,2)="#N/A""のところで「型が一致しません」とエラーが出てしまいます。 シート上で#N/Aは数式でなく値として記録されています。 どのようにすればエラーを回避できるでしょうか。 よろしくお願いします。

  • 2枚のエクセルのシートを図のように統合させる

    2枚のエクセルのシートを統合させるやり方を教えて下さい。 (同じ項目に2人の人が答えている場合2行に分けることはできますか。) 以前こちらで質問させていただいたとき、 Sub test() Dim Sh1 As Worksheet Dim Sh2 As Worksheet Dim Sh3 As Worksheet Set Sh1 = Workbooks("book1.xls").Sheets("Sheet1") Set Sh2 = Workbooks("book2.xls").Sheets("Sheet1") Set Sh3 = Workbooks("book3.xls").Sheets("Sheet1") Sh1.Range("B5").CurrentRegion.Copy Sh3.Range("B5") With Sh2.Range("B5").CurrentRegion .Resize(.Rows.Count - 1).Offset(1).Copy Sh3.Cells(Sh3.Rows.Count, "B").End(xlUp).Offset(1) End With With Sh3 Dim r As Long For r = .Cells(.Rows.Count, "B").End(xlUp).Row To 6 Step -1 If .Cells(r, "C").Value = "" Then .Rows(r).Delete Next r .Range("B5").CurrentRegion.Sort Key1:=.Range("B6"), Order1:=xlAscending, Header:=xlYes For r = .Cells(.Rows.Count, "B").End(xlUp).Row To 6 Step -1 If .Cells(r, "B").Value = .Cells(r - 1, "B").Value Then .Cells(r, "B").ClearContents Next r End With End Sub というコードを教えていただいたのですが、項目の中があいうえお順になってしまいうまくいきません。 そして、途中に項目があったりしてこれは1つだけ表示されるようにできますか? 説明が足りないところは、補足いたします。 いきなり部署を異動させられて今までやったことないようなことをやっています(涙) どなたか教えて下さいよろしくお願いします。

  • excelマクロの重複セルの削除について

    excelマクロ超初心者です。 E列に下記のようにデータが入っていたとします。   E列 1 いちご 2 りんご 3 みかん 4 いちご 5 りんご 6 れもん これを重複セルを削除して   E列 1 いちご 2 りんご 3 みかん 4 れもん としたいのですが、どうすればいいでしょうか? 自分なりに調べて、下記のように記述したのですが、 Sub test() lastRow = wb.Sheets("Sheet1").Range("E" & Rows.Count).End(xlUp).Row 'E列最終行 For i = lastRow To 2 Step -1 If Cells(i, 5).Value = Cells(i - 1, 5).Value Then Cells(i, 5).EntireRow.Delete Shift:=xlUp End If Next i End Sub() E4列から下のデータしか重複セルが削除されません。 ここでいうlastRow To 2 Step -1はどういう意味なのでしょうか? すみませんが宜しくお願いします。

  • エクセルVBAにて教えて下さい。

    WindowsMeエクセル2000を使用しています。 業務で使用していのですが、自分には知識が無く困っています。 どなたか分かるかた教えて下さい。宜しくお願い致します。 エクセルで下記のようなデータが有ります。 A列 B列 1  東京 2  大阪 1  千葉 下のコマンド実行ではA列で(1)が重複したので、後ろの業(千葉)を残し 前の業(東京)を削除します。 結果 A列 B列 2  大阪 1  千葉 これを逆に東京を残し、千葉を削除したいのですが、 A列 B列 1  東京 2  大阪 どのようにすれば良いのでしょうか? Sub CommandButton2_Click() Dim key As String Dim RCnt As Long Dim i As Long key = "A1" Worksheets("sheet1").Activate ActiveSheet.Range(key).Select Selection.Sort key1:=Range(key), order1:=xlAscending RCnt = ActiveSheet.Range(key).CurrentRegion.Rows.Count For i = 1 To RCnt With ActiveCell If .Value = .Offset(1, 0).Value Then Selection.EntireRow.Delete Else .Offset(1, 0).Select End If End With Next i End Sub

  • エクセル 同じ内容行削除マクロ 2

    シート1、シート2(基準)のB列を比較して同じ内容行を削除したいのですが、「栃木県3」と「#栃木県3」を同じのもと考えて削除されてしまいます。 Sub 削除()   Dim wh1     As Worksheet   Dim wh2     As Worksheet   Dim f      As Range   Dim wR     As Integer   Dim mR     As Long   Dim wStr    As String   '   Set wh1 = Worksheets("Sheet1")   Set wh2 = Worksheets("Sheet2")   wR = 0   With wh1     mR = .Cells(Rows.Count, "A").End(xlUp).Row     For wR = mR To 1 Step -1       wStr = .Cells(wR, "B")       Set f = wh2.Range("B1:B" & wh2.Cells(Rows.Count, "B").End(xlUp).Row).Find(wStr)       If Not f Is Nothing Then         .Rows(wR).Delete       End If     Next   End With End Sub 解決策教えて下さい。

  • ExcelにおけるVBAで、データの振り分けをしたい

    Sub a() Dim i As Long Dim s As Long Dim b As Worksheet Dim c As Worksheet Dim maxi As Long Dim maxs As Long Application.ScreenUpdating = False With ThisWorkbook Set b = .Worksheets("bbb") Set c = .Worksheets("ccc") End With maxi = b.Range("A1").CurrentRegion.Rows.Count maxs = c.Range("A1").CurrentRegion.Rows.Count For i = maxi To 2 Step -1 For s = maxs To 2 Step -1 If c.Cells(s, 1) = b.Cells(i, 1) And c.Cells(s, 2) = b.Cells(i, 2) Then c.Cells(s, 14) = b.Cells(i, 3) End If Next s Next i Application.ScreenUpdating = True End Sub ワークシートcとワークシートbの1列目と2列目が一致したときにだけ、cの14列目にbの3列目のデータを代入したく思い、以上のようなコードを書きましたが、重くて終わる様子がありません。 ・そもそもあっているのか、あっていないならどこを修正すればよいか ・早く終わるようにするにはどうしたらいいか アドバイスをよろしくお願いします。

専門家に質問してみよう