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