При написании обработок, будь то простой шаблон для чтения и загрузки из Excel (удобно через загрузка и массовое создание номенклатуры из Excel и CSV), инструменты для загрузки данных товаров из файлов YML и CSV или импорт XML, в конфигурации "1С:Управление Торговлей 11" (а также КА 2 и ERP) разработчики часто сталкиваются с неочевидным поведением системы. Казалось бы, простой код создания элемента справочника работает, элемент записывается, но при открытии карточки товара выясняется, что ключевые поля не заполнены, а система ведет себя некорректно.
Разберем типичную ситуацию: мы создаем номенклатуру, присваиваем ей ВидНоменклатуры, но настройки этого вида (ставка НДС, единица измерения, тип номенклатуры) не применяются к новому элементу автоматически. Попытаемся разобраться, почему так происходит, и как написать правильный код.
Рассмотрим пример кода, с которого начиналось обсуждение. Задача состоит в том, чтобы найти Вид номенклатуры и присвоить его новому элементу.
Первая ошибка — избыточные действия с базой данных:
// Неоптимальный код
СсылкаН = Справочники.ВидыНоменклатуры.НайтиПоНаименованию("Продукция", Истина);
ОбъектН = СсылкаН.ПолучитьОбъект(); // Лишнее действие!
НовыйЭлемент.ВидНоменклатуры = ОбъектН.Ссылка; // Возврат к тому, с чего начали
Здесь мы видим классическую ошибку начинающих разработчиков: получение объекта там, где достаточно ссылки. Метод НайтиПоНаименованию уже возвращает ссылку. Получать объект (который считывает все данные из базы) только для того, чтобы взять его же ссылку — бессмысленная трата ресурсов сервера. Правильный вариант выглядит так:
// Оптимальный код
ВидНоменклатурыСсылка = Справочники.ВидыНоменклатуры.НайтиПоНаименованию("Продукция", Истина);
НовыйЭлемент.ВидНоменклатуры = ВидНоменклатурыСсылка;
Однако главная проблема автора заключалась не в производительности, а в логике работы УТ 11. После записи элемента поле "Вид номенклатуры" было заполнено, но зависимые поля (НДС, Тип товара и т.д.) оставались пустыми, пока пользователь вручную не перевыберет вид в форме.
В современных конфигурациях ВидНоменклатуры — это не просто группировка. Это шаблон (template), содержащий значения по умолчанию и настройки учета (серии, характеристики, упаковки). Это особенно важно учитывать, если вы планируете сложную логику, например, когда требуется расчет объема, ширины и высоты в карточке номенклатуры, где корректность базовых единиц измерения критична.
Когда вы создаете номенклатуру интерактивно (руками в форме), срабатывают обработчики событий формы (например, ПриИзменении поля Вид), которые копируют настройки из Вида в реквизиты Номенклатуры. Когда вы создаете элемент программно, эти события формы не срабатывают. Простого присваивания ссылки НовыйЭлемент.ВидНоменклатуры = ... недостаточно. Система "не знает", что вы хотите применить шаблон.
Чтобы программно созданный элемент был полноценным (что особенно актуально, если выполняется комплексная загрузка номенклатуры, штрихкодов, цен и документов поступления), необходимо принудительно вызвать логику заполнения. В зависимости от версии конфигурации и контекста задачи, есть несколько способов сделать это.
В конфигурации у объекта справочника Номенклатура часто предусмотрены экспортные методы, дублирующие логику заполнения. Автор темы нашел решение в вызове процедуры:
НовыйЭлемент.ВидНоменклатуры = СсылкаН;
// Принудительно заполняем реквизиты значениями по умолчанию из Вида
НовыйЭлемент.ЗаполнитьРеквизитыПоВидуНоменклатуры();
Примечание: имя метода может отличаться в разных релизах (например, ЗаполнитьЗначенияСвойств или аналогичные). Всегда проверяйте наличие методов в модуле объекта через "Вычислить выражение" или синтакс-помощник.
Платформа 1С предоставляет стандартный метод Заполнить(ДанныеЗаполнения). В типовых конфигурациях в модуле объекта есть обработчик ОбработкаЗаполнения, который содержит всю необходимую логику инициализации нового элемента.
НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
// Заполняем на основании Вида (если логика это предусматривает)
НовыйЭлемент.Заполнить(ВидНоменклатурыСсылка);
// Или просто инициализируем дефолтные значения
НовыйЭлемент.Заполнить(Неопределено);
НовыйЭлемент.ВидНоменклатуры = ВидНоменклатурыСсылка;
// ... далее заполнение остальных полей
В исходном коде автора встречалась строка:
НовыйЭлемент.ОбменДанными.Загрузка = Истина;
Крайне не рекомендуется использовать этот флаг при создании справочников в УТ 11, КА 2 или ERP без крайней необходимости. Почему?
ТипНоменклатуры), которые потом невозможно будет использовать в документах.ПриЗаписи) заполняется множество служебных регистров: ключи доступа (RLS), очередь поиска, история изменений. Режим Загрузка = Истина отключает эти подписки. В результате товар может быть создан, но пользователи его "не увидят" в подборе из-за отсутствия записей в регистрах доступа.Соберем воедино корректный код. Этот подход является базой для любых интеграций, будь то простая обработка или полноценная выгрузка / загрузка в формате JSON данных по номенклатурам.
// 1. Получаем ссылку на вид номенклатуры (лучше искать по уникальному ID или коду, но для примера - по наименованию)
ВидСсылка = Справочники.ВидыНоменклатуры.НайтиПоНаименованию("Продукция");
Если ВидСсылка.Пустая() Тогда
// Обязательно обрабатываем ошибку, чтобы не плодить "битые" элементы
Сообщить("Вид номенклатуры не найден!");
Возврат;
КонецЕсли;
// 2. Создаем элемент
НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
// 3. Устанавливаем Вид
НовыйЭлемент.ВидНоменклатуры = ВидСсылка;
// 4. ВАЖНО: Вызываем заполнение значений по умолчанию (НДС, Ед.Изм., ТипНоменклатуры)
// Проверяем наличие метода в вашей версии конфигурации.
// Часто работает стандартный Заполнить() или специфичный метод объекта.
Попытка
НовыйЭлемент.ЗаполнитьРеквизитыПоВидуНоменклатуры();
Исключение
// Если специфичного метода нет, пробуем стандартную обработку заполнения
НовыйЭлемент.Заполнить(ВидСсылка);
КонецПопытки;
// 5. Заполняем уникальные поля
НовыйЭлемент.Наименование = "Апельсиновый сок";
НовыйЭлемент.Артикул = "ART-12345";
// Если ВидНоменклатуры предполагает характеристики, нужно включить флаг и в товаре
НовыйЭлемент.ИспользоватьХарактеристики = ВидСсылка.ИспользоватьХарактеристики;
// 6. Записываем БЕЗ ОбменДанными.Загрузка, чтобы сработали все проверки
Попытка
НовыйЭлемент.Записать();
Исключение
Сообщить("Ошибка при записи номенклатуры: " + ОписаниеОшибки());
КонецПопытки;
При программном создании номенклатуры в сложных конфигурациях 1С:
ПолучитьОбъект(), если нужна только ссылка.ВидНоменклатуры не заполняет автоматически зависимые реквизиты (Ставка НДС, Тип и т.д.).Заполнить() или специализированные методы модуля объекта), чтобы применить шаблон настроек Вида.ОбменДанными.Загрузка = Истина, чтобы не нарушить целостность служебных данных и механизмов RLS.После корректного создания карточки товара можно переходить к наполнению её медиа-контентом, например, используя выгрузку и загрузку картинок номенклатуры на базе БСП.