При разработке интерфейсных механизмов в 1С:Предприятии 8.3 часто возникает задача предварительной проверки данных перед показом формы пользователю. Типичный сценарий: при старте системы запускается отчет, который должен отобразиться только в том случае, если в нем есть актуальные данные (например, задачи, требующие внимания). В этой статье мы подробно разберем, как реализовать «невидимое» формирование отчета и почему штатное управление видимостью окна формы не всегда является оптимальным решением.
В управляемом приложении 1С не существует прямого аналога свойства Видимость для всего объекта УправляемаяФорма, которое позволило бы скрыть окно, оставив его активным в памяти. Если мы программно установим Видимость = Ложь для всех групп и элементов, само окно (рамка формы) все равно может отобразиться в панели открытых окон или в виде пустого серого прямоугольника.
Рассмотрим ситуацию: автор задачи хочет вызвать метод формы СкомпоноватьРезультат, чтобы отчет сформировался в фоновом задании, проанализировать результат и закрыть форму, если данных нет. Главный затык здесь — не дать пользователю увидеть мелькание открывающегося и закрывающегося окна.
Это наиболее архитектурно правильный подход. Мы не открываем форму до тех пор, пока не убедимся, что в отчете есть данные. Проанализируем алгоритм реализации этого метода:
ПриНачалеРаботыСистемы) запускается серверная процедура, которая формирует отчет без использования контекста формы.ВременноеХранилище.ОткрытьФорму. Если нет — пользователь даже не узнает, что проверка проводилась.Рассмотрим пример кода для серверной части:
Функция СформироватьДанныеНаСервере() Экспорт
// Создаем объект отчета программно
ОтчетОбъект = Отчеты.МойОтчет.Создать();
Схема = ОтчетОбъект.СхемаКомпоновкиДанных;
Настройки = ОтчетОбъект.КомпоновщикНастроек.ПолучитьНастройки();
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, Настройки);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
ТаблицаРезультата = Новый ТаблицаЗначений;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ПроцессорВывода.УстановитьОбъект(ТаблицаРезультата);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
Возврат ТаблицаРезультата.Количество() > 0;
КонецФункции
Выясним интересный нюанс платформы: объект управляемой формы можно создать в памяти без визуального отображения. Для этого используется метод ПолучитьФорму вместо ОткрытьФорму.
Проанализируем последовательность действий:
ФормаОтчета = ПолучитьФорму("Отчет.МойОтчет.ФормаОбъекта");. В этот момент форма создана, но не видна пользователю.ФормаОтчета можно вызывать экспортные методы и обращаться к его реквизитам.ФормаОтчета.СкомпоноватьРезультат(РежимКомпоновкиРезультата.Фоново);.Важное ограничение: Как было отмечено в ходе обсуждения, у формы, которая не была открыта методом Открыть(), не работают клиентские обработчики ожидания (ПодключитьОбработчикОжидания). Это означает, что если вы запустите фоновое формирование отчета через метод такой формы, вы не сможете стандартным способом «поймать» момент завершения формирования на клиенте в контексте этой формы.
Если вы работаете в современной конфигурации (например, 1С:Документооборот, как автор вопроса), наиболее эффективным будет использование программного интерфейса библиотеки стандартных подсистем (БСП). Механизм ДлительныеОперации позволяет запустить расчет на сервере и получить результат без привязки к форме отчета.
Рассмотрим, как это упрощает код:
// На клиенте
ПараметрыВыполнения = ДлительныеОперацииКлиент.ПараметрыВыполнения(ЭтотОбъект);
ПараметрыВыполнения.ОжиданиеРезультата = Истина;
Результат = ДлительныеОперацииКлиент.ВыполнитьВФоне(
"МойОбщийМодуль.СформироватьОтчетДляПроверки",
ПараметрыОтчета,
ПараметрыВыполнения
);
Если Результат.Статус = "Выполнено" Тогда
ДанныеЕсть = ПолучитьИзВременногоХранилища(Результат.АдресРезультата);
Если ДанныеЕсть Тогда
ОткрытьФорму("Отчет.МойОтчет.Форма");
КонецЕсли;
КонецЕсли;
Разберем ситуации, когда разработчики пытаются скрыть форму манипуляциями с интерфейсом. К таким методам относятся:
Лево = -10000. В современном интерфейсе «Такси» и веб-клиенте это работает крайне нестабильно, так как платформа сама управляет позиционированием окон.ПриОткрытии прописать Отказ = Истина, форма не откроется. Однако на этот момент мы еще не знаем, сформируется ли отчет в фоне и будут ли там данные. Если же закрывать форму после завершения фонового задания, пользователь увидит кратковременное появление окна.Проанализировав все варианты, мы приходим к выводу, что лучшим способом «сделать форму невидимой» является отказ от её создания до момента подтверждения необходимости вывода данных.
Рекомендуемая последовательность действий для реализации задачи автора:
1. В модуле менеджера отчета создайте экспортную процедуру, которая выполняет компоновку данных и возвращает Истина/Ложь (наличие результата).
2. При запуске системы вызывайте эту процедуру через ДлительныеОперации.
3. В случае положительного ответа используйте стандартный метод ОткрытьФорму. Это обеспечит чистоту интерфейса и отсутствие лишних «миганий» окон для пользователя.
Такой подход гарантирует стабильную работу как в тонком клиенте, так и в веб-интерфейсе, сохраняя при этом отзывчивость системы.