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