Как настроить автоматическую нумерацию договоров в 1С:Управление торговлей 11

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

При работе в конфигурации 1С:Управление торговлей 11 (УТ 11) многие пользователи и разработчики сталкиваются с тем, что в справочнике ДоговорыКонтрагентов отсутствует привычная по другим объектам автоматическая нумерация. Это вызывает массу вопросов: почему номера дублируются, как работает механизм префиксации и где найти тот участок кода, который отвечает за формирование номера. В этой статье мы детально разберем внутреннее устройство справочника и научимся реализовывать собственную логику нумерации.

Почему в типовой конфигурации номера договоров не уникальны?

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

  1. Внешние номера: В бизнесе часто принято использовать номер договора, предоставленный контрагентом. Если бы система жестко контролировала уникальность, вы не смогли бы ввести номер «1», если он уже существует у другого партнера.
  2. Сложная структура: Договоры часто имеют префиксы, дробные части или буквенные индексы (например, «11161/2024/7я»), которые стандартный механизм платформы не всегда может корректно инкрементировать (увеличить на единицу).
  3. Метаданные: В типовой поставке УТ 11 для этого справочника свойство Автонумерация обычно установлено в значение Не использовать или управляется программно через БСП.

Выясним причину, по которой отладчик уходит «вглубь» кода. Если нумерация в вашей базе все же срабатывает, скорее всего, она завязана на БСП (Библиотеку стандартных подсистем). Код формирования номера спрятан в общих модулях, таких как ПрефиксацияОбъектовСобытия. Система пытается найти последний номер в базе, учитывая префикс организации, но из-за отключенного контроля уникальности в метаданных она позволяет записывать дубли.

Вариант 1: Использование стандартного механизма префиксации

Прежде чем приступать к написанию кода, проверим настройки организации. В 1С:УТ 11 номер часто формируется динамически при записи, основываясь на префиксе организации. Если в справочнике Организации не задан префикс, система может генерировать пустые или повторяющиеся номера. Разберем по шагам, как это работает:

  1. Зайдем в карточку организации и установим Префикс (например, «ТД»); также возможна установка префикса у документов по условию.
  2. При создании договора система должна вызвать механизм УстановитьНовыйНомер.
  3. Если этого не происходит или номера «сбились», значит, в базе есть записи с номерами, которые парсер 1С не может распознать как числовые (например, номера, содержащие много спецсимволов).

Вариант 2: Реализация собственного алгоритма через расширение

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

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

Проанализируем пример кода для расширения справочника ДоговорыКонтрагентов:


&НаСервере
Процедура Расш1_ПередЗаписьюПеред(Отказ, ПараметрыЗаписи)
    Если Объект.ЭтоНовый() И ПустаяСтрока(Объект.Номер) Тогда
        // Укажем организацию, по которой будем искать последний номер
        ОрганизацияОбъекта = Объект.Организация;
        
        // Запрос для поиска последнего номера
        Запрос = Новый Запрос;
        Запрос.Текст = 
            "ВЫБРАТЬ ПЕРВЫЕ 1
            |	ДоговорыКонтрагентов.Номер КАК Номер
            |ИЗ
            |	Справочник.ДоговорыКонтрагентов КАК ДоговорыКонтрагентов
            |ГДЕ
            |	ДоговорыКонтрагентов.Организация = &Организация
            |УПОРЯДОЧИТЬ ПО
            |	ДоговорыКонтрагентов.Дата СОЗДАНИЯ УБЫВ"; // Или по коду
        
        Запрос.УстановитьПараметр("Организация", ОрганизацияОбъекта);
        Результат = Запрос.Выполнить();
        
        Если НЕ Результат.Пустой() Тогда
            Выборка = Результат.Выбрать();
            Выборка.Следующий();
            ПоследнийНомер = Выборка.Номер;
            // Здесь вызываем функцию инкремента номера
            Объект.Номер = СформироватьСледующийНомерДоговора(ПоследнийНомер);
        Иначе
            Объект.Номер = "1"; // Начальный номер
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

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

Сложная нумерация с буквенными индексами

Разберем ситуацию, когда номер имеет вид 11161/2024/7я. Платформенный механизм не поймет, что после «7я» должно идти «8а». Для таких случаев необходимо написать вспомогательную функцию разбора строки. Посмотрим на логику, которую можно применить:


Функция СформироватьСледующийНомерДоговора(ПредыдущийНомер)
    // Предположим, номер разделен знаками "/"
    ЧастиНомера = СтрРазделить(ПредыдущийНомер, "/");
    Если ЧастиНомера.Количество() < 3 Тогда
        Возврат ПредыдущийНомер + "_NEW"; // Заглушка
    КонецЕсли;

    ПоследняяЧасть = ЧастиНомера[2]; // Например, "7я"
    ЧисловаяЧасть = Число(Лев(ПоследняяЧасть, СтрДлина(ПоследняяЧасть) - 1));
    БуквеннаяЧасть = Прав(ПоследняяЧасть, 1);

    Если БуквеннаяЧасть = "я" Тогда
        НоваяБуква = "а";
        НовоеЧисло = ЧисловаяЧасть + 1;
    Иначе
        // Простая логика инкремента буквы (условно)
        НоваяБуква = БуквеннаяЧасть; 
        НовоеЧисло = ЧисловаяЧасть + 1;
    КонецЕсли;

    Возврат ЧастиНомера[0] + "/" + ЧастиНомера[1] + "/" + Формат(НовоеЧисло, "ЧГ=0") + НоваяБуква;
КонецФункции

Этот пример показывает, что возможности программной настройки практически безграничны. Вы можете реализовать любую логику, учитывающую основы учета вашей организации.

Использование дополнительных реквизитов

Если вы не хотите вносить изменения в программный код и рисковать целостностью поля Номер, рассмотрим альтернативный вариант — Дополнительные реквизиты (включая дополнительные реквизиты табличных частей). Это штатный механизм УТ 11, который позволяет добавить любое поле в пользовательском режиме.

  1. Перейдите в раздел Администрирование — Общие настройки — Дополнительные реквизиты и сведения.
  2. Найдите справочник «Договоры контрагентов» и добавьте новый реквизит «Внутренний номер договора».
  3. Для этого реквизита нельзя настроить автоматический инкремент без кода, но его можно использовать для хранения сложных строк, оставив системное поле Номер для автоматической (пусть и простой) нумерации 1С.

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

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

Мы выяснили, что отсутствие автоматической уникальности номеров договоров в УТ 11 — это не ошибка, а особенность конфигурации. Для решения проблемы дублирования мы рекомендуем:

Таким образом, комбинируя возможности платформы и небольшие доработки на языке 1С, можно добиться идеально работающей системы учета договоров, отвечающей всем требованиям вашего бизнеса.

← На главную