Lotus и Delphi

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

Tanitra

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

hosm

* so what *
18.05.2009
2 442
9
42
Kiev, Ukraine
#2
Есть у IBM несколько полезных ссылок:
http://www-01.ibm.com/support/docview.wss?...uid=swg21316690
http://www-01.ibm.com/support/docview.wss?uid=swg21093032
Возможно, ошибка при переборе коллекции документов?
Посмотрите код замены поля, если это поле типа ридерс, может, явно поставить при замене .IsReaders = True?
Или нужного итема всё-таки нет в документе, а Вы пытаетесь обратиться к его свойствам/методам?
 
T

Tanitra

Гость
#3
Подобным образом этому полю были присвоены новые значения в нескольких аналогичных базах. В тех базах где количество документов обрабатываемого вида не превышало 5 тыс. Все прошло нормально и отчеты формируются. Там же где количество примерно 15 тыс. доков возникают проблемы. Код замены значений в поле:
Код:
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
 

hosm

* so what *
18.05.2009
2 442
9
42
Kiev, Ukraine
#4
Сходу проверьте doc на Nothing
Redim Preserve itemnames(k) ???
выше не вижу просто
Redim itemnames(0) - оно должно быть перед Redim Preserve
проверьте правильность получения
itemName=DialogDoc.FieldName(0)
itemvalue= Arrayappend(doc.GetItemValue(itemname),DialogDoc.Fieldvalue)






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

Tanitra

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

K-Fire

Гость
#6
А сколько у вас этот агент работает по времени на 5 тыс документов?
 
T

Tanitra

Гость
#7
на 5 тыс доков примерно 2-3 минуты, на 15 тыс 15 мин
 

hosm

* so what *
18.05.2009
2 442
9
42
Kiev, Ukraine
#8
дельфи не понимает что последний документ закачан и не может завершить цикл
он точно вычитывает все данные? А как вы Delphi пытаетесь указать за завершение цикла?
Учитывается наличие удаленных документов, стабов, не содержащих итемы?
тогда посмотрите условие завершения цикла насчет проверки документа на Nothing, если документ не Nothing, то после этого полезно проверить на doc.IsValid and Not doc.isDeleted
P.S.: Если честно, я в агенте не могу понять в этом кусочке код в Else, зачем он вообще, поле в doc вообще тогда не должно меняться (if not Isarray(DialogDoc.fieldvalue), то скорее всего, оно Empty):
Код:
If Isarray(DialogDoc.fieldvalue) Then
itemvalue= Arrayappend(doc.GetItemValue(itemname),DialogDoc.Fieldvalue)				
Else 
itemvalue=doc.GetItemValue(itemname)
itemvalue=itemvalue+DialogDoc.Fieldvalue
End If
Добавлено: Возможно, слишком усложняю, но может, нужно-таки явное указание типа ридеров - нечто подобное:
Код:
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
 

TIA

:-)
Lotus team
15.05.2009
790
1
#9
В тех базах где количество документов обрабатываемого вида не превышало 5 тыс. Все прошло нормально и отчеты формируются. Там же где количество примерно 15 тыс. доков возникают проблемы. Код замены значений в поле:
5 тыс. - это дефолтное ограничение на количество найденных документов черех FTSearch. У вас он применяется?

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

Tanitra

Гость
#10
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">
Код:
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;
 

hosm

* so what *
18.05.2009
2 442
9
42
Kiev, Ukraine
#11
TIA Фт-поиска тут нет, берут кол-во ентри и проходят по документам.
Вьюха, похоже, не категоризированная, т.к. работает для небольшой БД корректно.
А вот почему игнорятся проверки на валидность, мне непонятно...
В лотусе я бы попробовала LNView.AutoUpdate = false перед выгрузкой и сделала проверки проверки тек. документа из коллекции на Nothing:
1)если документ Nothing - выйти из цикла.
2)если документ не Nothing, то после этого при проверках doc.IsValid and Not doc.isDeleted (или + IsEmpty(doc.Items)?) обработать, иначе - перейти к следующему.
Такое реализуемо и через Delphi, надеюсь?
 

hosm

* so what *
18.05.2009
2 442
9
42
Kiev, Ukraine
#13
со указанием строки для обработки ошибок в дельфи не помогу, я давно с этой средой не работаю
Ну, имхо, или в LNGetFieldStrValue на невалидном/удаленном или получение след. документа из коллекции.
(Я, кстати, в начале работы с лотусом такую ошибку именно на коллекции исправляла)
 

TIA

:-)
Lotus team
15.05.2009
790
1
#14
со указанием строки для обработки ошибок в дельфи не помог
Ну дебаггер-то ей точно доступен.

у, имхо, или в LNGetFieldStrValue на невалидном/удаленном или получение след. документа из коллекции.
Гипотезу поддерживаю.
 
T

Tanitra

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

hosm

* so what *
18.05.2009
2 442
9
42
Kiev, Ukraine
#16
значит, в 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;
 
T

Tanitra

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