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