• Познакомьтесь с пентестом веб-приложений на практике в нашем новом бесплатном курсе

    «Анализ защищенности веб-приложений»

    🔥 Записаться бесплатно!

  • CTF с учебными материалами Codeby Games

    Обучение кибербезопасности в игровой форме. Более 200 заданий по Active Directory, OSINT, PWN, Веб, Стеганографии, Реверс-инжинирингу, Форензике и Криптографии. Школа CTF с бесплатными курсами по всем категориям.

Работа с функциями

NickProstoNick

Статус как статус :)
Lotus Team
22.08.2008
1 851
27
BIT
0
Доброго времени суток!
Ребята, вопрос вот какого плана... есть глобальная переменная типа НотесДокумент... есть функция, которая должна возвращать НотесДокумент в переменную... но вот почему-то не возвращает :blink: хотя под отладчиком видно, что функции присваивается нужное значенме, но в переменную не передается :D
что это за глюк и как с ним бороться?
 
M

morpheus

NickProstoNick
глюк с тем что у вас скорее всего нету глобальной переменной базы данных. и как только фун-ция заканчивает работы, то экземпляр класса база "обнуляеться" и соответственно "обнуляеться" сама привязка к документу
 
O

Omh

Передвавай базу в функцию как параметер.
 
A

Akupaka

ради интереса :)
попробуй свою базу в функции объявить как static

правда, возможно, если функция будет вызываться несколько раз подряд для получения дока из разных баз, то, наверное, это не сработает :)
 
M

morpheus

неа, Omh прав:базу надо передавать как параметр
 
O

Omh

Вообще, NickProstoNick говорит что, дескать, есть глобальная переменная базы.
Но я в глобальные переменные не верю, поэтому лучше полирнуть параметром.
 
A

Akupaka

Morpheus ты просто так споришь? :)
про параметр и так понятно, я в какой-то теме описывал даже этот момент...
просто интересно, сработает ли такой способ, а самому некогда проверить :)

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

NickProstoNick

Статус как статус :)
Lotus Team
22.08.2008
1 851
27
BIT
0
Akupaka
:)
Ребята, прошу прощения.... разобрался сам... просто был не внимательный... на автомате спутал буквы в названии функции местами... и не заметил :(


Но теперь новый вопрос!
Есть рекурсивная функция (не та что обсуждалась выше)... входящий параметр типа Вариант... в этот параметр передается массив записей из Сиквела... так вот в чем проблема... при возвращении из рекурсии теряются данный из входящего параметра

Код:
Function CreateOU( OUInfo As Variant ) As Integer
Dim OUView As NotesView
Dim OUDocCollection As NotesDocumentCollection
Dim OUDoc As NotesDocument
Dim RefOUDoc As NotesDocument
Dim Ref As String


Set OUView = DB.GetView("OrgUnit:ProPeopleOrgUnitID")

If OUInfo( "OrgUnitREFID" ).Value ="-1" Then ' проверяем находится оргюнит на первом уровне

Set OUDocCollection = OUView.GetAllDocumentsByKey( "OUID_" + Trim( OUInfo( "OrgUnitREFID" ).Value ), True )	'!!!!!!!!!!!!!!!!!!!!!!!!!!!			
Set OUDoc = DB.CreateDocument		

OUDoc.Name = OUInfo( "CityName" ).Value + " №" + Cstr( OUInfo( "BranchNumber" ).Value ) + " (" + OUInfo( "BranchAdress" ).Value + ")"		
OUDoc.City = OUInfo( "CityName" ).Value  '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
OUDoc.CityEng = OUInfo( "OUCityEng" ).Value  '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

If OUInfo( "BranchNumber" ).Value <> "н/д" Then
OUDoc.BranchNumber = Cint( OUInfo( "BranchNumber" ).Value )
End If

Else

' если да - то создаем респонс у родителя

Set RefOUDoc = OUView.GetDocumentByKey( "ID_" + Trim( OUInfo( "OrgUnitREFID" ).Value ), True ) '!!!!!!!!!!!!!!!!!!!!!!!!!!!		

'	если родитель отсутствует - то создаем
If RefOUDoc Is Nothing Then

Dim TmpRec As Variant
Set TmpRec = OUInfo

TmpRec.Find "OrgUnitID = '" + Trim( OUInfo( "OrgUnitREFID" ).Value ) + "' "

CreateOU = CreateOU( TmpRec )

Set OUInfo = OURecordSet '  [color="#FF0000"]ТУТ УЖЕ НЕ ПРАВИЛЬНОЕ ЗНАЧЕНИЕ ПРИ ВОЗВРАЩЕНИИ ИЗ РЕКУРСИИ
OURecordSet - глобальная переменная. причем в этом месте OURecordSet = TmpRec [/color]

Set RefOUDoc = OUView.GetDocumentByKey( "ID_" + Trim( OUInfo( "OrgUnitREFID" ).Value ), True ) '!!!!!!!!!!!!!!!!!!!!!!!!!!!
End If

OUView.Refresh

Set OUDocCollection = OUView.GetAllDocumentsByKey( "OUREFID_" + Trim( OUInfo( "OrgUnitREFID" ).Value ), True )  '!!!!!!!!!!!!!!!!!!!!!!!!!!!

Set OUDoc = DB.CreateDocument	

Call OUDoc.MakeResponse(RefOUDoc) 

OUDoc.Name = OUInfo( "OrgUnitName" ).Value

End If

OUDoc.Type = OUInfo( "OrgUnitType" ).Value '!!!!!!!!!!!!!!!!!!!!!!!!!!!!

OUDoc.SubNumber = OUDocCollection.Count + 1

OUDoc.ProPeopleOrgUnitID = OUInfo( "OrgUnitID" ).Value	
OUDoc.ProPeopleOrgUnitRefID = OUInfo( "OrgUnitREFID" ).Value

OUDoc.Form = "subdivision"

Call OUDoc.ComputeWithForm( False,False )
Call OUDoc.Save( True, False, True )	

End Function

в чем ошибка?
 
O

Omh

А что означает коммент
Код:
'!!!!!!!!!!!!!!!!!!!!!!!!!!!!
?
 
A

Akupaka

Код:
			Dim TmpRec As Variant
Set TmpRec = OUInfo

TmpRec.Find "OrgUnitID = '" + Trim( OUInfo( "OrgUnitREFID" ).Value ) + "' "

CreateOU = CreateOU( TmpRec )

Set OUInfo = OURecordSet '  [color="#FF0000"]ТУТ УЖЕ НЕ ПРАВИЛЬНОЕ ЗНАЧЕНИЕ ПРИ ВОЗВРАЩЕНИИ ИЗ РЕКУРСИИ
OURecordSet - глобальная переменная. причем в этом месте OURecordSet = TmpRec [/color]

возможно, я и не прав, но ты сначала присваиваешь ссылке TmpRec значение ссылки OUInfo, т.е. фактически, они ссылаются на один объект в памяти, на одни и те же данные, потом вызываешь рекурсивно себя, потом присваиваешь ссылке OUInfo ссылку на какой-то глобальный объект OURecordSet, т.е. если у тебя вызов на втором уровне рекурсии проходит в эту же ветку, т.е. есть вход в третий уровень рекурсии, то ты получишь во всех ссылках одну и ту же, т.е.
TmpRec is OURecordSet, OUInfo is OURecordSet ну и TmpRec is OUInfo...

ты прослеживал рекурсию глубже первого уровня?.. посмотри, что у тебя происходит на нижних уровнях рекурсии...
 

NickProstoNick

Статус как статус :)
Lotus Team
22.08.2008
1 851
27
BIT
0
пока только один уровень... есть вариант до 4-х уровней... но до него я еще не дошел... точнее такой вариант еще не встретился
 
A

Akupaka

ну, не знаю, но у меня подозрение, что у тя в ссылках на объекты проблема...
 

NickProstoNick

Статус как статус :)
Lotus Team
22.08.2008
1 851
27
BIT
0
Кстати... я говорил что работаю с АДО?
пробовал сделать вот так

Set objRecordsetClone=objRecordset.Clone(locktype)

ругается... почему - не понятно :)
 
D

dobozy

Передавача параметра идёт по ссылке. Так как по значению тут сюдя по всему не передашь параметр, то нужно создать свой класс wrapper и менять участок кода так

Set TmpRec = New WrappedOUInfo(OUInfo)

CreateOU = CreateOU( TmpRec )

Правда это только предположения. Идяе в том, чтобы создать новый объект в памяти ну и т.д.
 
A

Akupaka

dobozy, идея-то понятна, да вот так, скорее всего, не поступишь...
но, можно создать свой класс, который будет хранителем результата из сиквела, и работать с ним...
а что за АДО? как объект создается? и как ругается при вызове .Clone(locktype)?
 
S

SkinGreek

ADO - Access Data Object это фича мелкомягкого для работы с источниками данных.
Как я понял с помощью Find тебе надо найти только 1 запись. То есть структура древовидная, и ты проходишь по нему снизу вверх, от одного листа.
Решение dobozy я думаю не поможет.
Вам необходимо перед продолжении рекурсии скинуть все необходимые данные из RS текущей записи.
Клонировать конечно можно но оно по моему работает только когда открываешь курсор на клиенте, то что вы используете find значит что тип курсора KeySet. Хотя возможно клонирование не работает из-за режима Lock'a. Но я всегда использовал оптимистичный и все было ок(правда это было не в лотусе)
В данной задачи клонирование излишне. Так как вы используете лишь Find и вам нужна лишь одна запись, вот если бы был Filter и вы бы дальше пробегались по коллекции, тогда бы без клонирования не обойтись.

Тут передавать в качестве параметра надо лишь OrgUnitID, толк от передачи RS никакого нет - он глобален и Find лишь переносит текущий курсор на первую найденную запись.
 
A

Akupaka

SkinGreek, я знаю, что такое ADO, в какой-то мере, к стати, это ActiveX Data Objects ;)
я имел в виду, каким образом этот объект получается, чтобы посмотреть его методы и свойства :)
 

NickProstoNick

Статус как статус :)
Lotus Team
22.08.2008
1 851
27
BIT
0
а что за АДО? как объект создается?
Это создание соединения
ADOConnection = CreateObject("ADODB.Connection")

Это создание RecordSet
Set TmpRec = CreateObject("ADODB.RecordSet")

и как ругается при вызове .Clone(locktype)?
на .Clone(locktype) просто ругается... код ошибки 213.... но в чем именно ошибка - не известно.
Ну я вобщкм решил проблему... но пришлось делать лишний запрос в Сиквел... :) пока будет так... до лучших времен
 
Мы в соцсетях:

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