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