В типовых конфигурациях 1С:Предприятие 8 стандартный механизм автонумерации работает по принципу разделения очередей: для каждого уникального префикса система ведет свой собственный счетчик. Например, если вы используете префиксы «А» и «Б», то после документа «А0001» система при создании документа с префиксом «Б» предложит номер «Б0001», а не «Б0002». Это часто не устраивает бухгалтерию или бизнес-заказчиков, которым требуется строго сквозная нумерация (А0001, Б0002, В0003 и так далее) независимо от буквенного кода.
В этой статье мы разберем, почему стандартный механизм ведет себя именно так, и проанализируем несколько способов реализации сплошной нумерации, от простых правок в модулях до продвинутого использования механизмов платформы.
Для начала разберем внутреннюю логику платформы. Когда объект (документ или справочник) записывается в базу, 1С ищет максимальный существующий номер. Однако поиск происходит не среди всех номеров, а по маске, соответствующей текущему префиксу. Если вы программно или вручную устанавливаете префикс «Б», система выполняет запрос к базе данных, пытаясь найти строку, начинающуюся на «Б». Естественно, номера, начинающиеся на «А», в выборку не попадают, и счетчик начинается заново.
Попытка вручную «подсунуть» нужный номер в процедуре ПриУстановкеНовогоНомера часто приводит к конфликтам уникальности или к тому, что при следующем создании документа система снова попытается выдать старый номер, не найдя актуальный «максимум» в своей кэшированной очереди.
Проанализируем наиболее изящный способ, к которому пришел автор темы. Его суть заключается в том, чтобы не хранить префикс в основном поле Номер, а добавлять его динамически только в момент отображения пользователю.
Рассмотрим по шагам, как это реализовать:
Номер. Таким образом, в базе номера будут храниться как «00001», «00002», «00003».ТипПрефикса или используем существующий реквизит Организация).ОбработкаПолученияПредставления.Посмотрим на пример кода в модуле менеджера:
Процедура ОбработкаПолученияПредставления(Данные, Представление, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
// Формируем строковое представление: Префикс из реквизита + системный номер
Представление = Строка(Данные.ПрефиксДляПечати) + " " + СокрЛП(Данные.Номер) + " от " + Формат(Данные.Дата, "ДЛФ=D");
КонецПроцедуры
В этом случае платформа всегда видит сплошную числовую последовательность и корректно инкрементирует ее (+1), а пользователь в списках и формах видит «красивый» номер с префиксом. Это решение полностью исключает проблемы с уникальностью.
Если ваша конфигурация построена на базе БСП (Библиотеки стандартных подсистем), за нумерацию отвечает общий модуль ПрефиксацияОбъектовСобытия. Мы можем вмешаться в процесс формирования префикса.
Разберем вариант с использованием подписки на событие ПриУстановкеНовогоНомера. Нам нужно динамически подставлять префикс, но при этом понимать, что стандартный механизм все равно будет искать «максимум» по этому префиксу.
Пример кода для подписки:
Процедура УстановитьПрефиксДокумента(Источник, СтандартнаяОбработка, Префикс) Экспорт
// Определяем логику префикса
НужныйПрефикс = "АБ"; // Здесь может быть ваша логика выбора префикса
// Формируем шаблон
ШаблонПрефикса = "[ОР][ИБ]-[Префикс]";
ШаблонПрефикса = СтрЗаменить(ШаблонПрефикса, "[ОР]", ПрефиксОрганизации);
ШаблонПрефикса = СтрЗаменить(ШаблонПрефикса, "[ИБ]", ПрефиксИнформационнойБазы);
ШаблонПрефикса = СтрЗаменить(ШаблонПрефикса, "[Префикс]", НужныйПрефикс);
Префикс = ШаблонПрефикса;
КонецПроцедуры
Важно: Если вы используете этот метод для сплошной нумерации, вам придется самостоятельно вычислять следующий номер, так как стандартный СтандартнаяОбработка = Истина не сработает ожидаемым образом при разных префиксах. Вам придется использовать запрос ВЫБРАТЬ МАКСИМУМ(Номер) по всем префиксам, что может привести к замедлению работы при большом количестве документов.
Проанализируем ситуацию: если префикс нужен только для того, чтобы «бухгалтер видел его в бумажном акте», то самым простым решением будет вообще не менять механизм нумерации в базе данных. Вы можете хранить чистые номера (1, 2, 3), а в макете печатной формы прописать алгоритм добавления нужного префикса в зависимости от условий.
Это самый «безопасный» метод с точки зрения стабильности конфигурации, так как он не затрагивает системные индексы и механизмы контроля уникальности 1С.
При реализации собственной системы нумерации (когда мы сами вычисляем следующий номер) крайне важно учитывать многопользовательскую работу. Рассмотрим основные риски:
ОбновитьНумерациюОбъектов(), чтобы сбросить кэш и заставить систему пересчитать актуальное значение из базы данных.Подводя итог, можно сказать, что наиболее стабильным и современным способом реализации сплошной нумерации с разными префиксами является использование события ОбработкаПолученияПредставления. Мы сохраняем чистоту данных для платформы (сплошной числовой ряд) и обеспечиваем нужный визуальный эффект для пользователя. Если же требования жестко диктуют хранение префикса непосредственно в строке номера, будьте готовы к написанию собственного алгоритма поиска максимального номера в транзакции с использованием исключительных блокировок.