Проблема автоматической нумерации в 1С — одна из самых часто встречающихся задач в практике программиста и администратора. Часто возникает ситуация, когда после ручного изменения номера или временной смены префикса система «забывает» старый порядок и начинает предлагать некорректные значения. Особенно критично это проявляется в документах типа Платежное поручение исходящее, где нумерация должна быть строго последовательной для каждой организации.
В данной статье мы подробно разберем, почему платформа 1С иногда игнорирует ваши попытки вернуть старый префикс и как технически устроен механизм поиска максимального номера. Мы проанализируем типичную ситуацию «вложенных» префиксов и найдем пути выхода из этой ситуации.
Для начала проанализируем, как именно платформа 1С формирует новый номер. Когда вы создаете новый документ или вызываете метод УстановитьНовыйНомер(), система выполняет следующие действия:
Главная ловушка кроется во втором пункте. Система ищет максимальный номер с помощью строкового сравнения, используя конструкцию, аналогичную SQL-запросу с оператором LIKE 'Префикс%'. Если у вас в базе есть префиксы «ЛП» и «Лпл», то при поиске номера для префикса «ЛП» в выборку попадут и все номера, начинающиеся на «Лпл», так как «Лпл» содержит в себе «ЛП».
Поскольку строчные буквы в большинстве кодировок SQL-серверов имеют приоритет над заглавными или просто следуют позже, строка «Лпл...» будет признана системой как «большая», чем «ЛП...». В результате 1С берет номер с нежелательным префиксом, прибавляет к нему единицу и выдает результат, который кажется пользователю ошибочным.
Рассмотрим стандартные попытки решения, которые часто оказываются неэффективными в данной ситуации:
ОбновитьНумерациюОбъектов() лишь подтвердит текущий ошибочный максимум.Самый надежный способ избежать конфликтов в нумерации — следовать правилу уникальности префиксов. Рассмотрим подробнее, что это значит. Префиксы не должны являться подмножеством друг друга. Например, пары «ГК» и «ГКг» или «ЛП» и «ЛПЛ» — это плохой выбор. Пары «ЛП1» и «ЛП2» — хороший выбор.
Проанализируем решение, которое помогло автору вопроса. Для исправления ситуации можно использовать префикс, который гарантированно не будет пересекаться с ошибочным. Например, вместо «ЛП» использовать «ЛПО».
Разберем по шагам, как правильно выполнить переход на новый префикс:
УниверсальныеПодборИОбработкаОбъектов (или аналогичной) массово измените префиксы в существующих документах, которые «сбивают» нумерацию.
ОбновитьНумерациюОбъектов(Метаданные.Документы.ПлатежноеПоручениеИсходящее);
Если бизнес-процессы требуют использования именно тех префиксов, которые конфликтуют, мы можем вмешаться в процесс генерации номера на уровне кода. В модуле объекта документа существует событие ПриУстановкеНовогоНомера. Рассмотрим пример кода, который принудительно задает нужный префикс, игнорируя «соседние» значения:
Процедура ПриУстановкеНовогоНомера(СтандартнаяОбработка, Префикс)
// Укажите логику определения префикса в зависимости от организации
Если Организация.Код = "000000001" Тогда
Префикс = "ЛП-"; // Добавление дефиса делает префикс уникальным
ИначеЕсли Организация.Код = "000000002" Тогда
Префикс = "ЛПЛ-";
КонецЕсли;
// Теперь система будет искать MAX(Номер) LIKE 'ЛП-%'
// и не зацепит 'ЛПЛ-', так как дефис и буква 'Л' — разные символы.
КонецПроцедуры
Использование знака-разделителя (дефиса или подчеркивания) после буквенного префикса — это «золотой стандарт» разработки в 1С. Это практически полностью исключает вероятность того, что один префикс станет началом другого.
Выясним причину, по которой иногда помогает создание нового пользователя. В современных версиях платформы 8.3 реализован механизм кэширования номеров на стороне сервера приложений для повышения производительности. Сервер «забирает» себе диапазон номеров (например, 10 штук) и выдает их пользователям без постоянного обращения к таблицам базы данных SQL.
Если нумерация сбилась, ошибочные номера могут «осесть» в сеансе конкретного пользователя. В этом случае могут помочь следующие действия:
ОбновитьНумерациюОбъектов(), которая должна программно инвалидировать этот кэш.Подводя итог, приведем основные правила, которые помогут вам избежать проблем с «летающей» нумерацией:
ОРГ- всегда лучше, чем просто ОРГ.Проанализировав вышеописанные ситуации, мы видим, что «слетевшая» нумерация — это не случайный сбой, а результат строгой логики работы платформы с данными. Понимая эту логику, вы сможете оперативно восстановить работу пользователей и предотвратить появление подобных ошибок в будущем.