[Notes/Domino] 取り込み処理でのキーチェックの問題
CSV や Excel からデータを読み込んで文書を作る際、「同じキーの文書が存在したら上書き(または何もしない)、存在しなければ新規作成」という処理を書くことは多いと思います。が、キーのチェックにビューを使用していると、取り込みデータのほうに重複が存在した場合、重複チェックができないことがあるようです。
再現方法
以下、実証コードです。(現象を実証するためだけのコードなので、あまり意味がないコードになっています。また動作には、フィールド Test を第1列にソートした TestView ビューが必要です。)
Dim ss As New NotesSession Dim db As NotesDatabase Dim vw As NotesView Dim doc As NotesDocument Dim i As Integer Set db = ss.CurrentDatabase Set vw = db.GetView("TestView") For i = 1 To 2 Set doc = vw.GetDocumentByKey("aaa", True) If doc Is Nothing Then Set doc = db.CreateDocument() doc.Form = "TestForm" doc.Test = "aaa" Call doc.Save(True, True) End If Next
同じ文書を作っているので、期待動作は「1文書のみ作成」ですが、初回実行時は2文書作成されてしまいます。また、2回目に実行した場合は、1文書も作成されません。
上記のことから、エージェントの処理実行中は、ビューが更新されていないことが判ります。「vw.AutoUpdate = True」を入れてみても結果は同じでした。
# R4くらいのときはビューが更新されたような気がしますが、記憶違いかな???
回避策
最も単純なのは、もちろん GetDocumentByKey の前に「Call vw.Refresh()」を入れること。簡単ではありますが、動作は遅くなります。
次に、取り込みデータがキーでソートされていることが確実であれば、ひとつ前のデータと比較することでチェックは可能です。これもとても簡単ですが、ソートされていることが前提なので、ソートされていることが確実でない場合は、この手段は採れません。
そこで管理人がおすすめする方法は、List を使うことです。List に処理したキーを入れていき、IsElement にてキーが存在するかどうかを確認すれば、重複が防げます。
以下、てきとーな処理イメージ
Dim chklst List As String … Do (終了条件) … If IsElement(chklst(キーの値)) = False Then Set doc = vw.GetDocumentByKey(キーの値, True) If doc Is Nothing Then … End If chklst(キーの値) = "" End If … Loop
配列だと上限が3万ちょっとで、値を検索するにもループで処理しなければなりませんが、List だとけっこうな個数でも大丈夫(10万個でも大丈夫でした)ですし、IsElement で一発チェックできるため、速く処理できます。(メモリは食うのかも知れませんが)
それにしても、なんでこんなことをやらなければならないのか……。管理人が何か間違っているようでしたら、コメントで指摘していただけるとありがたいです。
コメント
コメントはありません
※コメントは承認制となっております。管理者が承認するまで表示されません。申し訳ありませんが、投稿が表示されるまでしばらくお待ちください。