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

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

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

Разберем основные причины «невидимости» полей

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

  1. Отсутствие поля в расширении языка запросов: Если ваш набор данных — это запрос, то простого упоминания поля в блоке ВЫБРАТЬ недостаточно. Для СКД критически важны фигурные скобки {}.
  2. Компоновщик настроек не переинициализирован: Компоновщик настроек (объект, отвечающий за интерфейс выбора полей) хранит кэш доступных полей. Если вы изменили саму Схему (СхемаКомпоновкиДанных), но не обновили Компоновщик, он будет «помнить» только старый набор полей.
  3. Установленные ограничения: У поля набора данных есть свойства-флаги, такие как ОграничениеИспользованияВВыбранныхПолях. Если они установлены в Истина, поле будет скрыто.

Решение 1: Правильная модификация текста запроса

Рассмотрим случай, когда используется Набор данных - запрос. Для того чтобы СКД поняла, что поле является «доступным», оно должно быть описано в секции расширения (в фигурных скобках). Если вы динамически меняете текст запроса, вам нужно добавить поле и в основную выборку, и в блок {ВЫБРАТЬ...}.

Посмотрим на пример кода, который автоматизирует эту замену:


// Предположим, у нас есть существующий запрос в НабореДанных
ТекстЗапроса = НаборСКД.Запрос;

// 1. Добавляем поле в основную выборку (после ключевого слова ВЫБРАТЬ)
ПодстрокаПоиска = "ЕСТЬNULL(Источник.Номенклатура, ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)) КАК Номенклатура";
ПодстрокаЗамены = ПодстрокаПоиска + ", ИсходныеДанные.Вес КАК ВесДляОтчетов";
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, ПодстрокаПоиска, ПодстрокаЗамены);

// 2. Добавляем поле в секцию расширения СКД (фигурные скобки)
// Это именно то, что делает поле ДОСТУПНЫМ для выбора пользователем
ПодстрокаПоиска2 = "Номенклатура.*}";
ПодстрокаЗамены2 = "Номенклатура.*, ВесДляОтчетов}";
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, ПодстрокаПоиска2, ПодстрокаЗамены2);

НаборСКД.Запрос = ТекстЗапроса;

После изменения текста запроса необходимо обязательно добавить описание поля в объектную модель набора данных:


НовоеПоле = НаборСКД.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
НовоеПоле.Заголовок = "Вес для отчетов";
НовоеПоле.ПутьКДанным = "ВесДляОтчетов";
НовоеПоле.Поле = "ВесДляОтчетов";
НовоеПоле.ТипЗначения = Новый ОписаниеТипов("Число");

Решение 2: Инициализация Компоновщика настроек

Выясним причину, почему даже при правильном запросе поля могут не появиться на форме. Это происходит из-за того, что КомпоновщикНастроек инициализируется один раз при создании отчета. Если мы программно «подсунули» в схему новые поля, компоновщик об этом не знает.

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


// 1. Помещаем измененную схему во временное хранилище
АдресСхемы = ПоместитьВоВременноеХранилище(СхемаКомпоновкиДанных, ЭтаФорма.УникальныйИдентификатор);

// 2. Инициализируем компоновщик новым источником доступных настроек
ИсточникНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(АдресСхемы);
КомпоновщикНастроек.Инициализировать(ИсточникНастроек);

// 3. После этого компоновщик перечитает схему, и новые поля появятся в дереве доступных полей

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

Решение 3: Работа с Набором данных - объект

Если вы используете Набор данных - объект (передаете таблицу значений), секция с фигурными скобками в запросе отсутствует. Здесь порядок действий немного проще, но требования к уникальности имен строже. Рассмотрим пример программного создания набора данных «с нуля»:


// Создаем источник данных
ИсточникДанных = СхемаКомпоновкиДанных.ИсточникиДанных.Добавить;
ИсточникДанных.Имя = "ИсточникДанных1";
ИсточникДанных.ТипИсточникаДанных = "Local";

// Создаем набор данных (Объект)
НаборДанных = СхемаКомпоновкиДанных.НаборыДанных.Добавить(Тип("НаборДанныхОбъектСхемыКомпоновкиДанных"));
НаборДанных.Имя = "НаборДанныхОбъект";
НаборДанных.ИмяОбъекта = "ТаблицаВнешнихДанных"; // Имя ТЗ, которую передадим в процессор
НаборДанных.ИсточникДанных = "ИсточникДанных1";

// Добавляем поле
Поле = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
Поле.Заголовок = "Сотрудник";
Поле.ПутьКДанным = "Сотрудник"; // Именно этот путь будет виден в доступных полях
Поле.Поле = "Сотрудник";
Поле.ТипЗначения = Новый ОписаниеТипов("СправочникСсылка.Сотрудники");

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


ПолеРесурса = СхемаКомпоновкиДанных.ПоляИтога.Добавить;
ПолеРесурса.ПутьКДанным = "КоличествоЗамеров";
ПолеРесурса.Выражение = "СУММА(КоличествоЗамеров)";

Проверка ограничений видимости

Если после всех манипуляций поле всё равно не отображается в списке выбора, проверим свойства программно созданного поля. В СКД существуют настройки, которые могут блокировать использование поля в определенных частях отчета. Убедимся, что параметры доступности установлены в значение Ложь (то есть ограничения отсутствуют):

Проанализируем пример установки этих свойств:


Поле = НаборДанных.Поля.Найти("ПериодГодТ");
Если Поле <> Неопределено Тогда
    Поле.ОграничениеИспользованияВВыбранныхПолях = Ложь;
    Поле.ОграничениеИспользованияВОтборе = Ложь;
    Поле.ОграничениеИспользованияВПорядке = Ложь;
КонецЕсли;

Подведем итоги

Для успешного программного добавления полей в СКД мы должны выполнить три обязательных шага:

  1. Добавить описание поля в коллекцию Поля соответствующего набора данных схемы.
  2. Если это запрос — убедиться, что поле прописано в тексте запроса внутри блока {ВЫБРАТЬ ...}.
  3. Выполнить переинициализацию КомпоновщикаНастроек, используя ИсточникДоступныхНастроекКомпоновкиДанных.

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

← На главную