В процессе сопровождения конфигурации 1С:Управление торговлей 11.4 часто возникает задача массового изменения реквизитов справочника Номенклатура. Одной из самых трудоемких операций является смена Вида номенклатуры. Сложность заключается не только в написании кода, но и в строгих проверках целостности данных, которые встроены в типовое решение. Рассмотрим, как решить эту задачу правильно, разберем типичные ошибки новичков и выясним, почему система может блокировать ваши изменения.
Разберем ситуацию, с которой столкнулся автор темы. При попытке программно заменить вид номенклатуры часто совершается фатальная ошибка — вместо замены ссылки на новый элемент справочника ВидыНоменклатуры, программист начинает редактировать сам объект текущего вида. Проанализируем фрагмент ошибочного кода:
НовыйВид = НовыйАртикул.ВидНоменклатуры.ПолучитьОбъект();
НовыйВид.Наименование = "ДД8";
НовыйВид.Записать();
НовыйАртикул.ВидНоменклатуры = НовыйВид.Ссылка;
В чем здесь проблема? Метод ПолучитьОбъект() обращается к тому виду номенклатуры, который уже назначен данному товару. Строка НовыйВид.Наименование = "ДД8" не создает новый вид, а просто переименовывает существующий в базе данных. Если у вас 100 товаров с разными видами номенклатуры, этот код просто переименует все эти 100 видов в "ДД8". В итоге вы получите хаос в справочнике ВидыНоменклатуры, но связь товара с конкретным внутренним идентификатором вида останется прежней.
Для правильной подстановки нам нужно сначала найти ссылку на уже существующий в базе целевой вид или создать один новый и присваивать его всем товарам. Рассмотрим правильный вариант реализации поиска и назначения:
// 1. Находим ссылку на нужный вид номенклатуры один раз вне цикла
СсылкаНаНовыйВид = Справочники.ВидыНоменклатуры.НайтиПоНаименованию("ДД8");
Если СсылкаНаНовыйВид.Пустая() Тогда
// Если вида нет, его нужно создать (опционально)
ОбъектВид = Справочники.ВидыНоменклатуры.СоздатьЭлемент();
ОбъектВид.Наименование = "ДД8";
ОбъектВид.ТипНоменклатуры = Перечисления.ТипыНоменклатуры.Товар;
ОбъектВид.Записать();
СсылкаНаНовыйВид = ОбъектВид.Ссылка;
КонецЕсли;
// 2. В цикле по номенклатуре присваиваем именно ссылку
Для Каждого Стр Из ТЧ Цикл
ТоварСсылка = Справочники.Номенклатура.НайтиПоНаименованию(Стр.Наименование);
Если Не ТоварСсылка.Пустая() Тогда
ОбъектНоменклатура = ТоварСсылка.ПолучитьОбъект();
ОбъектНоменклатура.ВидНоменклатуры = СсылкаНаНовыйВид;
// Здесь могут быть проблемы с записью, которые мы разберем ниже
ОбъектНоменклатура.Записать();
КонецЕсли;
КонецЦикла;
Даже если ваш код написан синтаксически верно, при вызове метода Записать() вы, скорее всего, столкнетесь с ошибкой: "Изменение реквизита Вид номенклатуры недопустимо, так как по номенклатуре имеются движения". Выясним причину такого поведения.
В конфигурации УТ 11.4 за проверку возможности изменения критических реквизитов отвечает механизм, расположенный в модуле НоменклатураЛокализация. Система вызывает функцию ПроверитьВозможностьИзмененияРеквизитов. Если по данной позиции в базе данных есть хотя бы один документ (остатки на складах, продажи, резервы), штатная запись объекта будет заблокирована.
Вид номенклатуры — это "фундаментальный" реквизит. Он определяет:
ТоварыНаСкладах станут недоступны для списания, так как в новых документах поле характеристики будет заблокировано.Если вы осознаете все риски и уверены, что структура учета не пострадает (например, у товаров нет характеристик и серий), можно применить "силовой" метод записи. Для этого используется свойство ОбменДанными.Загрузка. Рассмотрим, как это применить:
ОбъектНоменклатура = СсылкаНаТовар.ПолучитьОбъект();
ОбъектНоменклатура.ВидНоменклатуры = СсылкаНаНовыйВид;
// Включаем режим загрузки, чтобы обойти проверки в модуле объекта
ОбъектНоменклатура.ОбменДанными.Загрузка = Истина;
Попытка
ОбъектНоменклатура.Записать();
Исключение
Сообщить("Ошибка при записи: " + ОписаниеОшибки());
КонецПопытки;
Важно: Установка флага Загрузка = Истина отключает не только проверки возможности изменения реквизитов, но и другие важные механизмы (например, автоматическое формирование наименований по шаблону или регистрацию изменений для обмена данными). Пользуйтесь этим методом крайне осторожно.
Проанализируем ситуацию: что делать, если компания действительно меняет учетную политику и товары уже задействованы в документах? Правильный и безопасный путь включает в себя следующие шаги:
ОбменДанными.Загрузка, если нет движений в регистрах накопления).Такой подход гарантирует, что в регистрах накопления (таких как ВыручкаИСебестоимостьПродаж или ТоварыНаСкладах) не возникнет "зависших" разрезов учета по характеристикам или сериям, которые невозможно будет закрыть в будущем.
Посмотрим на ситуацию с точки зрения бухгалтерии. Вид номенклатуры часто определяет значение по умолчанию для Группы финансового учета (ГФУ). ГФУ, в свою очередь, определяет счета учета (например, 41.01 или 10.01).
Если вы меняете вид номенклатуры, проверьте, не должна ли измениться и ГФУ. Если после смены вида товар должен учитываться на другом счете, старые документы поступления останутся на старом счету, а новые реализации попытаются списать себестоимость с нового. Это приведет к отрицательным остаткам на счетах учета и ошибкам при закрытии месяца. Поэтому при программном изменении вида всегда анализируйте реквизит ГруппаФинансовогоУчета.
Подводя итог, можно сказать, что технически задача решается простой заменой ссылки и использованием режима Загрузка = Истина, но практическая ценность такого решения без предварительной подготовки данных стремится к нулю и может привести к порче базы данных. Всегда выполняйте такие операции сначала на копии базы и проверяйте отчеты по остаткам и себестоимости до и после обработки.