[[20200402131507]] 『VBAで重複したデータと、重複していないデータを普x(maimino) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『VBAで重複したデータと、重複していないデータを分けて取り出したい』(maimino)

200000くらいのデータファイルの中から、もともと重複していないデータだけを抽出したいです。

現在は「条件付き書式設定」で重複する値のセルを色付けし、「色フィルター」で色のついていないセルを呼び出す方法で行っていますが、あまりに重くて処理できないまま落ちてしまうことも多いです。

重複したデータを削除する方法はマクロなどもいろいろ情報があるのですが、もともと重複していないデータだけを抽出するコードは見つからなかったので、簡単に行う方法はないかなと思い質問させていただきました。

どうぞよろしくお願いいたします。

やりたいこと:

A列に会社名が重複した状態で入力されている
(20000くらいのデータのなかで、すべての重複削除をすると一意のデータは100くらいになります)
その中でもともと重複がない会社名だけを抽出してG列に書き出す

A1  ABC商事             G1 ひふみ会社
A2  ABC商事             G2 わをん会社
|  ABC商事
|  ABC商事
A50  123証券
|  123証券
|  123証券
A100 あいう銀行
|  あいう銀行
A2000 ひふみ会社 
|  XYZ銀行
|  XYZ銀行
|  XYZ銀行
A3000 わをん会社

< 使用 Excel:Excel2019、使用 OS:Windows10 >


重複していないデータだけを取り出すのなら
重複の削除をすればいいのでは?

重複しているデータを全て削除すれば残りが重複していないデータですよね?
https://office-hack.com/excel/duplicate-delete/
(えく) 2020/04/02(木) 14:08


Sub main()
    Dim c As Range
    Range("G:G").ClearContents
    For Each c In Range("A:A").SpecialCells(2)
        If WorksheetFunction.CountIf(Range("A:A"), c.Value) = 1 And WorksheetFunction.CountIf(Range("G:G"), c.Value) = 0 Then
            Range("G" & Rows.Count).End(xlUp).Offset(1).Value = c.Value
        End If
    Next c
End Sub
(mm) 2020/04/02(木) 14:14

えく様
返信ありがとうございます。エクセルの重複の削除機能は「重複を削除して一意のデータだけ残す」だと思うのですが、それだと重複されている2個目のデータからの削除となりますよね。(ABC銀行が10個あった場合、9個削除して1個残る) 
今回行いたいのは、もともと1個しかないデータを取り出したいなのですが、なかなかうまく説明できず困っています。

(maimino) 2020/04/02(木) 14:37


mm様
コードありがとうございます。
が、countif関数だと処理が重いのか、何度やってもまったく動きません。。。
(maimino) 2020/04/02(木) 14:42

 dictionaryを使った例です。
 たぶん数秒で終了するはずです。

 Sub test()
     Dim dic As Object
     Dim key As Variant
     Dim c As Range
     Dim p As Long

     Set dic = CreateObject("Scripting.Dictionary")

     Range("G:G").ClearContents

     '出現回数のカウント
     For Each c In Range("A1", Cells(Rows.count, "A").End(xlUp))
         dic(c.Value) = dic(c.Value) + 1
     Next

     '一回だけのものを抽出
     For Each key In dic
         If dic(key) = 1 Then
             p = p + 1
             Cells(p, "G") = key
         End If
     Next
 End Sub

(γ) 2020/04/02(木) 15:05


さらに速度を求めるなら、
A列の対象範囲の値をいったん配列に読み込んで処理すればよいかもしれません。
出力も一括して書き込めば早くなりますが、そこまでの話でもないでしょう。

(γ) 2020/04/02(木) 15:27


20万件のデータを使って実測してみました。(そのうち250件が単一コードの例でした)

2020/04/02(木) 15:05 に提示したコードは、
1.9秒でした。

2020/04/02(木) 15:27 の方針でチューニングしたら(あえてコードは載せません)、
0.7秒になりました。こんなところに力を入れる必要は全くありませんが。

ちなみに、COUNTIFを使ったもの(ANDの後半条件は不要と思い取りました)は、
2時間12分かかりました。(昨日外出中に動作させっぱなしにして測定)

>20000くらいのデータのなかで
と書いてある所もあったので、それならいけるだろうとの思惑と推測されます。

どうして質問者さんから反応がないのか不思議でなりません。
こんな簡単に見えるコードでできているわけが無いと即断しているのか。

(γ) 2020/04/03(金) 13:55


Y様
コメントとコードありがとうございます!
気づくのが遅くて確認が遅くなってすみませんでした。
Dictionaryのオブジェクトは難しいと思ってあまり使ったことがなかったのですが、すごく早く処理できるのでびっくりしました。
ちゃんと勉強したいと思います!
ありがとうございました。お礼が遅くなって本当にすみませんでした。
(maimino) 2020/04/03(金) 17:17

了解。活用してください。
(γ) 2020/04/03(金) 17:43

Y様 ありがとうございました!
(maimino) 2020/04/03(金) 21:37

コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.