Как программно заполнить дополнительные реквизиты номенклатуры в 1С:УТ 11.4?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей IT и автоматизация бизнеса
← На главную

При автоматической загрузке данных из внешних файлов часто возникает необходимость программно заполнить дополнительные реквизиты номенклатуры. Разберем типичную проблему: разработчик пишет код, который добавляет строки напрямую в табличную часть ДополнительныеРеквизиты объекта. После записи данные отображаются на ценниках, но на вкладке "Реквизиты" в карточке пусто. А если изменить любой другой стандартный реквизит и сохранить элемент, все программно добавленные свойства бесследно стираются.

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

Почему прямое добавление строк в табличную часть не работает?

В современных конфигурациях 1С, таких как "Управление торговлей 11" (УТ 11), "Комплексная автоматизация 2" (КА 2) или "ERP", карточки справочников строятся динамически. Строки табличной части ДополнительныеРеквизиты заполняются из реквизитов формы каждый раз при ее записи. Если вы просто запишете данные в базу через объект, минуя механизмы БСП, форма при следующем открытии ничего не будет знать об этих данных, и при сохранении "затрет" ваши изменения.

Используем БСП: модуль УправлениеСвойствами

Для корректной работы с дополнительными реквизитами и сведениями необходимо использовать экспортные процедуры общего модуля УправлениеСвойствами. Рассмотрим подробнее метод записи свойств у объекта.

Функция имеет следующий синтаксис:


УправлениеСвойствами.ЗаписатьСвойстваУОбъекта(ВладелецСвойств, ТаблицаСвойствИЗначений);

Здесь ВладелецСвойств — это ссылка на объект базы данных (например, СправочникСсылка.Номенклатура), а ТаблицаСвойствИЗначений — предварительно сформированная таблица.

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

Пошаговый пример реализации через таблицу значений

Посмотрим на пример заполнения через классическую таблицу значений. Сначала сформируем таблицу нужной структуры, заполним ее и передадим в процедуру:


ТаблицаДопРеквизитов = Новый ТаблицаЗначений;
ТаблицаДопРеквизитов.Колонки.Добавить("Свойство", Новый ОписаниеТипов("ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения"));
ТаблицаДопРеквизитов.Колонки.Добавить("Значение");

НоменклатураСсылка = Справочники.Номенклатура.НайтиПоНаименованию("Кабель силовой");
Если ЗначениеЗаполнено(НоменклатураСсылка) Тогда
    НоваяСтрока = ТаблицаДопРеквизитов.Добавить();
    НоваяСтрока.Свойство = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Бренд");
    НоваяСтрока.Значение = "Название бренда"; // Тип данных должен строго совпадать с настройками свойства
    
    УправлениеСвойствами.ЗаписатьСвойстваУОбъекта(НоменклатураСсылка, ТаблицаДопРеквизитов);
КонецЕсли;

Альтернативный вариант: использование массива структур

В более свежих релизах БСП метод ЗаписатьСвойстваУОбъекта поддерживает работу не только со строго типизированной таблицей значений, но и с массивом структур. Разберем этот более простой и лаконичный подход:


МассивСвойств = Новый Массив;
ТекСвойство = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("АртикулПоставщика");
МассивСвойств.Добавить(Новый Структура("Свойство, Значение", ТекСвойство, "ABC-123"));

УправлениеСвойствами.ЗаписатьСвойстваУОбъекта(НоменклатураСсылка, МассивСвойств);

Решение проблемы с типами значений (Дополнительные значения)

Очень частая ошибка при программной загрузке — игнорирование типа самого свойства. Если свойство имеет тип значения Дополнительное значение (то есть выбор из заранее заданного списка), платформа не примет обычную строку текста. При попытке передать строку реквизит просто останется пустым.

Разберем по шагам, как правильно обработать такие ссылочные значения:

  1. Проанализируем тип свойства. Если это ссылочный тип, нужно искать значение в справочнике ЗначенияСвойствОбъектов.
  2. Выполним поиск существующего значения по наименованию с обязательным отбором по владельцу (самому свойству).
  3. Если значение не найдено — программно создадим новый элемент справочника, укажем владельца, запишем его и получим ссылку.
  4. Передадим эту ссылку в структуру или таблицу свойств.

Посмотрим на пример функции для поиска или автоматического создания такого значения:


Функция ПолучитьДополнительноеЗначение(СвойствоСсылка, ЗначениеСтрокой)
    // Ищем значение с учетом владельца свойства
    ЗначениеСсылка = Справочники.ЗначенияСвойствОбъектов.НайтиПоНаименованию(ЗначениеСтрокой, Истина, , СвойствоСсылка);
    
    Если ЗначениеСсылка.Пустая() Тогда
        НовоеЗначение = Справочники.ЗначенияСвойствОбъектов.СоздатьЭлемент();
        НовоеЗначение.Владелец = СвойствоСсылка;
        НовоеЗначение.Наименование = ЗначениеСтрокой;
        НовоеЗначение.Записать();
        ЗначениеСсылка = НовоеЗначение.Ссылка;
    КонецЕсли;
    
    Возврат ЗначениеСсылка;
КонецФункции

Правильный поиск свойств по виду номенклатуры

Поиск свойства конструкцией НайтиПоНаименованию("Цвет") без указания конкретного набора является потенциальной ошибкой. В системе может быть заведено множество свойств с одинаковым именем для разных "Видов номенклатуры".

Правильнее получать актуальный массив свойств для конкретного объекта, чтобы избежать путаницы. Рассмотрим, как это сделать через БСП:


// Получаем все доступные доп. реквизиты, привязанные к виду номенклатуры
МассивДопРеквизитов = УправлениеСвойствами.СвойстваОбъекта(НоменклатураСсылка, Истина);

Для Каждого ДопРеквизит Из МассивДопРеквизитов Цикл
    Если ДопРеквизит.Наименование = "ИскомоеСвойство" Тогда
        НоваяСтрока = ТаблицаДопРеквизитов.Добавить();
        НоваяСтрока.Свойство = ДопРеквизит;
        НоваяСтрока.Значение = ПолученноеЗначение;
    КонецЕсли;
КонецЦикла;

Обновление интерфейса открытой формы

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

Используйте следующий метод инициализации при возврате управления на сервер формы:

УправлениеСвойствами.ПриЧтенииНаСервере(ЭтаФорма, ТекущийОбъект);

Этот код обновит динамические элементы на экране и корректно отрисует только что записанные свойства.

← На главную