[[20161026085427]] 『Collectionについて』(ふみ) ページの最後に飛ぶ

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

 

『Collectionについて』(ふみ)

こんにちは。

[[20161019140551]背景色をコピーしたい]
の続きなのですが、
データベースシートに型式を記入する際は、重複していないか
確認してから書き込む様に出来たのですが、書き込んだ後、
スペースを消したり全角を半角に変換したりする事により、
重複した型式を登録してしまいます。

その為、定期的に重複をチェックするコードを探して見つけたのですが、
全角半角で異なっていたり、大文字小文字で異なっていても
重複と判断してしまいます。
完全一致でないと重複ではないと判断させるには、どの様に変更したら
良いのでしょうか?

よろしくお願い致します。

Sub 定期重複チェック()

Application.ScreenUpdating = False

 Dim i As Long, n As Long
 Dim s As String, co As Collection
 Dim t As Double

 Set co = New Collection
 Range("H:H").Value = "" 'H列を全てクリア
t = Timer

 For i = 3 To 1048576     '上限
    s = Cells(i, 2).Value
       If s = "" Then Exit For   '空白セルまでで終り
           On Error Resume Next
             co.Add s, s
               If Err Then
               On Error GoTo 0
             Cells(i, 8).Value = "重複"
            n = n + 1
       End If
   On Error GoTo 0
 Next

 Application.ScreenUpdating = True

 MsgBox "件数=" & i - 1 & " 重複件数=" & n & " 時間=" & Timer - t

 End Sub

< 使用 Excel:Excel2007、使用 OS:Windows7 >


http://www.excel.studio-kazu.jp/kw/20161019140551.html
(ふみ) 2016/10/26(水) 09:07

 >>全角半角で異なっていたり、大文字小文字で異なっていても 
重複と判断してしまいます。 

 そうですか?

 以下のコードを走らせてください。
 重複とみなされず、したがってエラーにはならず、最終的に3件が格納されますよ。

 Sub Test()
    Dim co As Collection

    Set co = New Collection

    co.Add "AAA"
    co.Add "aaa"
    co.Add "AAA"
    MsgBox co.Count

 End Sub

 ★Collection内の重複チェック、エラーハンドリングの他に、「まっとうな」有無チェックのメソッドがありますし
  せっかく、For/Next を使っているのに 1048576 までのループで 空白が来たら終わりという制御、
  Do/Loopとかわらないねぇといったところはありますが、それらは、横におきますね。

  
(β) 2016/10/26(水) 09:31

βさん、ありがとう御座います。

書いて頂いたコードを走らせると、確かに「3」が返ります。
しかし試しにUPしたコードで、B列に同じAAAを書いて走らせると、
aaaとAAAは「重複」で返ってきます。

シートの表示形式を「文字列」にしていますが、関係無いでしょうか?

(ふみ) 2016/10/26(水) 09:45


 ちょっとそちらのコードで試してみますね。

 ところで、

 >>、「まっとうな」有無チェックのメソッドがありますし

 ごめんなさい。Containsメソッドなんですが、VBAでは使えなかったです。
 Collection のかわりに Dictionary を使えばExistsメソッドで可能です。

(β) 2016/10/26(水) 09:48


調べる列が1つなので、私はArrayList案を推しますね。

 Sub test()
    Dim i As Long
    Dim n As Long
    Dim s As String
    Dim t As Double

    Application.ScreenUpdating = False

    Range("H:H").ClearContents
    t = Timer

    With CreateObject("System.Collections.ArrayList")
        For i = 3 To Cells(Rows.Count, "B").End(xlUp).Row
           s = Cells(i, 2).Value
           If Not .Contains(s) Then
                .Add s
            Else
                Cells(i, 8).Value = "重複"
                n = n + 1
            End If
        Next i
    End With

    Application.ScreenUpdating = True
    MsgBox "件数=" & i - 3 & " 重複件数=" & n & " 時間=" & Timer - t
 End Sub
(???) 2016/10/26(水) 10:09

???さん、ありがとう御座います。

書いて頂いたコードを走らせたら、重複を返しませんでした。
やはりCollectionだとダメと言う事なのでしょうか?
シートの表示形式も関係なかったですし、途方に暮れていました。

βさんが調べて頂いていると思うのですが、
???さんのコードに変更させて頂こうと思います。
申し訳御座いません。

(ふみ) 2016/10/26(水) 10:23


 はい。

 ArrayListなりDictionaryなり、確実に重複チェックができる方法に変更することを
 βも提案しようと思っていました。

 そちらのコード、ちょっとエラーハンドリングがごちゃついているので、それを、直した形で動かしているのですが
 (βにとっては)不思議な現象になっています。
 もともと、βがCollection を使うときにはキーを使いません。(キーはCollectionとしてはオプションなので)
 ですから、Collection内でのキーの扱いについてはよくわからないのですが、現象としては、キーについては
 全角も半角も大文字も小文字も同じ文字として扱われるようですね。

(β) 2016/10/26(水) 10:56


βさん、調べて頂いてありがとう御座います。

重複について、探したら様々な事例のコードがUPされており、
たまたま選んだコードがこれでした。
Collectionについても調べたのですが、説明を読んでも意味がわからず、
困っていました。(キーの事も書いてありましたが、何だ、これ?って感じです)

本当にありがとう御座いました。

(ふみ) 2016/10/26(水) 11:15


コメント返信:

[ 一覧(最新更新順) ]


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