Почему отбор в отчете СКД срабатывает только после перезапуска и как это исправить

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия
← На главную

При разработке отчетов на базе Системы компоновки данных (СКД) программисты часто сталкиваются с коварной ошибкой: пользователь устанавливает отбор на форме, нажимает кнопку «Сформировать», но данные в отчете не меняются. Однако стоит закрыть отчет и открыть его снова — отбор магическим образом начинает работать. Или же наоборот: после снятия галочки отбора отчет продолжает выводить отфильтрованные данные до тех пор, пока форма не будет полностью инициализирована заново.

В этой статье мы подробно разберем, почему возникает такая задержка в применении настроек, проанализируем механизм работы компоновщика и выясним, как заставить отчет реагировать на изменения пользователя мгновенно.

Разберем причину проблемы: иерархия настроек СКД

Для начала проанализируем ситуацию с точки зрения архитектуры платформы «1С:Предприятие 8». Проблема кроется в том, что в СКД существует три независимых уровня настроек, которые должны быть синхронизированы в момент формирования результата:

  1. Настройки схемы (в Конфигураторе): Это базовый скелет отчета.
  2. Настройки варианта (в режиме «1С:Предприятие»): Общие настройки для конкретного варианта отчета (например, «Ведомость по складам»).
  3. Пользовательские настройки: Это те возможности, которые предоставляет пользовательская СКД, и те «галочки», которые пользователь видит непосредственно на форме отчета.

Когда пользователь меняет значение отбора на форме, эти изменения попадают в объект КомпоновщикНастроек.ПользовательскиеНастройки. Однако само выполнение запроса в СКД часто происходит на основе объекта КомпоновщикНастроек.Настройки. Если программный код формирования отчета не выполняет явную «склейку» или синхронизацию этих двух объектов, компоновщик использует старые данные, сохраненные в основной структуре настроек, игнорируя оперативные правки пользователя.

Рассмотрим программное решение из практики

В ходе обсуждения на форуме было предложено решение, которое помогает принудительно обновить состояние компоновщика. Автор темы пришел к выводу, что если вручную перезагрузить настройки в компоновщик непосредственно перед формированием, система «подхватывает» актуальные данные.

Рассмотрим пример кода:


// В модуле отчета или в обработчике команды формирования

Отчет.КомпоновщикНастроек.ЗагрузитьНастройки(Отчет.КомпоновщикНастроек.Настройки);

Хотя этот метод кажется простым, он принудительно инициализирует внутренние структуры компоновщика. Рассмотрим подробнее, как это реализовать в типовой процедуре ПриКомпоновкеРезультата.

Проанализируем работу процедуры ПриКомпоновкеРезультата

Если вы используете ручное формирование отчета (например, в типовых конфигурациях вроде «Бухгалтерия предприятия 3.0»), важно проверить обработчик ПриКомпоновкеРезультата. Выясним причину, по которой типовые механизмы могут давать сбой.

Посмотрим на пример кода, изучив справочник по методам БСП, который часто встречается в отчетах, использующих Библиотеку стандартных подсистем:


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

В данном примере проблема заключается в том, что функция ЗаполнитьПараметрыОтчетаИзНастроекКомпоновщика берет данные из КомпоновщикНастроек.Настройки, в то время как пользовательские изменения еще «висят» в ПользовательскиеНастройки.

Правильный метод синхронизации настроек

Методически более верным способом решения является использование встроенного метода платформы для объединения настроек. Рассмотрим по шагам, как это сделать:

  1. Перед началом формирования отчета необходимо вызвать метод ЗагрузитьПользовательскиеНастройки().
  2. Этот метод берет все значения из пользовательского интерфейса (галочки, периоды, отборы) и накладывает их на основные настройки компоновщика.
  3. Только после этого можно передавать компоновщик в макет компоновки или в типовые функции формирования.

Применим этот подход на практике:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    // Принудительно применяем то, что пользователь ввел на форме
    ЭтотОбъект.КомпоновщикНастроек.ЗагрузитьПользовательскиеНастройки(ЭтотОбъект.КомпоновщикНастроек.ПользовательскиеНастройки);
    
    // Теперь Настройки содержат актуальный отбор
    // Можно продолжать формирование
    
КонецПроцедуры

Выясним дополнительные нюансы: Идентификаторы и Фиксированные настройки

Если вышеописанные методы не помогают, проанализируем еще несколько критических моментов:

1. Идентификаторы пользовательских настроек. Если вы программно добавляете отбор в схему, убедитесь, что вы назначили ему ИдентификаторПользовательскойНастройки. Если этого свойства нет, компоновщик не сможет сопоставить элемент на форме с элементом в структуре данных, и настройка будет игнорироваться при формировании.

2. Использование Фиксированных настроек. Если ваша задача — установить отбор программно так, чтобы пользователь не мог его испортить, используйте свойство КомпоновщикНастроек.ФиксированныеНастройки. Они имеют самый высокий приоритет и накладываются поверх любых пользовательских фильтров.

3. Свойства элементов пользовательских настроек. Обратите внимание на настройки самого варианта отчета в конфигураторе или в режиме «Еще — Прочее — Изменить вариант». В поле «Свойства элемента пользовательских настроек» должен быть установлен режим отображения (например, «Быстрый доступ»), иначе связь между формой и внутренним объектом может работать некорректно.

Рекомендации по исправлению

Подводя итог, если вы столкнулись с «залипанием» отбора в СКД, выполните следующие действия:

  1. Проверьте, не переопределена ли процедура ПриКомпоновкеРезультата. Если она есть, убедитесь, что в ней не теряются пользовательские правки.
  2. Добавьте в код формирования вызов ЗагрузитьПользовательскиеНастройки(). Это самый надежный способ синхронизации данных.
  3. В случае использования внешних отчетов попробуйте переименовать отчет и его варианты. Иногда платформа кэширует настройки по имени объекта, и старый «битый» кэш мешает работе новых механизмов.
  4. Проверьте, установлена ли СтандартнаяОбработка = Ложь. Если вы формируете отчет программно, но оставляете этот флаг в значении Истина, отчет может формироваться дважды с разными наборами настроек.

Следуя этим шагам, мы обеспечим корректное и предсказуемое поведение отчетов, а пользователи забудут о необходимости перезаходить в отчет для обновления данных.

← На главную