Работа в веб-клиенте 1С накладывает определенные ограничения на выполнение длительных серверных операций. Если отчет формируется дольше 30–60 секунд, браузер, не получая ответа от сервера, считает страницу «зависшей» и предлагает пользователю ее закрыть. Рассмотрим подробно, как решить эту проблему, используя механизмы асинхронности, фоновые задания и временные хранилища.
Проанализируем ситуацию: когда вы запускаете формирование отчета напрямую из модуля формы, вызывая серверную процедуру, поток выполнения на клиенте (в браузере) блокируется. Он ожидает окончания работы сервера. У веб-серверов (IIS, Apache) и самих браузеров есть жесткие лимиты на время ожидания ответа. Как только лимит превышен, соединение может быть разорвано, а пользователь увидит сообщение «Страница не отвечает».
Разберем важный технический момент: фоновое задание запускается в отдельном сеансе на сервере. Оно не имеет доступа к данным формы, ее реквизитам или экспортным процедурам модуля формы. Поэтому, как бы нам ни хотелось оставить код в форме, его необходимо перенести в МодульМенеджера отчета или в ОбщийМодуль с признаком «Сервер».
Проанализируем, что нужно передать в фоновое задание:
Рассмотрим пример процедуры, которую мы разместим в модуле менеджера отчета. Эта процедура будет выполняться в фоне.
Процедура СформироватьОтчетДляФона(ПараметрыОтчета, АдресХранилища) Экспорт
ТабДок = Новый ТабличныйДокумент;
// Здесь размещаем ваш запрос и логику вывода данных
// Например, программный вывод СКД:
ОтчетОбъект = Отчеты.МойСамописныйОтчет.Создать();
ОтчетОбъект.КомпоновщикНастроек.ЗагрузитьНастройки(ПараметрыОтчета.Настройки);
ОтчетОбъект.СкомпоноватьРезультат(ТабДок);
// Помещаем готовый табличный документ в хранилище по переданному адресу
ПоместитьВоВременноеХранилище(ТабДок, АдресХранилища);
КонецПроцедуры
Теперь выясним, как правильно инициировать процесс с клиента. Нам понадобится уникальный идентификатор формы, чтобы данные в хранилище «жили» до тех пор, пока форма открыта.
Посмотрим на пример кода в модуле формы:
&НаКлиенте
Процедура СформироватьОтчет(Команда)
// 1. Создаем адрес во временном хранилище
АдресХранилища = ПоместитьВоВременноеХранилище(Неопределено, ЭтаФорма.УникальныйИдентификатор);
// 2. Готовим параметры для передачи на сервер
ПараметрыОтчета = Новый Структура;
ПараметрыОтчета.Вставить("Настройки", Отчет.КомпоновщикНастроек.ПолучитьНастройки());
// 3. Запускаем фоновое задание
РезультатЗапуска = ЗапуститьВыполнениеНаСервере(ПараметрыОтчета, АдресХранилища);
ИдентификаторЗадания = РезультатЗапуска.ИдентификаторЗадания;
// 4. Подключаем обработчик ожидания, чтобы проверять готовность
ПодключитьОбработчикОжидания("Подключаемый_ПроверитьВыполнениеЗадания", 2, Ложь);
Состояние("Отчет формируется, подождите...");
КонецПроцедуры
Это критически важный этап для веб-клиента. Вместо того чтобы ждать ответа в одной длительной транзакции, мы «отпускаем» браузер и просим его заходить за результатом каждые 2 секунды. Это сохраняет отзывчивость интерфейса. Для реализации такого сценария подойдёт пример отслеживания фоновых заданий без БСП.
&НаКлиенте
Процедура Подключаемый_ПроверитьВыполнениеЗадания()
Если ЗаданиеЗавершено(ИдентификаторЗадания) Тогда
ОтключитьОбработчикОжидания("Подключаемый_ПроверитьВыполнениеЗадания");
// Получаем результат из хранилища
РезультатТабДок = ПолучитьИзВременногоХранилища(АдресХранилища);
// Выводим на форму (в реквизит типа ТабличныйДокумент)
Результат.Вывести(РезультатТабДок);
Состояние("Формирование завершено");
КонецЕсли;
КонецПроцедуры
Если ваша конфигурация содержит БСП, мы настоятельно рекомендуем использовать общий модуль ДлительныеОперации. Это позволит избежать написания кода по проверке статусов заданий вручную.
Разберем, как это выглядит с БСП:
ДлительныеОперации.ЗапуститьВыполнениеНаСервере(). Она сама создаст фоновое задание.ДлительныеОперацииКлиент.ОжидатьЗавершение(), которая откроет стандартное окно ожидания с «котиком» или прогресс-баром.ДлительныеОперации.ПолучитьРезультатВыполнения().Этот метод является наиболее стабильным для веб-клиента, так как учитывает все нюансы платформы. При необходимости можно использовать готовые примеры и шаблоны длительных операций для БСП, чтобы быстро настроить асинхронный вызов.
Даже при использовании фоновых заданий, иногда требуется подправить настройки самого веб-сервера. Проанализируем основные параметры:
Для IIS: В файле web.config проверьте параметр requestTimeout. Если он слишком мал, веб-сервер может обрывать даже короткие запросы проверки статуса при высокой нагрузке.
Для Nginx (реверс-прокси): Если 1С опубликована через Nginx, необходимо увеличить таймауты в конфигурационном файле:
proxy_read_timeout 300;proxy_send_timeout 300;send_timeout 300;Чтобы отчет в веб-клиенте перестал «вешать» страницу, мы выполнили следующие действия: вынесли расчет в модуль менеджера, запустили фоновое задание, организовали обмен через временное хранилище и внедрили циклический опрос сервера через обработчик ожидания. Такой подход гарантирует, что браузер будет считать страницу активной, а пользователь сможет дождаться результата даже самого тяжелого отчета.