• 🔥 Бесплатный курс от Академии Кодебай: «Анализ защищенности веб-приложений»

    🛡 Научитесь находить и использовать уязвимости веб-приложений.
    🧠 Изучите SQLi, XSS, CSRF, IDOR и другие типовые атаки на практике.
    🧪 Погрузитесь в реальные лаборатории и взломайте свой первый сайт!
    🚀 Подходит новичкам — никаких сложных предварительных знаний не требуется.

    Доступ открыт прямо сейчас Записаться бесплатно

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

NickProstoNick

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

правда, возможно, если функция будет вызываться несколько раз подряд для получения дока из разных баз, то, наверное, это не сработает :)
 
неа, Omh прав:базу надо передавать как параметр
 
Вообще, NickProstoNick говорит что, дескать, есть глобальная переменная базы.
Но я в глобальные переменные не верю, поэтому лучше полирнуть параметром.
 
Morpheus ты просто так споришь? :)
про параметр и так понятно, я в какой-то теме описывал даже этот момент...
просто интересно, сработает ли такой способ, а самому некогда проверить :)

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

в чем ошибка?
 
А что означает коммент
Код:
'!!!!!!!!!!!!!!!!!!!!!!!!!!!!
?
 
Код:
			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...

ты прослеживал рекурсию глубже первого уровня?.. посмотри, что у тебя происходит на нижних уровнях рекурсии...
 
пока только один уровень... есть вариант до 4-х уровней... но до него я еще не дошел... точнее такой вариант еще не встретился
 
ну, не знаю, но у меня подозрение, что у тя в ссылках на объекты проблема...
 
Кстати... я говорил что работаю с АДО?
пробовал сделать вот так

Set objRecordsetClone=objRecordset.Clone(locktype)

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

Set TmpRec = New WrappedOUInfo(OUInfo)

CreateOU = CreateOU( TmpRec )

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

Тут передавать в качестве параметра надо лишь OrgUnitID, толк от передачи RS никакого нет - он глобален и Find лишь переносит текущий курсор на первую найденную запись.
 
SkinGreek, я знаю, что такое ADO, в какой-то мере, к стати, это ActiveX Data Objects ;)
я имел в виду, каким образом этот объект получается, чтобы посмотреть его методы и свойства :)
 
а что за АДО? как объект создается?
Это создание соединения
ADOConnection = CreateObject("ADODB.Connection")

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

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

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab