- ベストアンサー
マクロで重複データの削除
過去ログを使っていろいろ試したのですが、うまくいかなかったので助言お願いします。 データ的には B列 C列 AAA 50 AAA 50 BBB 70 BBB 70 BBB 72 CCC 25 のようなデータあります。 これを「AAA」でC列のデータが同じやつはひとつにするということをやりたいのです。 B列 C列 AAA 50 BBB 70 BBB 72 CCC 25 のようになります。 B列第一優先にC列第二で並べ替えをして、過去ログ参照より、下のデータからループしてくというのを試したのですが、全部削除されてしまいます。 しかし、これでは並べ替えの場合によってはCの重複がおかしくなると思うので、B列参照したほうがいいのかな? 別シートに書き出しタイプでないやり方をしたいと思っています。お助けくださいよろしくお願いします。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
Cells(行,列) でA列は1ですので、 If Cells(i, 1).Value = Cells(i - 1, 1).Value Then はA列を比較しています。 また、この場合はB列とC列を同時に比較しないと希望に適いません。 If Cells(i, 2).Value = Cells(i - 1, 2).Value And _ Cells(i, 3).Value = Cells(i - 1, 3).Value Then Cells(i, 1).EntireRow.Delete Shift:=xlUp End If
その他の回答 (5)
- papayuka
- ベストアンサー率45% (1388/3066)
#2です。 > やっぱりだめでした。(並び替え) ソート不要案で解決かな? 例えば、 1.B5から始まる表で、C5,D5,E5・・・と5行目は全てタイトル行 2.B列は最後の行までデータが入っている 3.最終行は並び替えたくない こんなデータとして、B5とC5をキーに並び替える例です。 試すならテスト環境で。 Sub Test1() With Range("B5").CurrentRegion .Resize(.Rows.Count - 1, .Columns.Count).Sort _ key1:=Range("B5"), key2:=Range("C5"), Header:=xlYes End With End Sub #4さんじゃないけど、No5は > D6:D列の最後に「B6_C6」を全部のセルに入力する。 > という意味であっていますか? D6:D列最後に =B6&"_"&C6 という式を一気に代入してます。 相対参照で代入されたセルは相対的に変化するので D6 =B6&"_"&C6 D7 =B7&"_"&C7 D8 =B8&"_"&C8 ・ ・ D最後 =B最後&"_"&C最後 を入れたのと同じです。
お礼
範囲が決まっていない並べ替えは結構ややこしいですね。がんばって勉強してみます。 全部のセルにB6&"_"&C6がはいるのか思いました。 相対参照で代入されるんですね。なるほど 非常に勉強になりました。ありがとうございました。
- maruru01
- ベストアンサー率51% (1179/2272)
No.4です。 >rastrowなんですが・・・実は >http://oshiete1.goo.ne.jp/kotaeru.php3?q=965118 >のmaruru01さんのを参考にしているからなんです(汗) げ、本当だ・・・ 恥ずかしー さて、気を取り直して、 >Range("D6:D" & lastrow).Formula = "=B6 & ""_"" & C6" 今回はB列とC列の複数条件での重複削除です。 そういう場合は、B列とC列の値を連結することで、1つの条件にするということです。 間に"_"を入れているのは、B列とC列の境が分かるようにということで、別に"_"でなくてはならないということはないです。 質問欄の例のように、アルファベットと数字で完全にB列とC列が異なっていれば、直接、 B列 & C列 と連結してしまっても構いません。 >If Application.WorksheetFunction.CountIf(Range("D6:D" & lastrow), temp) > 1 の「>1」 この連結した値を、D列から条件カウントしますが、自分自身を含むので、必ず1以上になります。 言い換えれば、「1」なら、自分自身しかない(重複しない)ので、削除対象外になります。 つまり、「>1」が削除の条件ということです。 ちなみに、下から順に重複データが削除されていくので、最終的に重複データの中で一番上のデータだけが残ります。 あと、並べ替えを入れるのなら、No.2の方の方法で十分ですよ。
お礼
早い回答ありがとうございます。 「>1」の方は、countifで個数を返すんですね。 理解しました。 またしても >Range("D6:D" & lastrow).Formula = "=B6 & ""_"" & C6" なのですが、D6:D列の最後に「B6_C6」を全部のセルに入力する。という意味であっていますか? この解釈だと、なんかプログラム的におかしいきがするので、正しい解釈を教えていただいてもいいですか お世話をかけますが、よろしくお願いします。
- maruru01
- ベストアンサー率51% (1179/2272)
こんにちは。maruru01です。 並べ替えをしないで重複行を削除する方法です。 Sub macro() Dim i As Long Dim lastrow As Long Dim temp As String lastrow = Range("C65536").End(xlUp).Row Range("D6:D" & lastrow).Formula = "=B6 & ""_"" & C6" For i = lastrow To 6 Step -1 temp = Cells(i, 2).Value & "_" & Cells(i, 3).Value If Application.WorksheetFunction.CountIf(Range("D6:D" & lastrow), temp) > 1 Then Cells(i, 1).EntireRow.Delete Shift:=xlUp End If Next i Range("D6:D" & Range("C65536").End(xlUp).Row).Delete End Sub D列を作業列として、一時的に「B列 & "_" & C列」の値を書き込んでいます。 D列が空いてなければ、別の列にして下さい。 ところで、本論とは関係ないですが、 最終行ということなら、 ×rastrow ○lastrow では?(笑)
お礼
新たな技をありがとうございます。 シンプルでいいですね。 質問いいですか? Range("D6:D" & lastrow).Formula = "=B6 & ""_"" & C6" と If Application.WorksheetFunction.CountIf(Range("D6:D" & lastrow), temp) > 1 の「>1」 のところの意味を教えていただいていいでしょうか? 関数の意味はわかったのですが・・・ よろしくお願いします。 rastrowなんですが・・・実は http://oshiete1.goo.ne.jp/kotaeru.php3?q=965118 のmaruru01さんのを参考にしているからなんです(汗)
- papayuka
- ベストアンサー率45% (1388/3066)
#2です。 > タイトル行(5行目)それより上は空白になっています > マクロを実行すると空白行も削除されてしまいます。 #1さんへの補足はご自身で書かれたのでは無い? rastrow = Range("C65536").End(xlUp).Row For i = rastrow To 2 Step -1 日本語にすると rastrowにC列の最終行(65536行目)から空白を飛ばして上に進みデータ入っている行番号を代入 (ちなみに LastRow だと思うけど、、^^;) rastrow から 2行目まで -1 ずつ i に代入 と書いてあります。 仮に最終行が100だったら、100,99,98って感じで2行目までループするって事です。 5行目を残して6行目で止めたいなら For i = rastrow To 6 Step -1
お礼
出来ました!わかりやすい解説ありがとうございました。 並べ替えのプログラムも条件はあったものの 無理やり的ではありますが追加し 求めていることが出来るようになりました。 ありがとうございました。
補足
やっぱりだめでした。(並び替え) 普通にマクロを記憶すると、範囲が決められてしまいます。行は増えたりするので・・・ 最終行まで取得して最後の文字列がB列?行に合計って入っているので、これははずしたいのでその一個前の行を取得・・・for文使うのかな・・・だんだんわからなくなってしまいました。 (普通に並び替えをしても合計行も並び変わってしまいます。) 説明下手ですみません。 並べ替えのテクニックを教えていただけないでしょうか?よろしくお願いします。
- popesyu
- ベストアンサー率36% (1782/4883)
全部というのは全データということなのか、 C列のデータが同じで無いものもということなのかどちらなのでしょう。 まぁどちらにせよただの判定ミスでしょうから、コードが無いことには何とも。
補足
早い返事ありがとうございます。 タイトル行以外すべて消えてしまいます。 まったくのコピーですみません。 Sub test() Dim rastrow As Long Dim i As Long rastrow = Range("C65536").End(xlUp).Row For i = rastrow To 2 Step -1 If Cells(i, 1).Value = Cells(i - 1, 1).Value Then Cells(i, 1).EntireRow.Delete Shift:=xlUp End If Next i End Sub イメージはわかるのですが、勉強不足なのことは反省しています。アドバイスよろしくお願いします。
お礼
ありがとうございます。 出来ました、非常に感謝しています。 もうひとつだけいいでしょうか タイトル行(5行目)それより上は空白になっています マクロを実行すると空白行も削除されてしまいます。 回避の方法を教えていただけないでしょうか? iが6行目まできたらFor文を抜けるみたいな考え方でいいのでしょうか?でもやり方がわからないのですが・・・ すみません、よろしくお願いします。