Как получить значение реквизита по сложному свойству ПутьКДанным в управляемой форме 1С?

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

В процессе разработки управляемых форм 1С программисты часто сталкиваются с нестандартным проектированием интерфейса. Например, когда строки табличной части отображаются постранично на отдельных вкладках панели, а привязка элементов управления к данным формируется динамически в виде составного пути: Объект.ТЧОбъекта[0].Реквизит1.

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

Особенности и риски использования функции Вычислить() для путей к данным

Посмотрим на пример вызова, который на первый взгляд решает проблему получения значения по произвольной строке пути:

ЗначениеРеквизита = Вычислить(ЭлементФормы.ПутьКДанным);

В контексте клиентского модуля управляемой формы выражение вида Вычислить("Объект.ТЧОбъекта[0].Реквизит1") действительно вернет значение без явного серверного вызова, если коллекция уже находится в контексте формы в виде объекта ДанныеФормыКоллекция. Однако постоянное использование динамического вычисления выражений в интерфейсных механизмах влечет за собой ряд серьезных проблем:

  1. Падение производительности. Функция Вычислить() каждый раз инициирует динамическую компиляцию и интерпретацию переданной строки. При регулярном вызове в цикле или обработчиках событий формы это создает дополнительную нагрузку по сравнению с прямым обращением к свойствам объектов.
  2. Работа только в режиме чтения. Конструкция Вычислить() позволяет лишь прочитать данные. Выполнить обратную операцию — программно присвоить новое значение реквизиту по его строковому пути — с ее помощью невозможно.
  3. Сложности отладки и диагностирования ошибок. Если в момент вычисления произойдет сбой (например, индекс выйдет за границы коллекции или промежуточный объект примет значение Неопределено), платформа сформирует исключение в динамическом виртуальном контексте. Это существенно усложняет анализ журналов ошибок и локализацию проблемы при сопровождении конфигурации.
  4. Ограничения безопасности. Выполнение динамического кода может блокироваться платформой в безопасном режиме исполнения модулей или при строгих профилях безопасности кластера серверов. Кроме того, динамическое исполнение сформированных на клиенте строк считается нежелательной практикой с точки зрения стандартов разработки фирмы «1С».

Альтернатива 1. Прямой доступ к строкам коллекции на клиенте

Проанализируем структуру данных формы. Табличные части и списки в управляемой форме представлены специализированными типами платформы: ДанныеФормыКоллекция и ДанныеФормыЭлементКоллекции. Вся таблица уже загружена в контекст формы, поэтому для доступа к ее строкам по известному индексу нет необходимости вызывать поиск через НайтиСтроки() или обращаться к серверу.

Если известен номер или индекс строки, правильнее использовать прямое обращение по индексу к свойству Объект:


// Прямой доступ к строке коллекции без динамической компиляции
ИндексСтроки = 0;
Если Объект.ТЧОбъекта.Количество() > ИндексСтроки Тогда
    СтрокаТЧ = Объект.ТЧОбъекта[ИндексСтроки];
    ЗначениеРеквизита = СтрокаТЧ.Реквизит1;
КонецЕсли;

Если данные привязаны к элементу, выбранному пользователем в текущий момент, рекомендуется обращаться к выделенной строке через свойство ТекущиеДанные соответствующего элемента формы:


ТекущаяСтрока = Элементы.ТабличнаяЧасть.ТекущиеДанные;
Если ТекущаяСтрока <> Неопределено Тогда
    ЗначениеРеквизита = ТекущаяСтрока.Реквизит1;
КонецЕсли;

Альтернатива 2. Безопасный итеративный разбор составного пути к данным

Если в конфигурации требуется универсальная процедура, способная получать и устанавливать значения по произвольным вложенным путям (включая реквизиты составных объектов и табличных частей), разберем безопасный алгоритм разбора строки без вызова Вычислить().

Алгоритм последовательно разбирает путь к данным на составляющие сегменты и разыменовывает их через оператор квадратных скобок [] или метод Получить():


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

Рассмотрим преимущества такого подхода:

  1. Стабильность и предсказуемость: код выполняется стандартным интерпретатором без создания временных модулей и не нарушает профили безопасности.
  2. Безопасная обработка исключений: при передаче некорректного индекса или отсутствующего свойства алгоритм возвращает Неопределено без аварийного завершения работы формы.
  3. Универсальность: расширив логику последнего шага цикла, этот же подход позволяет реализовать процедуру безопасной записи значения в реквизит по строковому пути.
← На главную