|
みなさん、こんばんは。
>個人的には、多分、でれすけ さんご提案のMatchが速いのではと思います。
>但し、データが昇順または降順になっている または、並べ替えても良い という前提の場合ですが。
Match関数、速かったですよ!!ソートされていない場合のでれすけさんのコードでも
かなりものです。
今回は、データ数10000のみのテストで行ってみました。
他のコードも ScreenupdatingのFalse、Trueや
配列でセルに書き込みできるコードは、そのようにしてみました。
例えば、Test2は、
'============================================================
Sub test2(out_time, cnt)
st = Now()
Dim myarray()
Dim ans As Range
Dim rng As Range
Set rng = Range(Cells(1, 1), Cells(Rows.Count, 1).End(xlUp))
ad = rng.Address
With Range("d1:d" & cnt)
.Formula = "=if(CountIf(" & ad & ",Row())=0,row(),"""")"
.Value = .Value
On Error Resume Next
Set ans = .SpecialCells(xlCellTypeConstants)
If Err.Number = 0 Then
ReDim myarray(1 To ans.Count, 1 To 1)
For Each cc In ans
myarray(idx + 1, 1) = cc.Value
idx = idx + 1
Next
Range(Cells(LBound(myarray(), 1), 3), Cells(UBound(myarray(), 1), 3)).Value = myarray()
End If
.ClearContents
End With
Set rng = Nothing
out_time = Now() - st
End Sub
こんな感じに・・・(これで速度は上がっています、Test3より速い)。
全部載せると長くなるので、でれすけさんのコードだけテスト用に変更したものを
記述します。
'=======================================================
Sub test7(out_time, cnt)
st = Now()
Dim target As Range
Dim i As Integer, ret
Application.ScreenUpdating = False
Set target = Range("A1:A" & cnt)
For i = 1 To cnt
If IsError(Application.Match(i, target, False)) Then
Cells(j + 1, 8).Value = i
j = j + 1
End If
Next
Application.ScreenUpdating = True
out_time = Now() - st
End Sub
これをAsakiさんがおっしゃっているように並べ替えも行うコードは
以下のコードで実行してみました。
'==================================================================
Sub test8(out_time, cnt)
st = Now()
Dim target As Range
Dim i As Integer, ret
Dim ok As Boolean
Application.ScreenUpdating = False
Set target = Range("j1:j" & cnt)
With target
.Value = Range("a1:a" & cnt).Value
.Sort Key1:=Range("J1"), Order1:=xlAscending, Header:=xlGuess, _
OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, SortMethod _
:=xlPinYin
For i = 1 To cnt
ret = Application.Match(i, target, 1)
ok = False
If IsError(ret) Then
ok = True
ElseIf .Cells(ret).Value <> i Then
ok = True
End If
If ok Then
Cells(j + 1, 9).Value = i
j = j + 1
End If
Next
.ClearContents
End With
Application.ScreenUpdating = True
out_time = Now() - st
End Sub
データ数10000、欠番数3661のとき、
前回までのTest1〜Test6の中では、
最速がTest5の「00:02:17」でした。
これに対し、Test7は「00:00:47」でソートなしでもかなり速い結果をだしています。
さらに、Test8は、「00:00:22」でした。
つんさんもAsakiさんも速度というキーワードがあれば、もっと違うコードの投稿を
されていたと思います。
いろんな手法でのコード、予想はできても中々確認までしていられなかったので
このご質問を利用して、いろんなサンプルコードで確認する事ができました。
皆さん、ありがとうございました。
|
|