• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

    На последнюю неделю приходится экзамен, где нужно будет показать свои навыки, взломав ряд уязвимых учебных сайтов, и добыть флаги. Успешно сдавшие экзамен получат сертификат.

    Запись на курс до 25 апреля. Получить промодоступ ...

Lotus и Delphi

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

Tanitra

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

hosm

Есть у IBM несколько полезных ссылок:


Возможно, ошибка при переборе коллекции документов?
Посмотрите код замены поля, если это поле типа ридерс, может, явно поставить при замене .IsReaders = True?
Или нужного итема всё-таки нет в документе, а Вы пытаетесь обратиться к его свойствам/методам?
 
T

Tanitra

Подобным образом этому полю были присвоены новые значения в нескольких аналогичных базах. В тех базах где количество документов обрабатываемого вида не превышало 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
 
H

hosm

Сходу проверьте 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

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

K-Fire

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

Tanitra

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

hosm

дельфи не понимает что последний документ закачан и не может завершить цикл
он точно вычитывает все данные? А как вы 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
 
T

TIA

В тех базах где количество документов обрабатываемого вида не превышало 5 тыс. Все прошло нормально и отчеты формируются. Там же где количество примерно 15 тыс. доков возникают проблемы. Код замены значений в поле:

5 тыс. - это дефолтное ограничение на количество найденных документов черех FTSearch. У вас он применяется?

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

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">
Код:
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;
 
H

hosm

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

hosm

со указанием строки для обработки ошибок в дельфи не помогу, я давно с этой средой не работаю
Ну, имхо, или в LNGetFieldStrValue на невалидном/удаленном или получение след. документа из коллекции.
(Я, кстати, в начале работы с лотусом такую ошибку именно на коллекции исправляла)
 
T

TIA

со указанием строки для обработки ошибок в дельфи не помог
Ну дебаггер-то ей точно доступен.

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

Tanitra

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

hosm

значит, в 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

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

Обучение наступательной кибербезопасности в игровой форме. Начать игру!