Как в 1С программно сформировать полный номер документа с префиксами, если известна его числовая часть?

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

Часто при разработке, особенно в задачах интеграции или синхронизации данных между несколькими базами 1С (для чего часто применяется универсальная выгрузка и загрузка данных), возникает нестандартная потребность. Нам нужно не просто создать документ и позволить системе присвоить ему следующий по порядку номер, а сформировать номер на основе уже известного числового значения. Например, перенести документ с числовым номером 123 из одной базы в другую (в том числе при использовании адаптивной выгрузки XML для разных конфигураций), но в целевой базе он должен получить номер в стандартном формате, например, "УТОР-000123".

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

Анализ проблемы: почему нет готового метода?

Основная логика платформы 1С и типовых конфигураций рассчитана на последовательную и автоматическую нумерацию. Когда вы создаете новый документ и вызываете метод УстановитьНовыйНомер(), система сама определяет последний использованный номер в пределах заданного префикса и периода и присваивает следующий. Это гарантирует уникальность номеров и порядок в учете.

Задача "встроить" свой, заранее известный номер в эту последовательность является нетиповой. Система не предоставляет готового инструмента вида СформироватьПолныйНомер(МоеЧисло). Поэтому решение заключается в том, чтобы "сымитировать" работу стандартного механизма: самостоятельно получить все составные части номера и правильно их объединить.

Полный номер документа в типовых конфигурациях обычно состоит из трех частей:

  1. Префиксы: Например, префикс организации ("ОР") и префикс информационной базы ("ИБ"). Они нужны для обеспечения уникальности номеров в распределенных системах.
  2. Разделитель: Чаще всего это дефис "-".
  3. Числовая часть: Сам номер, дополненный слева нулями до общей длины, заданной в метаданных (например, 6 знаков).

Наша цель — собрать эти части в единую строку. Рассмотрим несколько подходов.

Решение 1: Простое формирование строки (менее гибкий способ)

Если вы точно знаете, какие префиксы должны быть, и они не меняются, можно собрать номер простой конкатенацией (сложением) строк.

Допустим, нам известен числовой номер ХХ, префикс информационной базы "ИИ" и префикс организации "ОО".

Самый простой, но не очень надежный вариант — "зашить" нули в код:


ЧислоНомера = 123;
// Предполагаем, что номер всегда шестизначный
НомерСтрокой = "ИИОО-000" + Строка(ЧислоНомера);
ДокОбъект.Номер = НомерСтрокой; // Получим "ИИОО-000123"

Этот код сломается, если число будет четырехзначным (например, 1234), так как количество нулей жестко задано. Более правильный подход — использовать форматирование.

Для форматирования числовой части с добавлением лидирующих нулей идеально подходит функция Формат().


ЧислоНомера = 123;
ДлинаЧисловойЧасти = 6; // Длину можно получить из метаданных: Метаданные.Документы.МойДокумент.ДлинаНомера

// Форматная строка "ЧГ=0" означает, что группировка разрядов отключена (ЧГ), а пустые позиции слева будут заменены нулями (0).
ФорматнаяСтрока = "ЧЦ=" + ДлинаЧисловойЧасти + "; ЧВН=; ЧГ=0";
ЧисловаяЧастьСтрокой = Формат(ЧислоНомера, ФорматнаяСтрока); // Получим "000123"

ДокОбъект.Номер = "ИИОО-" + ЧисловаяЧастьСтрокой;

Еще один популярный и компактный способ форматирования — использовать конкатенацию со строкой нулей и функцию Прав(). Этот метод очень нагляден:


ЧислоНомера = 123;
ДлинаЧисловойЧасти = 6;

// К строке нулей добавляем наше число и берем справа нужное количество символов
ЧисловаяЧастьСтрокой = Прав("00000000000" + Формат(ЧислоНомера, "ЧГ="), ДлинаЧисловойЧасти);

ДокОбъект.Номер = "ИИОО-" + ЧисловаяЧастьСтрокой;

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

Решение 2: Использование типовых механизмов (рекомендуемый способ)

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

Шаг 1. Получаем префиксы программно

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

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

Чтобы получить префикс для нашего документа, нам нужно передать в эту функцию объект документа с заполненным реквизитом Организация, так как префикс организации зависит от этого реквизита.

Посмотрим на пример. Предположим, мы создаем документ РеализацияТоваровУслуг.


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

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

Важно: Название модуля и функции может отличаться в вашей конфигурации (например, УправлениеПрефиксациейОбъектов.ПриПолученииПрефиксаНомера или НумерацияОбъектовПереопределяемый.УстановитьПрефикс). Чтобы найти нужную, откройте подписку на событие ПриУстановкеНовогоНомера для вашего вида документа и посмотрите, какая процедура там вызывается. Это самый надежный способ найти актуальную логику.

Шаг 2. Форматируем числовую часть

Этот шаг не отличается от того, что мы делали в первом решении. Мы берем наше известное число и дополняем его нулями до нужной длины.


ИзвестноеЧисло = 456;
ДлинаНомера = НовыйДокумент.Метаданные().ДлинаНомера; // Получаем длину из метаданных

ФорматнаяСтрока = "ЧЦ=" + ДлинаНомера + "; ЧВН=; ЧГ=0";
ЧисловаяЧасть = Формат(ИзвестноеЧисло, ФорматнаяСтрока); // Результат: "000456" (если длина 6)

Шаг 3. Собираем итоговый номер и присваиваем его документу

Теперь у нас есть все компоненты: полученный через типовую функцию префикс и отформатированная числовая часть. Осталось их объединить.


// ПолныйПрефикс мы получили на Шаге 1, например, "УТОР"
// ЧисловаяЧасть - на Шаге 2, например, "000456"

// Собираем итоговый номер
ИтоговыйНомер = ПолныйПрефикс + "-" + ЧисловаяЧасть; // Результат: "УТОР-000456"

// Присваиваем номер нашему объекту
НовыйДокумент.Номер = ИтоговыйНомер;

// Теперь документ можно записывать
НовыйДокумент.Записать();

Особый случай: синхронизация данных

Задача формирования номера по известному числу чаще всего возникает при переносе данных между базами. В этом контексте важно помнить о нескольких вещах:

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

← На главную