Возвращаемый объект пропадает при выходе из функции

Тема в разделе "Lotus - Программирование", создана пользователем savl, 9 июл 2012.

Статус темы:
Закрыта.
  1. savl

    savl Lotus team
    Lotus team

    Регистрация:
    28 окт 2011
    Сообщения:
    2.051
    Симпатии:
    146
    Коллеги, ситуация такая:
    Есть документ -> В документе поле -> В поле массив: путь к БД и UNID.

    Есть кнопка, которая открывает данный документ.
    Есть функция в библиотеке, которая получает документ на основе данного массива и возвращает в кнопку.

    НО есть момент:
    В библиотеке, документ виден, получен и все хорошо.
    В кнопке же, при возврате из функции, документа уже нет!
    Объект потерян, причем на выходе из функции он опять же есть.

    Проблему решил: получил базу, из которой открывается документ в кнопке, после этого объект стал виден.

    Привожу код из библиотеки и кнопки:

    <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):
            Dim linkArr As Variant
    Dim ses As New notessession
    Dim linkDb As NotesDatabase
    Dim linkDoc As NotesDocument

    Set GetLink = Nothing

    linkArr = project.Getitemvalue(Itemname & "Link")
    If linkArr(0) = "" Then GoTo endh

    Set linkDb = ses.Getdatabase(AgrDb.Server, linkArr(0), false)
    On Error resume Next
    Set linkDoc = linkDb.Getdocumentbyunid(linkArr(1))
    On Error GoTo handler
    Set GetLink = linkDoc
    <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):
        Dim ws As New NotesUIWorkspace 
    Dim pDoc As NotesDocument

    Dim linkArr As Variant
    [i]
    Dim ses As New notessession
    Dim linkDb As NotesDatabase

    linkArr = ProjDoc.Getitemvalue("respPersonLink")
    If linkArr(0) = "" Then Goto endh

    Set linkDb = ses.Getdatabase(ProjDoc.parentdatabase.Server, linkArr(0), False)
    [/i]

    [b] Set pDoc = Project.GetLink("respPerson")  [/b]

    If pDoc Is Nothing Then Goto endh

    Call ws.SetTargetFrame("_Blank")
    Call ws.URLOpen(pDoc.NotesURL)
    В коде кнопки выделена жирным строка (тег ) , которая делает вызов функции, курсивом выделил получение базы (тег ).
    Без этого получения документ в pDoc не возвращается.

    Вопрос: Это такая фича лотуса? Без объекта базы, который висит в памяти, документы теряются?
    Я понимаю это так : база из которой получается документ потеряна на выходе из функции библиотеки, в кнопке ее нет, соответственно документа тоже нет.
    Объясните пож-та.
     
  2. Medevic

    Medevic Что это ? :)
    Lotus team

    Регистрация:
    10 дек 2004
    Сообщения:
    3.346
    Симпатии:
    2
    Ну это баян. :)
    Да, на выходе объект базы прибивается вместе с документом. Поэтому базу лучше передавать в параметрах.
     
  3. savl

    savl Lotus team
    Lotus team

    Регистрация:
    28 окт 2011
    Сообщения:
    2.051
    Симпатии:
    146
    Так и думал. А никто глубже не копал, почему это так?
     
  4. phantom76

    phantom76 Lotus team
    Lotus team

    Регистрация:
    25 фев 2005
    Сообщения:
    363
    Симпатии:
    9
    насколько я вижу вы объекты инициализируете от одинаково называемых объектах SES - NotesSession (в функции и акции) , поэтому из функции Вам ничего не возвращается, Вам или через параметры надо передавать или SES делать глобальным объектом.
     
  5. morpheus

    morpheus скриптописец

    Регистрация:
    7 авг 2006
    Сообщения:
    3.927
    Симпатии:
    0
    а что тут копать, обьект обьявлен в рамках одной функции. По выходу из функции просто обязан изничтожится.
     
  6. savl

    savl Lotus team
    Lotus team

    Регистрация:
    28 окт 2011
    Сообщения:
    2.051
    Симпатии:
    146
    phantom76 от этого не зависит, проверял.

    Morpheus, про объект базы понятно почему исчезает. Мне интересно: почему с объектом базы прибивается объект документа?
    То что это фишка лотуса уже понятно, просто сам момент интересен.
    Передача вниз нормальная, потому что где-то вверху есть объект базы.
    Вот почему наверх нельзя... Какая там связь... :)
     
  7. ABarmin

    ABarmin Гость

    Документ жестко привязан к базе, содержит в себе ссылку на NotesDatabase, из которой он получен - специфика лотуса. Можете создать глобальный кэш баз данных, тогда проблема с потерей ссылок на БД решится.
     
  8. savl

    savl Lotus team
    Lotus team

    Регистрация:
    28 окт 2011
    Сообщения:
    2.051
    Симпатии:
    146
    ABarmin
    Вот для меня это и странно.
    Если рассуждать:

    Связь из документа к базе, то есть базу можно получить из документа. Напрямую.
    Какая разница исчезнет объект базы(в другой переменной) или нет, ее можно получить из объекта документа.
    Ощущение, будто свойство ParentDatabase для документа ничего не значит. Только для удобства получения, не более.
    Если ParentDatabase не более чем указатель, который создается в момент создания объекта документа, то он как-то получается.
    Записывается в память, логично предположить что при его уничтожении память очищается.
    Значит есть проверка, которая уничтожает объект документа при отсутствии значения по данному указателю.

    Однако, если этот указатель заполняется при создании, что мешает его заполнять при необходимости? механизм же тот же.
     
  9. nvyush

    nvyush Lotus team
    Lotus team

    Регистрация:
    22 апр 2009
    Сообщения:
    2.317
    Симпатии:
    0
    Указатель либо пуст (Nothing), либо указывает на объект в памяти. Если объект в памяти больше не нужен, он утилизируется сборщиком мусора. По завершении процедуры/функции все нестатические локальные переменные утилизируются, в том числе db. На что в этом случае будет указывать doc.ParentDatabase? На адрес, по которому уже находится другой объект или просто мусор. Что произойдёт при попытке обратиться по данному указателю? Скорее всего, "Красный квадрат". IBM конечно же могли хранить объект БД в памяти, пока не останется всех ссылок явных (в смысле объектных переменных типа NotesDatabase) и неявных (из полей других объектов), но видимо решили не усложнять себе жизнь. Смиритесь и передавайте БД в функции по ссылке, либо используйте свойство ParentDatabase переданных по ссылке объектов, либо объявите переменные сессии и БД глобально и инициализируйте их в общей библиотеке.
     
  10. savl

    savl Lotus team
    Lotus team

    Регистрация:
    28 окт 2011
    Сообщения:
    2.051
    Симпатии:
    146
    Это тоже понятно.
    Ладно, продолжать бессмысленно :)
     
Загрузка...
Статус темы:
Закрыта.

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