| 
    
     |  | みなさん、こんばんは。 
 >個人的には、多分、でれすけ さんご提案の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さんも速度というキーワードがあれば、もっと違うコードの投稿を
 されていたと思います。
 
 いろんな手法でのコード、予想はできても中々確認までしていられなかったので
 このご質問を利用して、いろんなサンプルコードで確認する事ができました。
 皆さん、ありがとうございました。
 
 |  |