Как реализовать сплошную нумерацию документов с разными префиксами в 1С

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В типовых конфигурациях 1С:Предприятие 8 стандартный механизм автонумерации работает по принципу разделения очередей: для каждого уникального префикса система ведет свой собственный счетчик. Например, если вы используете префиксы «А» и «Б», то после документа «А0001» система при создании документа с префиксом «Б» предложит номер «Б0001», а не «Б0002». Это часто не устраивает бухгалтерию или бизнес-заказчиков, которым требуется строго сквозная нумерация (А0001, Б0002, В0003 и так далее) независимо от буквенного кода.

В этой статье мы разберем, почему стандартный механизм ведет себя именно так, и проанализируем несколько способов реализации сплошной нумерации, от простых правок в модулях до продвинутого использования механизмов платформы.

Почему стандартная автонумерация «сбивается» при смене префикса?

Для начала разберем внутреннюю логику платформы. Когда объект (документ или справочник) записывается в базу, 1С ищет максимальный существующий номер. Однако поиск происходит не среди всех номеров, а по маске, соответствующей текущему префиксу. Если вы программно или вручную устанавливаете префикс «Б», система выполняет запрос к базе данных, пытаясь найти строку, начинающуюся на «Б». Естественно, номера, начинающиеся на «А», в выборку не попадают, и счетчик начинается заново.

Попытка вручную «подсунуть» нужный номер в процедуре ПриУстановкеНовогоНомера часто приводит к конфликтам уникальности или к тому, что при следующем создании документа система снова попытается выдать старый номер, не найдя актуальный «максимум» в своей кэшированной очереди.

Решение 1. Использование события ОбработкаПолученияПредставления (Самый надежный метод)

Проанализируем наиболее изящный способ, к которому пришел автор темы. Его суть заключается в том, чтобы не хранить префикс в основном поле Номер, а добавлять его динамически только в момент отображения пользователю.

Рассмотрим по шагам, как это реализовать:

  1. В метаданных документа оставляем автонумерацию включенной, но отказываемся от использования префиксов в самом поле Номер. Таким образом, в базе номера будут храниться как «00001», «00002», «00003».
  2. Добавляем в документ дополнительный реквизит (например, ТипПрефикса или используем существующий реквизит Организация).
  3. В модуле менеджера документа переопределяем процедуру ОбработкаПолученияПредставления.

Посмотрим на пример кода в модуле менеджера:


Процедура ОбработкаПолученияПредставления(Данные, Представление, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    // Формируем строковое представление: Префикс из реквизита + системный номер
    Представление = Строка(Данные.ПрефиксДляПечати) + " " + СокрЛП(Данные.Номер) + " от " + Формат(Данные.Дата, "ДЛФ=D");
КонецПроцедуры

В этом случае платформа всегда видит сплошную числовую последовательность и корректно инкрементирует ее (+1), а пользователь в списках и формах видит «красивый» номер с префиксом. Это решение полностью исключает проблемы с уникальностью.

Решение 2. Использование подписок и переопределение префикса в БСП

Если ваша конфигурация построена на базе БСП (Библиотеки стандартных подсистем), за нумерацию отвечает общий модуль ПрефиксацияОбъектовСобытия. Мы можем вмешаться в процесс формирования префикса.

Разберем вариант с использованием подписки на событие ПриУстановкеНовогоНомера. Нам нужно динамически подставлять префикс, но при этом понимать, что стандартный механизм все равно будет искать «максимум» по этому префиксу.

Пример кода для подписки:


Процедура УстановитьПрефиксДокумента(Источник, СтандартнаяОбработка, Префикс) Экспорт
    
    // Определяем логику префикса
    НужныйПрефикс = "АБ"; // Здесь может быть ваша логика выбора префикса
    
    // Формируем шаблон
    ШаблонПрефикса = "[ОР][ИБ]-[Префикс]";
    ШаблонПрефикса = СтрЗаменить(ШаблонПрефикса, "[ОР]", ПрефиксОрганизации);
    ШаблонПрефикса = СтрЗаменить(ШаблонПрефикса, "[ИБ]", ПрефиксИнформационнойБазы);
    ШаблонПрефикса = СтрЗаменить(ШаблонПрефикса, "[Префикс]", НужныйПрефикс);
    
    Префикс = ШаблонПрефикса;
    
КонецПроцедуры

Важно: Если вы используете этот метод для сплошной нумерации, вам придется самостоятельно вычислять следующий номер, так как стандартный СтандартнаяОбработка = Истина не сработает ожидаемым образом при разных префиксах. Вам придется использовать запрос ВЫБРАТЬ МАКСИМУМ(Номер) по всем префиксам, что может привести к замедлению работы при большом количестве документов.

Решение 3. Вывод префикса только в печатные формы

Проанализируем ситуацию: если префикс нужен только для того, чтобы «бухгалтер видел его в бумажном акте», то самым простым решением будет вообще не менять механизм нумерации в базе данных. Вы можете хранить чистые номера (1, 2, 3), а в макете печатной формы прописать алгоритм добавления нужного префикса в зависимости от условий.

Это самый «безопасный» метод с точки зрения стабильности конфигурации, так как он не затрагивает системные индексы и механизмы контроля уникальности 1С.

Технические нюансы: блокировки и кэширование

При реализации собственной системы нумерации (когда мы сами вычисляем следующий номер) крайне важно учитывать многопользовательскую работу. Рассмотрим основные риски:

  1. Взаимные блокировки (Deadlocks): Если два пользователя одновременно пытаются получить «Максимальный номер + 1», может возникнуть ситуация, когда оба прочитали одно и то же число и пытаются записать документ с одинаковым номером.
  2. Кэш номеров: Платформа 1С кэширует номера на стороне сервера приложений. Если вы изменили логику нумерации «на лету», рекомендуется вызвать метод ОбновитьНумерациюОбъектов(), чтобы сбросить кэш и заставить систему пересчитать актуальное значение из базы данных.
  3. Тип номера: Убедитесь, что длина номера в метаданных достаточна для хранения и префикса, и самого числа, иначе возникнет ошибка обрезания строки.

Итоги

Подводя итог, можно сказать, что наиболее стабильным и современным способом реализации сплошной нумерации с разными префиксами является использование события ОбработкаПолученияПредставления. Мы сохраняем чистоту данных для платформы (сплошной числовой ряд) и обеспечиваем нужный визуальный эффект для пользователя. Если же требования жестко диктуют хранение префикса непосредственно в строке номера, будьте готовы к написанию собственного алгоритма поиска максимального номера в транзакции с использованием исключительных блокировок.

← На главную