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

Тема в разделе "Lotus - Программирование", создана пользователем -, 29 дек 2009.

  1. Гость

    Суть цикла - беру первую запись и сраниваю ее с последующими и т.д. На 10 000 записей, ой блин, как долго работает :( Сможет помочь, pls.
    Код (Text):
    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
     
  2. Medevic

    Medevic Что это ? :)
    Lotus team

    Регистрация:
    10 дек 2004
    Сообщения:
    3.346
    Симпатии:
    2
    Заведи список.
    Код (Text):
    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
     
  3. ToxaRat

    ToxaRat Чёрный маг
    Lotus team

    Регистрация:
    6 ноя 2007
    Сообщения:
    3.047
    Симпатии:
    18
    Денис Кириченко
    принципиально неправильно подходишь к вопросу :(

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

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

    TIA :-)
    Lotus team

    Регистрация:
    15 май 2009
    Сообщения:
    790
    Симпатии:
    0
    Только dummy лучше сделать с типом "List As integer"
    больше влезет.
    Код (Text):
    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
     
  5. Omh

    Omh Lotus team
    Lotus team

    Регистрация:
    4 июл 2007
    Сообщения:
    2.210
    Симпатии:
    0
    Ещё можно сделать view с категорией, состоящей из слепленных значений, которые должны в итоге составлять уникальное значение.
    Если в категории больше одного документа - значит есть дубликаты.
     
  6. Гость

    Omh спасибо за идею. :(
     
  7. Гость

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

    Omh Lotus team
    Lotus team

    Регистрация:
    4 июл 2007
    Сообщения:
    2.210
    Симпатии:
    0
    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. turumbay

    Регистрация:
    13 мар 2009
    Сообщения:
    625
    Симпатии:
    2
    если делать спец. вид, то примерно так:
    первая колонка: формула: ContractParty, категоризованная
    вторая колонка: формула: 1 , totals: total, hide detail row
    Код (Text):
        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% проца так и осталось.
     
  12. Klido

    Klido Гость

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

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

    Код (Text):
        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
     
  14. hosm

    hosm * so what *

    Регистрация:
    18 май 2009
    Сообщения:
    2.450
    Симпатии:
    7
    тоталы не обработываются? тогда может так?
    Код (Text):
    if not entry is nothing then
    If entry.IsTotal Then Set entry = Nothing
    end if
    и для форматирования кода есть спец. тег code.
     
  15. Medevic

    Medevic Что это ? :)
    Lotus team

    Регистрация:
    10 дек 2004
    Сообщения:
    3.346
    Симпатии:
    2
    Ну так на последней entry она как раз становится Nothing. Нет следующей.
     
Загрузка...

Поделиться этой страницей