При добавлении нового элемента в справочник (например, Номенклатура) платформа 1С может неожиданно начать присваивать кодам непредусмотренный префикс — например, русскую букву «И» или любой другой символ, даже если ранее использовалась сплошная числовая нумерация. Разберем механику возникновения этой ошибки, выясним, почему стандартное удаление префиксов не всегда помогает сразу, и рассмотрим пошаговые способы восстановления правильной последовательности кодов.
Проанализируем базовый механизм автонумерации платформы. Когда вызывается метод УстановитьНовыйКод(), платформа определяет следующий номер на основе существующих записей в таблице базы данных. Выделение числовой части происходит справа налево: последовательность цифр с правого края воспринимается как числовой номер, а всё, что находится левее, интерпретируется как префикс.
При сортировке строковых кодов используется лексикографический порядок. В кодировке символов любая буква (включая «И») располагается старше цифр от 0 до 9. Если в информационной базе хотя бы один раз появился элемент, чей код начинается с буквы, платформа считает этот код наибольшим и начинает генерировать все последующие значения с тем же префиксом.
При этом удаление ошибочного элемента или исправление его кода в режиме «1С:Предприятие» не всегда сразу возвращает прежнюю нумерацию. Рассмотрим основные факторы, влияющие на это:
ПриУстановкеНовогоКода модуля объекта или соответствующие подписки на события, а также могут считываться из кодов предопределенного узла плана обмена ЭтотУзел либо констант префикса базы.Посмотрим на пример программного воспроизведения проблемы, который часто используется разработчиками для проверки:
тмц = Справочники.Номенклатура.СоздатьЭлемент();
// До вызова метода код остается пустым
тмц.УстановитьНовыйКод();
// После вызова генерируется код со сбившимся префиксом
Сообщить("Сгенерированный код: " + тмц.Код);
Разберем самый быстрый и правильный программный способ восстановления последовательности номеров без перезагрузки всей системы. Для принудительного обновления внутреннего кэша платформы предназначен метод глобального контекста ОбновитьНумерациюОбъектов().
Этот метод заставляет сервер перечитать максимальные номера непосредственно из таблиц базы данных. Выполнять его должен пользователь с административными правами. Посмотрим на пример кода обработки:
// Сброс нумерации для конкретного справочника
МетаданныеОбъекта = Метаданные.Справочники.Номенклатура;
ОбновитьНумерациюОбъектов(МетаданныеОбъекта);
// Или сброс нумерации для массива метаданных
МассивМетаданных = Новый Массив;
МассивМетаданных.Добавить(Метаданные.Справочники.Номенклатура);
ОбновитьНумерациюОбъектов(МассивМетаданных);
Если вызвать метод без параметров, нумерация обновится для всех объектов конфигурации сразу:
ОбновитьНумерациюОбъектов();
Важно: Перед вызовом этого метода необходимо убедиться, что все элементы с некорректным префиксом уже исправлены или физически удалены из базы, иначе платформа снова выберет их в качестве максимального значения.
Разберем по шагам, как найти источник проблемы, если визуально в списке справочника «кривой» код не виден:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка,
| Номенклатура.Код,
| Номенклатура.ПометкаУдаления
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Код ПОДОБНО ""И%""";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Сообщить("Найден объект: " + Строка(Выборка.Ссылка) + " с кодом " + Выборка.Код);
КонецЦикла;
ОбновитьНумерациюОбъектов(), описанный выше.Проанализируем ситуацию, когда все коды в базе исправлены, но метод автонумерации все равно выдает старый префикс. Это указывает на то, что информация застряла в оперативной памяти процессов сервера 1С.
В этом случае помогают административные действия: