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