Как динамически обращаться к элементам и реквизитам формы в цикле 1С

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

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

Проблема «пронумерованных» переменных

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

Метод 1: Использование скобочного синтаксиса (Коллекции)

Самый правильный и производительный способ в 1С:Предприятие 8 — это обращение к элементу через квадратные скобки по сформированному имени строки. В обычных формах (например, в УТ 10.3) все элементы управления хранятся в коллекции ЭлементыФормы, а реквизиты объекта или формы — в контексте ЭтотОбъект или ЭтаФорма.

Проанализируем пример кода, который позволяет управлять видимостью колонок в цикле:


Для НомерЦикла = 1 По 10 Цикл
    // Формируем имя колонки динамически
    ИмяКолонки = "Склад" + НомерЦикла;
    
    // Обращаемся к колонке через коллекцию ЭлементыФормы
    ЭлементыФормы.Список.Колонки[ИмяКолонки].Видимость = Ложь;
КонецЦикла;

Этот подход избавляет нас от необходимости писать десять строк кода. Мы просто склеиваем префикс «Склад» и номер итератора, получая доступ к нужному объекту.

Метод 2: Работа с реквизитами формы и объекта

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

Рассмотрим случай, когда нам нужно обнулить значения нескольких реквизитов «КоличествоN»:


Для N = 1 По 5 Цикл
    // Обращение к реквизиту обработки или документа
    ЭтотОбъект["Количество" + N] = 0;
    
    // Если это реквизит именно формы (не объекта)
    ЭтаФорма["пСкл" + N] = Неопределено;
КонецЦикла;

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

Метод 3: Перебор коллекции через «Для каждого»

Иногда мы не знаем точного количества элементов или их индексов, но знаем, что их имена начинаются с определенного слова. В этом случае эффективнее будет перебрать всю коллекцию и проверять имена элементов.

Разберем, как скрыть все колонки складов в табличном поле:


Для Каждого ТекКолонка Из ЭлементыФормы.Список.Колонки Цикл
    // Проверяем, начинается ли имя колонки на "Склад"
    Если Найти(ТекКолонка.Имя, "Склад") > 0 Тогда
        ТекКолонка.Видимость = Ложь;
    КонецЕсли;
КонецЦикла;

Этот метод более универсален: если вы добавите на форму «Склад11», код продолжит работать корректно без изменения границ цикла.

Метод 4: Безопасное обращение через «Найти»

Если существует вероятность, что элемента с конкретным номером может не оказаться на форме (например, «Склад3» удалили), прямое обращение через квадратные скобки Колонки["Склад3"] вызовет ошибку. Чтобы этого избежать, выясним причину возможного сбоя и применим метод Найти().


Для к = 1 По 10 Цикл
    ИмяЭлемента = "пСкл" + к;
    Элемент = ЭлементыФормы.Найти(ИмяЭлемента);
    
    Если Элемент <> Неопределено Тогда
        Элемент.Видимость = Истина;
    КонецЕсли;
КонецЦикла;

Почему не стоит использовать Вычислить() и Выполнить()?

В сообщениях форума упоминался метод Вычислить("Количество" + N + " = 0"). Мы настоятельно рекомендуем избегать таких конструкций по нескольким причинам:

  1. Низкая производительность: интерпретатор тратит время на парсинг строки.
  2. Сложность отладки: вы не сможете легко «провалиться» в ошибку внутри вычисляемой строки.
  3. Безопасность: использование Выполнить() с внешними данными может привести к выполнению нежелательного кода.

Рекомендации по архитектуре

Если вы обнаружили, что создаете переменные пСкл1, пСкл2... пСкл20, проанализируйте ситуацию. Возможно, вместо набора отдельных переменных стоит использовать один реквизит с типом Массив, Структура или ТаблицаЗначений. Это позволит работать с данными стандартными методами коллекций 1С, что сделает ваш код более «чистым» и понятным для других разработчиков.

Использование динамического обращения по имени — мощный инструмент, который делает код лаконичным. Помните о разнице между ЭлементыФормы (визуальные объекты) и данными формы (реквизитами), и всегда выбирайте наиболее безопасный способ обращения к ним.

← На главную