Как реализовать нумерацию документов на основании ID контрагента в 1С:УНФ

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

В типовых конфигурациях 1С, таких как «Управление нашей фирмой» (УНФ), механизмы нумерации обычно работают линейно или в разрезе префиксов организаций. Однако в управленческом учете часто возникает потребность в «умной» нумерации, когда номер документа должен содержать идентификатор (ID) контрагента и порядковый номер документа именно для этого клиента. Рассмотрим, как реализовать такую задачу, проанализируем возможные подходы и разберем программные примеры.

Постановка задачи и анализ требований

Представим ситуацию: бизнес требует, чтобы у каждого контрагента был свой уникальный трехзначный код (например, 001, 002 и т.д.). Все документы этого контрагента должны иметь номер, состоящий из его ID и порядкового номера документа. Например, для контрагента с кодом 123 заказ покупателя должен иметь номер 123-001, счет — 123-001-001 и так далее.

Основные сложности:

  1. Стандартное поле Номер в 1С является строковым и имеет свои механизмы автогенерации, которые не учитывают связи с другими справочниками «из коробки».
  2. Нужно обеспечить уникальность номеров, чтобы система не выдавала ошибку при записи.
  3. Необходимо учитывать ограничения длины номера (по умолчанию в УНФ это 11 символов).

Метод 1. Реализация через дополнительные реквизиты и событие «ПослеЗаписи»

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

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


&НаКлиенте
Процедура Расш1_ПослеЗаписиПосле(ПараметрыЗаписи)
    // Если ИД еще не заполнен, берем последние 3 цифры стандартного кода
    Если НЕ ЗначениеЗаполнено(Объект.ИДКонтрагента) Тогда
        Объект.ИДКонтрагента = Прав(Объект.Код, 3);
    КонецЕсли;
КонецПроцедуры

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


&НаСервере
Процедура Расш1_ПослеЗаписиНаСервереПосле(ТекущийОбъект, ПараметрыЗаписи)
    КонтрагентЗак = Объект.Контрагент;
    // Получаем объект контрагента для чтения его ИД
    ОбъектКА = КонтрагентЗак.ПолучитьОбъект();
    
    Если НЕ ЗначениеЗаполнено(Объект.ИДЗаказПокупателя) Тогда
        // Формируем новый номер: ИД Контрагента + последние 3 цифры номера заказа
        Объект.ИДЗаказПокупателя = ОбъектКА.ИДКонтрагента + Прав(Объект.Номер, 3);
        // Здесь важно понимать, что повторная запись объекта в ПослеЗаписи может привести к рекурсии
        // В реальном проекте лучше использовать ПередЗаписью или обертку ОбменДанными.Загрузка = Истина
    КонецЕсли;
КонецПроцедуры

Метод 2. Использование события «ПриУстановкеНовогоНомера»

Более правильный с точки зрения архитектуры 1С подход — вмешаться в сам процесс генерации номера. Это позволяет избежать двойной записи объекта и гарантирует, что номер будет корректным еще до того, как пользователь увидит документ в списке.

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


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

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

Проблема масштабируемости: что если контрагентов больше 999?

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

Рассмотрим вариант использования буквенно-цифрового кодирования (Base36). Если мы разрешим использовать цифры 0-9 и латинские буквы A-Z, то в те же 3 символа мы сможем уместить более 46 000 уникальных комбинаций. Это полностью решит проблему нехватки номеров для среднего и даже крупного бизнеса.

Важные замечания по счетам-фактурам

Будьте осторожны при изменении нумерации фискальных документов. Согласно законодательству РФ, счета-фактуры должны иметь сквозную порядковую нумерацию в хронологическом порядке. Если вы сделаете нумерацию счетов-фактур «по контрагентам» (например, 001-01, 002-01), это может вызвать претензии со стороны налоговой службы. Для таких документов лучше оставлять стандартный номер 1С, а кастомный ID выводить только в печатную форму как дополнительную информацию.

Рекомендации по реализации

  1. Используйте механизмы БСП: УНФ активно использует подсистему «Префиксация объектов». Изучите общий модуль ПрефиксацияОбъектовПереопределяемый. Часто добавление логики там позволяет решить задачу наиболее «чистым» способом.
  2. Избегайте записи в ПослеЗаписи: Как мы выяснили, это приводит к двойному срабатыванию триггеров базы данных и замедляет работу. Всегда старайтесь рассчитать номер в событии ПередЗаписью.
  3. Длина номера: Если вы добавляете префикс контрагента, убедитесь, что оставшейся длины поля Номер (например, 11 символов минус 3 на ID и 1 на дефис) достаточно для вашей интенсивности документооборота.

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

← На главную