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