Как добавить суффикс к номеру документа в 1С и сохранить правильную нумерацию?

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

В практике разработки на платформе 1С часто возникает задача модификации стандартного номера документа. Одной из специфических задач является добавление постоянного суффикса (часто называемого «префиксом в конце») к номеру, например, чтобы номер выглядел как 00999/401. Основная сложность здесь заключается в том, что стандартный механизм автоинкремента 1С при наличии нецифровых символов в конце строки перестает корректно определять числовую часть, что приводит к сбоям в последовательности (например, вместо 01000/401 система может выдать 0001000/4).

В рамках данной статьи мы разберем, как правильно реализовать собственную нумерацию, проанализируем алгоритмы разбора строки и рассмотрим программные способы решения проблемы.

Алгоритм реализации нестандартной нумерации

Для того чтобы система корректно инкрементировала номер, содержащий суффикс, нам необходимо временно «отделить» мух от котлет: выделить числовую часть, увеличить её и собрать номер обратно. Рассмотрим пошаговый алгоритм, который поможет избежать типичных ошибок:

  1. Получение последнего номера: Сначала необходимо найти в базе данных документ с самым большим номером за текущий период (год).
  2. Отсечение суффикса: Из полученной строки номера нужно удалить постоянную часть (в нашем примере это /401).
  3. Преобразование в число: Оставшуюся строковую часть (например, 00999) необходимо преобразовать в числовой тип данных для выполнения арифметической операции.
  4. Инкремент: Прибавляем к полученному числу единицу.
  5. Форматирование и сборка: Преобразуем число обратно в строку, возвращая лидирующие нули, чтобы сохранить общую длину номера, и добавляем суффикс в конец.

Программная реализация поиска и формирования номера

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


Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1
               |    СчетФактураВыданный.Номер КАК Номер
               |ИЗ
               |    Документ.СчетФактураВыданный КАК СчетФактураВыданный
               |ГДЕ
               |    СчетФактураВыданный.Дата МЕЖДУ &ДатаНач И &ДатаКон
               |    И СчетФактураВыданный.Номер ПОДОБНО ""%/401""
               |УПОРАДОЧИТЬ ПО
               |    Номер УБЫВ";

Запрос.УстановитьПараметр("ДатаНач", НачалоГода(Дата));
Запрос.УстановитьПараметр("ДатаКон", КонецГода(Дата));

Рез = Запрос.Выполнить();
ПрефиксКонце = "/401";

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

Важный момент: обратите внимание на параметр ЧЦ=5 в функции Формат. Если вы укажете слишком большое значение (например, ЧЦ=7), как в первоначальном варианте автора, система добавит лишние нули в начало, что может привести к обрезанию суффикса, если общая длина номера ограничена длиной реквизита в метаданных.

Использование сложных запросов для извлечения номера

Иногда требуется найти максимальный номер прямо в запросе, учитывая, что числовая часть может находиться внутри строки. Хотя 1С не поддерживает регулярные выражения в запросах, можно использовать конструкцию ПОДСТРОКА и логические условия. Рассмотрим пример (пусть и несколько громоздкий), который иллюстрирует принцип выделения значащих символов:


// Пример логики выделения символов для поиска максимума
// (фрагмент запроса)
"ВЫБРАТЬ
|    ПОДСТРОКА(ВтНомера.РегистрационныйНомер, 1, 1) КАК Симв1,
|    ПОДСТРОКА(ВтНомера.РегистрационныйНомер, 2, 1) КАК Симв2,
|    ...
|ПОМЕСТИТЬ ВтСимволы
|ИЗ
|    ВтНомера КАК ВтНомера"

Рекомендация: На практике такие сложные запросы с вложенными ВЫБОР КОГДА для каждого символа используются крайне редко из-за низкой производительности. Гораздо эффективнее использовать стандартную сортировку по строковому номеру УПОРЯДОЧИТЬ ПО Номер УБЫВ, предварительно убедившись, что все номера имеют одинаковую длину и лидирующие нули.

Рекомендации по работе с нумерацией

Рассмотрим несколько советов, которые помогут сделать вашу систему нумерации более надежной:

Заключение

Реализация номера с суффиксом в конце требует внимательного отношения к типам данных и функциям форматирования. Основная ошибка разработчиков — игнорирование лидирующих нулей или неправильный расчет длины строки. Используя функции Лев(), Число() и Формат() с корректными параметрами ЧЦ и ЧВН, вы сможете построить надежную систему нумерации, которая не «сломается» при переходе через десятичный разряд (например, с 999 на 1000).

← На главную