В современных конфигурациях 1С, построенных на базе Библиотеки стандартных подсистем (БСП), механизм дополнительных реквизитов и сведений является стандартом де-факто для расширения состава данных объектов без изменения метаданных. Однако при автоматизации загрузки данных, например, из файлов Excel, программисты часто сталкиваются с трудностями: как правильно найти нужный реквизит, как записать в него значение и что делать, если значение должно быть не строкой, а элементом специального справочника. В этой статье мы подробно разберем все способы программной работы с этим механизмом.
Прежде чем переходить к коду, проанализируем, где физически хранятся эти данные. Дополнительные реквизиты (в отличие от сведений) всегда хранятся в табличной части самого объекта (справочника или документа). Эта табличная часть обычно называется ДополнительныеРеквизиты и имеет две ключевые колонки:
ДополнительныеРеквизитыИСведения.Это наиболее правильный и рекомендуемый метод, так как он задействует стандартные функции подсистемы «Управление свойствами». Рассмотрим, как записать данные в объект с помощью метода УправлениеСвойствами.ЗаписатьСвойстваУОбъекта.
Для этого нам потребуется подготовить таблицу значений с данными, которые мы хотим записать. Разберем по шагам реализацию этой задачи:
// 1. Подготовим таблицу значений для записи свойств
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Свойство", Новый ОписаниеТипов("ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения"));
ТЗ.Колонки.Добавить("Значение");
// 2. Найдем нужное свойство (доп. реквизит) в системе
// Важно: Поиск по наименованию может быть ненадежным, если есть дубликаты.
// Рекомендуется искать с учетом владельца или использовать уникальный идентификатор.
ДопРеквизитСсылка = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Название (англ.)", Истина);
Если НЕ ДопРеквизитСсылка.Пустая() Тогда
НовСтр = ТЗ.Добавить();
НовСтр.Свойство = ДопРеквизитСсылка;
НовСтр.Значение = "English Product Name"; // Значение из файла Excel
КонецЕсли;
// 3. Запишем свойства у объекта.
// В качестве первого параметра передаем ССЫЛКУ на объект.
УправлениеСвойствами.ЗаписатьСвойстваУОбъекта(СсылкаНаОбъект, ТЗ);
Важное примечание: Если вы создаете новый объект (например, новую номенклатуру), вы обязательно должны сначала вызвать метод Записать() для самого объекта, чтобы получить ссылку, и только потом вызывать процедуру записи свойств. В противном случае система не поймет, к какому объекту привязывать дополнительные данные.
Иногда удобнее работать напрямую с объектом, особенно если вы выполняете массовую загрузку и хотите минимизировать количество обращений к базе данных. Рассмотрим ситуацию, когда мы уже получили объект справочника и хотим изменить его табличную часть ДополнительныеРеквизиты.
ОбъектНоменклатура = СсылкаНаНоменклатуру.ПолучитьОбъект();
// Находим нужное свойство
СвойствоСсылка = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Цвет", Истина);
// Ищем, есть ли уже такая строка в табличной части
ПараметрыПоиска = Новый Структура("Свойство", СвойствоСсылка);
НайденныеСтроки = ОбъектНоменклатура.ДополнительныеРеквизиты.НайтиСтроки(ПараметрыПоиска);
Если НайденныеСтроки.Количество() > 0 Тогда
СтрокаТЧ = НайденныеСтроки[0];
Иначе
СтрокаТЧ = ОбъектНоменклатура.ДополнительныеРеквизиты.Добавить();
СтрокаТЧ.Свойство = СвойствоСсылка;
КонецЕсли;
СтрокаТЧ.Значение = "Красный";
ОбъектНоменклатура.Записать();
Выясним причину, по которой код часто выдает ошибку при попытке записать значение в реквизит. Если в настройках доп. реквизита указан тип «Дополнительное значение», то вы не можете просто записать туда строку «Красный». Программа ожидает ссылку на элемент специального справочника ЗначенияСвойствОбъектов.
Проанализируем ситуацию: чтобы записать такое значение, нам нужно сначала найти (или создать) соответствующий элемент в этом справочнике, где владельцем является наше свойство. Посмотрим на пример кода:
// Сначала находим само свойство (характеристику)
СвойствоОбъекта = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Бренд", Истина);
// Теперь ищем конкретное значение ("Nike", "Adidas" и т.д.) внутри этого свойства
ЗначениеДляЗаписи = Справочники.ЗначенияСвойствОбъектов.НайтиПоНаименованию("Nike", Ложь, , СвойствоОбъекта);
Если ЗначениеДляЗаписи.Пустая() Тогда
// Если значения не существует, его можно создать программно (опционально)
НовоеЗначение = Справочники.ЗначенияСвойствОбъектов.СоздатьЭлемент();
НовоеЗначение.Наименование = "Nike";
НовоеЗначение.Владелец = СвойствоОбъекта;
НовоеЗначение.Записать();
ЗначениеДляЗаписи = НовоеЗначение.Ссылка;
КонецЕсли;
// Теперь подставляем эту ссылку в таблицу значений для записи через БСП
НовСтр.Значение = ЗначениеДляЗаписи;
Часто возникает обратная задача: получить значение доп. реквизита для анализа или выгрузки. БСП предоставляет для этого удобную функцию в модуле УправлениеСвойствами. Рассмотрим подробнее ее использование:
// Объект - ссылка на элемент (Номенклатура, Контрагент и т.д.)
// Свойство - ссылка на ПВХ ДополнительныеРеквизитыИСведения или его имя
Значение = УправлениеСвойствами.ЗначениеСвойства(СсылкаНаОбъект, "НазваниеНаАнглийском");
Если Значение <> Неопределено Тогда
Сообщить("Значение реквизита: " + Значение);
КонецЕсли;
Функция ЗначениеСвойства удобна тем, что она сама определяет, где искать данные: в табличной части объекта или в регистре сведений (если это дополнительное сведение), и возвращает готовый результат.
Разберем ситуацию, когда дополнительные значения в справочнике ЗначенияСвойствОбъектов организованы иерархически (имеют группы и элементы). При программном заполнении таких данных из Excel важно соблюдать иерархию:
НайтиПоНаименованию обязательно передавайте четвертый параметр — Владельца (ссылку на доп. реквизит). Это исключит нахождение одноименных значений из других свойств.Родитель у нового элемента справочника ЗначенияСвойствОбъектов.УправлениеСвойствами.ЗаписатьСвойстваУОбъекта, так как это минимизирует риск нарушения логики БСП.ЗначенияСвойствОбъектов, а не текстовую строку.Объект.Записать(), и только потом добавляйте доп. реквизиты.УправлениеСвойствами.ЗначениеСвойства универсален для обоих случаев.Используя эти подходы, вы сможете гибко и надежно управлять дополнительными данными в любой современной конфигурации на платформе 1С:Предприятие 8.3.