Как решить проблему уникальности номеров документов в РИБ 1С без БСП?

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

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

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

Почему нельзя просто проигнорировать дублирование номеров?

Давайте проанализируем, почему нельзя просто проигнорировать эту проблему или отключить контроль уникальности номеров в свойствах объектов метаданных. Если мы отключим проверку уникальности, в системе действительно смогут существовать два документа разных узлов с номером 000001. Однако это влечет за собой крайне неприятные последствия для учета:

  1. Бухгалтерия и аудит: Печать документов с одинаковыми номерами от одного юридического лица законодательно недопустима во многих отраслях.
  2. Поиск и интеграция: Внешние системы (клиент-банки, CRM, системы электронного документооборота) сойдут с ума, пытаясь сопоставить документы по их номерам.
  3. Блокировка редактирования: Если уникальность в метаданных все же включена, пользователь в подчиненном узле не сможет даже перезаписать документ, если его номер совпадет с номером пришедшего из центра документа.

Поэтому решать проблему уникальности необходимо на системном уровне. Выясним, какие варианты у нас есть.

Метод 1. Префиксация на основе кодов узлов РИБ (Классический подход)

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

Разберем реализацию по шагам:

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

Посмотрим на пример кода для обработчика подписки документов:


Процедура ПодпискаНаСобытиеУстановкаНовогоНомераПриУстановкеНовогоНомера(Источник, СтандартнаяОбработка, Префикс) Экспорт

    // Если документ загружается в процессе обмена РИБ, префикс менять нельзя!
    Если Источник.ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;

    // Получаем код текущего узла плана обмена
    ТекущийУзел = ПланыОбмена.ПочтовыеУзлы.ЭтотУзел();
    КодУзла = СокрЛП(ТекущийУзел.Код);

    // Используем код узла в качестве префикса
    Если Не ПустаяСтрока(КодУзла) Тогда
        Префикс = КодУзла + "-";
    КонецЕсли;

    // Платформа автоматически добавит префикс и сгенерирует уникальный номер внутри этого префикса
КонецПроцедуры

Аналогичным образом настроим подписку для справочников на событие ПриУстановкеНовогоКода:


Процедура ПодпискаНаСобытиеПриУстановкеНовогоКода(Источник, СтандартнаяОбработка, Префикс) Экспорт

    Если Источник.ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;

    ТекущийУзел = ПланыОбмена.ПочтовыеУзлы.ЭтотУзел();
    КодУзла = СокрЛП(ТекущийУзел.Код);

    Если Не ПустаяСтрока(КодУзла) Тогда
        Префикс = КодУзла + "-";
    КонецЕсли;

КонецПроцедуры

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

Метод 2. Раздача номеров через централизованный веб-сервис

Что делать, если заказчик категорически требует сквозную строго последовательную нумерацию без каких-либо буквенных или цифирных префиксов в номере документа? В таком случае мы можем использовать веб-сервис или HTTP-сервис, развернутый в главном узле.

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

Проанализируем плюсы и минусы этого подхода:

Метод 3. Пост-фактум перенумерация в главном узле

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

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

Если дубль обнаружен, главный узел:

  1. Автоматически присваивает загруженному документу новый уникальный номер по порядку.
  2. Регистрирует этот документ к выгрузке обратно в тот периферийный узел, откуда он только что пришел.
  3. При следующем сеансе связи документ в периферийном узле обновляется и получает правильный номер.

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

Метод 4. Выделение диапазонов (пулов) номеров для узлов

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

Мы можем создать регистр сведений ДиапазоныНомерации со следующей структурой:

При создании документа в периферийном узле система обращается к этому регистру и берет значение из ресурса ТекущееЗначение, увеличивая его на единицу. Например:

Чтобы не прописывать эти диапазоны вручную на десятилетия вперед, мы можем реализовать автоматический запрос новых пулов из центра через веб-сервис, когда текущий пул узла исчерпан более чем на 90%.

Метод 5. Использование бизнес-префиксов

Иногда разработчики жестко привязывают технические префиксы к кодам узлов планов обмена. Но что произойдет, если базу подчиненного узла придется пересоздать или переименовать? Привязка может сломаться, и начнется путаница в номерах.

Гораздо надежнее использовать бизнес-префиксы, привязанные к реальным сущностям учета, например, к справочнику Организации, Подразделения или Склады. Добавим в справочник Организации реквизит Префикс (тип: Строка, длина 2-3 символа).

Тогда в подписке на событие ПриУстановкеНовогоНомера мы будем динамически считывать этот префикс:


Процедура ПодпискаНаСобытиеПриУстановкеНовогоНомераБизнес(Источник, СтандартнаяОбработка, Префикс) Экспорт

    Если Источник.ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;

    // Предположим, у документа есть реквизит Организация
    Если ОбщегоНазначения.ЕстьРеквизитОбъекта("Организация", Источник.Метаданные()) Тогда
        ПрефиксОрганизации = СокрЛП(Источник.Организация.Префикс);
        Если Не ПустаяСтрока(ПрефиксОрганизации) Тогда
            Префикс = ПрефиксОрганизации;
        КонецЕсли;
    КонецЕсли;

КонецПроцедуры

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

Метод 6. Двухэтапная нумерация (Временные номера)

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

При создании документа в периферийном узле ему присваивается временный номер с префиксом "ВРЕМ-" (или даже GUID в качестве номера). Документ проводится и печатается во внутреннем контуре как временный. После отправки в центральный узел, специальный обработчик в модуле обмена сбрасывает временный номер и присваивает документу финальный красивый сквозной номер центральной базы. Измененный документ отправляется обратно в периферию при следующем сеансе связи.

Резюме

Подводя итог, можно сказать, что выбор метода зависит исключительно от требований бизнеса к внешнему виду номеров документов. Самым стабильным, простым в реализации и надежным способом является классическая префиксация через подписки на события 1С с использованием кодов узлов или бизнес-префиксов организаций. Это решение внедряется буквально за пару часов даже в полностью самописную конфигурацию без БСП и гарантирует полное отсутствие коллизий в РИБ.

← На главную