При программном создании отчетов или динамических выборок с использованием схемы компоновки данных (СКД) разработчики часто сталкиваются с неприятной ситуацией. На управляемую форму выводится реквизит КомпоновщикНастроекНастройкиОтбор, однако в режиме «1С:Предприятие» таблица «Доступные поля отбора» остается абсолютно пустой. Пользователь не может интерактивно выбрать поля для фильтрации, несмотря на то, что в самом запросе схемы все поля описаны верно.
В этой статье мы подробно разберем, почему возникает эта проблема, изучим внутренние механизмы платформы «1С:Предприятие» и напишем правильный, отказоустойчивый код для инициализации компоновщика настроек на управляемой форме.
Главная причина, по которой список доступных полей отбора оказывается пустым при передаче самого объекта СхемаКомпоновкиДанных в конструктор источника настроек, заключается в особенностях клиент-серверного взаимодействия на управляемых формах.
Рассмотрим эту цепочку событий детально:
СхемаКомпоновкиДанных является тяжелым серверным объектом. Он физически не может существовать на стороне клиента (в тонком или веб-клиенте).
ИсточникНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных);
КомпоновщикНастроек.Инициализировать(ИсточникНастроек);
ИсточникДоступныхНастроекКомпоновкиДанных адрес временного хранилища (строку URL), мы гарантируем, что платформа сохранит схему в памяти сеанса. При любых действиях пользователя на форме (например, разворачивании дерева полей) система сама обратится по этому адресу на сервер и получит актуальные данные.Просто поместить схему во временное хранилище недостаточно. Рассмотрим следующий вызов:
АдресСхемы = ПоместитьВоВременноеХранилище(СКД); // Ошибка! Нет привязки к форме
Если мы не передадим вторым параметром уникальный идентификатор формы, помещенные данные будут жить в хранилище только до первого серверного вызова (так называемый roundtrip). При первом же интерактивном действии пользователя на форме адрес станет недействительным, и доступные поля снова бесследно пропадут.
Для решения этой проблемы необходимо явно связывать время жизни данных в хранилище с временем жизни формы, передавая УникальныйИдентификатор текущей формы:
АдресСхемы = ПоместитьВоВременноеХранилище(СКД, УникальныйИдентификатор);
Теперь схема гарантированно будет находиться в памяти сервера до тех пор, пока пользователь не закроет данную форму.
Даже если схема успешно помещена в хранилище, поля отбора могут остаться пустыми по другим распространенным причинам, связанным с программным конструированием схемы. Разберем их, чтобы не допустить ошибок:
АвтоЗаполнениеДоступныхПолей по умолчанию принимает значение Ложь. Если его не включить, платформа не станет анализировать текст запроса для поиска доступных полей. Обязательно добавляйте строчку:
НаборДанных.АвтоЗаполнениеДоступныхПолей = Истина;
КомпоновщикНастроек.ЗагрузитьНастройки(СКД.НастройкиПоУмолчанию);
ОграничениеИспользованияВОтборе имеет значение Ложь.
Ниже представлен готовый к использованию шаблон кода, который решает проблему пустых доступных полей отбора. Этот фрагмент кода необходимо разместить в модуле управляемой формы в процедуре ПриСозданииНаСервере:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Шаг 1. Создаем схему компоновки данных программно
СКД = Новый СхемаКомпоновкиДанных;
// Добавляем источник данных
ИсточникДанных = СКД.ИсточникиДанных.Добавить;
ИсточникДанных.Имя = "Local";
ИсточникДанных.ТипИсточникаДанных = "Local";
// Добавляем набор данных - запрос
НаборДанных = СКД.НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));
НаборДанных.Имя = "ОсновнойНаборДанных";
НаборДанных.ИсточникДанных = "Local";
НаборДанных.Запрос =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Номенклатура,
| Номенклатура.Код КАК Код
|ИЗ
| Справочник.Номенклатура КАК Номенклатура";
// КРИТИЧЕСКИ ВАЖНО: Включаем автозаполнение полей запроса
НаборДанных.АвтоЗаполнениеДоступныхПолей = Истина;
// Шаг 2. Помещаем схему во Временное Хранилище с привязкой к форме
АдресСхемыВоВременномХранилище = ПоместитьВоВременноеХранилище(СКД, УникальныйИдентификатор);
// Шаг 3. Инициализируем компоновщик настроек по адресу хранилища
ИсточникНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(АдресСхемыВоВременномХранилище);
КомпоновщикНастроек.Инициализировать(ИсточникНастроек);
// Шаг 4. Загружаем настройки по умолчанию для синхронизации структуры компоновщика
КомпоновщикНастроек.ЗагрузитьНастройки(СКД.НастройкиПоУмолчанию);
КонецПроцедуры
При использовании этого шаблона таблица доступных полей отбора на управляемой форме будет корректно заполняться, стабильно работать во всех клиентских сессиях и позволит пользователям полноценно настраивать фильтрацию данных.