Цикл статей:
События Типов справочников и ТКЭД. Часть 1.
События Типов справочников и ТКЭД. Часть 2.
События Типов справочников и ТКЭД. Часть 3.
Данная статья описывает события, происходящие в Типах справочников (ТС) и Типах карточек документов (ТКЭД), при работе с ними. Описываются правила ведения качественной разработки для повышения быстродействия системы. Материал предназначен для понимания того, что и в каких событиях рекомендуется делать, а что делать нельзя. Статья будет полезна в первую очередь новичкам, которым только предстоит постичь азы разработки на IS-Builder, а также всем более опытным участникам сообщества для того чтобы освежить знания, и, может быть, узнать что-то новое. Описание событий будет представлено применительно к ТС, т.к. для ТКЭД приведенная информация практически идентична. Но обо всем по порядку.
Статья написана на основе справки.
Для работы с событиями ТС, прежде всего, необходимо понимать, что происходит на уровне платформы. Отталкиваясь от этих данных, можно манипулировать поведением ТС в разные моменты работы с ними.
Вообще, все действия с ТС можно условно разделить на две части:
Это событие выполняется до считывания данных с сервера. Поэтому тут все сводится к тому, какие данные необходимо получить с сервера, а какие нет. Это особенно критично для ТС с большим набором данных, таких как: РКК, Поручения, Договоры и т.д. Так же влияние оказывает количество реквизитов в наборе данных, проще говоря – количество полей таблицы MBAnalit. Существуют заказные разработки DIRECTUM, где количество реквизитов справочника в несколько раз больше, чем в самых «толстых» справочниках стандартной версии.
Для ограничения загружаемых данных можно использовать метод AddWhere:
// Получить код главной НОР
OurOrgCode = Конст("КОДГЛОРГ")
// Получить ИД главной НОР (данная функция доступна с версии IS-Builder 7.9.2)
ReferenceRequisiteValue('НОР'; OurOrgCode; SYSREQ_ID)
AddWhereStr = Format("%s.%s = %s"; ArrayOf(
Object.TableName;
Object.Requisites(SYSREQ_OUR_FIRM).SQLFieldName;
OurOrgID))
// Отфильтровать справочник по Нашей Организации
AddWhereID = Object.AddWhere(AddWhereStr)
// Записать AddWhereID в переменную окружения
Object.Environment.SetVar('ADD_WHERE_ID'; AddWhereID)
// ***Событие Набор Данных – Закрытие***
// Не забыть удалить заданное ограничение
Environment = Object.Environment
// Проверить, что в окружении есть переменная с нужным именем
if Environment.IndexOfName('ADD_WHERE_ID') > -1
AddWhereID = Object.Environment.PopVar('ADD_WHERE_ID')
// Удалить ограничение
Object.DelWhere(AddWhereID)
endif
Также можно использовать специальную функцию СпрИзмНабДан():
// Получить код главной НОР
OurOrgCode = Конст("КОДГЛОРГ")
// Получить ИД главной НОР
OurOrgID = СпрРекв("НОР"; OurOrgCode; SYSREQ_ID)
AddWhereStr = Format("%s.%s = %s"; ArrayOf(
Object.TableName;
Object.Requisites(SYSREQ_OUR_FIRM).SQLFieldName;
OurOrgID))
// Отфильтровать справочник по Нашей Организации
СпрИзмНабДан(;; AddWhereStr)
Так же можно манипулировать загрузкой реквизитов с помощью свойства Preloaded:
// Не загружать значение реквизита Дополнение
Object.Requisites('Дополнение').Preloaded = FALSE
В результате, в форме-списке справочника все значения для реквизита Дополнения окажутся пустыми. При открытии конкретной записи данные подгрузятся с сервера.
Внимание! Значения предопределенных реквизитов (ИД, Код, Состояние и т.д.) загружаются в любом случае, независимо от свойства Preloaded.
Также для увеличения производительности, стоит отказаться от вычисляемых реквизитов, или свести их количество к минимуму, если совсем отказаться нет возможности. Данный тип реквизитов не сохраняется в БД, а вычисляется при открытии набора данных. Начиная с версии IS-Builder 7.10 и выше, есть возможность воспользоваться Дополнительными реквизитами (доступны с версии IS-Builder 7.10.0), заменив ими вычисляемые реквизиты.
Тут важно понимать, что после открытия набора данных, указатель всегда находится на какой-нибудь записи (если есть хотя бы одна запись в наборе данных). Так как добавляемая запись еще не существует ни на клиенте, ни на сервере, то работать с ее реквизитами нельзя. Указатель в данном событии будет указывать либо на предыдущую запись, либо (в случае пустого набора данных) на пустое значение. Если в процессе вычислений произойдет ошибка, то добавление записи будет отменено.
В этом событии целесообразно производить проверки на возможность добавления записи. Например, сделать проверку о том, что напрямую в справочник добавлять запись нельзя, а можно только из другого справочника, с означенной при этом переменной окружения.
В момент выполнения этого события, запись существует только на клиенте. В случае ошибки в вычислениях – добавление записи будет также отменено. Если запись создана копированием, то все копируемые реквизиты уже заполнены, и с ними можно работать. В данном событии нужно вычислять и заполнять значения реквизитов. Так как в данном событии происходит уже непосредственное изменение реквизитов, то существенное влияние на производительность могут оказать вычисления на самих реквизитах.
Вычисления на реквизитах, срабатывают после изменения значений этих реквизитов. В платформе есть возможность отключения этого механизма.
// Получить объект типа IRequisite
AdditionReq = Object.Requisites('Дополнение')
// Отключить вычисления на реквизите Дополнение
AdditionReq.Events.Events(reOnChange).Enabled = FALSE
// Присвоить значение
AdditionReq Value = <значение>
// Включить вычисления на реквизите обратно
AdditionReq.Events.Events(reOnChange).Enabled = TRUE
Также в этом событии, при необходимости, нужно очищать значения реквизитов, если запись была скопирована:
if Object.Copied
UncopiedReqArray = ArrayOf("Реквизит1"; "Реквизит2"; "Реквизит3")
foreach ReqName in CArrayElement(UncopiedReqArray)
CurrentRequisite = Object.FindRequisite(ReqName)
if Assigned(CurrentRequisite)
CurrentRequisite.Value = NULL
endif
endforeach
endif
Событие выполняется при открытии карточки существующей записи и при открытии карточки вновь добавляемой записи. В случае ошибки в вычислениях события выводится сообщение об ошибке и открытие записи отменяется.
Если идет работа с версией IS-Builder (до 7.7.0.1601/7.8.3.1011), в которой еще нет события «Форма-карточка – Показ», то в этом событии можно управлять доступностью реквизитов, кнопок, таблиц и др. элементов формы, перед этим обязательно проверив, что происходит визуальная работа с карточкой.
if not VarIsNull(Object.View) and InteractiveMode()
<вычисления>
endif
Во всех остальных случаях управлять доступностью элементов формы нужно в событии «Форма-карточка – Показ».
В этом событии из БД загружаются значения всех реквизитов, в том числе и табличных частей. Тут можно работать с вычисляемыми реквизитами табличной части. Также можно запоминать значения каких-либо реквизитов, чтобы использовать эти значения в событиях Сохранения, для проверки, изменилось значение реквизита или нет. Либо просто вычислять значения одних реквизитов на основе значений других.
Не рекомендуется производить в этом событии автоматическое формирование отчетов и других расчетов, которые могут быть произведены уже после открытия. Это может сильно снизить производительность системы. Если нужен отчет, то следует сделать специальное действие, при активации которого отчет будет выполняться.
Внимание! Событие срабатывает не только при программном или визуальном открытии записи, но и при открытии свойств записи в списке записей (пункт меню Файл/Свойства записи).
// Определить, открываются ли свойства записи можно таким кодом:
if Object.Params.IndexOfName(SHOW_RECORD_PROPERTIES_FORM) > -1
// Открылись свойства записи
endif
Продолжение следует...
Что такое InteractiveMode() ? - в WinHelp-е про это ничего не написано.
InteractiveMode
Определить текущий режим работы IS-Builder.
Группа:
Синтаксис:
Возвращаемое значение:
При работе в интерактивном режиме - True, иначе - False.
Описание:
Функция определяет текущий режим работы IS-Builder. В интерактивном режиме работы разрешен показ форм и сообщений. Такой режим установлен по умолчанию. При обработке задач службой Workflow, а также при выполнении сценариев с использованием утилиты SAJobRunner интерактивный режим выключен. При попытке показа форм и сообщений при выключенном интерактивном режиме будет сгенерировано исключение.
Примечание: показ индикатора при выключенном интерактивном режиме не приведет к генерации исключения. Индикатор в этом случае не будет показан.
Начиная с версии IS-Builder 7.10 и выше, есть возможность воспользоваться Дополнительными реквизитами (доступны с версии IS-Builder 7.10.0), заменив ими вычисляемые реквизиты.
IS-Builder 7.10 - это 4.8.сколько? Или даже не "8" :)?По первому примеру. Что будет если добавленное через AddWhere ограничение не удалить? Отразится ли это только на текущем пользователе или на всех пользователях системы?
Написано:
Тут важно понимать, что после открытия набора данных, указатель всегда находится на какой-нибудь записи (если есть хотя бы одна запись в наборе данных).
Поясните, пожалуйста, а для чего это важно понимать? Из текста не понял.
Такой вопрос может ли кто пояснить особенность работы события Набор - Открытие Данных для таких справочников как НОР, ПОЛ, кажется еще для ТЭД и ВЭД было такое. У них данное событие вызывается дважды. Причем при первом вызове, у события странный режим - можно вызывать только системные функции, глобальные переменные с фабриками также пустые.
Авторизуйтесь, чтобы написать комментарий