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

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

При работе с Системой Компоновки Данных (СКД) разработчики часто сталкиваются со странной ситуацией: в конфигураторе или в свойствах элемента формы ПутьКДанным выглядит как понятная цепочка, например, Отчет.КомпоновщикНастроек.ПользовательскиеНастройки[0].Значение. Однако при попытке написать аналогичный код в модуле формы, система выдает ошибку, сообщая, что обращение по индексу недоступно. Выясним причину этого несоответствия и разберем правильные методы программной работы с настройками.

Анализируем причину различия путей

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

Рассмотрим основные причины, по которым возникают различия:

  1. Абстракция коллекций. Платформа намеренно упрощает иерархию объектов в строковых путях. Для интерфейсного механизма коллекция ПользовательскиеНастройки представляется как прямой массив. Однако в программной объектной модели (Object Model) объект типа ПользовательскиеНастройкиКомпоновкиДанных является контейнером, внутри которого физически находится коллекция Элементы.
  2. Сокращение записи. Чтобы сделать строки путей короче и унифицировать их для разных типов данных, платформа исключает промежуточные технические свойства, такие как .Элементы, .Строки или .Колонки. Это стандартное поведение для многих коллекций в 1С.
  3. Разные уровни доступа. Элемент формы «знает», как достучаться до значения напрямую через внутренние механизмы платформы, в то время как встроенный язык требует строгого соблюдения типизации и иерархии объектов.

Правильный программный доступ к настройкам

Проанализируем, как правильно обратиться к пользовательской настройке, если мы знаем ее индекс или хотим перебрать все настройки. Поскольку прямое обращение через квадратные скобки к объекту ПользовательскиеНастройкиКомпоновкиДанных невозможно, мы должны использовать свойство Элементы.

Посмотрим на пример правильного обращения:


// Неправильно (вызовет ошибку):
// Значение = Отчет.КомпоновщикНастроек.ПользовательскиеНастройки[0].Значение;

// Правильно:
Значение = Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы[0].Значение;

Или, если мы работаем в контексте формы отчета:


ЭлементНастройки = ЭтаФорма.Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.Получить(0);
Если ТипЗнч(ЭлементНастройки) = Тип("ЗначениеПараметраНастроекКомпоновкиДанных") Тогда
    ТекущееЗначение = ЭлементНастройки.Значение;
КонецЕсли;

Как надежно найти конкретный параметр (например, Период)

Рассмотрим более сложную, но практическую задачу. Поиск по индексу ([0]) крайне ненадежен, так как состав пользовательских настроек может меняться пользователем или при обновлении схемы компоновки. Чтобы программно найти, например, параметр «Период», необходимо использовать Идентификатор пользовательской настройки.

Выясним алгоритм действий:

  1. Сначала найдем нужный нам параметр в основных настройках компоновщика (те, что заданы в схеме).
  2. Получим его уникальный идентификатор, который связывает основную настройку с пользовательской.
  3. По этому идентификатору найдем элемент в коллекции ПользовательскиеНастройки.Элементы.

Разберем это в коде:


// 1. Ищем параметр в общих настройках
ИмяПараметра = "ПериодОтчета";
ПараметрСКД = Отчет.КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти(ИмяПараметра);

Если ПараметрСКД <> Неопределено Тогда
    // 2. Получаем ID пользовательской настройки
    Идентификатор = ПараметрСКД.ИдентификаторПользовательскойНастройки;
    
    // 3. Ищем соответствующий элемент в пользовательских настройках
    ЭлементПользовательскойНастройки = Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.Найти(Идентификатор);
    
    Если ЭлементПользовательскойНастройки <> Неопределено Тогда
        // Теперь мы можем безопасно работать со значением
        ЭлементПользовательскойНастройки.Значение = ТекущаяДата();
        ЭлементПользовательскойНастройки.Использование = Истина;
    КонецЕсли;
КонецЕсли;

Особенности работы с автоматическими формами СКД

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

Важно помнить: программные имена таких элементов формы часто содержат в себе строковое представление идентификатора настройки. Однако самый надежный способ — это перебор элементов формы и проверка их свойства ПутьКДанным.

Пример поиска элемента формы по пути к данным:


НужныйПуть = "Отчет.КомпоновщикНастроек.ПользовательскиеНастройки[0].Значение";

Для Каждого ТекущийЭлемент Из ЭтаФорма.Элементы Цикл
    // Проверяем, есть ли у элемента свойство ПутьКДанным (оно есть не у всех типов)
    Если Найти(ТипЗнч(ТекущийЭлемент), "ПолеФормы") > 0 Тогда
        Если ТекущийЭлемент.ПутьКДанным = НужныйПуть Тогда
            // Мы нашли поле, можем назначить ему обработчик
            ТекущийЭлемент.УстановитьДействие("ПриИзменении", "Подключаемый_ПриИзмененииНастройки");
        КонецЕсли;
    КонецЕсли;
КонецЦикла;

Резюме

Подведем итоги нашего анализа. Разница между DataPath в свойствах элемента и реальным путем в коде — это архитектурная особенность 1С для упрощения разработки интерфейсов. При написании программного кода всегда помните:

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

← На главную