Accessテーブルと紐づく帳票フォームで、キーではない項目の重複入力チェックをやるにあたって。
なぜかネットではしっくりくる結果が得られなかったので、いろいろやった結果のメモ。
1.レコードの重複チェック⇒DCount関数を使う
ネットで「Access 重複チェック」とググったら、ほぼこれ一辺倒。
あと「重複クエリ」云々なんてのもありました。
いや、でもね。
例えば帳票フォームで10レコードくらいしかなく、目チェックが早いレベルとして。
その裏にベースのテーブルが数十万レコードあったら(しかもインデックスなし)、どうすんよ?
2.そやったら
人間の動きをシミュレーションしてやってみては?
フォームに表示したレコードのみで処理するから、DCountより速いのでは?
Dim rs1 As DAO.Recordset, rs2 As DAO.Recordset
Dim i As Long, 検索条件 As String
Set rs1 = Me.RecordsetClone
Set rs2 = rs1.Clone ' フォームのRecordsetCloneの、さらにCloneを作成
rs1.MoveFirst
i = 1
Do While (Not rs1.EOF) ' 帳票フォームの先頭からチェック
検索条件 = "[条件1] = " & rs1![条件1]
With rs2
.FindFirst 検索条件 ' 調べてるキーで最初から検索⇒ここで、おそらくrs1のカレントレコードがヒット
.FindNext 検索条件 ' 同一キーで次を検索⇒キー重複がなければここでNoMatchのはず
If Not .NoMatch Then ' さらにマッチした=重複あり
MsgBox i & "行目と" & (.AbsolutePosition + 1) & "行目のデータが重複しています。", vbExclamation
Exit Do
End If
End With
rs1.MoveNext
i = i + 1
Loop
これやと、具体的な重複行を指摘できて親切かも。
3.で、パフォーマンスはどうなん?
DCountと比べ、どちらがどのくらい速いかを実験。
【環境】
・Windows10 Pro/Intel Xeon Gold 6126(2.6GHz×2)/8MB RAM/Access2013(VDI環境)
・ベースのレコードはインデックスなしの10,000件
・フィルターでフォームの表示件数を変えながら、最後&最後から1件前が重複するケースを5回計測
【結果(平均:秒)】
画面表示 | DCount | Find検索 |
---|---|---|
10,000件 | 228.29 | 123.81 |
1,000件 | 22.81 | 1.14 |
100件 | 1.95 | 0.01 |
当然ではありますが、フォーム表示件数が少ないほど、Find検索の速さが際立ちますね・・・