При автоматизации бизнес-процессов в 1С:Предприятие, особенно в таких гибких конфигурациях, как Управление торговлей 11 (УТ 11), часто возникает задача программного создания документов. Одной из специфических проблем является необходимость продолжить нумерацию документа, учитывая нестандартный префикс (например, зависящий от склада, конкретного подразделения или типа операции), который пользователи ранее вводили вручную.
В этой статье мы подробно разберем, как правильно реализовать инкремент (увеличение на единицу) номера документа, сохраняя префикс и правильное количество лидирующих нулей. Мы рассмотрим как "ручной" метод манипуляции со строками, так и более правильный, "платформенный" подход.
Разберем ситуацию: пользователям нужно, чтобы для разных складов документы ПересчетТоваров имели разные префиксы (например, "ПК-" для первого склада и "УТ-" для второго). Многие разработчики пытаются "изобрести велосипед", вычисляя последний номер запросом и прибавляя единицу вручную. Однако платформа 1С уже имеет встроенный механизм для решения этой задачи.
Рассмотрим использование метода УстановитьНовыйНомер(). Если в параметрах этого метода передать желаемый префикс, система сама проанализирует существующие записи в базе данных, найдет максимальный номер с этим префиксом и присвоит новому объекту следующий по порядку номер.
Пример программного кода:
НовыйДокумент = Документы.ПересчетТоваров.СоздатьДокумент();
// Заполняем необходимые реквизиты, например, организацию и склад
НовыйДокумент.Организация = Справочники.Организации.НайтиПоНаименованию("Наша Организация");
НовыйДокумент.Дата = ТекущаяДата();
// Устанавливаем номер с нужным префиксом
// Платформа сама найдет последний номер, начинающийся на "ПК-", и увеличит его
НовыйДокумент.УстановитьНовыйНомер("ПК-");
НовыйДокумент.Записать();
Важное замечание: Чтобы этот метод работал корректно, длина всех номеров в базе с данным префиксом должна быть единообразной. Если в базе уже есть "кривые" номера (например, разной длины), автонумерация может работать непредсказуемо. В таких случаях может потребоваться использование обработки "Обновление нумерации объектов".
Иногда возникают задачи, когда нам нужно получить номер именно как строку, модифицировать его и только потом подставить в документ (или использовать для других целей). Основная сложность здесь заключается в том, что при преобразовании строковой части номера "00000002" в число 2 и прибавлении единицы, мы получаем число 3, теряя при этом лидирующие нули.
Проанализируем ситуацию, как правильно "разрезать" номер и собрать его обратно. Для этого нам понадобится функция Формат.
Разберем алгоритм по шагам:
Число и увеличиваем на 1.Пример реализации "ручного" инкремента:
// Предположим, у нас есть последний номер "ПК-000000008"
СтарыйНомер = "ПК-000000008";
ДлинаНомера = СтрДлина(СтарыйНомер);
// Определяем, где заканчивается префикс (ищем первую цифру с конца)
Сч = ДлинаНомера;
Пока Сч > 0 Цикл
Если СтрНайти("0123456789", Сред(СтарыйНомер, Сч, 1)) = 0 Тогда
Прервать; // Мы нашли границу префикса
КонецЕсли;
Сч = Сч - 1;
КонецЦикла;
Префикс = Лев(СтарыйНомер, Сч);
СтроковаяЧастьНомера = Сред(СтарыйНомер, Сч + 1);
ДлинаЧисловойЧасти = СтрДлина(СтроковаяЧастьНомера);
// Увеличиваем число на единицу
НовоеЧисло = Число(СтроковаяЧастьНомера) + 1;
// Форматируем обратно с сохранением нулей
// Параметр ЧВН= отвечает за вывод лидирующих нулей
// Параметр ЧГ=0 убирает группировку разрядов (чтобы не было пробелов в номере)
ФорматнаяСтрока = "ЧЦ=" + Строка(ДлинаЧисловойЧасти) + "; ЧВН=; ЧГ=0";
НовыйНомер = Префикс + Формат(НовоеЧисло, ФорматнаяСтрока);
Сообщить(НовыйНомер); // Результат: ПК-000000009
Выясним причину, по которой многие начинающие разработчики сталкиваются с трудностями при работе с номерами. В 1С тип Число не хранит информацию о визуальном представлении (количестве нулей слева). Поэтому при сложении Число("001") + 1 система всегда вернет 2.
Чтобы превратить 2 обратно в "002", мы используем конструкцию Формат(Значение, "ЧВН=").
Параметр ЧВН= (Число Выводить Нули) является ключевым. Если мы не укажем длину через ЧЦ (Число Целых), система может использовать настройки по умолчанию, поэтому всегда рекомендуется явно вычислять СтрДлина исходной числовой части.
Рассмотрим архитектурные особенности УТ 11. Данная конфигурация построена на базе БСП (Библиотеки стандартных подсистем). Это значит, что механизмы формирования префиксов там сильно автоматизированы.
Проанализируем, как система формирует итоговый номер. Обычно он состоит из:
Если вы создаете документы программно, лучшим местом для переопределения логики нумерации будет подписка на событие ПриУстановкеНовогоНомера или одноименная процедура в модуле объекта документа.
Рассмотрим пример в модуле объекта:
Процедура ПриУстановкеНовогоНомера(СтандартнаяОбработка, Префикс)
// Если документ создается для определенного склада, меняем префикс
Если ЗначениеЗаполнено(Склад) И Склад.Наименование = "Склад электроники" Тогда
Префикс = "СЭ-" + Префикс; // Добавляем свой префикс к стандартному
КонецЕсли;
КонецПроцедуры
Использование этого события гарантирует, что ваш номер будет уникальным, так как платформа вызывает этот код непосредственно перед записью документа в транзакции. Это предотвращает ситуацию, когда два пользователя одновременно получают один и тот же "последний" номер из базы.
Посмотрим на ошибки, которые могут привести к сбою нумерации во всей системе:
УстановитьНовыйНомер будет постоянно выдавать ошибки уникальности.Подводя итог: для большинства задач в УТ 11 идеально подходит метод объект.УстановитьНовыйНомер(НужныйПрефикс). Если же вам требуется именно строковая манипуляция, всегда используйте функцию Формат с параметрами ЧВН= и ЧГ=0 для сохранения структуры номера.