Почему в компоновщике настроек пустые доступные поля отбора и как это исправить?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

В этой статье мы подробно разберем, почему возникает эта проблема, изучим внутренние механизмы платформы «1С:Предприятие» и напишем правильный, отказоустойчивый код для инициализации компоновщика настроек на управляемой форме.

В чем кроется причина проблемы? Разбор архитектуры 1С

Главная причина, по которой список доступных полей отбора оказывается пустым при передаче самого объекта СхемаКомпоновкиДанных в конструктор источника настроек, заключается в особенностях клиент-серверного взаимодействия на управляемых формах.

Рассмотрим эту цепочку событий детально:

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

Важность привязки к уникальному идентификатору формы

Просто поместить схему во временное хранилище недостаточно. Рассмотрим следующий вызов:

АдресСхемы = ПоместитьВоВременноеХранилище(СКД); // Ошибка! Нет привязки к форме

Если мы не передадим вторым параметром уникальный идентификатор формы, помещенные данные будут жить в хранилище только до первого серверного вызова (так называемый roundtrip). При первом же интерактивном действии пользователя на форме адрес станет недействительным, и доступные поля снова бесследно пропадут.

Для решения этой проблемы необходимо явно связывать время жизни данных в хранилище с временем жизни формы, передавая УникальныйИдентификатор текущей формы:

АдресСхемы = ПоместитьВоВременноеХранилище(СКД, УникальныйИдентификатор);

Теперь схема гарантированно будет находиться в памяти сервера до тех пор, пока пользователь не закроет данную форму.

Дополнительные подводные камни программной настройки СКД

Даже если схема успешно помещена в хранилище, поля отбора могут остаться пустыми по другим распространенным причинам, связанным с программным конструированием схемы. Разберем их, чтобы не допустить ошибок:

Готовый шаблон правильной программной инициализации СКД

Ниже представлен готовый к использованию шаблон кода, который решает проблему пустых доступных полей отбора. Этот фрагмент кода необходимо разместить в модуле управляемой формы в процедуре ПриСозданииНаСервере:


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

При использовании этого шаблона таблица доступных полей отбора на управляемой форме будет корректно заполняться, стабильно работать во всех клиентских сессиях и позволит пользователям полноценно настраивать фильтрацию данных.

← На главную