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

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

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

Разберем причину: жизненный цикл объекта в управляемом приложении

В обычных формах (ОФ) объект обработки или отчета постоянно «живет» в памяти клиента. В управляемых формах (УФ) ситуация иная: между вызовами сервера состояние объекта не сохраняется автоматически. Каждый раз, когда происходит обращение к серверу через РеквизитФормыВЗначение, объект создается заново, а его переменные модуля обнуляются.

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

Выясним роль метода Инициализировать

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

Посмотрим на пример правильной инициализации в управляемой форме:


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

Важный момент: если вы программно загружаете новые настройки в компоновщик (например, из XML или другого отчета), всегда вызывайте метод Инициализировать повторно, иначе визуальный список доступных полей в интерфейсе может «отвалиться».

Проанализируем проблему потери данных между вызовами сервера

В сообщениях форума автор упоминает, что переменная СхемаВыгрузки затирается. Это происходит потому, что в управляемом приложении контекст модуля объекта теряется. Чтобы избежать постоянной пересборки схемы (что может быть ресурсоемко), рекомендуется кэшировать схему во временном хранилище и сохранять адрес этого хранилища в реквизите формы.

Рассмотрим по шагам алгоритм работы с динамически формируемой схемой:

  1. При создании формы на сервере формируем СКД.
  2. Помещаем СКД во временное хранилище.
  3. Сохраняем адрес хранилища в переменную формы (АдресСхемы).
  4. В любом методе, где требуется работа с компоновщиком (например, перед выводом результата), восстанавливаем связь через этот адрес.

Специфика работы с методом ПолучитьНастройки()

Одной из часто встречающихся ошибок является использование свойства Объект.КомпоновщикНастроек.Настройки вместо метода ПолучитьНастройки(). Проанализируем разницу:

Если в коде для формирования макета компоновки вы используете просто свойство Настройки, то все изменения, внесенные пользователем в интерфейсе, будут проигнорированы. Посмотрим на правильный пример формирования результата:


ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;

// Используем ПолучитьНастройки() для объединения всех правок пользователя
ТекущиеНастройки = Объект.КомпоновщикНастроек.ПолучитьНастройки();

МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаВыгрузки, ТекущиеНастройки, ДанныеРасшифровки);

Проверим настройки пользовательского интерфейса

Иногда поля не отображаются не из-за ошибок в коде, а из-за настроек видимости в самой СКД. В управляемом интерфейсе 1С более строго относится к флажкам ограничений на закладке «Наборы данных».

Рекомендуется проверить следующие пункты:

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

Итоги и рекомендации

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

При соблюдении этих структурных подходов универсальные обработки и сложные отчеты на базе СКД будут работать стабильно, обеспечивая пользователю полный доступ ко всем полям метаданных.

← На главную