При разработке сложных отчетов на базе Системы компоновки данных (СКД) часто возникает задача программного анализа структуры отчета. Например, когда нам нужно получить список полей, выбранных пользователем, узнать их типы или программно изменить вывод данных в нетипичный интерфейс. Основная сложность здесь заключается в понимании того, как объект ПолеКомпоновкиДанных, находящийся в настройках (группировках или выбранных полях), соотносится с конкретными полями в НаборахДанных схемы компоновки.
В этой статье мы подробно разберем механизмы этой связи, рассмотрим несколько способов получения метаданных полей и напишем примеры кода для решения практических задач.
Разберем ситуацию: у нас есть объект ПолеКомпоновкиДанных, полученный из коллекции ВыбранныеПоля. На первый взгляд, это сложный объект, но на самом деле он является оболочкой для строки, которая описывает уникальный Путь к данным. Именно этот путь является ключом, связывающим настройки и описание данных в схеме.
Проанализируем, как получить этот путь. Самый простой и эффективный способ — преобразовать объект поля в строку. 1С спроектирована так, что при приведении ПолеКомпоновкиДанных к строковому типу мы получаем именно тот идентификатор, который указан в поле Путь к данным в схеме компоновки (на вкладке "Наборы данных" или "Вычисляемые поля").
// Пример получения строкового пути из выбранного поля
Для Каждого ЭлементИзВыбранныхПолей Из КомпоновщикНастроек.Настройки.Выбор.Элементы Цикл
Если ТипЗнч(ЭлементИзВыбранныхПолей) = Тип("ВыбранноеПолеКомпоновкиДанных") Тогда
ПутьКДанным = Строка(ЭлементИзВыбранныхПолей.Поле);
Сообщить("Выбранное поле имеет путь: " + ПутьКДанным);
КонецЕсли;
КонецЦикла;
Если нам нужно найти подробную информацию о поле (например, его заголовок, тип значения или роль), мы можем обратиться напрямую к СхемеКомпоновкиДанных. Однако стоит помнить, что поля могут находиться в разных местах схемы. Рассмотрим алгоритм поиска:
НаборДанных (будь то запрос или объект) есть коллекция Поля.ВычисляемыеПоля схемы компоновки.ПутьКДанным каждого найденного элемента.Проанализируем пример кода для поиска поля в схеме:
Функция НайтиОписаниеПоляВСхеме(Схема, ПутьКДанным)
// Ищем в наборах данных
Для Каждого Набор Из Схема.НаборыДанных Цикл
Для Каждого Поле Из Набор.Поля Цикл
Если Поле.ПутьКДанным = ПутьКДанным Тогда
Возврат Поле;
КонецЕсли;
КонецЦикла;
КонецЦикла;
// Ищем в вычисляемых полях
Для Каждого Поле Из Схема.ВычисляемыеПоля Цикл
Если Поле.ПутьКДанным = ПутьКДанным Тогда
Возврат Поле;
КонецЕсли;
КонецЦикла;
Возврат Неопределено;
КонецФункции
Выясним, почему ручной перебор схемы не всегда удобен. Основная причина — вложенные поля. Если пользователь выбрал поле Контрагент.ИНН, то в самой схеме (в наборах данных) такого поля может не быть. Там есть только Контрагент. Механизм СКД автоматически "разворачивает" свойства объектов через точку.
Чтобы не заниматься рекурсивным разбором метаданных конфигурации самостоятельно, лучше использовать свойство ДоступныеПоля объекта КомпоновщикНастроек. Рассмотрим, как это работает:
ДоступныеПоляВыбора, ДоступныеПоляГруппировок и другие.НайтиПоле() этих коллекций принимает объект ПолеКомпоновкиДанных и возвращает объект типа ДоступноеПолеКомпоновкиДанных.ТипЗначения, Заголовок и возможность работы с иерархией.Посмотрим на пример реализации, который решает задачу автора темы — получение типов выбранных пользователем полей:
// Получаем настройки, которые действуют в данный момент (с учетом пользовательских)
Настройки = КомпоновщикНастроек.ПолучитьНастройки();
ДоступныеПоля = КомпоновщикНастроек.Настройки.ДоступныеПоляВыбора;
Для Каждого ВыбранноеПоле Из Настройки.Выбор.Элементы Цикл
Если ТипЗнч(ВыбранноеПоле) <> Тип("ВыбранноеПолеКомпоновкиДанных") Тогда
Продолжить;
КонецЕсли;
// Ищем описание поля среди доступных полей
ОписаниеПоля = ДоступныеПоля.НайтиПоле(ВыбранноеПоле.Поле);
Если ОписаниеПоля <> Неопределено Тогда
ТекстЗаголовка = ?(ЗначениеЗаполнено(ВыбранноеПоле.Заголовок), ВыбранноеПоле.Заголовок, ОписаниеПоля.Заголовок);
ТипПоля = ОписаниеПоля.ТипЗначения;
Сообщить("Поле: " + ТекстЗаголовка + " | Тип: " + ТипПоля);
КонецЕсли;
КонецЦикла;
Разберем несколько критических моментов, которые часто упускают при разработке:
1. Фиксированные настройки: При программном формировании отчета не забывайте проверять КомпоновщикНастроек.FixedSettings. Если поле добавлено в фиксированные настройки, оно может отсутствовать в обычных Settings, но все равно будет выводиться в отчет.
2. Пользовательские поля: Если пользователь создал свое поле (например, формулу) прямо в режиме "1С:Предприятие", оно будет находиться в коллекции ПользовательскиеПоля. Путь к такому полю будет иметь специфический вид (например, ПользовательскиеПоля.Поле1). Для их обработки нужно отдельно анализировать коллекцию Настройки.ПользовательскиеПоля.
3. Идентификаторы: Для надежной связи элементов структуры (группировок) с их настройками используйте свойство ИдентификаторПользовательскойНастройки. Это позволит вам точно знать, какой элемент структуры изменил пользователь в интерфейсе.
Для того чтобы предоставить пользователю список полей с их типами из СКД и затем вывести только нужные колонки, нам необходимо выполнить следующие шаги:
КомпоновщикНастроек для доступа к текущим настройкам.ДоступныеПоляВыбора получить список всех возможных полей, их заголовков и типов.ПолеКомпоновкиДанных с данными в результате (например, через ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений), ориентируясь на строковое имя колонки, которое совпадает с путем к данным.Таким образом, основной связью является строковый путь к данным, а наиболее удобным инструментом для получения метаданных этого пути является коллекция Доступных полей компоновщика настроек.