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