Как правильно обойти элементы управляемой формы в 1С и изменить их доступность?

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

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

Выясняем причину ошибки: Элементы против ЭлементовФормы

Первым делом проанализируем ситуацию, описанную автором темы. Попытка использовать привычное по «обычным» формам свойство ЭлементыФормы в тонком клиенте (управляемом приложении) приводит к ошибке компиляции. Почему так происходит? В платформе 1С:Предприятие 8.3 для управляемых форм разработчики изменили объектную модель.

Разберем основные отличия:

  1. Обычные формы (Толстый клиент): Используется коллекция ЭлементыФормы. Она содержит плоский список всех объектов, размещенных на форме.
  2. Управляемые формы (Тонкий/Веб-клиент): Используется коллекция Элементы. Она имеет иерархическую структуру, где элементы могут быть вложены в группы, страницы и таблицы.

Следовательно, для исправления ошибки в коде достаточно заменить ЭлементыФормы на Элементы. Рассмотрим правильный синтаксис обращения:


// Правильное обращение в управляемой форме
Для Каждого ЭлементФормы Из Элементы Цикл 
    // Ваш код обработки элемента
КонецЦикла;

Простой обход коллекции элементов

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

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


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

В данном коде мы проанализируем типы объектов. Важно понимать, что если мы установим Доступность = Ложь для объекта типа ГруппаФормы, то все элементы внутри этой группы автоматически станут недоступными. Это мощный инструмент, который позволяет управлять интерфейсом целыми блоками.

Рекурсивный обход: работа со сложными интерфейсами

Как мы уже упоминали, коллекция Элементы в управляемом приложении иерархична. Простой цикл Для каждого по коллекции Элементы увидит только объекты «верхнего уровня» (те, что не вложены в другие группы). Если ваша форма имеет сложную структуру со страницами и подгруппами, простой цикл может не сработать для глубоко вложенных полей.

Рассмотрим более продвинутый, рекурсивный метод обхода. Этот способ позволяет добраться до каждого «закоулка» формы, независимо от того, насколько глубоко спрятан элемент.


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

Проанализируем этот подход (который также полезен при доработке динамических списков). Использование свойства ПодчиненныеЭлементы позволяет нам «проваливаться» внутрь групп. Это гарантирует, что ни один элемент не будет пропущен.

Выбор между Доступностью и ТолькоПросмотром

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

Доступность (Enabled):

ТолькоПросмотр (ReadOnly):

Если ваша задача — запретить редактирование документа, но оставить возможность копирования данных, лучше использовать свойство формы ЭтаФорма.ТолькоПросмотр = Истина;. Однако, если вам нужно оставить доступным один конкретный элемент (например, кнопку «Разблокировать»), то общая блокировка формы не подойдет, и придется использовать перебор элементов в цикле, как мы рассмотрели выше.

Оптимизация работы с кнопками и командами

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

Например, если у вас есть кнопка, связанная с командой ЗаписатьИЗакрыть, вы можете выполнить следующий код:

ЭтаФорма.Команды.ЗаписатьИЗакрыть.Доступность = Ложь;

Это автоматически отключит все кнопки на форме, которые связаны с этой командой (например, и в командной панели, и где-нибудь внизу формы). Это более «чистый» и надежный способ управления логикой приложения.

Итоги и рекомендации

Подводя итог нашему разбору, выделим ключевые правила работы с элементами формы в 1С 8.3:

  1. Всегда используйте Элементы вместо ЭлементыФормы в управляемом приложении.
  2. При обходе коллекции учитывайте, что формы иерархичны. Для сложных интерфейсов используйте свойство ПодчиненныеЭлементы.
  3. Различайте визуальное состояние: Доступность блокирует взаимодействие полностью, а ТолькоПросмотр позволяет просматривать и копировать данные.
  4. Для массового изменения свойств учитывайте типы элементов (ДекорацияФормы, ГруппаФормы), чтобы избежать ошибок выполнения или нежелательного поведения интерфейса.

Используя предложенные методики, вы сможете гибко управлять интерфейсом ваших решений, делая их удобными и защищенными от ошибочных действий пользователя.

← На главную