Как восстановить автонумерацию документов в 1С, если она сбилась из-за ручного ввода?

Программист 1С v8.3 (Управляемые формы) 1С:Управление нашей фирмой Управленческий учет
← На главную

Проблема нарушения автоматической нумерации — это классическая ситуация, с которой сталкивается практически каждый администратор или разработчик 1С. Суть проблемы заключается в механизме платформы, который при создании нового документа ищет максимальное строковое значение номера в базе данных за текущий период и прибавляет к нему единицу. Если пользователь вручную ввел номер, начинающийся на букву, которая в алфавите стоит позже текущего префикса (например, «ЮКС» вместо «УУ»), система начнет отсчитывать новые номера от этого «неправильного» значения.

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

Почему стандартные методы не всегда помогают?

Разберем ситуацию: в базе есть документы с номерами УУ-001, УУ-002. Пользователь ошибочно вводит ЮКС/0245. Поскольку буква «Ю» в таблице кодировки находится значительно дальше буквы «У», платформа при попытке создать новый документ выполнит поиск максимума и обнаружит, что ЮКС/0245 больше любого номера, начинающегося на УУ. В итоге следующий документ получит номер ЮКС/0246.

Использование функции ОбновитьНумерациюОбъектов() в данном случае не дает результата, так как эта функция лишь обновляет кэш номеров в оперативной памяти сервера, но не игнорирует реально существующий «большой» номер в таблице базы данных. Чтобы исправить ситуацию, нам нужно «обмануть» алгоритм поиска максимума.

Способ 1: Использование лидирующего пробела (Визуальный хак)

Проанализируем работу строковой сортировки. Символ пробела в таблице символов Unicode (и ASCII) стоит значительно раньше любых букв и цифр. Если мы добавим пробел в начало «неправильного» номера, для платформы этот номер станет «меньше» номеров, начинающихся с УУ.

  1. Найдем все документы, которые сбивают нумерацию (в нашем примере — те, что начинаются на ЮКС).
  2. Программно или вручную добавим в начало их номера символ пробела: было ЮКС/0245, стало ЮКС/0245.
  3. Поскольку в большинстве печатных форм 1С используется функция СокрЛП() (TrimAll) при выводе номера, этот пробел исчезнет при печати и не будет виден пользователю.

Рассмотрим пример кода для обработки таких документов:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   МойДокумент.Ссылка КАК Ссылка,
    |   МойДокумент.Номер КАК Номер
    |ИЗ
    |   Документ.МойДокумент КАК МойДокумент
    |ГДЕ
    |   МойДокумент.Номер ПОДОБНО ""ЮКС%""";

Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();

Пока Выборка.Следующий() Цикл
    ОбъектДок = Выборка.Ссылка.ПолучитьОбъект();
    ОбъектДок.Номер = " " + СокрЛП(Выборка.Номер);
    ОбъектДок.ОбменДанными.Загрузка = Истина; // Чтобы не срабатывали проверки
    ОбъектДок.Записать();
КонецЦикла;

После выполнения этой операции выполним метод ОбновитьНумерациюОбъектов(Метаданные.Документы.МойДокумент), и система снова начнет предлагать номера из серии УУ, так как они теперь являются «максимальными».

Способ 2: Использование невидимых символов (Zero Width Space)

Если лидирующий пробел все же мешает (например, в списках документов виден небольшой отступ), можно использовать специальный символ U+200B (невидимый пробел с нулевой шириной). Проанализируем этот вариант: этот символ вообще не занимает места на экране и в печатной форме, но для базы данных это полноценный символ, который меняет результат сортировки.

Однако стоит учитывать, что не все шрифты и внешние системы корректно обрабатывают Unicode-символы нулевой ширины, поэтому обычный пробел считается более надежным и «проверенным» средством.

Способ 3: Программная установка префикса

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

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


Процедура ПриУстановкеНовогоНомера(СтандартнаяОбработка, Префикс)
    // Явно задаем префикс, который нам нужен
    Префикс = "УУ-";
    
    // Платформа теперь будет искать максимальный номер 
    // только среди тех, что начинаются на "УУ-"
КонецПроцедуры

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

Способ 4: Очистка серверного кэша и принудительное обновление

Иногда после исправления номеров (удаления или добавления пробелов) система продолжает выдавать старую последовательность. Выясним причину: это происходит из-за кэширования номеров на стороне сервера приложений 1С (rphost). Чтобы гарантированно сбросить счетчик, выполним следующие шаги:

  1. Убедимся, что все «неправильные» номера исправлены (пробелом или удалением).
  2. Запустим обработку с кодом: ОбновитьНумерациюОбъектов(Метаданные.Документы.ИмяВашегоДокумента);
  3. Если это не помогло, попробуем временно изменить длину номера в конфигураторе (например, с 13 до 14 символов), сохранить конфигурацию БД, а затем вернуть длину обратно. Это заставляет платформу полностью переиндексировать поле Номер.
  4. В крайнем случае поможет перезапуск службы 1С:Предприятия (кластера серверов), что полностью очистит все оперативные кэши нумерации.

Рекомендации по предотвращению проблемы

Чтобы ситуация не повторилась, проанализируем возможные административные меры:

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

← На главную