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