Переоткрытие Родителя

Тема в разделе "Lotus - Программирование", создана пользователем juk-777, 16 апр 2014.

  1. juk-777

    juk-777 Active Member

    Регистрация:
    5 авг 2013
    Сообщения:
    38
    Симпатии:
    0
    Доброго времени суток, уважаемые! Помогите пожалста разобраться...

    Существует документ-родитель, к которому создается дочерний (документ правда не совсем "дочерний", а имеет поле UniRoditelya, в которое я заношу UniversalID родительского дока. Ну и потом по этому полю я строю необходимую мне иерархию во встроенных вьюхах).
    Это была маленькая прелюдия, а проблема в следующем: в родительском доке имеется RT-поле History, в которое я хочу вносить каждое действие, которое совершает пользователь по редактированию/созданию новых дочерних документов.
    Так вот, мне надо чтобы после сохранения дочки, которая открыта или создана из родителя, открытый родитель переоткрывался в режиме просмотра. Долго я бился над кодом, который сейчас выложу... Он работает, но как-то не стабильно. Не стабильность в том, что то нормально закрывает все открытые доки и открывает для чтения родителя, то отставляет "старого" родителя открытым и открывает "нового" для чтения. То дочку оставляет открытой для редактирования :)(
    Прошу помочь в решении проблемы, может туплю по-страшному где-то).

    В событии QuerySave дочки идет проверка: на заполнение необходимых полей на форме и запись в историю родителя:
    Continue=ProverkaPeople(Source.Document)

    Теперь приведу выборочный код самой проверки ProverkaPeople.
    сразу чуть поясню по коду:
    nd - это получаемый функцией дочерний документ
    pardoc - это получаемый из дочки родительский документ

    <div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">Код проверки ProverkaPeople</div></div><div class="sp-body"><div class="sp-content">
    Function ProverkaPeople (nd As NotesDocument) As Boolean
    'здесь идет объявление переменных...

    ProverkaPeople = True

    On Error GoTo err1

    'тут идет проверка на заполнение полей в форме...


    'после проверки на заполнение полей оставляю код как в ориггинале, чтобы было легче понять что к чему

    mes=nd.UniRoditelya(0)
    Set pardoc = db.GetDocumentByUNID(mes)

    If pardoc Is Nothing Then
    ProverkaPeople = False
    Exit Function
    End If

    Set NameItm=New NotesName(session.UserName)
    formul$="" + Date$ + " " + Time() + " - " + CStr(NameItm.Abbreviated) +_
    ". " + nd.PeopleRol(0) +_
    ". ФИО: " + nd.PeopleFIO(0) +_
    ". Год рождения: " + nd.PeopleGodRozh(0) +_
    ". Место жительства: " + nd.PeopleMestoZhit(0) +_
    ". Место работы: " + nd.PeopleMestoRab(0) + "."

    Set RTItm=pardoc.getFirstItem("HistoryUD")
    Call RTItm.Appendtext(formul$)
    Call RTItm.Addnewline(1,True)
    Call pardoc.Save(1,0)
    Call pardoc.ReplaceItemValue("SAVEOPTIONS","0")

    If nd.Isnewnote Then
    nd.Form="FormPeople"
    Call nd.Save(1,0)
    Call nd.ReplaceItemValue("SAVEOPTIONS","0")
    End If


    Set uidoc = ws.Currentdocument
    Call uidoc.Close
    Call ws.URLOpen(pardoc.NotesURL)
    Set uidoc = ws.Currentdocument
    Call uidoc.Close

    Call ws.EditDocument(false, pardoc)

    Exit Function


    err1:

    Print "Ошибка в функции ProverkaPeople. Err=" & Err & ", Error=" & Error & ", Line=" & Erl
    ProverkaPeople = False
    Exit Function
    End Function
     
  2. savl

    savl Lotus team
    Lotus team

    Регистрация:
    28 окт 2011
    Сообщения:
    2.051
    Симпатии:
    146
    "Зачем..." ну да ладно.
    Можно немного поменять код (сделайте копию функции ProverkaPeople, назавите её ProverkaPeople2):
    1. Если функция вызывается в QuerySave, то думаю лучше вызвать ProverkaPeople2(Source)
    То есть поменять тип входящего значения и уже внутри функции получать документ.
    Это может сократить количество вызовов ws.Currentdocument, который достаточно глючный.
    2. Попробовать получить ui-объект родителя через ws.EditDocument, но метод глючит порой, в частности во фреймах, так что нужны тесты.

    Итого примерно такие правки (код не проверял, решение на ходу):
    Код (LotusScript):
    Function ProverkaPeople (ndUI As NotesUIDocument) As Boolean
    '.... Ваши другие Dim
    Dim nd as Notesdocument
    set Nd = ndUI.Document
    '..... Ваш основной код
    Call ndUI .Close
    Set uidoc = ws.EditDocument(false, pardoc,,,,true,false)
    Call uidoc.Close
    Call ws.URLOpen(pardoc.NotesURL)
    End Function
    Добавлено: А как по мне, я бы при создании дочерки - закрывал родителя, затем при сохранении - закрывал дочерку, открывал родителя.
    Или бы не открывал, а сделал кнопку "Открыть основной документ" и пусть нажимают.
     
  3. juk-777

    juk-777 Active Member

    Регистрация:
    5 авг 2013
    Сообщения:
    38
    Симпатии:
    0
    Огромное спасибо за ответ!

    сократив кол-во вызовов ws.Currentdocument получил вроде 100% результат по НЕГЛЮЧНОСТИ)) За время тестирования все срабатывало на УРА! Изменил чуток ваш код на следующий, так как с вашим кодом закрывались все документы и оставалась открыта только база.
    Call ndui.Close
    Call ws.URLOpen(pardoc.NotesURL)
    Set uidoc = ws.Currentdocument
    Call uidoc.Close
    Call ws.EditDocument(False, pardoc)

    Редактирую пост спустя некоторое время: погорячился я все-таки со ста процентами ... (( проглючивает все равно его .. оставляет иногда открытым старого родителя и открывает еще вдобавок нового. Вопрос про закрытие родителя при открытии и дальнейшем изменении дочки, а не при ее создании, остается открытым)
    Кнопку открыть родителя я смастерил тоже, но хотел, чтобы поменьше юзвери шелкали мышками) Посмотрю как покажет себя код в работе .. и если будя глючить - буду закрывать родителя при создании дочки.

    Кстати .. вопрос походу возник (может глуповатый - но простите :) ):
    А как закрыть родителя, если дочка не создается новая, а открывается существующая из внедренного представления?
     
  4. alexas

    alexas Well-Known Member

    Регистрация:
    10 июн 2009
    Сообщения:
    215
    Симпатии:
    0
    Не надо, в Вашем случае, использовать ws.URLOpen() вообще!
    Чтобы придти в UI дока используйте ws.EditDocument(false/true, pardoc,,,,,false), как правильно savl отметил, и всё будет нормально (если док открыт в отдельной вкладке, т.е. НЕ в фрэйме).
    С фрэймами другой разговор, но тоже есть решение.
    И старайтесь не прыгать туда-сюда из UI одного дока в другой (не любит нотус этого): сделайте всё в UI одного дока, перейдите в UI другого и завершите скрипт.
     
  5. juk-777

    juk-777 Active Member

    Регистрация:
    5 авг 2013
    Сообщения:
    38
    Симпатии:
    0
    Спасибо за ответ!
    Вчера еще немного поэкспериментировал с кодом и пришел к такому варианту, без ws.URLOpen().

    <div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">функция ProverkaPeople</div></div><div class="sp-body"><div class="sp-content">
    Function ProverkaPeople (ndUI As NotesUIDocument) As Boolean

    ...основной код

    Call ndui.Close 'закрывает дочку

    Set uidoc = ws.EditDocument(False, pardoc,,,True,False) 'переходим в открытого родителя
    Call uidoc.Close 'закрываем родителя

    Call ws.EditDocument(False, pardoc) 'открываем родителя для чтения

    End Function

    Вчера и сегодня мучаю лотус в этом варианте - все пока отлично..
     
  6. savl

    savl Lotus team
    Lotus team

    Регистрация:
    28 окт 2011
    Сообщения:
    2.051
    Симпатии:
    146
    о! Вспомнил, стоит добавить.
    Когда закрывается вкладка документа, то лотус возвращает фокус на предыдущий UI объект.
    Возможен такой случай:
    0. Открываем родитель
    1. Создаем/Открываем дочку
    2. Переходим в Почту
    3. Переходим в дочку
    4. Сохраняем.

    По логике после закрытии дочки фокус перемещается в Почту, следовательно скрипт может закрыть вкладку с Почтой.
    Возврат UI-объекта родителя должен решить этот вопрос. Попробуйте повторить мои шаги.
     
  7. alexas1

    alexas1 Lotus team
    Lotus team

    Регистрация:
    10 апр 2014
    Сообщения:
    567
    Симпатии:
    214
    Ещё момент...
    Вы храните "историю" в RTF (поэтому и требуется "переоткрытие"). Зачем?
    У Вас ведь нет какого-то специфического форматирования инфы в "истории" или добавления в "историю" аттачей-ссылок-и т.д.?
    Если это так, то лучше использовать обычное текстовое поле.
    Тогда, после добавления "истории", просто сохраните parent и переведите его в чтение (и первое и второе - в UI, в который Вы пришли через ws.EditDocument...). Так будет лучше.

    P.S.
    Добавление к "истории": pardoc.HistoryUD = pardoc.HistoryUD(0) + Chr(13) + "NewInfo"

    Добавлено:
    А если юзверь поработал с дочкой, открыл ещё чего-нибудь и опять вернулся в дочку?
    Так нехорошо, надо целенаправленно приходить в открытый док.
     
  8. savl

    savl Lotus team
    Lotus team

    Регистрация:
    28 окт 2011
    Сообщения:
    2.051
    Симпатии:
    146
    alexas1
    32k problem...

    Так я и не говорю обратное, а даже наоборот. Такой глюк возможен, если не получать UI родителя принудительно.
    Вот и советую проверить скрипт на такой случай, интересно как отработает.
     
  9. alexas1

    alexas1 Lotus team
    Lotus team

    Регистрация:
    10 апр 2014
    Сообщения:
    567
    Симпатии:
    214
    savl
    32k - Да! Я лопух.
    А в остальном - "Мы с тобой одной крови, ты и я."(с) :)
     
  10. ToxaRat

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

    Регистрация:
    6 ноя 2007
    Сообщения:
    3.046
    Симпатии:
    18
    RT-поле History
    :lamer:

    лучше бы для этого функционала налепил отдельную базу!
     
  11. juk-777

    juk-777 Active Member

    Регистрация:
    5 авг 2013
    Сообщения:
    38
    Симпатии:
    0
    С приведенным мною кодом выше все отлично работает, даже если открыто на редактирование множество документов и переключаешься с одного на другой. Код удачно закрывает дочку и родителя и снова открывает родителя для чтения. Остальные открытые документы остаются в том же состоянии.

    To ToxaRat: отдельную базу я тож сделаю для накопления истории по всем документам, но хотелось сделать и историю внутри отдельного документа-родителя .. как мне показалось - так будет удобно:lamer: )

    Спасибо огромное всем за ответы.
     
Загрузка...

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