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