Как сделать невидимой управляемую форму при фоновом формировании отчета

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

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

Анализ проблемы видимости управляемой формы

В управляемом приложении 1С не существует прямого аналога свойства Видимость для всего объекта УправляемаяФорма, которое позволило бы скрыть окно, оставив его активным в памяти. Если мы программно установим Видимость = Ложь для всех групп и элементов, само окно (рамка формы) все равно может отобразиться в панели открытых окон или в виде пустого серого прямоугольника.

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

Решение 1: Разделение получения данных и вывода отчета

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

  1. Запуск фонового задания: При старте системы (в обработчике ПриНачалеРаботыСистемы) запускается серверная процедура, которая формирует отчет без использования контекста формы.
  2. Передача данных: Результат формирования (например, количество строк или таблица значений) помещается во ВременноеХранилище.
  3. Ожидание на клиенте: С помощью обработчика ожидания или механизмов БСП проверяется состояние фонового задания.
  4. Принятие решения: Если данные найдены, вызывается ОткрытьФорму. Если нет — пользователь даже не узнает, что проверка проводилась.

Рассмотрим пример кода для серверной части:


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

Решение 2: Использование метода ПолучитьФорму без Открыть

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

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

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

Решение 3: Использование БСП (ДлительныеОперации)

Если вы работаете в современной конфигурации (например, 1С:Документооборот, как автор вопроса), наиболее эффективным будет использование программного интерфейса библиотеки стандартных подсистем (БСП). Механизм ДлительныеОперации позволяет запустить расчет на сервере и получить результат без привязки к форме отчета.

Рассмотрим, как это упрощает код:


// На клиенте
ПараметрыВыполнения = ДлительныеОперацииКлиент.ПараметрыВыполнения(ЭтотОбъект);
ПараметрыВыполнения.ОжиданиеРезультата = Истина;

Результат = ДлительныеОперацииКлиент.ВыполнитьВФоне(
    "МойОбщийМодуль.СформироватьОтчетДляПроверки", 
    ПараметрыОтчета, 
    ПараметрыВыполнения
);

Если Результат.Статус = "Выполнено" Тогда
    ДанныеЕсть = ПолучитьИзВременногоХранилища(Результат.АдресРезультата);
    Если ДанныеЕсть Тогда
        ОткрытьФорму("Отчет.МойОтчет.Форма");
    КонецЕсли;
КонецЕсли;

Почему не стоит использовать визуальные «трюки»?

Разберем ситуации, когда разработчики пытаются скрыть форму манипуляциями с интерфейсом. К таким методам относятся:

  1. Вынос формы за пределы экрана: Установка координат Лево = -10000. В современном интерфейсе «Такси» и веб-клиенте это работает крайне нестабильно, так как платформа сама управляет позиционированием окон.
  2. Программное закрытие в ПриОткрытии: Если в событии ПриОткрытии прописать Отказ = Истина, форма не откроется. Однако на этот момент мы еще не знаем, сформируется ли отчет в фоне и будут ли там данные. Если же закрывать форму после завершения фонового задания, пользователь увидит кратковременное появление окна.
  3. Переключение фокуса: Переход на форму рабочего стола сразу после открытия отчета. Это не скрывает форму, а лишь уводит её на задний план, что путает пользователя и оставляет лишние вкладки в панели открытых окон.

Итоговые рекомендации

Проанализировав все варианты, мы приходим к выводу, что лучшим способом «сделать форму невидимой» является отказ от её создания до момента подтверждения необходимости вывода данных.

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

1. В модуле менеджера отчета создайте экспортную процедуру, которая выполняет компоновку данных и возвращает Истина/Ложь (наличие результата).

2. При запуске системы вызывайте эту процедуру через ДлительныеОперации.

3. В случае положительного ответа используйте стандартный метод ОткрытьФорму. Это обеспечит чистоту интерфейса и отсутствие лишних «миганий» окон для пользователя.

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

← На главную