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