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