Динамический состав реквизитов

14 декабря 2012

Файлы для загрузки:

Конфигурация с примером из статьи

Постановка задачи

Решим нестандартную задачу. Нам необходимо добавить к документам некие реквизиты, которые появляются у объектов в зависимости от настроек (значений реквизитов документа).

Есть несколько способов решения:

  1. Добавить в каждый документ реквизит и управлять его видимостью и проверкой заполнения на форме.
  2. Создать общий реквизит для документов и также управлять видимостью и проверкой заполнения.
  3. Использовать динамический состав реквизитов объектовДинамические реквизиты

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

Используемые объекты

Нам понадобится несколько справочников, которые мы будем использовать в качестве типов для динамического состава реквизитов. Мной были созданы несколько справочников без какого-либо дополнительного функционала. Достаточно стандартных реквизитов.

Далее создаем план видов характеристик (ПВХ), я назвал его "СоставРеквизитов". В свойствах объекта устанавливаем в тип значения характеристик составной тип, включающий все созданные нами справочники. Чтобы можно было настраивать порядок отображения реквизитов на форме, можно добавить в ПВХ реквизит "Порядок" с типом "Число".

ПВХ

Состав отображаемых реквизитов будет зависеть от двух параметров: "ВидДокумента" и "ТипДокумента" с типами соответственно "ПеречислениеСсылка.ВидДокумента" и "ПеречислениеСсылка.ТипДокумента". В документе эти параметры должны сохраняться, например, в реквизитах.

Состав реквизитов настраивается в регистре сведений. В примере регистр называется "СоставРеквизитовДокументов" и состоит из трех измерений: "Вид", "Тип", "Реквизит". Тип измерения "Реквизит" - "ПланВидовХарактеристикСсылка.СоставРеквизитов". Структура регистра не позволит к одному документу привязать один реквизит несколько раз. Пример настройки состава реквизитов документа приведен ниже.

Настройка состава реквизитов документаНепосредственно значения реквизитов для каждого документа будут записываться в регистр сведений "Значения реквизитов документов", состав которого имеет в себе два измерения и ресурс. 

Измерения "Документ" и "Реквизит" позволяют привязать запись регистра к документу по определенному реквизиту. В ресурсе хранится значение для указанного в измерении реквизита. Тип значения, хранящийся в ресурсе - это характеристика ПВХ "Состав реквизитов".

Для демонстрации примера создадим документ "ДокументПример" с реквизитами, хранящими вид и тип документа (о типе реквизитов см. выше). На форме документа добавим группу "ДинамическиеРеквизиты" с входящими в него группами формы "Лево" и "Право". Последнее необходимо, чтобы реквизиты на форме отображались в две колонки.

Скелет объектов конфигурации готов, осталось написать алгоритмы для динамического создания реквизитов на форме и последующего их сохранения в регистр сведений.

Алгоритмы

Поскольку в будущем динамически формировать реквизиты на форме может понадобиться для других документов, основные алгоритмы работы с ними вынесем в общий модуль. В примере модуль называется "ДинамическиеРеквизитыДокументов" и имеет доступность только на сервере.

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

Общий принцип работы заключается в получении состава реквизитов для текущего документа в зависимости от значений его реквизитов "ВидДокумента" и "ТипДокумента" из регистра сведений "СоставРеквизитовДокументов". Далее из регистра "ЗначенияРеквизитовДокументов" получаем значения для состава реквизитов, если они имеются.

Поскольку пользователь в режиме "предприятия" может изменять вид и тип документа, необходимо предусмотреть удаление недействительных реквизитов формы. Для этого программно создается таблица значений на форме, в которой содержится две колонки - название реквизита на форме и ссылка на элемент ПВХ. При изменении вида или типа документа срабатывает процедура удаления реквизитов по данным таблицы значений "СписокДобавленныхРеквизитов". После срабатывает процедура создания реквизитов и элементов формы.

Форма документа

В события формы "ПриЗаписиНаСервере" запускается процедура общего модуля "ЗаписатьЗначенияДинамическихРеквизитов", где производится запись в регистр сведений "ЗначенияРеквизитовДокументов" по данным таблицы значений добавленных реквизитов и значений в созданных реквизитах формы.

При создании формы документа вызывается процедура общего модуля "ИнициализироватьДинамическиеРеквизитыНаФорме", которая создает реквизиты и элементы формы, а также производит их заполнение сохраненными значениями.

Что это нам дает?

Теперь мы можем создавать реквизиты для документов в режиме предприятия и определять их тип. Фактически, документ теперь имеет ряд дополнительных свойств, которые мы можем редактировать как реквизиты. Для пользователей это будет привычней, чем если бы мы вынесли редактирование полей в отдельную таблицу или в списке регистра сведений.

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

Отбор по динамическим реквизитам

Выводы

Использование такого механизма удобно в случаях, когда нужно для объекта хранить данные в гибком виде, когда вид и размер данных зависит от настроек программы и значения реквизитов объекта.

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

Ускорить работу механизма можно, если сохранять состав реквизитов в отдельной таблице для каждого документа (некое подобие ключей аналитики). Тогда мы можем в регистр "ЗначенияРеквизитовДокументов" записывать более рациональным способом.. Изменим  структуру регистра таким образом, чтобы в первое измерения записывать ссылку на документ, во второе ключ состава реквизитов в документе, а в соответствующие ресурсы значения реквизитов в порядке, аналогичном порядку ключа состава в измерении. Этот подход ускорит запросы получения данных из таблицы регистра, поскольку для каждого документа будет одна запись в регистре. 

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

Быстродействие

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

С помощью механизма, описанного выше, можно создавать динамический состав реквизитов практически для любого объекта (справочники, планы видов характеристик, перечисления (!) и др.).



comments powered by Disqus