Почему документы, не входящие в последовательность, сдвигают её границу в 1С?

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

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

Программное управление границей последовательности

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

Разберем основной метод, который используется для этих целей: Последовательности[ИмяПоследовательности].УстановитьГраницу(). Рассмотрим пример кода, который может скрываться в недрах конфигурации:


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

Если такой код вызывается в модуле документа, который формально не входит в последовательность, граница все равно будет перемещена. Проанализируем ситуацию: зачем это может быть нужно? Часто это делается в самописных решениях для того, чтобы «подтянуть» последовательность при вводе исторических данных или при выполнении регламентных операций, которые должны считаться «финальной точкой» актуальности данных.

Подписки на события — скрытый фактор

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

Выясним причину влияния через подписку. Внутри обработчика может стоять универсальный вызов:


Процедура ПриПроведенииДокументаДляПоследовательности(Источник, Отказ, РежимПроведения) Экспорт
    // Логика может проверять наличие определенных движений по регистрам
    // и, если они есть, двигать границу конкретной последовательности
    Если Источник.Движения.Хозрасчетный.Количество() > 0 Тогда
        Последовательности.ПартионныйУчет.УстановитьГраницу(Источник.МоментВремени());
    КонецЕсли;
КонецПроцедуры

В этом случае документ может даже не «знать» о существовании последовательности, но глобальный механизм контроля будет двигать ГП при каждом его проведении.

Влияние регистров и пересечение данных

Последовательность в 1С тесно связана с регистрами. Если документ (даже не входящий в последовательность) делает записи в регистр накопления или сведений, который является «контрольным» для этой последовательности, это может инициировать пересчет. Хотя сама платформа редко двигает ГП для «чужих» документов без команды, в типовых или сложных самописных решениях часто реализуется механизм автоматической актуализации.

Рассмотрим подробнее: если ваша последовательность имеет измерения (например, Организация), то граница хранится в разрезе каждого значения этого измерения. Если сторонний документ меняет данные по этой организации в связанных регистрах, программный код может быть настроен так, чтобы сбрасывать границу назад или, наоборот, считать данные актуальными на момент этого документа.

Как найти причину: пошаговый алгоритм

Чтобы разобраться, какой именно механизм двигает вашу последовательность, пройдем по следующим шагам:

  1. Глобальный поиск: Нажмите Ctrl+Shift+F и введите имя вашей последовательности. Ищите все вхождения, особенно те, где используются методы УстановитьГраницу или Записать.
  2. Поиск по методам: Отдельно поищите текст .Границы (обращение к таблице границ последовательности).
  3. Анализ подписок: Просмотрите список всех подписок на события ОбработкаПроведения и ПередЗаписью. Проверьте программный код их обработчиков.
  4. Использование отладчика: Это самый надежный способ. Установите точку остановки в общем модуле, где происходит работа с последовательностями. Если вы не знаете, где это, воспользуйтесь инструментом «Замер производительности» при проведении «проблемного» документа. В результатах замера вы увидите вызовы функций, связанных с объектом Последовательности.
  5. Проверка свойств последовательности: Посмотрите на закладку «Использование» в свойствах последовательности в конфигураторе. Проверьте, какие регистры там указаны и не делает ли ваш сторонний документ движений по этим же регистрам.

Важность использования измерений

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


Отбор = Новый Структура;
Отбор.Вставить("Организация", СсылкаНаОрганизацию);
Отбор.Вставить("Склад", СсылкаНаСклад);

Момент = Новый МоментВремени(ДатаДокумента, СсылкаНаДокумент);
Последовательности.УчетТоваров.УстановитьГраницу(Момент, Отбор);

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

← На главную