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