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