Как программно определить выполнение группового перепроведения документов в 1С

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

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

Метод 1: Использование коллекции ДополнительныеСвойства

Разберем самый гибкий и рекомендуемый способ, который обсуждался на форуме. Суть метода заключается в использовании свойства ДополнительныеСвойства объекта документа. Это временная коллекция (структура), которая живет в памяти только пока существует сам объект ДокументОбъект и не сохраняется в базе данных. Это делает её идеальным контейнером для передачи служебных флагов.

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


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

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


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    
    // Проверяем, задано ли наше свойство
    ГрупповаяОбработка = Ложь;
    Если ДополнительныеСвойства.Свойство("ЭтоГрупповоеПроведение") Тогда
        ГрупповаяОбработка = ДополнительныеСвойства.ЭтоГрупповоеПроведение;
    КонецЕсли;
    
    // Если это групповая обработка — пропускаем тяжелую логику
    Если ГрупповаяОбработка Тогда
        Возврат;
    КонецЕсли;

    // Далее идет обычный алгоритм
    // ...
КонецПроцедуры

Метод 2: Использование стандартного механизма ОбменДанными.Загрузка

Проанализируем другой способ, который считается «стандартом де-факто» в среде 1С. У любого объекта базы данных есть свойство ОбменДанными, содержащее флаг Загрузка. По умолчанию система (и типовые конфигурации) интерпретирует ОбменДанными.Загрузка = Истина как сигнал о том, что данные записываются «как есть» (например, при загрузке из другой базы), и никакие проверки выполнять не нужно.

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


// В коде обработки
ДокументОбъект = ВыбраннаяСсылка.ПолучитьОбъект();
ДокументОбъект.ОбменДанными.Загрузка = Истина;
ДокументОбъект.Записать();

В начале каждого обработчика событий (в модуле объекта или в подписке) принято ставить «заглушку»:


Процедура ПередЗаписью(Отказ)
    Если ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;
    // ... остальной код
КонецПроцедуры

Важный нюанс: Использование ОбменДанными.Загрузка отключает не только ваши проверки, но и многие системные проверки платформы, а также практически все стандартные механизмы типовых конфигураций (например, формирование движений в БП или УТ). Используйте этот метод с осторожностью.

Метод 3: Использование параметров сеанса

Иногда требуется отключить алгоритмы глобально для всего сеанса, например, если групповое проведение запускает цепочку связанных изменений в разных объектах. В этом случае удобно использовать Параметры сеанса. Рассмотрим шаги реализации:

  1. В дереве конфигурации создаем параметр сеанса ВыполняетсяМассоваяОперация (тип Булево).
  2. В обработке, запускающей процесс, устанавливаем значение.
  3. В подписках проверяем значение параметра.

Разберем пример кода для запуска:


ПараметрыСеанса.ВыполняетсяМассоваяОперация = Истина;
Попытка
    // Блок кода с массовым проведением
    // ...
    ПараметрыСеанса.ВыполняетсяМассоваяОперация = Ложь;
Исключение
    ПараметрыСеанса.ВыполняетсяМассоваяОперация = Ложь;
    ВызватьИсключение КраткоеОписаниеОшибки(ИнформацияОбОшибке());
КонецПопытки;

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

Метод 4: Определение через фоновое задание

Современные конфигурации 1С (ERP, УТ 11, КА) часто выполняют массовые операции в фоновом режиме, чтобы не блокировать интерфейс пользователя. Мы можем программно проверить, выполняется ли текущий код в контексте фонового задания. Рассмотрим, как это сделать:


Если ФоновыеЗадания.ТекущееФоновоеЗадание() <> Неопределено Тогда
    // Мы находимся в фоновом задании. 
    // С большой вероятностью это программная обработка или регламентная операция.
КонецЕсли;

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

Метод 5: Анализ стандартных механизмов БСП

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


Если Объект.ДополнительныеСвойства.Свойство("ЭтоГрупповоеИзменениеОбъектов") Тогда
    // Логика для массового изменения
КонецЕсли;

Подведем итоги

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

  1. ДополнительныеСвойства — лучший способ для точечного управления своими обработками.
  2. ОбменДанными.Загрузка — радикальный способ для полной деактивации бизнес-логики.
  3. Параметры сеанса — глобальный флаг для всей текущей сессии.
  4. Проверка фонового задания — автоматическое определение контекста выполнения.
  5. Стандарты БСП — использование готовых механизмов типовых конфигураций.

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

← На главную