Приветствуем вас, коллеги! В процессе сопровождения и доработки исторических конфигураций на платформе 1С:Предприятие 8, таких как «Управление производственным предприятием 1.3» (УПП), «Комплексная автоматизация 1.1» (КА) или «Управление торговлей 10.3» (УТ), разработчики часто сталкиваются с необходимостью расширения стандартной аналитики. Для этого пользователи или администраторы добавляют новые свойства к объектам (например, договорам контрагентов) прямо в режиме «1С:Предприятие». Однако вывод этих свойств в отчеты или их программная обработка могут вызвать затруднения, так как они хранятся не в реквизитах самого объекта, а в отдельной структуре метаданных.
В этой статье мы подробно разберем, как устроена архитектура хранения дополнительных свойств в УПП 1.3, и рассмотрим три практических способа получения этих данных: с помощью механизма характеристик в СКД, через левое соединение в запросах и программным кодом на языке 1С.
Прежде чем переходить к написанию кода и настройке отчетов, давайте проанализируем, как платформа и конфигурация хранят дополнительные свойства объектов. В отличие от современных конфигураций на базе БСП (где используются дополнительные реквизиты и сведения), в УПП 1.3 механизм реализован на базе трех ключевых объектов метаданных:
СвойстваОбъектов — этот объект определяет метаданные самих свойств. Здесь регистрируются их названия (например, «Статус договора», «Регион продаж», «Ответственный за исполнение») и задаются допустимые типы данных (число, строка, дата, булево или ссылка на значение свойства).ЗначенияСвойствОбъектов — используется в тех случаях, когда тип значения дополнительного свойства является ссылочным. В этом справочнике хранятся конкретные элементы-значения (например, для свойства «Статус договора» здесь будут созданы элементы «Действует», «Приостановлен», «Расторгнут»).ЗначенияСвойствОбъектов — это связующее звено и ключевое место хранения данных. Регистр является непериодическим и независимым. Он содержит два измерения: Объект (в нашем случае — ссылка на договор контрагента) и Свойство (ссылка на план видов характеристик). В ресурсе Значение хранится конкретное установленное значение этого свойства для данного объекта.Понимание этой структуры позволяет нам легко извлекать свойства как с помощью интерактивных инструментов платформы, так и напрямую через запросы.
Если перед вами стоит задача вывести дополнительное свойство в отчет, разработанный на базе Схемы компоновки данных (СКД), наиболее правильным и элегантным решением будет использование механизма «Характеристик». Настроив характеристики один раз, вы позволите пользователям перетаскивать свойства мышкой прямо в режиме «1С:Предприятие» — добавлять их в группировки, отборы, колонки и условное оформление так, как будто это стандартные реквизиты договора.
Разберем процесс настройки по шагам:
Договор или ДоговорКонтрагента).Таблица (это позволит гибко настроить источник видов характеристик запросом).ПланВидовХарактеристик.СвойстваОбъектов. Для того чтобы не выводить пользователю абсолютно все свойства базы (например, свойства номенклатуры или контрагентов), рекомендуем использовать запрос с фильтрацией по назначению:
ВЫБРАТЬ
СвойстваОбъектов.Ссылка КАК Ссылка,
СвойстваОбъектов.Наименование КАК Наименование,
СвойстваОбъектов.ТипЗначения КАК ТипЗначения
ИЗ
ПланВидовХарактеристик.СвойстваОбъектов КАК СвойстваОбъектов
ГДЕ
СвойстваОбъектов.НазначениеСвойства = ЗНАЧЕНИЕ(ПланВидовХарактеристик.НазначенияСвойствКатегорийОбъектов.Справочник_ДоговорыКонтрагентов)
Ссылка.Наименование.ТипЗначения.РегистрСведений.ЗначенияСвойствОбъектов.Объект.Свойство.Значение.Договор (нажав на значок «+» рядом с ним в настройках группировок или выбранных полей), вы увидите ваше дополнительное свойство как полноценный подчиненный реквизит.Рассмотрим ситуацию, когда отчет строится на базе простого запроса без использования СКД (например, при выводе в построитель отчетов или ручном формировании табличного документа), либо если вам необходимо жестко завязаться на конкретное свойство договора в алгоритме проведения документа.
Для решения этой задачи мы используем левое соединение таблицы договоров с регистром сведений ЗначенияСвойствОбъектов. Разберем пример готового запроса:
ВЫБРАТЬ
Договоры.Ссылка КАК Договор,
Договоры.Владелец КАК Контрагент,
ЕСТЬNULL(РегистрСвойств.Значение, "Свойство не заполнено") КАК ЗначениеСвойства
ИЗ
Справочник.ДоговорыКонтрагентов КАК Договоры
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияСвойствОбъектов КАК РегистрСвойств
ПО Договоры.Ссылка = РегистрСвойств.Объект
И РегистрСвойств.Свойство = &ПараметрСвойство
Важные детали реализации запроса:
ЛЕВОЕ СОЕДИНЕНИЕ, а не внутреннее соединение. Если применить внутреннее соединение, то договоры, у которых данное свойство вообще не заполнено или не задано, полностью исчезнут из результирующей выборки.РегистрСвойств.Свойство = &ПараметрСвойство) необходимо накладывать непосредственно в секции связи ПО, а не в секции ГДЕ. Это критически важно для производительности СУБД и корректности работы левого соединения.ЕСТЬNULL позволяет нам подставить дефолтное значение (например, строку «Свойство не заполнено» или пустую ссылку), если для конкретного договора запись в регистре сведений отсутствует.Выясним, как быстро получить значение свойства конкретного договора в программном коде, например, в модуле объекта при проверке заполнения реквизитов перед проведением или при выводе данных в печатную форму макета.
Вариант 1. Использование менеджера записи регистра (для одиночного объекта)
Если вам нужно получить значение свойства для одного конкретного договора, самым быстродействующим и простым решением будет обращение к менеджеру записи регистра сведений. Это избавляет от необходимости писать громоздкие запросы:
// Определяем ссылку на договор и нужное нам свойство
ДоговорСсылка = СсылкаНаДоговор; // Ваша переменная с договором
НужноеСвойство = ПланыВидовХарактеристик.СвойстваОбъектов.НайтиПоНаименованию("Статус договора");
Если ЗначениеЗаполнено(НужноеСвойство) Тогда
// Создаем менеджер записи для чтения конкретной строки регистра
МенеджерЗаписи = РегистрыСведений.ЗначенияСвойствОбъектов.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Объект = ДоговорСсылка;
МенеджерЗаписи.Свойство = НужноеСвойство;
МенеджерЗаписи.Прочитать();
Если МенеджерЗаписи.Выбран() Тогда
ЗначениеСвойства = МенеджерЗаписи.Значение;
// Выполняем логику с полученным значением
Иначе
ЗначениеСвойства = Неопределено;
КонецЕсли;
КонецЕсли;
Вариант 2. Использование типовых функций конфигурации УПП 1.3
Разработчики конфигурации УПП 1.3 предусмотрели готовые процедуры и функции для облегчения работы со свойствами. Для получения всех свойств объекта или конкретного значения можно использовать функции общего модуля РаботаСОсвойствами:
// Получаем таблицу всех свойств, установленных для договора
ТаблицаСвойств = РаботаСОсвойствами.ПолучитьСвойстваОбъекта(СсылкаНаДоговор);
// Вы можете обойти таблицу циклом и найти нужное значение
Для Каждого СтрокаСвойства Из ТаблицаСвойств Цикл
Если СтрокаСвойства.Свойство.Наименование = "Статус договора" Тогда
ЗначениеСвойства = СтрокаСвойства.Значение;
Прервать;
КонецЕсли;
КонецЦикла;
Проанализируем перспективу перехода на современные конфигурации, разработанные на управляемых формах под управлением Библиотеки стандартных подсистем (БСП). Если вы в будущем столкнетесь с аналогичной задачей в 1С:ERP или 1С:Комплексная автоматизация 2, помните, что архитектура работы со свойствами там кардинально изменилась:
РегистрСведений.ДополнительныеСведения, что аналогично старому подходу в УПП.ДополнительныеРеквизиты. Поэтому для их извлечения в запросе нужно обращаться к табличной части объекта (например, Справочник.ДоговорыКонтрагентов.ДополнительныеРеквизиты), а не к внешним регистрам сведений.Используя описанные выше методы, вы сможете быстро и эффективно решать любые задачи интеграции дополнительных аналитик в отчетность и логику проведения документов в конфигурации 1С:УПП 1.3.