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