Как программно заполнить регистр «Номенклатура контрагентов БЭД» и избежать ошибки пустого поля «Владелец»

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

При разработке механизмов интеграции с маркетплейсами или системами электронного документооборота в конфигурациях 1С:Комплексная автоматизация 2, 1С:ERP или 1С:Управление торговлей 11 программисты часто сталкиваются с необходимостью программного заполнения регистра сведений НоменклатураКонтрагентовБЭД. Одной из самых распространенных проблем является ошибка: «Запись не верна! Значение поля "Владелец" не может быть пустым!», даже если код поиска объекта кажется верным.

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

Разбор ситуации и причины возникновения ошибки

Рассмотрим типичный сценарий: программист пытается создать запись в регистре, используя поиск контрагента по наименованию. Если вам необходимо связать учетную систему с торговыми площадками, то вместо разработки собственного кода можно использовать модуль интеграции 1С с Ozon, Wildberries и Яндекс.Маркетом, в котором эти механизмы уже настроены. Код выглядит следующим образом:


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

При выполнении этого кода система выдает ошибку заполнения. Проанализируем причину. В современных конфигурациях 1С используется разделение на справочники Партнеры и Контрагенты. Определяемый тип, используемый в поле Владелец данного регистра, ссылается именно на справочник Партнеры.

Важный нюанс: Если в настройках системы отключена функциональная опция «Независимо вести партнеров и контрагентов», пользователю в интерфейсе может казаться, что это один и тот же объект. Однако на уровне метаданных это разные таблицы. Попытка записать в поле, ожидающее ссылку на СправочникСсылка.Партнеры, ссылку типа СправочникСсылка.Контрагенты приведет к тому, что значение будет проигнорировано или очищено, что и вызывает ошибку «пустого поля».

Решение 1: Поиск по справочнику Партнеры

Самый простой способ исправить ошибку — обращаться напрямую к справочнику Партнеры, если вам известно их управленческое наименование. Выясним, как изменить код для корректной работы:


// Вместо поиска в Контрагентах используем Партнеров
ПартнерСсылка = Справочники.Партнеры.НайтиПоНаименованию("ИНТЕРНЕТ РЕШЕНИЯ ООО");

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

Однако поиск по наименованию крайне ненадежен. Рассмотрим более профессиональный подход.

Решение 2: Получение Партнера через ИНН Контрагента (с помощью запроса)

Чаще всего при интеграции у нас есть ИНН организации. Поскольку в справочнике Партнеры реквизита ИНН нет (он хранится в Контрагентах), нам необходимо реализовать связку. Проанализируем структуру: у каждого контрагента есть реквизит Партнер, который и является ключом для связи.

Рассмотрим пример функции, которая находит Партнера по ИНН контрагента:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ ПЕРВЫЕ 1
    |	Контрагенты.Партнер КАК Партнер
    |ИЗ
    |	Справочник.Контрагенты КАК Контрагенты
    |ГДЕ
    |	Контрагенты.ИНН = &ИНН";

Запрос.УстановитьПараметр("ИНН", "7704217370"); // Пример ИНН

РезультатЗапроса = Запрос.Выполнить();

Если Не РезультатЗапроса.Пустой() Тогда
    ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
    ВыборкаДетальныеЗаписи.Следующий();
    НужныйВладелец = ВыборкаДетальныеЗаписи.Партнер;
КонецЕсли;

Используя такой подход, мы гарантируем, что в поле Владелец попадет объект нужного типа, а поиск будет осуществляться по уникальному идентификатору (ИНН), а не по строковому наименованию.

Пошаговый алгоритм правильного заполнения регистра

Разберем по шагам весь процесс программного создания записи в регистре НоменклатураКонтрагентовБЭД:

  1. Определяем Владельца: Находим ссылку на Партнера. Если у вас есть только ИНН, используйте запрос к справочнику Контрагенты для получения связанного партнера.
  2. Получаем данные номенклатуры: Найдите объект в вашем справочнике Номенклатура (например, по артикулу), чтобы заполнить единицы измерения и коды.
  3. Используем МенеджерЗаписи: Для одиночных записей это наиболее удобный способ. Если планируется массовая загрузка, лучше использовать НаборЗаписей для повышения производительности.
  4. Заполнение обязательных полей:
    • Владелец — ссылка на Партнера;
    • Идентификатор — уникальный код товара в системе контрагента;
    • Наименование — как товар называется у контрагента;
    • Номенклатура (если требуется сопоставление) — ссылка на ваш справочник.
  5. Запись: Вызываем метод Записать(Истина), где параметр Истина означает замещение существующей записи с таким же ключом.

Пример полного кода для записи

Посмотрим на пример законченного кода, который учитывает все нюансы:


Процедура ЗаполнитьНоменклатуруКонтрагента(ИНН_Контрагента, АртикулНаш, ID_Внешний, НазваниеВнешнее)
    
    // 1. Ищем партнера
    Запрос = Новый Запрос("ВЫБРАТЬ ПЕРВЫЕ 1 Партнер ИЗ Справочник.Контрагенты ГДЕ ИНН = &ИНН");
    Запрос.УстановитьПараметр("ИНН", ИНН_Контрагента);
    Выборка = Запрос.Выполнить().Выбрать();
    
    Если Не Выборка.Следующий() Тогда
        Возврат; // Контрагент не найден
    КонецЕсли;
    
    ПартнерСсылка = Выборка.Партнер;
    
    // 2. Ищем нашу номенклатуру
    НашаНоменклатура = Справочники.Номенклатура.НайтиПоРеквизиту("Артикул", АртикулНаш);
    
    // 3. Записываем в регистр
    МенеджерЗаписи = РегистрыСведений.НоменклатураКонтрагентовБЭД.СоздатьМенеджерЗаписи();
    МенеджерЗаписи.Владелец = ПартнерСсылка;
    МенеджерЗаписи.Идентификатор = ID_Внешний;
    МенеджерЗаписи.Наименование = НазваниеВнешнее;
    
    Если Не НашаНоменклатура.Пустая() Тогда
        МенеджерЗаписи.Номенклатура = НашаНоменклатура;
        МенеджерЗаписи.ЕдиницаИзмерения = НашаНоменклатура.ЕдиницаИзмерения;
        // Код единицы измерения часто требуется в БЭД
        МенеджерЗаписи.ЕдиницаИзмеренияКод = НашаНоменклатура.ЕдиницаИзмерения.Код;
    КонецЕсли;
    
    Попытка
        МенеджерЗаписи.Записать(Истина);
    Исключение
        ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Ошибка записи: " + ОписаниеОшибки());
    КонецПопытки;

КонецПроцедуры

Важные рекомендации

Проанализируем еще несколько моментов, которые помогут сделать ваш код более надежным. Во-первых, всегда проверяйте Определяемые типы в конфигураторе. Если ваша база сильно кастомизирована, состав типа ВладелецНоменклатурыКонтрагента мог быть расширен. Во-вторых, помните о существовании дублей контрагентов. Если у одного партнера создано несколько контрагентов с одинаковым ИНН (например, филиалы), запрос без уточнения КПП может вернуть первого попавшегося, что в контексте партнера обычно не критично, но требует внимания при отладке. Для решения проблемы сопоставления документов при наличии нескольких контрагентов у одного партнера можно использовать расширение для выбора контрагента в ЭДО.

Используя предложенные методы, вы сможете корректно работать с регистром НоменклатураКонтрагентовБЭД, избегая типичных ошибок сопоставления типов в сложных конфигурациях на базе 1С:ERP и КА 2. А для автоматической выгрузки сопоставленных данных в файл обмена можно использовать расширение для подстановки артикула партнера в УПД по ЭДО.

← На главную