gifts2017

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

Опубликовал Юрий Пермитин (YPermitin) в раздел Программирование - Практика программирования

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

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

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

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

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

 

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

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

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

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

 

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

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

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

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

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

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

Алгоритмы

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

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

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

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

 

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

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

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

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

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

 

Выводы

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

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

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

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

 

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

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

devel1c.blogspot.ru

Скачать файлы

Наименование Файл Версия Размер Кол. Скачив.
Демонстрационная конфигурация
.cf 75,93Kb
14.12.12
28
.cf 75,93Kb 28 Скачать

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Алексей 1 (AlX0id) 14.12.12 20:45
Ну задача нестандартна настолько, что даже в библиотеке стандартных подсистем есть..
http://its.1c.ru/db/bspdoc#content:104:1
2. Юрий Пермитин (YPermitin) 14.12.12 22:01
(1) AlX0id, знаком с БСП.

Для меня эта задача была нестандартной, поскольку надо было уменьшить количество записей в таблице SQL-базы. На этом я не заострил внимание, а лишь в общем описал в конце статьи.

К БСП всегда относился с осторожностью, уж очень много лишнего там. Если нужно задействовать какой-либо функционал подсистемы, приходится очень много лишнего тащить в конфигурацию. В моем случае все только самое необходимое.
3. Яков Коган (Yashazz) 18.12.12 19:32
(0) А вы в курсе, что во всех типовых конфигурациях подобные возможности (в том или ином виде и урезанности) давным-давно есть?
После беглого просмотра я не понял, чем ваш подход принципиально отличается от классического. Поясните, плиз, может я правда чего упустил.

Насчёт БСП - это да, но механика доп.свойств заново делается в течение 1 рабочего дня.
4. Юрий Пермитин (YPermitin) 19.12.12 05:18
(3) Yashazz, в типовых практически тоже самое, за исключением написанного в конце статьи. Если не ошибаюсь, в тип. конфигурациях хранение значений свойств работает в рег. сведений "ДополнительныеСведения" таким образом, что если, например, у объекта 5 свойств, то и в регистре будет 5 записей.

Для меня же была поставлена задача сделать так, чтобы для объекта свойства всегда хранились в одной записи таблицы для одного документа. В регистре измерения "Объект", "Состав реквизитов" (элемент справочника, в котором хранится состав реквизитов для тек. объекта) и ресурсы, в которых хранятся значения для реквизитов, описанных в эл. справочника. Ссылка на эл. спр. состава реквизитов хранится и в самом документе, что позволяет ускорить поиск по регистру.

Подход не применим для типовых, так как теряется универсальность (реквизитов/свойств может быть ограниченное количество в зависимости от кол-ва ресурсов рег. сведений и реквизитов справочника состава реквизитов). См. скриншот в конце статьи.
5. Александр Лапшин (zfilin) 19.12.12 14:01
Хотя в целом подход известный, с составом реквизитов получилось любопытно.
6. Яков Коган (Yashazz) 19.12.12 18:17
(4) Понял. Тогда это фрагмент той же концепции, что раньше предлагал я: http://infostart.ru/public/127853/
Хотя у меня количество записей, если считать строки таб.части, полюбому равно количеству разных значений, но зато динамичнее. :)
7. Юрий Пермитин (YPermitin) 19.12.12 18:26
(6) Yashazz, жаль, что эта статья мне раньше на глаза не попалась)

Почти всегда приходиться выбирать между универсальностью и быстродействием.

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