Почему программно не меняется вид номенклатуры в 1С:Розница 2.3 и как это исправить

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

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

Анализ проблемы и типичные ошибки в коде

Рассмотрим стандартный фрагмент кода, который часто используют начинающие разработчики, и проанализируем, где в нем могут крыться ошибки:


НоменОбъект = Справочники.Номенклатура.НайтиПоКоду(Стр.Номенклатура.Код).ПолучитьОбъект();
НоменОбъект.ВидНоменклатуры = Стр.ВидыНоменклатуры;
Попытка
    НоменОбъект.Записать();
Исключение
    Сообщить("Не удалось сменить вид номенклатуры: " + ОписаниеОшибки());
КонецПопытки;

В этой ситуации мы видим сразу несколько потенциально проблемных мест:

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

Использование режима загрузки данных

Одним из самых быстрых способов обойти стандартные проверки конфигурации является использование флага ОбменДанными.Загрузка = Истина. Этот механизм сообщает системе, что объект записывается в режиме обмена, и большинство логических проверок в модуле объекта должны быть пропущены.

Рассмотрим, как модифицировать наш код:


НоменОбъект = Справочники.Номенклатура.НайтиПоКоду(КодТовара).ПолучитьОбъект();
Если НоменОбъект <> Неопределено Тогда
    НоменОбъект.ОбменДанными.Загрузка = Истина;
    НоменОбъект.ВидНоменклатуры = НовыйВидНоменклатуры;
    // Важно также обновить тип номенклатуры, если он отличается
    НоменОбъект.ТипНоменклатуры = НовыйВидНоменклатуры.ТипНоменклатуры;
    Попытка
        НоменОбъект.Записать();
    Исключение
        Сообщить("Ошибка при записи: " + ОписаниеОшибки());
    КонецПопытки;
КонецЕсли;

Важное предупреждение: Использование ОбменДанными.Загрузка = Истина — это «тяжелая артиллерия». Этот метод отключает проверку целостности данных. Если вы измените вид номенклатуры с типа «Товар» на «Услуга» для позиции, по которой есть складские остатки, вы получите логическую ошибку в базе, которую потом будет сложно исправить.

Синхронизация скрытого реквизита ТипНоменклатуры

В 1С:Розница (и других конфигурациях на базе БСП) в справочнике Номенклатура существует скрытый реквизит ТипНоменклатуры (это перечисление). Он дублирует значение реквизита ТипНоменклатуры, установленного в справочнике ВидыНоменклатуры.

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

Рекомендация: При программном изменении всегда устанавливайте оба значения:

  1. Объект.ВидНоменклатуры
  2. Объект.ТипНоменклатуры (взяв значение из Объект.ВидНоменклатуры.ТипНоменклатуры)

Учет систем маркировки и дополнительных реквизитов

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

Вызов типовых серверных процедур

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

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

Альтернатива: Групповое изменение реквизитов

Если задача разовая и программирование не является обязательным требованием, воспользуйтесь стандартным инструментом «Групповое изменение реквизитов» (раздел Администрирование — Обслуживание — Корректировка данных).

Разберем по шагам, как сделать это правильно:

  1. Откройте обработку и выберите объект «Номенклатура».
  2. Настройте отбор по нужным позициям.
  3. Зайдите в «Дополнительные параметры» (под кнопкой «Настройки») и установите флаги «Показывать служебные реквизиты» и «Режим разработчика».
  4. Теперь в списке реквизитов вам станут доступны не только Вид номенклатуры, но и Тип номенклатуры.
  5. Измените оба реквизита одновременно. Это гарантирует максимальную корректность с точки зрения логики базы данных.

Заключение

Программная смена вида номенклатуры в 1С:Розница 2.3 — это задача, требующая понимания структуры данных. Простого присвоения ссылки недостаточно из-за наличия дублирующих и зависимых реквизитов (таких как ТипНоменклатуры), а также жестких проверок в модуле объекта.

Для успешного решения задачи используйте проверку найденного объекта, синхронизируйте тип номенклатуры и, при необходимости, применяйте ОбменДанными.Загрузка = Истина, предварительно убедившись в отсутствии складских движений, которые могут противоречить новому виду номенклатуры.

← На главную