Постановка задачи
Решим не стандартную задачу. Нам необходимо добавить к документам некие реквизиты, которые появляются у объектов в зависимости от настроек (значений реквизитов документа).
Есть несколько способов решения:
- Добавить в каждый документ реквизит и управлять его видимостью и проверкой заполнения на форме.
- Создать общий реквизит для документов и также управлять видимостью и проверкой заполнения.
- Использовать динамический состав реквизитов объектов.
Рассмотрим последний вариант решения, поскольку он самый гибкий по возможностям, вплоть до того, что пользователи в режиме предприятия могут сами изменять состав реквизитов для документов.
Используемые объекты
Нам понадобится несколько справочников, которые мы будем использовать в качестве типов для динамического состава реквизитов. Мной были созданы несколько справочников без какого-либо дополнительного функционала. Достаточно стандартных реквизитов.
Далее создаем план видов характеристик (ПВХ), я назвал его "СоставРеквизитов". В свойствах объекта устанавливаем в тип значения характеристик составной тип, включающий все созданные нами справочники. Чтобы можно было настраивать порядок отображения реквизитов на форме, можно добавить в ПВХ реквизит "Порядок" с типом "Число".
Состав отображаемых реквизитов будет зависеть от двух параметров: "ВидДокумента" и "ТипДокумента" с типами соответственно "ПеречислениеСсылка.ВидДокумента" и "ПеречислениеСсылка.ТипДокумента". В документе эти параметры должны сохраняться, например, в реквизитах.
Состав реквизитов настраивается в регистре сведений. В примере регистр называется "СоставРеквизитовДокументов" и состоит из трех измерений: "Вид", "Тип", "Реквизит". Тип измерения "Реквизит" - "ПланВидовХарактеристикСсылка.СоставРеквизитов". Структура регистра не позволит к одному документу привязать один реквизит несколько раз. Пример настройки состава реквизитов документа приведен ниже.
Непосредственно значения реквизитов для каждого документа будут записываться в регистр сведений "Значения реквизитов документов", состав которого имеет в себе два измерения и ресурс.
Измерения "Документ" и "Реквизит" позволяют привязать запись регистра к документу по определенному реквизиту. В ресурсе хранится значение для указанного в измерении реквизита. Тип значения, хранящийся в ресурсе - это характеристика ПВХ "Состав реквизитов".
Для демонстрации примера создадим документ "ДокументПример" с реквизитами, хранящими вид и тип документа (о типе реквизитов см. выше). На форме документа добавим группу "ДинамическиеРеквизиты" с входящими в него группами формы "Лево" и "Право". Последнее необходимо, чтобы реквизиты на форме отображались в две колонки.
Скелет объектов конфигурации готов, осталось написать алгоритмы для динамического создания реквизитов на форме и последующего их сохранения в регистр сведений.
Алгоритмы
Поскольку в будущем динамически формировать реквизиты на форме может понадобиться для других документов, основные алгоритмы работы с ними вынесем в общий модуль. В примере модуль называется "ДинамическиеРеквизитыДокументов" и имеет доступность только на сервере.
В модуле три основных процедуры для создания, удаления и записи в базу данных значений для динамического состава реквизитов. Пример вы можете посмотреть на демонстрационной конфигурации, прикрепленной к публикации.
Общий принцип работы заключается в получении состава реквизитов для текущего документа в зависимости от значений его реквизитов "ВидДокумента" и "ТипДокумента" из регистра сведений "СоставРеквизитовДокументов". Далее из регистра "ЗначенияРеквизитовДокументов" получаем значения для состава реквизитов, если они имеются.
Поскольку пользователь в режиме "предприятия" может изменять вид и тип документа, необходимо предусмотреть удаление недействительных реквизитов формы. Для этого программно создается таблица значений на форме, в которой содержится две колонки - название реквизита на форме и ссылка на элемент ПВХ. При изменении вида или типа документа срабатывает процедура удаления реквизитов по данным таблицы значений "СписокДобавленныхРеквизитов". После срабатывает процедура создания реквизитов и элементов формы.
В события формы "ПриЗаписиНаСервере" запускается процедура общего модуля "ЗаписатьЗначенияДинамическихРеквизитов", где производится запись в регистр сведений "ЗначенияРеквизитовДокументов" по данным таблицы значений добавленных реквизитов и значений в созданных реквизитах формы.
При создании формы документа вызывается процедура общего модуля "ИнициализироватьДинамическиеРеквизитыНаФорме", которая создает реквизиты и элементы формы, а также производит их заполнение сохраненными значениями.
Что это нам дает?
Теперь мы можем создавать реквизиты для документов в режиме предприятия и определять их тип. Фактически, документ теперь имеет ряд дополнительных свойств, которые мы можем редактировать как реквизиты. Для пользователей это будет привычней, чем если бы мы вынесли редактирование полей в отдельную таблицу или в списке регистра сведений.
Преимущество использования ПВХ в данном случае проявляется в том, что мы в режиме предприятия можем гибко настраивать состав реквизитов для документов, а также использовать характеристики в системе компоновки данных. В конфигурации к статье написан отчет, где демонстрируется использование характеристик. В конечном счете, мы можем делать отбор по реквизитам документа в отчете (см. на следующем скриншоте).
Выводы
Использование такого механизма удобно в случаях, когда нужно для объекта хранить данные в гибком виде, когда вид и размер данных зависит от настроек программы и значения реквизитов объекта.
Но есть и обратная сторона. Производительность работы с таким механизмом будет ниже, нежели мы использовали непосредственно реквизиты документа для хранения логически привязанных к нему данных. Связано это с тем, что состав и значения реквизитов хранятся в отдельных таблицах, обращение к которым будет происходить при открытии документа и при его записи.
Ускорить работу механизма можно, если сохранять состав реквизитов в отдельной таблице для каждого документа (некое подобие ключей аналитики). Тогда мы можем в регистр "ЗначенияРеквизитовДокументов" записывать более рациональным способом.. Изменим структуру регистра таким образом, чтобы в первое измерения записывать ссылку на документ, во второе ключ состава реквизитов в документе, а в соответствующие ресурсы значения реквизитов в порядке, аналогичном порядку ключа состава в измерении. Этот подход ускорит запросы получения данных из таблицы регистра, поскольку для каждого документа будет одна запись в регистре.
В документе, в соответствующем реквизите, будет храниться ключ состава реквизитов, который будет использоваться в запросе к значениям реквизитов.
Минус описанной схемы в том, что к документу можно будет создавать ограниченное количество реквизитов - максимум от количества ресурсов в регистре сведений и количества хранимых реквизитов в ключе аналитики.
С помощью механизма, описанного выше, можно создавать динамический состав реквизитов практически для любого объекта (справочники, планы видов характеристик, перечисления (!) и др.).