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