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

Программист 1С v8.3 (Обычные формы)
← На главную

При работе с системой 1С пользователи и программисты могут столкнуться с неожиданной проблемой: автоматическая нумерация документов 'застревает' на значении, например, 999999999. Это происходит даже после того, как мы увеличили разрядность номера документа в конфигураторе и использовали стандартные методы для обновления нумерации. Давайте подробно разберем, почему возникает такая ситуация и какие существуют способы её решения.

Выясняем корень проблемы: почему нумерация застряла?

Основная причина, по которой нумерация документов в 1С может 'застрять' на максимальном значении, например, 999999999, даже после увеличения разрядности, кроется в способе хранения и сравнения номеров документов. В 1С номера документов хранятся как строки, а не как числа. Это приводит к тому, что сортировка и сравнение происходят посимвольно, а не по числовым правилам. Например, '999999999' может считаться 'большим' числом, чем '1000000000', если сравнение идет посимвольно (первая девятка '9' больше первой единицы '1').

Рассмотрим подробнее факторы, приводящие к проблеме:

  1. Ручное редактирование номеров: Чаще всего сбой нумерации происходит из-за того, что пользователи вручную изменяют автоматически сформированные номера документов. Если пользователь сокращает номер документа (например, с "000001000" до "1000"), система может начать присваивать новые номера, игнорируя ведущие нули, или столкнуться с ошибкой неуникальности, когда номер, соответствующий полной разрядности, уже существует.
  2. Некорректное увеличение разрядности: Когда мы увеличиваем длину номера документа в конфигураторе (например, с 9 до 10 символов), существующие номера не изменяются автоматически. Если до увеличения разрядности максимальным был номер 999999999, а после увеличения мы создаем документ с номером 1000000000, система при поиске следующего номера может выбрать 999999999 как строково максимальный, если в базе есть хоть один документ с таким форматом.
  3. Особенности метода УстановитьНовыйНомер: Этот метод пытается найти максимальный номер в базе для данного типа документа и присвоить следующий. Однако, из-за строкового сравнения, он может ошибочно считать 999999999 самым большим, игнорируя более длинные, но числово большие номера (например, 1000000000).
  4. Проблемы с кэшем нумерации: В некоторых случаях система кэширует последний использованный номер, и этот кэш может не обновиться должным образом после изменения разрядности или ручных корректировок.

Анализируем стандартные методы и их ограничения

В своей попытке решить проблему, вы, вероятно, пробовали использовать стандартные методы 1С. Давайте выясним, почему они не всегда помогают в данном случае.

Метод ОбновитьНумерациюОбъектов()

Мы знаем, что метод ОбновитьНумерациюОбъектов() предназначен для обновления номеров в соответствии с данными, уже записанными в базе. Он должен использоваться администратором системы. Однако для корректной работы этого метода часто требуется предварительно исправить все 'неправильные' номера в документах, либо вручную, либо с помощью обработки. После его вызова все выданные, но не записанные номера становятся недействительными. В данном случае, даже если мы вызываем его как:


ОбновитьНумерациюОбъектов(Документы.УстановкаМаршрутов.СоздатьДокумент.Метаданные);

или даже так:

ОбновитьНумерациюОбъектов(Метаданные.Документы.УстановкаМаршрутов);

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

Метод УстановитьНовыйНомер

Аналогично, при создании нового документа и вызове метода УстановитьНовыйНомер:


Док = Документы.УстановкаМаршрутов.СоздатьДокумент;
Док.Дата = ТекущаяДата;
Док.УстановитьНовыйНомер;

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

Решения и обходные пути

Теперь, когда мы понимаем причины, давайте рассмотрим различные подходы к решению проблемы.

1. Ручная корректировка "проблемного" максимального номера

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

Порядок действий:

  1. В режиме предприятия, используя поиск или стандартные отчеты, найдите все документы типа "УстановкаМаршрутов" с номером 999999999.
  2. Для найденного документа измените его номер вручную на, например, 0999999999 или А999999999, или 1000000000. Важно, чтобы новый номер был уникальным и по строковому представлению был "больше" всех девяток.
  3. После изменения попробуйте создать новый документ и вызвать УстановитьНовыйНомер.

Мы выяснили, что даже добавление '0' в начале (например, 0999999999) может не помочь, если система по-прежнему считает 999999999 максимальным. В этом случае, если мы вручную создаем документ с номером 1000000000, он может оказаться в начале списка при сортировке, но 1С все равно будет предлагать 999999999 для новых документов. Это подтверждает проблему строкового сравнения.

2. Использование буквенных префиксов для разделения нумерации

Это быстрый и эффективный способ "обмануть" систему и начать новую нумерацию, не меняя старые номера.

Порядок действий:

  1. Создайте новый документ.
  2. Вручную присвойте ему номер с буквенным префиксом, например, А0000000001. Этот номер, будучи строкой, будет считаться "больше" любого числового номера из девяток (например, 999999999).
  3. Система, ища следующий номер, увидит А0000000001 как максимальный и начнет присваивать номера А0000000002, А0000000003 и так далее.

Дополнительно:

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

3. Реализация собственной функции определения следующего номера (временное решение)

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

Пример кода из обсуждения:


Функция ОпределитьСледующийНомер()

    Запрос = Новый Запрос;
    Запрос.Текст = "ВЫБРАТЬ
    | УстановкаМаршрутов.Номер КАК Номер
    |ИЗ
    | Документ.УстановкаМаршрутов КАК УстановкаМаршрутов
    |ГДЕ
    | УстановкаМаршрутов.Дата > &Дата" ;
    Запрос.УстановитьПараметр("Дата", НачалоДня(ТекущаяДата - 3 * 24 * 3600)); // Ищем номера за последние 3 дня

    макс = 0;
    Выборка = Запрос.Выполнить().Выбрать();
    Пока Выборка.Следующий Цикл
        Попытка
            Ном = Число(Выборка.Номер); // Пытаемся преобразовать номер в число
        Исключение
            Продолжить; // Если не число, пропускаем
        КонецПопытки;

        Если Ном > Макс Тогда
            Макс = Ном;
        КонецЕсли;
    КонецЦикла;

    ном = макс + 1;
    _ном = СтрЗаменить(Строка(ном),Символы.НПП,""); // Удаляем неразрывный пробел, если есть
    Возврат _ном;

КонецФункции

Как работает этот код:

  1. Запрос выбирает номера документов "УстановкаМаршрутов" за определенный период (в данном случае, за последние 3 дня, чтобы ограничить объем данных и ускорить работу).
  2. В цикле мы пытаемся преобразовать каждый номер в число с помощью функции Число(). Это позволяет корректно сравнивать номера как числа, а не как строки.
  3. Если преобразование не удалось (например, номер содержит буквы), мы пропускаем такой номер.
  4. Находим максимальное числовое значение среди всех корректных номеров.
  5. Следующий номер рассчитывается как Макс + 1.
  6. Из результата удаляются неразрывные пробелы, если они появились при преобразовании числа в строку.

Применение: Эту функцию можно вызывать в обработчике события ПриУстановкеНовогоНомера документа или перед записью нового документа. Это решение является временным и должно быть интегрировано в конфигурацию или использоваться через внешнюю обработку.

4. Создание нового регистра сведений для собственной нумерации

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

Порядок действий:

  1. В конфигураторе создаем новый регистр сведений, например, "НумерацияДокументов".
  2. В этом регистре создаем измерения (например, "ВидДокумента" типа "Метаданные.Документы") и ресурсы (например, "ТекущийНомер" типа "Число" или "Строка").
  3. В обработчике события ПриУстановкеНовогоНомера для нужного документа или в отдельной функции мы будем получать текущий номер из этого регистра, увеличивать его и записывать обратно.
  4. Это позволяет полностью контролировать логику нумерации, хранить номера как числа (если это требуется для сравнения) и избежать проблем со строковым сравнением.

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

5. Полная перенумерация документов с помощью обработки

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

Порядок действий:

  1. Обязательно сделайте резервную копию базы данных! Это критически важно перед массовыми изменениями.
  2. Напишите собственную обработку или используйте типовую "Групповое изменение реквизитов" (если она позволяет изменять номера, что не всегда так).
  3. В обработке пройдитесь по всем документам нужного типа. Для каждого документа можно:
    1. Присвоить новый номер, добавляя ведущие нули, чтобы привести его к новой разрядности (например, 1 превратить в 0000000001).
    2. Присвоить новый номер последовательно, начиная с 1 (или другого значения), если старые номера не имеют значения.
  4. После перенумерации всех документов, вызовите ОбновитьНумерациюОбъектов() для данного типа документа.
  5. Рекомендуется также запретить ручное редактирование номеров для пользователей, чтобы предотвратить повторение проблемы.

Влияние на производительность: Перенумерация большого количества документов в объемной базе может быть ресурсоемкой операцией и значительно повлиять на работу предприятия. Это может потребовать длительного простоя базы.

Важные аспекты и дополнительные рекомендации

При решении проблем с нумерацией всегда полезно учитывать следующие моменты:

  1. Увеличение длины номера документа: Изменение длины номера документа выполняется через Конфигуратор и требует обращения к программисту 1С. При этом важно понимать, что типовые конфигурации 1С могут резервировать часть символов номера под служебные префиксы (например, 2 символа для префикса организации, 2 для префикса узла обмена, плюс разделитель), что уменьшает количество доступных символов для самого порядкового номера. Всегда проводите такие изменения в тестовой копии.
  2. Контроль уникальности номера: В настройках нумерации документа в конфигураторе можно установить флаг "Контроль уникальности", который будет проверять номер на уникальность в пределах заданного периода (например, года или месяца). Это поможет предотвратить дублирование номеров, но не решит проблему с порядком, если числа сравниваются как строки.
  3. Периодичность нумерации: В 1С можно настроить периодичность нумерации (например, по году, месяцу, дню или без ограничения). Это определяет, в каких пределах контролируется уникальность номеров и когда нумерация начинается заново. Если нумерация периодическая, то проблема 'застревания' может быть менее критичной, так как с началом нового периода она обычно сбрасывается.
  4. "Нумераторы" как объекты метаданных: В некоторых конфигурациях 1С существуют объекты "Нумератор", которые задают порядок нумерации документов. Они привязываются к одному или нескольким видам документов и имеют гибкие настройки формата номера, включая периодичность и тип номера (строка или число). В случае, если номер должен включать буквы или разделительные символы, используется строковый тип номера. Проверьте настройки нумератора, если он используется в вашей конфигурации.
  5. Тестирование в копии базы: Любые изменения, связанные с нумерацией или структурой данных, мы должны выполнять и тестировать исключительно на копии рабочей базы данных. Это позволит избежать непредвиденных проблем и потерь данных в 'живой' системе.
  6. Остановка работы предприятия: Некоторые из предложенных решений, такие как полная перенумерация или создание новых регистров, могут потребовать вывода всех пользователей из системы на длительное время. Мы должны заранее спланировать такие операции и уведомить пользователей.

Таким образом, для решения проблемы со 'сбросом нумерации', когда она 'застряла' на 999999999, нам необходимо комплексно подходить к вопросу, учитывая настройки конфигурации, принципы работы автонумерации в 1С (особенно строковое хранение номеров), а также возможные причины сбоев, связанные с действиями пользователей или обменом данными.

← На главную