Программное создание Номенклатуры в УТ 11: как корректно заполнить реквизиты по Виду номенклатуры?

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

При написании обработок, будь то простой шаблон для чтения и загрузки из Excel (удобно через загрузка и массовое создание номенклатуры из Excel и CSV), инструменты для загрузки данных товаров из файлов YML и CSV или импорт XML, в конфигурации "1С:Управление Торговлей 11" (а также КА 2 и ERP) разработчики часто сталкиваются с неочевидным поведением системы. Казалось бы, простой код создания элемента справочника работает, элемент записывается, но при открытии карточки товара выясняется, что ключевые поля не заполнены, а система ведет себя некорректно.

Разберем типичную ситуацию: мы создаем номенклатуру, присваиваем ей ВидНоменклатуры, но настройки этого вида (ставка НДС, единица измерения, тип номенклатуры) не применяются к новому элементу автоматически. Попытаемся разобраться, почему так происходит, и как написать правильный код.

Анализ исходной проблемы и ошибок в коде

Рассмотрим пример кода, с которого начиналось обсуждение. Задача состоит в том, чтобы найти Вид номенклатуры и присвоить его новому элементу.

Первая ошибка — избыточные действия с базой данных:


// Неоптимальный код
СсылкаН = Справочники.ВидыНоменклатуры.НайтиПоНаименованию("Продукция", Истина);
ОбъектН = СсылкаН.ПолучитьОбъект(); // Лишнее действие!
НовыйЭлемент.ВидНоменклатуры = ОбъектН.Ссылка; // Возврат к тому, с чего начали

Здесь мы видим классическую ошибку начинающих разработчиков: получение объекта там, где достаточно ссылки. Метод НайтиПоНаименованию уже возвращает ссылку. Получать объект (который считывает все данные из базы) только для того, чтобы взять его же ссылку — бессмысленная трата ресурсов сервера. Правильный вариант выглядит так:


// Оптимальный код
ВидНоменклатурыСсылка = Справочники.ВидыНоменклатуры.НайтиПоНаименованию("Продукция", Истина);
НовыйЭлемент.ВидНоменклатуры = ВидНоменклатурыСсылка;

Однако главная проблема автора заключалась не в производительности, а в логике работы УТ 11. После записи элемента поле "Вид номенклатуры" было заполнено, но зависимые поля (НДС, Тип товара и т.д.) оставались пустыми, пока пользователь вручную не перевыберет вид в форме.

Особенность архитектуры УТ 11 и ERP

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

Когда вы создаете номенклатуру интерактивно (руками в форме), срабатывают обработчики событий формы (например, ПриИзменении поля Вид), которые копируют настройки из Вида в реквизиты Номенклатуры. Когда вы создаете элемент программно, эти события формы не срабатывают. Простого присваивания ссылки НовыйЭлемент.ВидНоменклатуры = ... недостаточно. Система "не знает", что вы хотите применить шаблон.

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

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

Способ 1. Использование экспортного метода объекта (Решение автора)

В конфигурации у объекта справочника Номенклатура часто предусмотрены экспортные методы, дублирующие логику заполнения. Автор темы нашел решение в вызове процедуры:


НовыйЭлемент.ВидНоменклатуры = СсылкаН;
// Принудительно заполняем реквизиты значениями по умолчанию из Вида
НовыйЭлемент.ЗаполнитьРеквизитыПоВидуНоменклатуры(); 

Примечание: имя метода может отличаться в разных релизах (например, ЗаполнитьЗначенияСвойств или аналогичные). Всегда проверяйте наличие методов в модуле объекта через "Вычислить выражение" или синтакс-помощник.

Способ 2. Стандартный метод Заполнить()

Платформа 1С предоставляет стандартный метод Заполнить(ДанныеЗаполнения). В типовых конфигурациях в модуле объекта есть обработчик ОбработкаЗаполнения, который содержит всю необходимую логику инициализации нового элемента.


НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
// Заполняем на основании Вида (если логика это предусматривает)
НовыйЭлемент.Заполнить(ВидНоменклатурыСсылка); 
// Или просто инициализируем дефолтные значения
НовыйЭлемент.Заполнить(Неопределено);

НовыйЭлемент.ВидНоменклатуры = ВидНоменклатурыСсылка;
// ... далее заполнение остальных полей

Опасность использования ОбменДанными.Загрузка = Истина

В исходном коде автора встречалась строка:


НовыйЭлемент.ОбменДанными.Загрузка = Истина;

Крайне не рекомендуется использовать этот флаг при создании справочников в УТ 11, КА 2 или ERP без крайней необходимости. Почему?

  1. Отключение проверок. Вы можете записать некорректные данные (например, товар без указания ТипНоменклатуры), которые потом невозможно будет использовать в документах.
  2. Служебные регистры. В этих конфигурациях при записи номенклатуры (в событии ПриЗаписи) заполняется множество служебных регистров: ключи доступа (RLS), очередь поиска, история изменений. Режим Загрузка = Истина отключает эти подписки. В результате товар может быть создан, но пользователи его "не увидят" в подборе из-за отсутствия записей в регистрах доступа.

Итоговый правильный алгоритм

Соберем воедино корректный код. Этот подход является базой для любых интеграций, будь то простая обработка или полноценная выгрузка / загрузка в формате JSON данных по номенклатурам.


// 1. Получаем ссылку на вид номенклатуры (лучше искать по уникальному ID или коду, но для примера - по наименованию)
ВидСсылка = Справочники.ВидыНоменклатуры.НайтиПоНаименованию("Продукция");

Если ВидСсылка.Пустая() Тогда
    // Обязательно обрабатываем ошибку, чтобы не плодить "битые" элементы
    Сообщить("Вид номенклатуры не найден!");
    Возврат;
КонецЕсли;

// 2. Создаем элемент
НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();

// 3. Устанавливаем Вид
НовыйЭлемент.ВидНоменклатуры = ВидСсылка;

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

// 5. Заполняем уникальные поля
НовыйЭлемент.Наименование = "Апельсиновый сок";
НовыйЭлемент.Артикул = "ART-12345";
// Если ВидНоменклатуры предполагает характеристики, нужно включить флаг и в товаре
НовыйЭлемент.ИспользоватьХарактеристики = ВидСсылка.ИспользоватьХарактеристики;

// 6. Записываем БЕЗ ОбменДанными.Загрузка, чтобы сработали все проверки
Попытка
    НовыйЭлемент.Записать();
Исключение
    Сообщить("Ошибка при записи номенклатуры: " + ОписаниеОшибки());
КонецПопытки;

Резюме

При программном создании номенклатуры в сложных конфигурациях 1С:

  1. Не используйте ПолучитьОбъект(), если нужна только ссылка.
  2. Не забывайте, что назначение ВидНоменклатуры не заполняет автоматически зависимые реквизиты (Ставка НДС, Тип и т.д.).
  3. Используйте методы заполнения (Заполнить() или специализированные методы модуля объекта), чтобы применить шаблон настроек Вида.
  4. Избегайте ОбменДанными.Загрузка = Истина, чтобы не нарушить целостность служебных данных и механизмов RLS.

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

← На главную