Много документов: пересчитать вычисляемые поля

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

  1. dimat

    dimat Lotus team
    Lotus team

    Регистрация:
    31 июл 2008
    Сообщения:
    518
    Симпатии:
    0
    Всем привет!
    В представлении отображается порядка 7 тысяч документов, в них во всех необходимо пересчитать вычисляемые поля.
    Делаю цикл по этим документам и каждому делаю:

    Код (Text):
    Call NotesDocument.ComputeWithForm(False,False)
    Call NotesDocument.Save(True,False)
    Есть ли какие то более быстрые способы, реализации данной задачи?

    Заранее спасибо за ответы!
     
  2. ToxaRat

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

    Регистрация:
    6 ноя 2007
    Сообщения:
    3.047
    Симпатии:
    18
    а как же - не использовать ComputeWithForm
    сделать вычисления всех нужных полей самому, даже если это будут все поля в доке всё равно будет быстрее чем ComputeWithForm
     
  3. Medevic

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

    Регистрация:
    10 дек 2004
    Сообщения:
    3.346
    Симпатии:
    2
    @Command([ToolsRefreshAllDocs])

    Добавлено: Вариант: @Command([ToolsRefreshSelectedDocs])
     
  4. dimat

    dimat Lotus team
    Lotus team

    Регистрация:
    31 июл 2008
    Сообщения:
    518
    Симпатии:
    0
    А если делать это в агенте, который запускается шедульно на сервере, как указать в каком представлении обновлять?
     
  5. lmike

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

    Регистрация:
    27 авг 2008
    Сообщения:
    6.081
    Симпатии:
    300
    UI команды не работают в бэкэнде...

    а воще - подойти к вопросу творчески... :ya_lamo:
    ведь вычисляемые поля берут данные откуда-то, и не всегда каждое вычисление уникально (чаще всего - не уникально)
    вычислять поля для опред условий и копировать результат в соответ доки

    Добавлено: либо вынести вычисления в отдельный блок кода и вызывать его по мере надобности
     
  6. dimat

    dimat Lotus team
    Lotus team

    Регистрация:
    31 июл 2008
    Сообщения:
    518
    Симпатии:
    0
    Еще одна проблема: при выполнения на документами
    Код (Text):
    Call NotesDocument.ComputeWithForm(False,False)
    Call NotesDocument.Save(True,False)
    не приводит к ожидаемому результату, то есть flag=true, но поля остаются не пересчитанными.

    В чем может быть проблема?
     
  7. oshmianski

    oshmianski Гость

    ComputeWithForm очень коварная штука.
    перевычисление полей происходит в порядке расположения полей на форме слева направо, сверху вниз.
    при возникновении ошибки перевычисления поля дальнейшее перевычисления документа прерывается.

    если есть список полей для перевычисления, лучше напишите обработку вручную для каждого поля
     
  8. Omh

    Omh Lotus team
    Lotus team

    Регистрация:
    4 июл 2007
    Сообщения:
    2.210
    Симпатии:
    0
    А ещё лучше вообще не кодировать логику приложения на уровне полей, а всё вынести в функции (только не использовать как входные параметры всякие там UI).
    Вызываем ф-ию на QuerySave (ну или по желанию на recalc, если надо) - всё пересчиталось.
    Надо обработать кучу док-ов, вызываем эту же ф-ию из агента.

    Всё, геморррой отпал как класс.

    А да, ComputeWithForm - в печь!
     
  9. dimat

    dimat Lotus team
    Lotus team

    Регистрация:
    31 июл 2008
    Сообщения:
    518
    Симпатии:
    0
    в моем случае значение поля в одном документе зависит от значиния поля в другом.
    Пример: есть документ организации в нем поле "тип" (принимает значения клиент или пусто).
    так же есть дкумент продукт (в нем поле со значениями "на обслуживании" или "в отказе" ), этих продуктов у организации может быть несколько. Необходимо вычислать значение поля в документе Организации по следущему правилу: Если хотя бы в одном документе продукта значение поля="На обслуживании"- то клиент, иначе пусто
     
  10. Omh

    Omh Lotus team
    Lotus team

    Регистрация:
    4 июл 2007
    Сообщения:
    2.210
    Симпатии:
    0
    dimat
    Мне, честно говоря, лень вдаваться в подробности, но я не видел такой формульной логики, которую бы нельзя было перенести на скрипт.
    В отличие от обратного :blush:

    Да, иногда получается чуть медленне (и то это почти всегда решаемо: static переменные, подумать иногда можно), но зато приобретается централицация кода + гибкость вызова когда и где надо.

    У тебя, наверно, там стоит какой-то либо @DbLookup, как я понял из описания.
    Это меняется на получение view (достаточно медленная операция, тут можно поиграться со static) и проверки по ключу.
     
  11. dimat

    dimat Lotus team
    Lotus team

    Регистрация:
    31 июл 2008
    Сообщения:
    518
    Симпатии:
    0
    Да
    не понял что имеется ввиду
     
  12. nvyush

    nvyush Lotus team
    Lotus team

    Регистрация:
    22 апр 2009
    Сообщения:
    2.317
    Симпатии:
    0
    Set view = db.GetView(...)
    Set doc = view.GetDocumentByKey(...)
    ...
     
  13. Omh

    Omh Lotus team
    Lotus team

    Регистрация:
    4 июл 2007
    Сообщения:
    2.210
    Симпатии:
    0
    Если обощить, то имеется в виду, что надо избавляться от логики на уровне полей и писать логику в биб-ках.

    Т.е. @DbLookup в choices у DialogBox - это нормально и правильно.
    Но всякие сложные формулы у computed полей, inpit validation, input translation и т.д. нафик выносить в скрипт.
    Насчёт input translation можно подискутировать, иногда там удобно что-то быстро преобразовать, но делать проверку обязательных полей на inpit validation - сразу руки под корень :)
    То же самое относится и к каким-либо расчётам на формулах - это же пипец потом в поддержке.
     
  14. ToxaRat

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

    Регистрация:
    6 ноя 2007
    Сообщения:
    3.047
    Симпатии:
    18
    забыл сказать самое главное :)
    если вычисления собираются в какое-то временное CFD поле и потом из него берётся в обычные поля то ComputeWithForm тут не поможет, так как CFD поля он не расчитывает и все формулы зависящие от них тоже слетают ;)
     
  15. lmike

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

    Регистрация:
    27 авг 2008
    Сообщения:
    6.081
    Симпатии:
    300
    как и положено CFD и работают тока в UI :)
     
  16. dimat

    dimat Lotus team
    Lotus team

    Регистрация:
    31 июл 2008
    Сообщения:
    518
    Симпатии:
    0
    То есть правильней будет заменить вычисляемые поля на скрипт в квери сейв? я правильно понял?
     
  17. oshmianski

    oshmianski Гость

    у меня каждому (ну или почти каждому) объекту базы (читай форме) соответствует самописный класс, который наследуется от базового самописного суперкласса. в суперклассе описана логика уровня приложения, в наследуемых классах описана логика, специфичная для данного объета. в этих двух классах перегружены все ui методы формы, и только они дергаются в форме.
    кроме того, очень полезно разделять ui и background логику. и чем больше получится в backgound, тем лучше.

    советую поглядеть как такое реализовано в почтовой базе.
    в качестве эталона я бы не стал это советовать, но кое-что там можно почерпнуть.
    кроме того существует куча уже ставших стандартными паттернов для решения различных задач.
    в качестве примера паттернов можно почитать здесь.
     
  18. Omh

    Omh Lotus team
    Lotus team

    Регистрация:
    4 июл 2007
    Сообщения:
    2.210
    Симпатии:
    0
    dimat
    Если уверен в том, что можешь безошибочно перенвести @Formula -> LS, то да.

    Правильнее будет логику (скрипт) вынести в ф-ию которую ты сам будешь вызывать, где надо.
    В первую очередь, конечно, на QS формы, быть может тебе ещё понадобится на QRC.
    + в том злополучном агенте, из-за которого началась заварушка.

    Я бы оформил это дело примерно так

    <!--shcode--><pre><code class='vb'>Function Calc_Logic_By_Dimat(doc as notesdocument) as boolean
    Exit Function[/CODE]

    Т.е. ф-ия получающая на входе NotesDocument и возвращающая True только в том случае, если в результате пересчёта помеялось значение какого-либо поля.

    Тогда потом в твоём агенте будет удобно:
    <!--shcode--><pre><code class='vb'>Dim session As New NotesSession

    Dim Agent As NotesAgent
    Set Agent = Session.CurrentAgent

    Dim Db As NotesDatabase
    Set Db = Agent.Parent

    Dim Query As String
    Query = {Form = "Тра-ля-ля"}

    Dim Coll As NotesDocumentCollection
    Set Coll = Db.Search(Query, Nothing, 0)

    Set Doc = Coll.GetFirstDocument
    While Not Doc Is Nothing
    if Calc_Logic_By_Dimat(Doc) then Call Doc.Save(True, False)
    Set Doc = Coll.GetNextDocument(Doc)
    Wend
    End If[/CODE]

    Я обычно использую примерно такой подход.
     
  19. Omh

    Omh Lotus team
    Lotus team

    Регистрация:
    4 июл 2007
    Сообщения:
    2.210
    Симпатии:
    0
    oshmianski
    Ну то что там написано болдом - сущая правда: "для изменения информации (т.е. для реализации бизнес-логики) всегда и везде использовать скрипт!"

    Правда, я классы использую только там, где (imho) действительно нужно: напрмер word обернуть в класс, ну или что-то в этом роде.
    Мне обычно для бизнес логики хватает функционального подхода, т.е. всё делается в ф-иях.
    Всё-таки 6-7 лотус не очень, кмк, подходит для классов - вылазит вся убогость встроенного дизайнера :)

    Судя по микро-срачу в комментариях, не только я так думаю ;)

    Хотя, статья хорошая несомненно.
     
Загрузка...

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