Lotus и Delphi

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

  1. Tanitra

    Tanitra Гость

    Всем привет! Может кто-нибудь сталкивался с подобной проблемой?
    Есть отчеты сделанные в дельфи. Тягаем данные из лотуса посредством OLE/COM. Все идет прекрасно, но есть одно НО…В документах имеется поле ReaderDefault, которое заполняется из настроечного документа базы. В некий момент времени требуется изменить значение этого поля в уже существующих документах, ручками. Что и делается путем замены содержимого этого поля. Для лотуса все остается нормальным, т.е. дефолт читатели видят эти документы. Но при формировании отчетов происходят странности: дельфи вытягивает данные по условию полностью , но потом затыкается и говорит: function is valid ADT argument.
     
  2. hosm

    hosm * so what *

    Регистрация:
    18 май 2009
    Сообщения:
    2.450
    Симпатии:
    7
    Есть у IBM несколько полезных ссылок:
    http://www-01.ibm.com/support/docview.wss?...uid=swg21316690
    http://www-01.ibm.com/support/docview.wss?uid=swg21093032
    Возможно, ошибка при переборе коллекции документов?
    Посмотрите код замены поля, если это поле типа ридерс, может, явно поставить при замене .IsReaders = True?
    Или нужного итема всё-таки нет в документе, а Вы пытаетесь обратиться к его свойствам/методам?
     
  3. Tanitra

    Tanitra Гость

    Подобным образом этому полю были присвоены новые значения в нескольких аналогичных базах. В тех базах где количество документов обрабатываемого вида не превышало 5 тыс. Все прошло нормально и отчеты формируются. Там же где количество примерно 15 тыс. доков возникают проблемы. Код замены значений в поле:
    Код (Text):
    Sub Initialize
    Dim ws As New notesuiworkspace
    Dim view As notesview
    Dim item As notesitem
    Dim itemvalue As Variant
    Dim session As New NotesSession
    Dim db As NotesDatabase
    Dim collection As NotesDocumentCollection
    Dim doc As NotesDocument

    Set db = session.CurrentDatabase
    Set collection = db.UnprocessedDocuments
    Set doc=collection.GetFirstDocument
    '+++++++++++++++++++++++   


    Set DialogDoc = New NotesDocument (db)
    k=1
    Forall x In doc.Items
    Redim Preserve itemnames(k)
    itemnames(k)=x.Name
    k=k+1
    End Forall


    DialogDoc.itemsSET=itemnames
    m:  result = ws.DialogBox ("Corrector_yulduz", True, True,False,False,False,False,"Corrector_yulduz", DialogDoc)

    itemName=DialogDoc.FieldName(0)

    If (result = True) Then
    If DialogDoc.Act(0)="R" Then

    If  Isarray(DialogDoc.fieldvalue) Then
    For i = 1 To collection.Count
    Set doc = collection.GetNthDocument( i )

    Set item=doc.GetFirstItem(itemName)

    Call doc.ReplaceItemValue(itemname, DialogDoc.fieldvalue)  
    Call doc.save(True,True)

    Next

    Else
    Call collection.StampAll(itemName, DialogDoc.Fieldvalue(0))
    End If

    Else


    For i = 1 To collection.Count
    Set doc = collection.GetNthDocument( i )
    Set item=doc.GetFirstItem(itemName)

    If Isarray(DialogDoc.fieldvalue) Then
    itemvalue= Arrayappend(doc.GetItemValue(itemname),DialogDoc.Fieldvalue)            


    Else
    itemvalue=doc.GetItemValue(itemname)
    itemvalue=itemvalue+DialogDoc.Fieldvalue




    End If
    Call doc.ReplaceItemValue(itemname, itemvalue)
    Call doc.save(True,True)

    Next           
    End If
    End If



    Call ws.Viewrefresh
    End Su
     
  4. hosm

    hosm * so what *

    Регистрация:
    18 май 2009
    Сообщения:
    2.450
    Симпатии:
    7
    Сходу проверьте doc на Nothing
    Redim Preserve itemnames(k) ???
    выше не вижу просто
    Redim itemnames(0) - оно должно быть перед Redim Preserve
    проверьте правильность получения
    itemName=DialogDoc.FieldName(0)
    itemvalue= Arrayappend(doc.GetItemValue(itemname),DialogDoc.Fieldvalue)






    Добавлено: еще добавить обработчик ошибок On Error с информацией о строке ошибки - так будет проще отловить причину ошибки
     
  5. Tanitra

    Tanitra Гость

    доброе утро!
    так агент отрабатывается нормально!!! и лотус это поле видит и читает замечательно! проблема уже после закачки данных в дбф. дельфи не понимает что последний документ закачан и не может завершить цикл.
     
  6. K-Fire

    K-Fire Гость

    А сколько у вас этот агент работает по времени на 5 тыс документов?
     
  7. Tanitra

    Tanitra Гость

    на 5 тыс доков примерно 2-3 минуты, на 15 тыс 15 мин
     
  8. hosm

    hosm * so what *

    Регистрация:
    18 май 2009
    Сообщения:
    2.450
    Симпатии:
    7
    он точно вычитывает все данные? А как вы Delphi пытаетесь указать за завершение цикла?
    Учитывается наличие удаленных документов, стабов, не содержащих итемы?
    тогда посмотрите условие завершения цикла насчет проверки документа на Nothing, если документ не Nothing, то после этого полезно проверить на doc.IsValid and Not doc.isDeleted
    P.S.: Если честно, я в агенте не могу понять в этом кусочке код в Else, зачем он вообще, поле в doc вообще тогда не должно меняться (if not Isarray(DialogDoc.fieldvalue), то скорее всего, оно Empty):
    Код (Text):
    If Isarray(DialogDoc.fieldvalue) Then
    itemvalue= Arrayappend(doc.GetItemValue(itemname),DialogDoc.Fieldvalue)            
    Else
    itemvalue=doc.GetItemValue(itemname)
    itemvalue=itemvalue+DialogDoc.Fieldvalue
    End If
    Добавлено: Возможно, слишком усложняю, но может, нужно-таки явное указание типа ридеров - нечто подобное:
    Код (Text):
    Dim SetRead As boolean

    Set item=doc.GetFirstItem(itemName)
    if item.isReaders = True then
    SetRead = True
    else
    SetRead = False
    end if
    '...
    if SetRead = True then
    doc.ReplaceItemValue(itemname, itemvalue).Isreaders = True
    else
    Call doc.ReplaceItemValue(itemname, itemvalue)
    end if
     
  9. TIA

    TIA :-)
    Lotus team

    Регистрация:
    15 май 2009
    Сообщения:
    790
    Симпатии:
    0
    5 тыс. - это дефолтное ограничение на количество найденных документов черех FTSearch. У вас он применяется?

    Если применяется, был ли обновлён FT-индекс после модификации полей доступа агентом?
    Проверяете ли вы документы, отобранные для построения отчёта на валидность (NotesDocument.IsValid, not NotesDocument.IsDeleted ... )?
     
  10. Tanitra

    Tanitra Гость

    1.само поле риедер дефолт является текст лист.
    2. количество обрабатываемых документов берется простым ctrl+a (случай для обновления поля)
    3. документы отобранные для построения отчета не проверяются на валидность
    <div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">дельфийский цикл выкачивающий данные:</div></div><div class="sp-body"><div class="sp-content">
    Код (Text):
    PanelWait.Caption:='Экспорт данных из Lotus';
    Application.ProcessMessages;


    //**************************
    // ПЫТАЕМСЯ ПОЛУЧИТЬ КОЛИЧЕСТВО ДОКУМЕНТОВ ВО ВЬЮХЕ

    try
    vcount:=    LNView.entrycount;  // количество документов - строк в базе
    except
    if MessageDlg('У вас нет прав доступа к базе данных!'+#13+'Обратитесь к администратору!',
    mterror, [mbOK], 0) = mrOK then
    close;
    end;


    ProgressBar1.Max:=vcount;
    ProgressBar1.Position:=ProgressBar1.Min;
    ProgressBar1.Visible:=true;


    // закачиваем данные из лотуса
    Lndoc:=LNView.getFirstDocument;  // получаем первый документ = строка

    for i:=0 to vcount-1

    do  begin

    if
    (   // проблема форматирования в дату просмотреть

    (
    strtodate(FormatDateTime('dd.mm.yyyy',strtodate(COPY(LNGetFieldStrValue(LnDoc,'InputDate','01.01.1700'),0,10))))>=strtodate(FormatDateTime('dd.mm.yyyy',globalStart))
    )
    and
    (
    strtodate(FormatDateTime('dd.mm.yyyy',strtodate(COPY(LNGetFieldStrValue(LnDoc,'InputDate','01.01.1700'),0,10))))<=strtodate(FormatDateTime('dd.mm.yyyy',globalEnd))
    )
    AND
    (
    (LNGetFieldStrValue(LnDoc,'Contr','')='1') or (LNGetFieldStrValue(LnDoc,'ContrM','')='1' )
    and
    (LNGetFieldStrValue(LnDoc,'StatusNew','')<>'4')
    )
    AND
    ( LNGetFieldStrValue(LnDoc,'ExecNameOtv','')<>'')  // ЕСЛИ ЕСЬ ОТВЕСТВЕННЫЕ

    AND ( LNGetFieldStrValue(LnDoc,'TypeDoc','')='Входящий')

    )



    then
    begin
    try

    dm.qFromLotus.close;
    dm.qFromLotus.SQL.Text:='begin '+#13
    +'insert into tfromlotus( Body1,Chief, From1,Contr,ContrM,......) '+#13
    +'values('''+StringReplace(StringReplace(LNGetFieldStrValue(LnDoc,'Body1',''),'''',' ',[rfReplaceAll]),'"',' ',[rfReplaceAll])+''','''
    +LNGetFieldStrValue(LnDoc,'Chief','')+''','+#13
    +''''+LNGetFieldStrValue(LnDoc,'From1','')+''','+#13
    +''''+LNGetFieldStrValue(LnDoc,'Contr','')+''','''+LNGetFieldStrValue(LnDoc,'ContrM','')+''','+#13.....);'+#13
    + 'commit; '+ #13
    + 'end; ' ;

    // showmessage(dm.qFromLotus.SQL.Text);
    dm.qFromLotus.Execute;

    // закачиваем данные в vreport.dbf
    except showmessage(dm.qFromLotus.SQL.Text);
    end;
    end;

    lndoc:= LNView.getnextDocument(lndoc);

    ProgressBar1.Position:=ProgressBar1.Position+1;
    Application.ProcessMessages;
    end;
    dm.qFromLotus.Close;
     
  11. hosm

    hosm * so what *

    Регистрация:
    18 май 2009
    Сообщения:
    2.450
    Симпатии:
    7
    TIA Фт-поиска тут нет, берут кол-во ентри и проходят по документам.
    Вьюха, похоже, не категоризированная, т.к. работает для небольшой БД корректно.
    А вот почему игнорятся проверки на валидность, мне непонятно...
    В лотусе я бы попробовала LNView.AutoUpdate = false перед выгрузкой и сделала проверки проверки тек. документа из коллекции на Nothing:
    1)если документ Nothing - выйти из цикла.
    2)если документ не Nothing, то после этого при проверках doc.IsValid and Not doc.isDeleted (или + IsEmpty(doc.Items)?) обработать, иначе - перейти к следующему.
    Такое реализуемо и через Delphi, надеюсь?
     
  12. TIA

    TIA :-)
    Lotus team

    Регистрация:
    15 май 2009
    Сообщения:
    790
    Симпатии:
    0
    Да-да, вижу. Вот ещё бы строку Tanitra указала, на которой ошибка генерируется.
     
  13. hosm

    hosm * so what *

    Регистрация:
    18 май 2009
    Сообщения:
    2.450
    Симпатии:
    7
    со указанием строки для обработки ошибок в дельфи не помогу, я давно с этой средой не работаю
    Ну, имхо, или в LNGetFieldStrValue на невалидном/удаленном или получение след. документа из коллекции.
    (Я, кстати, в начале работы с лотусом такую ошибку именно на коллекции исправляла)
     
  14. TIA

    TIA :-)
    Lotus team

    Регистрация:
    15 май 2009
    Сообщения:
    790
    Симпатии:
    0
    Ну дебаггер-то ей точно доступен.

    Гипотезу поддерживаю.
     
  15. Tanitra

    Tanitra Гость

    ошибка при получении некст документа, причем ВСЕ документы уже закачаны. (парадокс, но это так). в дебагере мне все доступно, но лотус то не ругается))))
     
  16. hosm

    hosm * so what *

    Регистрация:
    18 май 2009
    Сообщения:
    2.450
    Симпатии:
    7
    значит, в for i:=0 to vcount-1 может быть vcount неправильный.
    посмотрите насчет LNView.AutoUpdate = false


    Добавлено: Что в lndoc до этой строчки непосредственно перед ошибкой? проверьте в отладчике
    lndoc:= LNView.getnextDocument(lndoc);


    Добавлено: можно ж дописать:
    если lndoc равно "пустому значению перед ошибкой" (Nothing, null или как там правильно по дельфийскому синтаксису), то выйти из цикла.
    можно иначе - сделать обработку
    try
    lndoc:= LNView.getnextDocument(lndoc);
    except
    // сообщение/получение кол-ва прочитанных/установка прогресс-бара в конечную позицию...
    break //или как там делается выход из цикла
    end;
     
  17. Tanitra

    Tanitra Гость

    добрый день или утро))) спасибо за советы, мы попробовали, но правда не помогло... я забыла уточнить, что все это происходило на домино 5.0.8, после обновления до 7.0.2 все вроде бы "починилось", но после прогона агента опять сломалось!!! сейчас будем пытаться решить проблему же с семеркой)))
     
Загрузка...

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