Как реализовать отдельную нумерацию документов для конкретного контрагента в 1С:Комплексная автоматизация?

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

В процессе сопровождения систем на базе 1С:Комплексная автоматизация (КА) или 1С:ERP часто возникает задача по разделению нумерации. Например, когда крупный заказчик требует, чтобы в номерах документов (Реализаций, Счет-фактур) присутствовал определенный символ или использовалась отдельная последовательность. Иногда требуется изменение механизма нумерации, чтобы вносить документы задним числом, не сбивая общий поток. Рассмотрим, почему стандартные попытки решить эту задачу "в лоб" через код приводят к сбою всей нумерации в базе, и разберем правильные подходы к реализации.

Почему ломается стандартная нумерация: анализ проблемы

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

Выясним причину такого поведения:

  1. Алгоритм поиска максимума: Платформа 1С при создании нового номера ищет в базе документ с максимальным номером в текущем периоде. Если вы записываете номер вида ХХ00-00001К, система анализирует его структуру. Буква в конце (постфикс) сбивает парсер платформы. Она может ошибочно принять часть номера за префикс или решить, что это новый формат приращения. В таких случаях может потребоваться поиск и нормализация нестандартных номеров, чтобы привести базу в порядок.
  2. Кэширование номеров: В современных конфигурациях используется механизм кэширования номеров (обычно по 10 штук в памяти). Ручное вмешательство в номер после того, как он был забронирован системой, создает "дыры" и конфликты уникальности.
  3. Событие записи: Использование процедуры ПриЗаписи — это слишком поздний этап. К этому моменту номер уже должен быть окончательно сформирован. Изменение номера "на лету" в момент записи заставляет платформу заново пересчитывать индексы, что часто ведет к непредсказуемым результатам.

Способ №1: Использование механизмов БСП (Рекомендуемый)

Проанализируем архитектуру 1С:Комплексная автоматизация. Она построена на Библиотеке Стандартных Подсистем (БСП), где за нумерацию отвечает подсистема "Префиксация объектов". Вместо того чтобы добавлять букву в конец номера (что платформа не любит), мы добавим её в префикс. Например, вместо НЛ00-000001 мы получим НЛК0-000001. Если база уже запущена, возможно, потребуется общее изменение нумерации документов и установка префикса для существующих объектов.

Для реализации этого метода нам не нужно менять модуль документа. Мы воспользуемся механизмом расширения и переопределим логику формирования префикса. Разберем по шагам:

  1. Создадим расширение конфигурации.
  2. Найдем общий модуль ПрефиксацияОбъектовПереопределяемый.
  3. Нам понадобится процедура ПриУстановкеПрефикса.

Посмотрим на пример кода, который нужно внедрить в расширение:


Процедура Расш1_ПриУстановкеПрефикса(Объект, Префикс) Экспорт
    
    // Проверяем, что это нужный нам тип документа
    Если ТипЗнч(Объект) = Тип("ДокументОбъект.РеализацияТоваровУслуг") Тогда
        
        // Проверяем условие по контрагенту
        // Лучше использовать ДополнительныеРеквизиты или Сегменты, но для примера возьмем наименование
        Если Объект.Контрагент.Наименование = "ООО КЛЕВ" Тогда
            // Добавляем символ 'К' к текущему префиксу
            // Было "НЛ00-", станет "НЛК0-"
            Префикс = Префикс + "К";
        КонецЕсли;
        
    КонецЕсли;
    
КонецПроцедуры

Преимущества этого метода:

Способ №2: Использование события ПриУстановкеНовогоНомера

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

Разберем пример реализации в модуле объекта документа:


Процедура ПриУстановкеНовогоНомера(СтандартнаяОбработка, Префикс)
    
    // Если условие выполняется, берем управление на себя
    Если ЗначениеЗаполнено(Контрагент) И Контрагент.Наименование = "ООО КЛЕВ" Тогда
        
        // Отключаем стандартный механизм 1С
        СтандартнаяОбработка = Ложь;
        
        // Получаем последний номер из нашего самописного регистра
        // Важно: запрос должен быть эффективным!
        Запрос = Новый Запрос;
        Запрос.Текст = 
            "ВЫБРАТЬ
            |   Максимум(Нумерация.ПоследнийНомер) КАК Номер
            |ИЗ
            |   РегистрСведений.НумерацияКлев КАК Нумерация";
            
        Результат = Запрос.Выполнить();
        Выборка = Результат.Выбрать();
        
        НовыйПорядковыйНомер = 1;
        Если Выборка.Следующий() И Выборка.Номер <> NULL Тогда
            НовыйПорядковыйНомер = Выборка.Номер + 1;
        КонецЕсли;
        
        // Формируем строку номера. ХХ00 - префикс организации
        // ЧЦ=6; ЧН=; ЧГ=0 - форматирование числа с ведущими нулями
        ЭтотОбъект.Номер = "НЛ00-" + Формат(НовыйПорядковыйНомер, "ЧЦ=6; ЧН=; ЧГ=0") + "К";
        
    КонецЕсли;
    
КонецПроцедуры

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

Работа с стандартным нумератором

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

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

Выводы и рекомендации

Подведем итоги нашего исследования проблемы нумерации в 1С:КА:

  1. Не используйте постфиксы: Буквы в конце номера — главный враг автоматического нумератора 1С. По возможности убедите заказчика использовать префиксы (буквы в начале номера).
  2. Работайте через БСП: В современных конфигурациях вмешательство в ПрефиксацияОбъектовПереопределяемый — самый чистый и безопасный способ реализации раздельной нумерации.
  3. Избегайте ПриЗаписи для нумерации: Если вам нужно программно изменить номер, делайте это в ПриУстановкеНовогоНомера или перед открытием формы (для новых объектов).
  4. Помните о налоговой: Сквозная нумерация счетов-фактур является требованием законодательства. Разделение нумерации по контрагентам может вызвать вопросы при проверках. Иногда целесообразнее использовать автоматическую установку номера счета-фактуры как у реализации, чтобы обеспечить прозрачное соответствие документов, вместо создания "спецномеров". Использование префиксов организаций или подразделений — стандартная практика, а вот хаотичная нумерация может быть признана ошибкой учета.

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

← На главную