При работе в среде 1С:Предприятие 7.7 пользователи и программисты нередко сталкиваются с ситуацией, когда при создании нового документа система перескакивает через номер (например, вместо ожидаемого номера 154 предлагает сразу 155), а при попытке ввести пропущенный номер вручную выдает ошибку: «Номер не уникальный!». При этом визуальный поиск в журнале показывает, что документа с таким номером нет. Разберем по шагам, почему так происходит, где скрывается «невидимый» документ и как организовать нумерацию так, чтобы исключить появление дыр.
Если в журнале конкретного вида документа номер отсутствует, но система блокирует его ввод, первой и главной причиной является использование общего нумератора. В дереве конфигурации для каждого документа можно настроить собственный счетчик либо назначить объект метаданных «Нумератор». Когда один и тот же нумератор назначен нескольким видам документов (например, «Расходная накладная» и «Акт выполненных работ»), они делят общее пространство номеров.
Проанализируем эту ситуацию: если документ одного вида уже записан под номером 154, то документ другого вида с тем же общим нумератором уже не сможет занять номер 154 в рамках заданного периода уникальности (например, года). Программа выдаст предупреждение о нарушении уникальности, хотя в журнале текущего вида документов номер 154 отсутствует.
Выясним, как проверить и исправить эту настройку:
Нумератор. Если там указан общий нумератор, выясним, какие еще документы к нему привязаны.Важно: отвязка документа от общего нумератора переводит его на собственный счетчик. В системной таблице журнала 1SJOURN поле принадлежности к нумератору очищается, однако для старых документов это может потребовать контроля уникальности задним числом, чтобы избежать пересечения номеров при будущей автонумерации.
Если общий нумератор не используется, но номер 154 все равно определяется как занятый, рассмотрим другие распространенные сценарии:
1SJOURN.DBF) и продолжает проверяться на уникальность. Чтобы освободить номер, необходимо запустить процедуру физического удаления помеченных объектов в монопольном режиме.Разберем механизм автонумерации платформы. Когда пользователь нажимает кнопку создания нового документа или в коде вызывается метод Док.Новый(), платформа определяет максимальный номер в базе на данный момент и резервирует следующий. Если в этот момент два пользователя одновременно открывают новый документ, первый получает номер 154, а второй — 155.
Если второй пользователь сохраняет документ (получая номер 155), а первый закрывает окно без сохранения, номер 154 оказывается навсегда пропущенным. Встроенный автонумератор не возвращается назад для заполнения пустых ячеек, отсчитывая новые значения строго от максимального записанного номера.
Чтобы гарантировать отсутствие пропусков при отказе пользователей от сохранения документов, применяется алгоритм отложенной нумерации. Номер не должен присваиваться при интерактивном открытии формы.
Рассмотрим популярную схему с временным префиксом. При создании документа ему назначается заведомо временный префикс (например, «ВР» или «ЫЫ»), а реальный номер генерируется встроенной функцией УстановитьНовыйНомер() непосредственно в момент сохранения или проведения.
Посмотрим на пример реализации в модуле формы документа:
Процедура ПриОткрытии()
Если Выбран() = 0 Тогда
// При создании нового документа назначаем временный префикс
Префикс = "ВР";
УстановитьНовыйНомер(Префикс);
КонецЕсли;
КонецПроцедуры
Далее перехватываем момент окончательной фиксации документа в процедуре ПриЗаписи():
Процедура ПриЗаписи()
// Проверяем, содержит ли номер временный префикс
Если Найти(СокрЛП(НомерДок), "ВР") > 0 Тогда
// Устанавливаем рабочий префикс базы или организации
РабочийПрефикс = СокрЛП(Константа.ПрефиксБазы);
УстановитьНовыйНомер(РабочийПрефикс);
КонецЕсли;
КонецПроцедуры
Проанализируем этот подход: пока пользователь редактирует документ, в поле номера отображается временное значение, не затрагивающее основную последовательность. Если пользователь отменит ввод, временный номер просто исчезнет без образования бреши в официальной отчетности. При успешной записи метод УстановитьНовыйНомер() мгновенно вычисляет следующий по порядку рабочий номер непосредственно перед сохранением в базу данных.