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

nvyush

Lotus team
22.04.2009
2 317
0
#1
Пытаюсь переоткрыть документ процедурой
<!--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]
Док благополучно закрывается и не открывается. Пробовал засунуть данный код в кнопку формы - и там не работает. Откуда взято уже не помню, вроде раньше работало...
 

ToxaRat

Чёрный маг
Lotus team
06.11.2007
3 231
18
#2
nvy
советую запомнить одно, весьма главное и возможно самое непонятное условие :)

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

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

nvyush

Lotus team
22.04.2009
2 317
0
#3
nvy
советую запомнить одно, весьма главное и возможно самое непонятное условие :)

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

а юзать нуно только так:
call pUIDoc.Close()
и помнить что данная команда выполняется всегда в самом конце кода
А в 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.

Кому верить?
 

ToxaRat

Чёрный маг
Lotus team
06.11.2007
3 231
18
#4
nvy
верить можно только мне :)

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

TIA

:-)
Lotus team
15.05.2009
790
3
#5
Сделай последний параметр = True и открываться будет.
Call UIWorkSpace.EditDocument(False, Doc, False, , , True)

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

nvyush

Lotus team
22.04.2009
2 317
0
#6
nvy
верить можно только мне :)

команда pUIDoc.Close True сворачивает клиента, и вопрос с ней не решен даже в последней версии
Код переделал и всё заработало:
<!--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
 

TIA

:-)
Lotus team
15.05.2009
790
3
#7
команда pUIDoc.Close True сворачивает клиента, и вопрос с ней не решен даже в последней версии
При каких условиях клиент сворачивается? Метод Close(True) действительно опасный, но если аккуратно пользовать - выручает.
 

divankin

Senjor developer
13.08.2009
182
0
#8
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
 

ToxaRat

Чёрный маг
Lotus team
06.11.2007
3 231
18
#9
nvy
работает и хорошо :)
еще один маленький нюанс, проследите чтобы после Doc.SaveOptions = "0" это поле не попало в редактируемый документ потом и не сохранилось там, ненароком
иначе потом начнете играть в игру "как удалить это поле в существующих доках"
 

TIA

:-)
Lotus team
15.05.2009
790
3
#10
Тогда уж надо предварительно проверять, не удален ли он уже. Потому что, если код выполняется в агенте, то после UIDoc.Close(true) полученный через него NotesDocument тоже обращается в Nothing.
Как раз в случае закрытия текущего документа Close(True) вреден, и из приведённого кода его надо убрать. А delete - добавить. Необходимость проверять параметр на соответствие -- зависит от контекста применения. Может, и нужна.
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 583
269
#11
к слову пришлось :) ...
не забываем про SaveOptions="00" (либо др. значение не "0" и не "1") фичу
поле можно сделать CFD (и удалять не придётся)
хотм сэйвим, хотим - нет
в веб не работает
 

nvyush

Lotus team
22.04.2009
2 317
0
#12
к слову пришлось :) ...
не забываем про SaveOptions="00" (либо др. значение не "0" и не "1") фичу
поле можно сделать CFD (и удалять не придётся)
хотм сэйвим, хотим - нет
в веб не работает
Прошу прощения за отсталость, а что за фича и что она даёт?
По теме поста - теперь словил новый глюк. UIDoc.EditMode = False. Меняю значения полей дока, выполняю нужный код, затем вызываю вышеприведённую процедуру и вижу модифицированные значения полей. Но документ-то я не сохранял! Закрываю ручками, открываю - всё верно, старые значения полей.
Добавил в процедуру Set Doc = Nothing - то же самое.
По смыслу приложения должно быть следующее: меняю статусы откликов, для рассылки извещений временно меняю значение статуса главного документа, вызываю стандартную процедуру рассылки извещений, переоткрываю док.
 

divankin

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

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

nvyush

Lotus team
22.04.2009
2 317
0
#16
Что касается сборщика мусора, то, действительно, он не собирает объекты NotesDocument, на которые в программе не осталось ссылок. Поэтому если вы перебираете документы в большой коллекции, то после GetNextDocument рекомендуется делать Delete объекта, с которым окончили работу.
Типа так?
<!--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]
 

ToxaRat

Чёрный маг
Lotus team
06.11.2007
3 231
18
#17
Divankin
Что касается сборщика мусора, то, действительно, он не собирает объекты NotesDocument, на которые в программе не осталось ссылок. Поэтому если вы перебираете документы в большой коллекции, то после GetNextDocument рекомендуется делать Delete объекта, с которым окончили работу.
что-то не вьехал
еще раз и помедленней, зачем после GetNextDocument удалять обьект?
 

TIA

:-)
Lotus team
15.05.2009
790
3
#18
nvy
Про delete я же сразу сказал, а вы так и не попробовали. :)

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

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

nvyush

Lotus team
22.04.2009
2 317
0
#19
nvy
Про delete я же сразу сказал, а вы так и не попробовали. :(


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

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

TIA

:-)
Lotus team
15.05.2009
790
3
#20
nvy
Нет проблем - ничего менять не надо. Посмотри мой предыдущий пост.