Поиск дублей контрагентов в БД

  • Автор темы -
  • Дата начала

Гость
#1
Суть цикла - беру первую запись и сраниваю ее с последующими и т.д. На 10 000 записей, ой блин, как долго работает :( Сможет помочь, pls.
Код:
Sub Initialize
Dim session As New NotesSession
Dim db As NotesDatabase

On Error Goto catch

Set db = session.CurrentDatabase		
Set view = db.getview ("Contragents") 	
Set CollectionOfFirstDocs = view.GetAllDocumentsByKey("Да", True)
Set CollectionOfDocs = view.GetAllDocumentsByKey("Да", True)

Set FirstDoc = CollectionOfFirstDocs.getFirstDocument
While Not (FirstDoc Is Nothing) 
CountOfFirm = 0
FirstCompany = FirstDoc.GetItemValue("ContractParty") ' ContractParty - в этом поле контрагент

Set Doc = CollectionOfDocs.getFirstDocument
While Not (Doc Is Nothing) 
Company = Doc.GetItemValue("ContractParty") ' ContractParty - в этом поле контрагент
If FirstCompany(0) = Company(0) Then 
CountOfFirm = CountOfFirm + 1
End If 
Set Doc = CollectionOfDocs.GetNextDocument(Doc) 
Wend 

If CountOfFirm > 1 Then
Msgbox "Фирма " + Company(0) + " " + CountOfFirm + " повторений."
End If

Set FirstDoc = CollectionOfFirstDocs.GetNextDocument(FirstDoc) 
Wend 

Exit Sub
catch:
Msgbox Error & | in line | & Erl(), 64, |Lotus Notes (| & Lsi_info(2) & |)|
Exit Sub
End Sub
 

Medevic

Что это ? :)
Lotus team
10.12.2004
3 346
2
36
Россия, Калуга
#2
Заведи список.
Код:
Dim session As New NotesSession
Dim db As NotesDatabase
Dim doc As NotesDocument
Dim view As NotesView
Dim dummy List As String

Set db = session.CurrentDatabase()
Set view = db.GetView("Contragents")
Set doc = view.GetFirstDocument()
While Not (doc Is Nothing)
If Iselement(dummy(doc.GetItemValue("ContractParty")(0))) Then
' есть совпадение. делаем что-нибудь.
Else
' нет совпадений. внесем в список.
dummy(doc.GetItemValue("ContractParty")(0)) = doc.UniversalID
End If
Set doc = view.GetNextDocument(doc)
Wend
 

ToxaRat

Чёрный маг
Lotus team
06.11.2007
3 203
24
38
Киев
ToxaRat.com
#3
Денис Кириченко
принципиально неправильно подходишь к вопросу :(

Прежде всего если записей много то ты должен организовать исключительно однопроходной цикл - дважды документ НЕ читать.

Я бы в твоей ситуации глотал бы доки в свой класс и в процессе глотания сразу бы их сортировал двоичным деревом и удалял дубликаты - да такой код написать тяжелее но у него будет самая быстрая скорость обработки
 

TIA

:-)
Lotus team
15.05.2009
790
1
#4
Только dummy лучше сделать с типом "List As integer"
больше влезет.
Код:
Dim session As New NotesSession
Dim db As NotesDatabase
Dim doc As NotesDocument
Dim view As NotesView
Dim dummy List As integer

Set db = session.CurrentDatabase()
Set view = db.GetView("Contragents")
Set CollectionOfDocs = view.GetAllDocumentsByKey("Да", True)
Set doc = CollectionOfDocs.GetFirstDocument()
While Not doc Is Nothing
If Iselement(dummy(doc.GetItemValue("ContractParty")(0))) Then
' есть совпадение. делаем что-нибудь.
Else
' нет совпадений. внесем в список.
dummy(doc.GetItemValue("ContractParty")(0)) = 1
End If
Set doc = CollectionOfDocs.GetNextDocument(doc)
Wend
 

Omh

Well-Known Member
Lotus team
04.07.2007
2 210
1
37
Латвиджа, Рига
#5
Ещё можно сделать view с категорией, состоящей из слепленных значений, которые должны в итоге составлять уникальное значение.
Если в категории больше одного документа - значит есть дубликаты.
 

Гость
#7
Omh не подскажишь, какими методами получить категорию и проверить количество потомков. Через entry не получается :(
 

Omh

Well-Known Member
Lotus team
04.07.2007
2 210
1
37
Латвиджа, Рига
#8
NotesViewNavigator

Вообще, я что-то похожее делал так:
строил такое view, потом получал все уникальные категории (через @DbColumn или через ViewNavigator) в лист.
И потом проходился по листу, проверяя через GetAllDocuments, кол-во докуов в каждой категории.

Сейчас вижу, что это не самый оптимальный способ, но побыстрее твоего будет.
 

Гость
#9
Слушай, я метода GetAllCategory, нет? Блин, я совсем ламер. Может есть у кого, help расширеный, с примерами кода. А то все что я по категориям нашел, так это:
Set nav = view.CreateViewNav
Set entryA = nav.GetFirst
Set entryB = nav.GetNextCategory(entryA)
Set entryC = nav.GetPrevCategory(entryB)
 
#10
если делать спец. вид, то примерно так:
первая колонка: формула: ContractParty, категоризованная
вторая колонка: формула: 1 , totals: total, hide detail row
Код:
	view.AutoUpdate = False ' отключаем автообновление индекса
Set nav = view.CreateViewNav 
nav.MaxLevel = 0 ' "схлопываем" вид
Dim entry As NotesViewEntry
Set entry = nav.GetFirst ' понеслась
while not entry is nothing 
If Clng( entry.ColumnValues(1) ) > 1 Then Print entry.ColumnValues(0) & " : " & entry.ColumnValues(1)
Set entry = nav.GetNext( entry )
If entry.IsTotal Then Set entry = Nothing
Wend
нужно помнить, что лишний вид - это доп. нагрузка на сервер.
если вариант, предложенный medevic ( со списком ) устраивает по скорости работы( или проверка дублей выполняется нечасто ) - юзайте лучше его.
 

Гость
#11
turumbay даже если View скрыта? А еще хотел узнать на счет производительности. У нас под Lotus выделен отдельный сервак, так еще пару приложений крутится, но они не в счет. Загрузки на нем, сколько я работаю не переваливала даже за половину мощностей. И вот что интересно запустил я как-то раз бесконечный цикл, не тачка на которой был запущен Lotus, не сам сервак не нагружался как было 100 mb, и 2% проца так и осталось.
 
K

Klido

Гость
#12
апустил я как-то раз бесконечный цикл
это не нагрузки :angry2: основная нагрузка на сервер domino - задачи indexer и replicator, если сервер 1 и приложений мало с небольшим кол-вом доков и вьюх - нагрузки ты никогда особой и не заметишь...
 

Гость
#13
Помогите с кодом:
В строке - If entry.IsTotal Then Set entry = Nothing говорит что не проницилиолизирована переменная. Не могу отловить че-так происходит первые десятка два цикла проходит нормально, мне так кажется это происходит, когда выполняется условие entry.IsTotal.

Код:
	view.AutoUpdate = False 	' отключаем автообновление индекса
nav.MaxLevel = 0 		' "схлопываем" вид
Set entry = nav.GetFirst 		' понеслась
While Not entry Is Nothing 
col% = 0
Forall colval In entry.ColumnValues
col% = col% + 1
End Forall

If Not col% > 0 Then 
If Clng( entry.ColumnValues(1) ) > 1 Then Print entry.ColumnValues(0) & " : " & entry.ColumnValues(1)		
End If
Set entry = nav.GetNext( entry )
If entry.IsTotal Then Set entry = Nothing
Wend
 

hosm

* so what *
18.05.2009
2 442
9
42
Kiev, Ukraine
#14
тоталы не обработываются? тогда может так?
Код:
if not entry is nothing then
If entry.IsTotal Then Set entry = Nothing
end if
и для форматирования кода есть спец. тег code.