Оглавление
ПОДСИСТЕМА "УПРАВЛЕНИЕ ФОРМОЙ"
Обработчик события "ПриИзменении"
Общая демонстрация. Стенд "УправлениеФормой"
Управление доступностью. Исключение из общего режима "Только просмотр"
Управление видимостью. Стенд "Валютный платеж"
Установка пометки. Стенд "Включение панелей"
Оформление заголовков. Стенд "Гиперссылка"
Введение
Любая форма, даже самая простая, содержит в себе элементы. Если в форме предусмотрено несколько состояний, то каждое из них должно поддерживаться соответствующими состояниями её элементов.
Запрограммировать элементы для всех состояний формы может оказаться нетривиальной задачей. Дело в том, что количество состояний формы может исчисляться десятками (см. Формулу 1. числа состояний n элементов по k состояниям) и необходимость предусмотреть их большое количество приводит к созданию запутанных и сложных алгоритмов перехода.
В типовых решениях можно встретить разные варианты поддержки состояний формы. Как правило выделяется одна процедура и в ней происходит настройка всех элементов для текущего состояния. Возможен также вариант, когда есть выделенная универсальная процедура, которая использует набор процедур для настройки различных групп элементов. В втором случае возможен вариант, когда при изменении состояния формы вызывается не общая процедура, а конкретная, соответствующая группе элементов, настройка которых требуется для перехода в следующее состояние.
Платформа поддерживает также декларативную настройку оформления для табличных элементов. Это великолепная возможность декларативного описания оформления элементов таблицы, которая не требует написания ни строчки кода. К сожалению, для прочих элементов такая возможность не поддерживается.
В предлагаемом решении используется декларативный подход к описанию состояния формы. На основании описания подсистема выполняет настройку свойств элементов формы. В подсистеме используется оптимизация: каждый раз при изменении состояния формы настраиваются только те элементы, состояние которых также было изменено.
В качестве готового примера реализации декларативного подхода к описанию элементов можно взять подход для описания условного оформления. Однако для условного оформления необходимо задействовать достаточно тяжелый механизм отбора условий на технологии СКД. Использование такой технологии требует серверного исполнения, а решение может быть весьма требовательным к вычислительным ресурсам.
Предлагаемый вариант реализации базируется на использовании функций, которые специально создаются под элемент формы и в задачу которых входит определять свойства элемента по входящим параметрам текущего состояния формы.
Использование функционального подхода для определения свойств элементов может показаться очень расточительным. Однако основные потери при этом не в производительности (дополнительные потери здесь возникают на сам вызов функции, но это во первых очень незначительное время, во вторых поддается оптимизации путем использования вызова только по изменениям), а в объеме кода. Но кого особо волнует объём кода в современном мире ПО? Особенно если сам код получается путем генерации по декларативному описанию. Нельзя забывать и о том, что элементы можно группировать и применять функцию к группе - тогда количество таких функций будет меньше.
Работает это следующим образом. При изменении состояния формы подсистема вычисляет изменение параметров состояния и по зависимостям от них определяет список элементов, состояние которых также изменилось. Далее для каждого такого элемента вызывается своя функция состояния с параметрами состояния формы. Результатом выполнения функции будет новый набор свойств элемента.
Состояние формы в описываемом решении должно описываться параметрами состояния. Параметры задаются в момент создания формы и их список больше не меняется. Значения параметров рассчитываются как напрямую из реквизитов формы, так и через другие параметры или при вычислении функции. Пересчет значений параметров происходит после изменений в форме. Пересчитываются только те параметры, которые могли измениться при данном изменении в форме. Список измененных параметров формируется на основании зависимостей параметров от реквизитов формы, от других параметров и от элементов формы, которые связаны с реквизитами формы.
При непрямом расчете параметра используется функция значения. Результатом работы функции является новое значение параметра.
Инициализация данных подсистемы производится в процедуре модуля формы ПриСозданииНаСервере. В процедуре создается структура данных состояния формы. Декларативное описание параметров и настроек элементов формы производится через вызов соответствующих процедур: ДобавитьПараметр, ДобавитьНастройку.
В завершение, с помощью процедуры ДобавитьРеквизитФормыДанныеУправленияФормой создается реквизит формы, в котором сохраняется структура данных настройки состояния. В процедуре ДобавитьОбработчикиПриИзменении происходит установка обработчика в элементах формы, с которыми есть связь параметра с элементом через общие данные.
Листинг 1. Настройка параметров управления формой при создании формы
Параметры состояния могут зависеть либо напрямую от данных, либо вычисляться на основе параметров, которые в конечном счете ссылаются на данные.
Обработка события ПриИзменении позволяет в момент изменения данных также обновлять данные параметров состояния. Далее при настройке элементов формы для нового состояния подсистема анализирует изменения параметров и по списку измененных определяет список зависимых от измененных параметров элементов формы. Полученный список элементов приводится к текущему состоянию.
Параметры состояния
Пользователь воздействует на параметры формы через её элементы. В обработчике события ПриИзменении фиксируется изменение параметров, на которые распространяется влияние элемента формы. Как правило элементы формы и параметры связаны через использование для хранения значений одних и тех же данных. В любом случае в настройке данных управления формой при добавлении параметра состояния явно указываются имена элементов, также связанных с добавляемым параметром.
Вначале пересчитываются параметры прямого получения из данных. Далее пересчитываются параметры, зависимые от тех, которые были изменены. Для корректного расчета зависимых параметров необходимо обеспечить такой порядок параметров при добавлении, при котором зависимые параметры всегда будут идти позже тех, от которых они зависят.
Значения параметров могут браться напрямую из данных, а могут быть рассчитаны. В последнем случае используется функция расчета значения параметра. Функция параметра может использовать значения других параметров, при этом возникает та самая зависимость одних параметров от других, описанная ранее.
Листинг 2. Пример реализации функции значения
Основное назначение функции состояния - определять свойства элемента по значениям параметров. Функция вызывается для тех элементов, состояние которых зависит от измененных параметров.
Функция может возвращать значение. Практически анализируется только одно значение - если возвращено Ложь, то обновление состояния элемента не происходит. Практическое применение возвращаемого значения я пока не нашел, однако заменить функцию на процедуру тоже нельзя. Последнее связано с ограничением платформы: для вычисления функции используется оператор Вычислить, а для процедуры - Выполнить. Первый работает везде, а второй только в толстом и тонком клиенте (не работает в веб-клиенте, на iOS). И кроме того, функцию можно отлаживать в отличии от кода в операторе Выполнить.
Листинг 3. Пример реализации функции состояния
Процедуры подсистемы
По расположению функций можно заметить, что часть из них располагается в модуле формы. Это связано с расположением функций состояния и значения параметров, которые предполагается также располагать в модуле формы. Расположение их в каком либо другом модуле сделает невозможным вызов функций формы в бесконтекстном режиме на клиенте.
Таблица 1. API
Модуль | Функция/процедура |
Модуль формы | УправлениеФормой |
НастройкаЭлементовФормы | |
РассчитатьЗначенияПараметров | |
РассчитатьЗначениеПараметра | |
УправлениеФормойКлиентСервер | ПолучитьСтруктуруДанныхУправленияФормой |
ПолучитьСтруктуруПараметра | |
ДобавитьПараметр | |
ПолучитьСтруктуруНастройки | |
ДобавитьНастройку | |
УправлениеФормой | ДобавитьРеквизитФормыДанныеУправленияФормой |
ДобавитьОбработчикиПриИзменении |
Рисунок 1. Диаграмма взаимодействия
Структура данных
В подсистеме используется два основных элемента данных: элементы и параметры состояния и два вспомогательных - зависимые от параметров элементы и зависимые от параметров параметры.
Статичные данные заполняются в момент создания формы и сохраняются в фиксированной структуре в реквизите формы ДанныеУправленияФормой. Значения параметров состояния запоминаются в таблице реквизита формы ЗначенияПараметровСостояния.
Рисунок 2. ER-диаграмма
Рисунок 3. Объектная модель данных
Исследование производительности показало, что в рамках одного контекста исполнения (сервер или клиент) различия в производительности при расчете элементов формы определяются самыми длительными операциями: например, операция получения дополнительных реквизитов объекта. В тоже время, благодаря механизму расчета по изменениям, показатели производительности остаются очень высокими и определяются временем исполнения отдельных функций состояния.
Для тестирования производительности в форме обработки стенда достаточно убрать параметр ИзмененныеРеквизиты при вызове процедуры УправлениеФормой. Такой вызов приведет к полному расчету формы при каждом изменении. Измерять нужно вызов процедуры УправлениеФормой.
Практические примеры
Общая демонстрация. Стенд "УправлениеФормой"
В качестве иллюстрации проблематики и механизма работы формы я разработал обработку-стенд. Форма обработки содержит 12 реквизитов. Состояние формы описывается 4 параметрами. Если для простоты считать, что параметры могут принимать всего два значения, то общее число состояний формы согласно формуле сочетаний k из n будет 70. Однако из числа возможных сочетаний я выбрал всего 14 доступных. Эти состояния представлены в таблице ниже.
Приведенные расчеты показывают, как быстро растет число возможных состояний (при количестве значений параметров 12 число состояний уже будет около 500). С другой стороны не все состояния имеют смысл и это спасает ситуацию с программированием этих состояний. Однако при достаточно сложном программном коде можно «легко» не уследить и тогда число недокументированных доступных состояний может резко возрасти.
Формула 1. Число сочетаний k из n
Формула 2. Число сочетаний 4 из 8
Рисунок 4. Форма стенда в различный состояниях
Таблица 1. Состояния формы
Управление доступностью. Исключение из общего режима "Только просмотр"
Платформой поддерживается установка свойства только просмотр на уровне формы. Это очень удобно, т.к. позволяет однозначно определить недоступность изменения реквизитов через элементы формы, если того требует бизнес-логика. Однако иногда нужны исключения: часть реквизитов формы не должна попадать под действие этого признака.
Для реализации описанного поведения такие элементы нужно отвязать от реквизитов объекта данных и сбросить признак «Сохранение данных». Именно при такой настройке платформа не будет распространять признак "Только просмотр", установленный для формы, на элементы исключения.
Для управления признаком "Только просмотр" для таких элементов нужно добавить их настройку в подсистему "Управление формой". Порядок внедрения подсистемы рассмотрим на примере доработки документа _ДемоПеремещениеТоваров из демо-базы БСП. Добавим реквизит формы Комментарий и элемент-поле редактирования реквизита с таким же именем - Комментарий. Далее выполним следующие шаги:
- Скопируем в форму документа функции области ПроцедурыПодсистемыУправлениеФормой из формы демо-обработки стенда
- Добавим настройку параметров в процедуре ПриСозданииНаСервере
- Добавим функцию состояния элемента формы Комментарий
Листинг 4. Модуль формы доработанного документа. Где область КодБСП содержит код из демо-базы БСП, а функция состояния здесь одна - РассчитатьСвойстваЭлементаКомментарий.
Управление видимостью. Стенд "Валютный платеж"
Следующий стенд демонстрирует настройку формы с двумя валютами и табличной частью. В форме обыгрываются состояния равенства валют, когда вторая сумма избыточна и скрывается. Также в форме меняется отображения заголовков элемента валюты и сумм в зависимости от выбранных валют.
Рисунок 5.
Листинг 5.
Установка пометки. Стенд "Включение панелей"
В стенде демонстрируется настройка включения видимостей групп элементов и изменение состояния пометки кнопок командной панели.
Рисунок 6.
Листинг 6.
Оформление заголовков. Стенд "Гиперссылка"
В последнем стенде рассматривается возможность изменения заголовка гиперссылки от двух состояний параметра ВключитьОтбор.
Рисунок 7.
Листинг 7.
Поставка
Решение поставляется в виде конфигурации и обработок демо-стендов. Подсистема использует общие процедуры БСП. Перед объединением сбросьте признак объединять свойства конфигурации.
Для использования демо-обработок разверните демо-базу БСП и объедините с конфигурацией подсистемы.
Порядок использования в своих формах:
- Из демо-стенда скопируйте в модуль формы область ПроцедурыПодсистемыУправлениеФормой
- Создайте область ФункцииСостоянияИЗначения и добавьте свои функции состояния и значения параметров
- Добавьте настройку данных управления формой в процедуре ПриСозданииНаСервере
Таблица 2. Состав поставки
Метаданные | Наименование | Назначение | Ограничения |
ОбщийМодуль | УправлениеФормой | Использует БСП | |
УправлениеФормойКлиентСервер | Использует БСП | ||
ОбщийКлиентСервер | вспомогательный | ||
ОбщийВызовСервера | вспомогательный | ||
Обработка | СтендУправлениеФормой | демо | |
СтендВключениеПанелей | демо | ||
СтендРасчетВВалюте | демо | ||
СтендЗаголовокГиперссылки | демо |