Не переоткрывается документ

Тема в разделе "Lotus - Программирование", создана пользователем nvyush, 27 авг 2009.

  1. nvyush

    nvyush Lotus team
    Lotus team

    Регистрация:
    22 апр 2009
    Сообщения:
    2.317
    Симпатии:
    0
    Пытаюсь переоткрыть документ процедурой
    <!--shcode--><pre><code class='LotusScript'>Public Sub ReloadUIDoc(pUIDoc As NotesUIDocument)
    Dim Doc As NotesDocument
    Dim UNID As String
    Set Doc =pUIDoc.Document
    UNID = Doc.UniversalID
    Doc.SaveOptions = "0"
    pUIDoc.Close True
    Dim UIWorkSpace As New NotesUIWorkspace
    Set Doc = ThisDatabase.GetDocumentByUNID(UNID)
    Call UIWorkSpace.EditDocument(False, Doc, False, , , False)
    End Sub[/CODE]
    Док благополучно закрывается и не открывается. Пробовал засунуть данный код в кнопку формы - и там не работает. Откуда взято уже не помню, вроде раньше работало...
     
  2. ToxaRat

    ToxaRat Чёрный маг
    Lotus team

    Регистрация:
    6 ноя 2007
    Сообщения:
    3.047
    Симпатии:
    18
    nvy
    советую запомнить одно, весьма главное и возможно самое непонятное условие :)

    pUIDoc.Close True - не работает ВООБЩЕ

    а юзать нуно только так:
    call pUIDoc.Close()
    и помнить что данная команда выполняется всегда в самом конце кода
     
  3. nvyush

    nvyush Lotus team
    Lotus team

    Регистрация:
    22 апр 2009
    Сообщения:
    2.317
    Симпатии:
    0
    А в help'е написано:
    Syntax
    Call notesUIDocument.Close( [ immediate ] )
    Parameters
    immediate
    Boolean. Optional. If True, the document is immediately closed. If False, closing the document may be delayed. The default is False.
    Note This parameter is new with Release 5.0.7.

    Кому верить?
     
  4. ToxaRat

    ToxaRat Чёрный маг
    Lotus team

    Регистрация:
    6 ноя 2007
    Сообщения:
    3.047
    Симпатии:
    18
    nvy
    верить можно только мне :)

    команда pUIDoc.Close True сворачивает клиента, и вопрос с ней не решен даже в последней версии
     
  5. TIA

    TIA :-)
    Lotus team

    Регистрация:
    15 май 2009
    Сообщения:
    790
    Симпатии:
    0
    Сделай последний параметр = True и открываться будет.
    Call UIWorkSpace.EditDocument(False, Doc, False, , , True)

    Бессмысленно
    Set Doc = ThisDatabase.GetDocumentByUNID(UNID)
    без предварительного delete Doc.
     
  6. nvyush

    nvyush Lotus team
    Lotus team

    Регистрация:
    22 апр 2009
    Сообщения:
    2.317
    Симпатии:
    0
    Код переделал и всё заработало:
    <!--shcode--><pre><code class='LS'>Public Sub ReloadUIDoc(pUIDoc As NotesUIDocument)
    Dim Doc As NotesDocument
    Dim UNID As String
    Set Doc =pUIDoc.Document
    UNID = Doc.UniversalID
    Doc.SaveOptions = "0"
    Dim UIWorkSpace As New NotesUIWorkspace
    Set Doc = ThisDatabase.GetDocumentByUNID(UNID)
    Call UIWorkSpace.EditDocument(False, Doc, False, , True, True)
    pUIDoc.Close 'True
    End Sub[/CODE]
    +1
     
  7. TIA

    TIA :-)
    Lotus team

    Регистрация:
    15 май 2009
    Сообщения:
    790
    Симпатии:
    0
    При каких условиях клиент сворачивается? Метод Close(True) действительно опасный, но если аккуратно пользовать - выручает.
     
  8. divankin

    divankin Senjor developer

    Регистрация:
    13 авг 2009
    Сообщения:
    182
    Симпатии:
    0
    TIA
    Тогда уж надо предварительно проверять, не удален ли он уже. Потому что, если код выполняется в агенте, то после UIDoc.Close(true) полученный через него NotesDocument тоже обращается в Nothing.


    nvy
    Не нравится мне ваш вариант. Вы теряете все изменения, внесенные пользователем. Кроме того, не работает с новыми документами.

    По-моему, лучше сделать так
    1. Код должен выполняться не из агента.
    2. Делать резервную копию документа и сохранять в каком-нибудь временном месте. Можно на локале.
    3. Выставлять SaveOptions и делать UIClose(true)
    4. Проверять не потерялся ли NotesDocument. (В моей практике такое изредка случалось)
    5. Если потерялся, то создавать новый по копии, не забыв востановить UniversalID
    6. Пометить резервный документ на удаление (у вас должен быть механизм удаления таких документов)
    7. Удалить поле SaveOptions.
    8. Открывать документ заново с параметрами returnNotesUIDocument=false и newInstance= true
     
  9. ToxaRat

    ToxaRat Чёрный маг
    Lotus team

    Регистрация:
    6 ноя 2007
    Сообщения:
    3.047
    Симпатии:
    18
    nvy
    работает и хорошо :)
    еще один маленький нюанс, проследите чтобы после Doc.SaveOptions = "0" это поле не попало в редактируемый документ потом и не сохранилось там, ненароком
    иначе потом начнете играть в игру "как удалить это поле в существующих доках"
     
  10. TIA

    TIA :-)
    Lotus team

    Регистрация:
    15 май 2009
    Сообщения:
    790
    Симпатии:
    0
    Как раз в случае закрытия текущего документа Close(True) вреден, и из приведённого кода его надо убрать. А delete - добавить. Необходимость проверять параметр на соответствие -- зависит от контекста применения. Может, и нужна.
     
  11. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.081
    Симпатии:
    300
    к слову пришлось :) ...
    не забываем про SaveOptions="00" (либо др. значение не "0" и не "1") фичу
    поле можно сделать CFD (и удалять не придётся)
    хотм сэйвим, хотим - нет
    в веб не работает
     
  12. nvyush

    nvyush Lotus team
    Lotus team

    Регистрация:
    22 апр 2009
    Сообщения:
    2.317
    Симпатии:
    0
    Прошу прощения за отсталость, а что за фича и что она даёт?
    По теме поста - теперь словил новый глюк. UIDoc.EditMode = False. Меняю значения полей дока, выполняю нужный код, затем вызываю вышеприведённую процедуру и вижу модифицированные значения полей. Но документ-то я не сохранял! Закрываю ручками, открываю - всё верно, старые значения полей.
    Добавил в процедуру Set Doc = Nothing - то же самое.
    По смыслу приложения должно быть следующее: меняю статусы откликов, для рассылки извещений временно меняю значение статуса главного документа, вызываю стандартную процедуру рассылки извещений, переоткрываю док.
     
  13. divankin

    divankin Senjor developer

    Регистрация:
    13 авг 2009
    Сообщения:
    182
    Симпатии:
    0
    Добавьте
    If not doc is nothing then Delete doc
     
  14. nvyush

    nvyush Lotus team
    Lotus team

    Регистрация:
    22 апр 2009
    Сообщения:
    2.317
    Симпатии:
    0
    Вроде работает. Эх не догоняю я логику разработчиков Лотуса, без бубна фиг заставишь работать даже тривиальный код.
     
  15. divankin

    divankin Senjor developer

    Регистрация:
    13 авг 2009
    Сообщения:
    182
    Симпатии:
    0
    А тут бубен не причем.
    Есть такая фича в Лотусе, на мой взгляд достаточно удобная: если уже открыт экземпляр объекта NotesDocument c данным UniversalID, то если функции получения документа из базы возвращают именно его, а не создают новый. Поэтому если вы хотите сбросить все изменения, сделанные в документе, то объект нужно очистить и взять из базы по новой.

    Что касается сборщика мусора, то, действительно, он не собирает объекты NotesDocument, на которые в программе не осталось ссылок. Поэтому если вы перебираете документы в большой коллекции, то после GetNextDocument рекомендуется делать Delete объекта, с которым окончили работу.
     
  16. nvyush

    nvyush Lotus team
    Lotus team

    Регистрация:
    22 апр 2009
    Сообщения:
    2.317
    Симпатии:
    0
    Типа так?
    <!--shcode--><pre><code class='LS'>Set nextdoc = docs.GetFirstDocument
    Do Until nextdoc Is Nothing
    set doc = nextdoc
    ...
    Set nextdoc = docs.GetNextDocument(Doc)
    Delete Doc
    loop[/CODE]
     
  17. ToxaRat

    ToxaRat Чёрный маг
    Lotus team

    Регистрация:
    6 ноя 2007
    Сообщения:
    3.047
    Симпатии:
    18
    Divankin
    что-то не вьехал
    еще раз и помедленней, зачем после GetNextDocument удалять обьект?
     
  18. TIA

    TIA :-)
    Lotus team

    Регистрация:
    15 май 2009
    Сообщения:
    790
    Симпатии:
    0
    nvy
    Про delete я же сразу сказал, а вы так и не попробовали. :)

    Сказанное не верно. Подтверждается nsd-логами и кол-вом обрабатываемых документов. Недавно разбиралась ситуация, когда документы кэшеровались в массиве. После того, как кэширование убрали - сервер перестал падать. Если бы документы оставались в памяти, утечки бы сохранялись и сервер продолжал падать.

    Я скорее склонен к гипотезе, что скриптовые объекты (не нотусовые), имеющие перекрёстные ссылки (а может даже и без них) не удаляются сразу. А только при завершении работы исполняемого модуля (типа агента, формы). Косвенно подтверждается тем, что в таком случае после последней строчки кода, агент что-то ещё долго делает, пока не вернёт управление. Скорее всего в этот момент он и уничтожает такие объекты. Расстановка явных delete устраняет долгую выгрузку.
     
  19. nvyush

    nvyush Lotus team
    Lotus team

    Регистрация:
    22 апр 2009
    Сообщения:
    2.317
    Симпатии:
    0
    Я попробовал set doc = nothing, думал этого достаточно/одно и то же. Признаю свою ошибку. Что касается перебора коллекции, я так и не понял, нужнО там delete или нет? А то как-то неохота все переборы коллекции во всех базах переделывать :)
     
  20. TIA

    TIA :-)
    Lotus team

    Регистрация:
    15 май 2009
    Сообщения:
    790
    Симпатии:
    0
    nvy
    Нет проблем - ничего менять не надо. Посмотри мой предыдущий пост.
     
Загрузка...

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