Работа с Системой компоновки данных (СКД) программно — это мощный инструмент, который позволяет создавать гибкие отчеты «на лету» — для этого пригодится инструменты разработчика с консолью запросов и СКД. Однако часто разработчики сталкиваются с ситуацией: поле в код добавлено, в наборе данных оно присутствует, но в пользовательских настройках (в списке «Доступные поля») оно не отображается. Рассмотрим подробно, почему это происходит и как правильно реализовать программное добавление полей, чтобы они стали доступны пользователю.
Проанализируем ситуацию: когда мы работаем с СКД через конструктор, платформа берет на себя много рутинных операций. При программном подходе нам нужно явно указать системе, что новое поле предназначено для выбора пользователем. Основных причин отсутствия поля в списке выбора обычно три:
ВЫБРАТЬ недостаточно. Для СКД критически важны фигурные скобки {}.ОграничениеИспользованияВВыбранныхПолях. Если они установлены в Истина, поле будет скрыто.Рассмотрим случай, когда используется Набор данных - запрос. Для того чтобы СКД поняла, что поле является «доступным», оно должно быть описано в секции расширения (в фигурных скобках). Если вы динамически меняете текст запроса, вам нужно добавить поле и в основную выборку, и в блок {ВЫБРАТЬ...}.
Посмотрим на пример кода, который автоматизирует эту замену:
// Предположим, у нас есть существующий запрос в НабореДанных
ТекстЗапроса = НаборСКД.Запрос;
// 1. Добавляем поле в основную выборку (после ключевого слова ВЫБРАТЬ)
ПодстрокаПоиска = "ЕСТЬNULL(Источник.Номенклатура, ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)) КАК Номенклатура";
ПодстрокаЗамены = ПодстрокаПоиска + ", ИсходныеДанные.Вес КАК ВесДляОтчетов";
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, ПодстрокаПоиска, ПодстрокаЗамены);
// 2. Добавляем поле в секцию расширения СКД (фигурные скобки)
// Это именно то, что делает поле ДОСТУПНЫМ для выбора пользователем
ПодстрокаПоиска2 = "Номенклатура.*}";
ПодстрокаЗамены2 = "Номенклатура.*, ВесДляОтчетов}";
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, ПодстрокаПоиска2, ПодстрокаЗамены2);
НаборСКД.Запрос = ТекстЗапроса;
После изменения текста запроса необходимо обязательно добавить описание поля в объектную модель набора данных:
НовоеПоле = НаборСКД.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
НовоеПоле.Заголовок = "Вес для отчетов";
НовоеПоле.ПутьКДанным = "ВесДляОтчетов";
НовоеПоле.Поле = "ВесДляОтчетов";
НовоеПоле.ТипЗначения = Новый ОписаниеТипов("Число");
Выясним причину, почему даже при правильном запросе поля могут не появиться на форме. Это происходит из-за того, что КомпоновщикНастроек инициализируется один раз при создании отчета. Если мы программно «подсунули» в схему новые поля, компоновщик об этом не знает.
Проанализируем ситуацию: чтобы обновить список доступных полей на форме, нам нужно выполнить инициализацию заново. Рассмотрим, как это сделать правильно:
// 1. Помещаем измененную схему во временное хранилище
АдресСхемы = ПоместитьВоВременноеХранилище(СхемаКомпоновкиДанных, ЭтаФорма.УникальныйИдентификатор);
// 2. Инициализируем компоновщик новым источником доступных настроек
ИсточникНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(АдресСхемы);
КомпоновщикНастроек.Инициализировать(ИсточникНастроек);
// 3. После этого компоновщик перечитает схему, и новые поля появятся в дереве доступных полей
Важный нюанс: при повторной инициализации текущие настройки пользователя (выбранные поля, фильтры) могут сброситься. Если вам нужно их сохранить, предварительно выгрузите их в переменную через КомпоновщикНастроек.ПолучитьНастройки(), а после инициализации загрузите обратно через ЗагрузитьНастройки().
Если вы используете Набор данных - объект (передаете таблицу значений), секция с фигурными скобками в запросе отсутствует. Здесь порядок действий немного проще, но требования к уникальности имен строже. Рассмотрим пример программного создания набора данных «с нуля»:
// Создаем источник данных
ИсточникДанных = СхемаКомпоновкиДанных.ИсточникиДанных.Добавить;
ИсточникДанных.Имя = "ИсточникДанных1";
ИсточникДанных.ТипИсточникаДанных = "Local";
// Создаем набор данных (Объект)
НаборДанных = СхемаКомпоновкиДанных.НаборыДанных.Добавить(Тип("НаборДанныхОбъектСхемыКомпоновкиДанных"));
НаборДанных.Имя = "НаборДанныхОбъект";
НаборДанных.ИмяОбъекта = "ТаблицаВнешнихДанных"; // Имя ТЗ, которую передадим в процессор
НаборДанных.ИсточникДанных = "ИсточникДанных1";
// Добавляем поле
Поле = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
Поле.Заголовок = "Сотрудник";
Поле.ПутьКДанным = "Сотрудник"; // Именно этот путь будет виден в доступных полях
Поле.Поле = "Сотрудник";
Поле.ТипЗначения = Новый ОписаниеТипов("СправочникСсылка.Сотрудники");
При использовании объектного набора данных убедитесь, что ПутьКДанным не содержит точек (кроме случаев обращения к реквизитам) и совпадает с именем колонки в передаваемой таблице значений. Если поле должно быть ресурсом, не забудьте добавить его в коллекцию ПоляИтога схемы:
ПолеРесурса = СхемаКомпоновкиДанных.ПоляИтога.Добавить;
ПолеРесурса.ПутьКДанным = "КоличествоЗамеров";
ПолеРесурса.Выражение = "СУММА(КоличествоЗамеров)";
Если после всех манипуляций поле всё равно не отображается в списке выбора, проверим свойства программно созданного поля. В СКД существуют настройки, которые могут блокировать использование поля в определенных частях отчета. Убедимся, что параметры доступности установлены в значение Ложь (то есть ограничения отсутствуют):
ОграничениеИспользованияВВыбранныхПолях — должно быть Ложь.ОграничениеИспользованияВОтборе — должно быть Ложь.ОграничениеИспользованияВГруппировке — должно быть Ложь.Проанализируем пример установки этих свойств:
Поле = НаборДанных.Поля.Найти("ПериодГодТ");
Если Поле <> Неопределено Тогда
Поле.ОграничениеИспользованияВВыбранныхПолях = Ложь;
Поле.ОграничениеИспользованияВОтборе = Ложь;
Поле.ОграничениеИспользованияВПорядке = Ложь;
КонецЕсли;
Для успешного программного добавления полей в СКД мы должны выполнить три обязательных шага:
Поля соответствующего набора данных схемы.{ВЫБРАТЬ ...}.КомпоновщикаНастроек, используя ИсточникДоступныхНастроекКомпоновкиДанных.Соблюдение этого алгоритма гарантирует, что ваши программные изменения корректно отобразятся в пользовательском интерфейсе, и пользователь сможет выбирать новые поля для вывода в отчет или использования в фильтрах.