В практике разработки на платформе 1С часто возникает задача модификации стандартного номера документа. Одной из специфических задач является добавление постоянного суффикса (часто называемого «префиксом в конце») к номеру, например, чтобы номер выглядел как 00999/401. Основная сложность здесь заключается в том, что стандартный механизм автоинкремента 1С при наличии нецифровых символов в конце строки перестает корректно определять числовую часть, что приводит к сбоям в последовательности (например, вместо 01000/401 система может выдать 0001000/4).
В рамках данной статьи мы разберем, как правильно реализовать собственную нумерацию, проанализируем алгоритмы разбора строки и рассмотрим программные способы решения проблемы.
Для того чтобы система корректно инкрементировала номер, содержащий суффикс, нам необходимо временно «отделить» мух от котлет: выделить числовую часть, увеличить её и собрать номер обратно. Рассмотрим пошаговый алгоритм, который поможет избежать типичных ошибок:
/401).00999) необходимо преобразовать в числовой тип данных для выполнения арифметической операции.Рассмотрим код, который позволяет найти последний номер в справочнике или документе и сформировать следующий. Проанализируем пример, предложенный автором темы, с учетом необходимых правок.
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1
| СчетФактураВыданный.Номер КАК Номер
|ИЗ
| Документ.СчетФактураВыданный КАК СчетФактураВыданный
|ГДЕ
| СчетФактураВыданный.Дата МЕЖДУ &ДатаНач И &ДатаКон
| И СчетФактураВыданный.Номер ПОДОБНО ""%/401""
|УПОРАДОЧИТЬ ПО
| Номер УБЫВ";
Запрос.УстановитьПараметр("ДатаНач", НачалоГода(Дата));
Запрос.УстановитьПараметр("ДатаКон", КонецГода(Дата));
Рез = Запрос.Выполнить();
ПрефиксКонце = "/401";
Если Рез.Пустой() Тогда
// Если документов еще нет, создаем первый номер
НовыйНомер = "00001" + ПрефиксКонце;
Иначе
Выборка = Рез.Выбрать();
Выборка.Следующий();
// Извлекаем первые 5 символов, которые являются числом
ЧисловаяЧасть = Лев(Выборка.Номер, 5);
ПоследнийНомерЧислом = Число(ЧисловаяЧасть);
// Формируем новую строку с лидирующими нулями
// Используем форматную строку: ЧЦ (Число цифр) и ЧВН (Выводить нули)
ТекНомерСтрокой = Формат((ПоследнийНомерЧислом + 1), "ЧЦ=5; ЧВН=; ЧГ=0");
НовыйНомер = ТекНомерСтрокой + ПрефиксКонце;
КонецЕсли;
Важный момент: обратите внимание на параметр ЧЦ=5 в функции Формат. Если вы укажете слишком большое значение (например, ЧЦ=7), как в первоначальном варианте автора, система добавит лишние нули в начало, что может привести к обрезанию суффикса, если общая длина номера ограничена длиной реквизита в метаданных.
Иногда требуется найти максимальный номер прямо в запросе, учитывая, что числовая часть может находиться внутри строки. Хотя 1С не поддерживает регулярные выражения в запросах, можно использовать конструкцию ПОДСТРОКА и логические условия. Рассмотрим пример (пусть и несколько громоздкий), который иллюстрирует принцип выделения значащих символов:
// Пример логики выделения символов для поиска максимума
// (фрагмент запроса)
"ВЫБРАТЬ
| ПОДСТРОКА(ВтНомера.РегистрационныйНомер, 1, 1) КАК Симв1,
| ПОДСТРОКА(ВтНомера.РегистрационныйНомер, 2, 1) КАК Симв2,
| ...
|ПОМЕСТИТЬ ВтСимволы
|ИЗ
| ВтНомера КАК ВтНомера"
Рекомендация: На практике такие сложные запросы с вложенными ВЫБОР КОГДА для каждого символа используются крайне редко из-за низкой производительности. Гораздо эффективнее использовать стандартную сортировку по строковому номеру УПОРЯДОЧИТЬ ПО Номер УБЫВ, предварительно убедившись, что все номера имеют одинаковую длину и лидирующие нули.
Рассмотрим несколько советов, которые помогут сделать вашу систему нумерации более надежной:
Номер. Если длина составляет 11 символов, а ваш суффикс занимает 4 (/401), то на числовую часть остается всего 7 знаков.ПриУстановкеНовогоНомера. Это позволит избежать «ручных» запросов к базе.000000001), а в счете-фактуре напечатается 1/401. Это самый безопасный метод, не нарушающий работу платформенных механизмов.Реализация номера с суффиксом в конце требует внимательного отношения к типам данных и функциям форматирования. Основная ошибка разработчиков — игнорирование лидирующих нулей или неправильный расчет длины строки. Используя функции Лев(), Число() и Формат() с корректными параметрами ЧЦ и ЧВН, вы сможете построить надежную систему нумерации, которая не «сломается» при переходе через десятичный разряд (например, с 999 на 1000).