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

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

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

В этой статье мы разберем, как программно определить, что документ проводится не индивидуально, а в составе массовой операции, чтобы в коде подписки или модуля объекта можно было вовремя "заглушить" ненужные в данный момент алгоритмы.

Метод 1: Использование стандартных свойств БСП

Если ваша конфигурация построена на базе Библиотеки стандартных подсистем (БСП), то в ней уже заложены механизмы для идентификации массовых операций. При запуске стандартных обработок или выполнении групповых действий из форм списков, система зачастую помечает объект специальным флагом. Проанализируем, как это реализовано в типовых решениях (ERP, КА, УТ 11, БП 3.0).

Чаще всего для этих целей используется коллекция ДополнительныеСвойства. Рассмотрим функцию, которая помогает определить статус операции:


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

    // В некоторых версиях БСП флаг может называться иначе
    Если Объект.ДополнительныеСвойства.Свойство("ЭтоГрупповоеПроведение", Результат) Тогда
        Возврат (Результат = Истина);
    КонецЕсли;
    
    Возврат Ложь;
КонецФункции

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

Метод 2: Использование признака «Обмен данными»

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

Это позволяет "убить двух зайцев": автоматически отключить типовые проверки (которые по стандарту 1С не должны выполняться при Загрузка = Истина) и ускорить процесс. Рассмотрим пример проверки в коде:


Процедура ПриЗаписиДокумента(Источник, Отказ) Экспорт
    // Если идет загрузка данных или массовая обработка с этим флагом — выходим
    Если Источник.ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;

    // Ваш сложный код обработки...
КонецПроцедуры

Важный нюанс: Стандартное групповое проведение из формы списка (через кнопку "Провести") НЕ устанавливает этот флаг автоматически. Поэтому данный метод эффективен только в паре с кастомными обработками.

Метод 3: Определение контекста выполнения через фоновое задание

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

Мы можем проверить, выполняется ли код в фоновом задании следующим образом:


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

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

Метод 4: Переопределение команд в формах списков

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

  1. Создадим в форме списка свою команду (например, КомандаПровестиГруппово).
  2. В обработчике этой команды программно обойдем все выделенные строки (массив ВыделенныеСтроки).
  3. Для каждого документа будем устанавливать свой собственный признак в ДополнительныеСвойства.

Пример кода для формы списка:


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

Теперь в любой подписке на событие этого документа вы сможете проверить наличие свойства МойПризнакГрупповойОбработки. Это самый точный метод, так как вы сами контролируете передачу контекста.

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

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

Перед началом цикла мы можем установить значение в заранее созданный параметр сеанса:

ПараметрыСеанса.глМассовоеПроведение = Истина;

А в коде подписки проверять:


Если ПараметрыСеанса.глМассовоеПроведение Тогда
    Возврат;
КонецЕсли;

Важно: Не забудьте в блоке Попытка...КонецПопытки или в конце обработки вернуть значение параметра в Ложь, иначе до конца сеанса пользователя подписки перестанут работать вообще.

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

Для надежного определения группового проведения мы рекомендуем комбинированный подход. Проанализируем иерархию проверок:

1. Проверка стандартных флагов БСП. Это "правило хорошего тона" для разработки в типовых конфигурациях. Если ДополнительныеСвойства.ГрупповоеПерепроведение присутствует, значит, система уже позаботилась об идентификации процесса.
2. Проверка режима загрузки. Использование ОбменДанными.Загрузка позволяет автоматически отключать не только ваши подписки, но и многие системные механизмы, что критически важно для скорости.
3. Кастомные флаги. Если вам нужно исключить проведение только конкретной "пачки" документов из списка, используйте ДополнительныеСвойства с вашим уникальным ключом.

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

← На главную