Как программно изменить номера документов в 1С и избежать типичных ошибок при перенумерации

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При написании обработок для изменения нумерации документов начинающие разработчики часто сталкиваются со странным поведением платформы: вместо ожидаемого увеличения номера на единицу (например, из УТ-01333 получить УТ-01334) программа просто дописывает единицу в конец строки, превращая её в УТ-013331. Кроме того, часто измененные на форме номера никак не сохраняются в самой базе данных.

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

Выясняем причину: почему «УТ-01333» + 1 превращается в «УТ-013331»?

Основная ошибка кроется в фундаментальном понимании типов данных. Реквизит Номер у любого документа в системе 1С:Предприятие имеет тип Строка. Это сделано для того, чтобы система могла поддерживать сложные префиксы организаций, касс, складов или информационных баз (например, МСК-000125 или УТ-000001).

Когда мы пытаемся выполнить выражение вида Стр.Номер = Номер + 1, где переменная Номер является строкой (например, полученной из поля ввода на форме), платформа 1С выполняет не арифметическое сложение, а конкатенацию (склеивание строк). При этом число 1 автоматически и неявно приводится к строковому типу. В результате получается склеенная строка.

Для корректного изменения номера нам необходимо разделять префиксную (буквенную) и числовую части, увеличивать числовую часть математически, а затем собирать номер обратно в строку, сохраняя при этом исходную длину и лидирующие нули.

Критическая ошибка автора: отсутствие физической записи в базу данных

Даже если мы напишем идеальный алгоритм преобразования строки, код автора из сообщения форума по-прежнему не изменит номера документов в самой системе. Автор производит цикл по табличной части обработки:


Для Каждого Стр Из Объект.Результат Цикл
    Стр.Номер = Номер + 1; // Изменение происходит только в оперативной памяти формы!
КонецЦикла;

Этот код меняет значения только внутри временной таблицы на форме обработки (в реквизите Объект.Результат). Чтобы изменения зафиксировались в базе данных 1С, необходимо для каждой строки таблицы получить реальный объект документа, присвоить ему новое значение номера и принудительно вызвать метод записи.

Давайте посмотрим на правильный шаблон обхода документов:


Для Каждого Стр Из Объект.Результат Цикл
    // Получаем реальный объект документа из ссылки для редактирования
    ДокОбъект = Стр.Ссылка.ПолучитьОбъект();
    
    // Рассчитываем новый номер (различные варианты рассмотрим ниже)
    НовыйНомер = "УТ-01334"; 
    
    ДокОбъект.Номер = НовыйНомер;
    
    // Записываем изменения в базу данных в режиме записи (без перепроведения)
    ДокОбъект.Записать(РежимЗаписиДокумента.Запись); 
КонецЦикла;

Использование режима РежимЗаписиДокумента.Запись критически важно: это позволяет просто перезаписать реквизит номера, не запуская тяжелые механизмы проведения документа и не меняя движения по регистрам учета.

---

Способ 1. Использование встроенного платформенного метода (Самый простой и безопасный)

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

Разберем готовый код этого решения:


Для Каждого Стр Из Объект.Результат Цикл
    ДокОбъект = Стр.Ссылка.ПолучитьОбъект();
    
    // Передаем в метод префикс организации или базы данных
    // Платформа сама рассчитает следующий свободный номер, например, "УТ-00001334"
    ДокОбъект.УстановитьНовыйНомер("УТ-");
    
    ДокОбъект.Записать(РежимЗаписиДокумента.Запись);
КонецЦикла;

Этот способ минимизирует вероятность ошибок уникальности номера, так как платформа сама контролирует процесс генерации.

---

Способ 2. Ручное формирование номера с лидирующими нулями

Если перед нами стоит задача жестко задать начальный номер (например, начать строго с номера УТ-01333 и далее увеличивать его по порядку на единицу в рамках цикла), нам придется формировать строку номера самостоятельно.

При этом важно помнить про лидирующие нули. Если мы просто сложим префикс и число (например, "УТ-" + 1333), мы получим номер УТ-1333. Из-за уменьшения длины номера (разрядности) в будущем автонумерация 1С может сбиться. Поэтому мы обязаны использовать функцию Формат() для выравнивания числовой части.

Разберем по шагам, как это реализовать:


Префикс = "УТ-";
ТекущийСчетчик = 1333; // Начальное число, которое мы указали в поле ввода на форме

Для Каждого Стр Из Объект.Результат Цикл
    ДокОбъект = Стр.Ссылка.ПолучитьОбъект();
    
    // Преобразуем число в строку фиксированной длины с лидирующими нулями
    // Параметры форматирования:
    // ЧЦ=5 — общая длина числовой части номера (5 символов)
    // ЧВН= — указывает платформе выводить лидирующие (левые) нули
    // ЧГ=0 — отключает группировку разрядов пробелами (чтобы не получилось "01 333")
    СтрокаЧисла = Формат(ТекущийСчетчик, "ЧЦ=5; ЧВН=; ЧГ=0"); 
    
    // Собираем готовый номер: префикс + отформатированное число
    ДокОбъект.Номер = Префикс + СтрокаЧисла; 
    
    // Фиксируем изменения в информационной базе
    ДокОбъект.Записать(РежимЗаписиДокумента.Запись);
    
    // Увеличиваем счетчик для следующего по порядку документа
    ТекущийСчетчик = ТекущийСчетчик + 1; 
КонецЦикла;

---

Способ 3. Использование функций БСП (для конфигураций на управляемых формах)

Если вы работаете в современных типовых конфигурациях (таких как Управление торговлей 11, Бухгалтерия предприятия 3.0, ERP или Комплексная автоматизация), в них интегрирована Библиотека Стандартных Подсистем (БСП). В составе БСП есть удобные готовые программные интерфейсы для работы со строками номеров документов.

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

---

Критически важный шаг: Обновление кэша нумерации объектов в 1С

Многие программисты, выполнив программное перенумерование документов, сталкиваются со следующей проблемой: при попытке пользователя создать новый документ вручную, система выдает ошибку «Значение поля "Номер" не уникально» или подставляет старый, уже неактуальный номер.

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

Чтобы решить эту проблему, в самом конце нашей обработки (сразу после завершения цикла записи документов) обязательно нужно выполнить принудительный сброс и обновление кэша для нашего типа метаданных. Делается это с помощью встроенного метода:


// Очищаем кэш номеров для документов "Поступление товаров и услуг"
ОбновитьНумерациюОбъектов(Метаданные.Документы.ПоступлениеТоваровУслуг);

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

---

Альтернатива: Использование готовых инструментов без написания кода

Поскольку автор темы упомянул, что он не является профессиональным программистом 1С, для него может быть безопаснее воспользоваться стандартными инструментами, которые уже встроены в программу или доступны бесплатно.

  1. Групповое изменение реквизитов: Это встроенная обработка, доступная администраторам во всех типовых решениях (раздел НСИ и администрирование -> Обслуживание -> Корректировка данных). С ее помощью можно отобрать документы за определенный период и массово изменить им префиксы или номера.
  2. Универсальный подбор и обработка объектов: Внешняя обработка, которую можно скачать на профильных форумах. Она позволяет гибко настраивать формулы для перенумерации документов без необходимости вручную писать код в конфигураторе.

Важное предупреждение: Перед запуском любых обработок, изменяющих номера документов в работающей базе данных, обязательно сделайте резервную копию вашей информационной базы!

← На главную