Постановка задачи
Решим не стандартную задачу. Нам необходимо добавить к документам некие реквизиты, которые появляются у объектов в зависимости от настроек (значений реквизитов документа).
Есть несколько способов решения:
- Добавить в каждый документ реквизит и управлять его видимостью и проверкой заполнения на форме.
- Создать общий реквизит для документов и также управлять видимостью и проверкой заполнения.
- Использовать динамический состав реквизитов объектов.
Рассмотрим последний вариант решения, поскольку он самый гибкий по возможностям, вплоть до того, что пользователи в режиме предприятия могут сами изменять состав реквизитов для документов.
Используемые объекты
Нам понадобится несколько справочников, которые мы будем использовать в качестве типов для динамического состава реквизитов. Мной были созданы несколько справочников без какого-либо дополнительного функционала. Достаточно стандартных реквизитов.
Далее создаем план видов характеристик (ПВХ), я назвал его «СоставРеквизитов». В свойствах объекта устанавливаем в тип значения характеристик составной тип, включающий все созданные нами справочники. Чтобы можно было настраивать порядок отображения реквизитов на форме, можно добавить в ПВХ реквизит «Порядок» с типом «Число».
Состав отображаемых реквизитов будет зависеть от двух параметров: «ВидДокумента» и «ТипДокумента» с типами соответственно «ПеречислениеСсылка.ВидДокумента» и «ПеречислениеСсылка.ТипДокумента». В документе эти параметры должны сохраняться, например, в реквизитах.
Состав реквизитов настраивается в регистре сведений. В примере регистр называется «СоставРеквизитовДокументов» и состоит из трех измерений: «Вид», «Тип», «Реквизит». Тип измерения «Реквизит» — «ПланВидовХарактеристикСсылка.СоставРеквизитов». Структура регистра не позволит к одному документу привязать один реквизит несколько раз. Пример настройки состава реквизитов документа приведен ниже.
Непосредственно значения реквизитов для каждого документа будут записываться в регистр сведений «Значения реквизитов документов», состав которого имеет в себе два измерения и ресурс.
Измерения «Документ» и «Реквизит» позволяют привязать запись регистра к документу по определенному реквизиту. В ресурсе хранится значение для указанного в измерении реквизита. Тип значения, хранящийся в ресурсе — это характеристика ПВХ «Состав реквизитов».
Для демонстрации примера создадим документ «ДокументПример» с реквизитами, хранящими вид и тип документа (о типе реквизитов см. выше). На форме документа добавим группу «ДинамическиеРеквизиты» с входящими в него группами формы «Лево» и «Право». Последнее необходимо, чтобы реквизиты на форме отображались в две колонки.
Скелет объектов конфигурации готов, осталось написать алгоритмы для динамического создания реквизитов на форме и последующего их сохранения в регистр сведений.
Алгоритмы
Поскольку в будущем динамически формировать реквизиты на форме может понадобиться для других документов, основные алгоритмы работы с ними вынесем в общий модуль. В примере модуль называется «ДинамическиеРеквизитыДокументов» и имеет доступность только на сервере.
В модуле три основных процедуры для создания, удаления и записи в базу данных значений для динамического состава реквизитов. Пример вы можете посмотреть на демонстрационной конфигурации, прикрепленной к публикации.
Общий принцип работы заключается в получении состава реквизитов для текущего документа в зависимости от значений его реквизитов «ВидДокумента» и «ТипДокумента» из регистра сведений «СоставРеквизитовДокументов». Далее из регистра «ЗначенияРеквизитовДокументов» получаем значения для состава реквизитов, если они имеются.
Поскольку пользователь в режиме «предприятия» может изменять вид и тип документа, необходимо предусмотреть удаление недействительных реквизитов формы. Для этого программно создается таблица значений на форме, в которой содержится две колонки — название реквизита на форме и ссылка на элемент ПВХ. При изменении вида или типа документа срабатывает процедура удаления реквизитов по данным таблицы значений «СписокДобавленныхРеквизитов». После срабатывает процедура создания реквизитов и элементов формы.
В события формы «ПриЗаписиНаСервере» запускается процедура общего модуля «ЗаписатьЗначенияДинамическихРеквизитов», где производится запись в регистр сведений «ЗначенияРеквизитовДокументов» по данным таблицы значений добавленных реквизитов и значений в созданных реквизитах формы.
При создании формы документа вызывается процедура общего модуля «ИнициализироватьДинамическиеРеквизитыНаФорме», которая создает реквизиты и элементы формы, а также производит их заполнение сохраненными значениями.
Что это нам дает?
Теперь мы можем создавать реквизиты для документов в режиме предприятия и определять их тип. Фактически, документ теперь имеет ряд дополнительных свойств, которые мы можем редактировать как реквизиты. Для пользователей это будет привычней, чем если бы мы вынесли редактирование полей в отдельную таблицу или в списке регистра сведений.
Преимущество использования ПВХ в данном случае проявляется в том, что мы в режиме предприятия можем гибко настраивать состав реквизитов для документов, а также использовать характеристики в системе компоновки данных. В конфигурации к статье написан отчет, где демонстрируется использование характеристик. В конечном счете, мы можем делать отбор по реквизитам документа в отчете (см. на следующем скриншоте).
Выводы
Использование такого механизма удобно в случаях, когда нужно для объекта хранить данные в гибком виде, когда вид и размер данных зависит от настроек программы и значения реквизитов объекта.
Но есть и обратная сторона. Производительность работы с таким механизмом будет ниже, нежели мы использовали непосредственно реквизиты документа для хранения логически привязанных к нему данных. Связано это с тем, что состав и значения реквизитов хранятся в отдельных таблицах, обращение к которым будет происходить при открытии документа и при его записи.
Ускорить работу механизма можно, если сохранять состав реквизитов в отдельной таблице для каждого документа (некое подобие ключей аналитики). Тогда мы можем в регистр «ЗначенияРеквизитовДокументов» записывать более рациональным способом.. Изменим структуру регистра таким образом, чтобы в первое измерения записывать ссылку на документ, во второе ключ состава реквизитов в документе, а в соответствующие ресурсы значения реквизитов в порядке, аналогичном порядку ключа состава в измерении. Этот подход ускорит запросы получения данных из таблицы регистра, поскольку для каждого документа будет одна запись в регистре.
В документе, в соответствующем реквизите, будет храниться ключ состава реквизитов, который будет использоваться в запросе к значениям реквизитов.
Минус описанной схемы в том, что к документу можно будет создавать ограниченное количество реквизитов — максимум от количества ресурсов в регистре сведений и количества хранимых реквизитов в ключе аналитики.
С помощью механизма, описанного выше, можно создавать динамический состав реквизитов практически для любого объекта (справочники, планы видов характеристик, перечисления (!) и др.).
Ну задача нестандартна настолько, что даже в библиотеке стандартных подсистем есть..
http://its.1c.ru/db/bspdoc#content:104:1
(1) AlX0id, знаком с БСП.
Для меня эта задача была нестандартной, поскольку надо было уменьшить количество записей в таблице SQL-базы. На этом я не заострил внимание, а лишь в общем описал в конце статьи.
К БСП всегда относился с осторожностью, уж очень много лишнего там. Если нужно задействовать какой-либо функционал подсистемы, приходится очень много лишнего тащить в конфигурацию. В моем случае все только самое необходимое.
(0) А вы в курсе, что во всех типовых конфигурациях подобные возможности (в том или ином виде и урезанности) давным-давно есть?
После беглого просмотра я не понял, чем ваш подход принципиально отличается от классического. Поясните, плиз, может я правда чего упустил.
Насчёт БСП — это да, но механика доп.свойств заново делается в течение 1 рабочего дня.
(3) Yashazz, в типовых практически тоже самое, за исключением написанного в конце статьи. Если не ошибаюсь, в тип. конфигурациях хранение значений свойств работает в рег. сведений «ДополнительныеСведения» таким образом, что если, например, у объекта 5 свойств, то и в регистре будет 5 записей.
Для меня же была поставлена задача сделать так, чтобы для объекта свойства всегда хранились в одной записи таблицы для одного документа. В регистре измерения «Объект», «Состав реквизитов» (элемент справочника, в котором хранится состав реквизитов для тек. объекта) и ресурсы, в которых хранятся значения для реквизитов, описанных в эл. справочника. Ссылка на эл. спр. состава реквизитов хранится и в самом документе, что позволяет ускорить поиск по регистру.
Подход не применим для типовых, так как теряется универсальность (реквизитов/свойств может быть ограниченное количество в зависимости от кол-ва ресурсов рег. сведений и реквизитов справочника состава реквизитов). См. скриншот в конце статьи.
Хотя в целом подход известный, с составом реквизитов получилось любопытно.
(4) Понял. Тогда это фрагмент той же концепции, что раньше предлагал я:http://infostart.ru/public/127853/
Хотя у меня количество записей, если считать строки таб.части, полюбому равно количеству разных значений, но зато динамичнее. 🙂
(6) Yashazz, жаль, что эта статья мне раньше на глаза не попалась)
Почти всегда приходиться выбирать между универсальностью и быстродействием.
Решать, конечно, в зависимости от конкретной задачи.