При переходе с конфигурации 1С:Управление торговлей 11 на 1С:ERP Управление предприятием 2 программисты часто сталкиваются с неожиданным поведением системы при создании объектов. Одна из таких проблем — невозможность простого программного заполнения реквизита Артикул. Даже если вы явно указываете значение в коде, после выполнения метода Записать() в карточке товара может появиться автоматически сгенерированный номер (например, с префиксом "ЕРП-"), игнорирующий ваши установки.
В этой статье мы подробно разберем, почему это происходит, как найти "виновника" в коде конфигурации и какие существуют способы обхода этого механизма.
В типовых конфигурациях на базе ERP и КА 2 реализованы жесткие механизмы контроля нормативно-справочной информации (НСИ). Если в УТ 11.4 артикул часто является просто строковым полем, то в ERP он может быть частью системы автонумерации или контроля уникальности. Проанализируем, где именно может скрываться логика перезаполнения:
ПередЗаписью для справочника Номенклатура, которая проверяет, является ли объект новым, и если да — генерирует артикул по шаблону.ПередЗаписью или ПриЗаписи непосредственно в самом справочнике.Чтобы точно определить, в какой момент ваш артикул заменяется на системный, пройдемся по шагам отладки. Разберем этот процесс подробнее:
Установите точку останова в вашем коде на строке Номенклатура.Записать(). Когда выполнение остановится, нажмите F11 (Шагнуть внутрь). Вы попадете в модуль объекта справочника. Продолжайте движение, пока не выйдете из всех процедур модуля объекта и не попадете в общие модули, вызываемые подписками на события.
Особое внимание уделите моменту перехода в процедуры с названиями вроде СгенерироватьАртикулНоменклатуры или УстановитьПрефиксИНомер. Как только вы увидите, что значение ЭтотОбъект.Артикул изменилось — цель найдена.
Если логика в конфигурации написана таким образом, что она срабатывает только для новых объектов (проверка ЭтоНовый()), то самым простым, хоть и не самым оптимальным с точки зрения производительности решением, будет двойная запись объекта.
Рассмотрим пример кода, реализующий этот подход:
НоваяНоменклатура = Справочники.Номенклатура.СоздатьЭлемент();
НоваяНоменклатура.Наименование = "Тестовый товар";
// Устанавливаем ВидНоменклатуры и другие обязательные реквизиты
НоваяНоменклатура.ВидНоменклатуры = Справочники.ВидыНоменклатуры.НайтиПоНаименованию("Товар");
// Первая запись: здесь сработает подписка и присвоит системный артикул
НоваяНоменклатура.Записать();
// Теперь объект уже не новый, и подписка при повторной записи его не тронет
НоваяНоменклатура.Артикул = "МОЙ-АРТИКУЛ-001";
НоваяНоменклатура.Записать();
Важный момент: Этот метод гарантированно работает в большинстве случаев, но он создает лишнюю нагрузку на базу данных и увеличивает количество записей в журнале регистрации.
Разберем более изящный способ. В профессиональной разработке на 1С принято предусматривать в подписках на события возможность отключения их логики. Это делается через структуру ДополнительныеСвойства. Если вы сами дорабатываете конфигурацию (или расширение), добавьте в начало процедуры автозаполнения артикула проверку флага.
В вашем коде создания номенклатуры это будет выглядеть так:
НоваяНоменклатура = Справочники.Номенклатура.СоздатьЭлемент();
НоваяНоменклатура.Наименование = "Товар с моим артикулом";
НоваяНоменклатура.Артикул = "СПЕЦ-123";
// Добавляем специальный флаг в объект
НоваяНоменклатура.ДополнительныеСвойства.Вставить("ПропуститьАвтозаполнениеАртикула", Истина);
НоваяНоменклатура.Записать();
А в коде подписки (или расширения), который генерирует артикул, нужно добавить соответствующее условие:
Процедура ПередЗаписью_АвтозаполнениеАртикула(Источник, Отказ) Экспорт
Если Источник.ДополнительныеСвойства.Свойство("ПропуститьАвтозаполнениеАртикула")
И Источник.ДополнительныеСвойства.ПропуститьАвтозаполнениеАртикула Тогда
Возврат;
КонецЕсли;
// ... далее стандартная логика генерации артикула
КонецПроцедуры
Проанализируем ситуацию, когда вам нужно загрузить большой объем данных и вы хотите полностью отключить все типовые проверки и подписки. Для этого используется свойство ОбменДанными.Загрузка.
НоваяНоменклатура = Справочники.Номенклатура.СоздатьЭлемент();
НоваяНоменклатура.Наименование = "Загруженный товар";
НоваяНоменклатура.Артикул = "АРТ-999";
НоваяНоменклатура.ОбменДанными.Загрузка = Истина;
НоваяНоменклатура.Записать();
Внимание: Использование этого метода требует крайней осторожности. При ОбменДанными.Загрузка = Истина система не только не будет генерировать артикул, но и пропустит проверку на заполнение обязательных полей, не зарегистрирует изменения для обмена с другими базами и не выполнит важные бизнес-расчеты (например, создание упаковок по умолчанию). Используйте это только в разовых обработках переноса данных.
Если вы видите, что артикул имеет вид ЕРП-000001, возможно, в системе задействован стандартный механизм префиксирования. Посмотрим на настройки в разделе НСИ и администрирование -> Номенклатура. Там может быть включен контроль уникальности артикулов. Если вы пытаетесь программно записать артикул, который уже существует, ERP может автоматически модифицировать его или выдать ошибку.
Также стоит проверить справочник Виды номенклатуры. В некоторых отраслевых решениях именно там задаются настройки того, как должен выглядеть артикул для каждой конкретной категории товаров. Если в настройках вида указано "Генерировать автоматически", то программное переопределение будет конфликтовать с настройками системы.
Для успешного программного заполнения артикула в 1С:ERP рекомендуется придерживаться следующего алгоритма:
ДополнительныеСвойства. Это наиболее "чистый" путь, сохраняющий целостность системы.