При переходе с обычных форм на управляемые разработчики часто сталкиваются с досадной ошибкой: «Переменная не определена (ЭлементыФормы)». Эта ситуация возникает из-за глубоких различий в архитектуре платформ. Давайте подробно разберем, почему «лыжи не едут», как правильно обращаться к коллекции элементов в современном интерфейсе 1С и каким образом эффективно управлять доступностью полей на форме.
Первым делом проанализируем ситуацию, описанную автором темы. Попытка использовать привычное по «обычным» формам свойство ЭлементыФормы в тонком клиенте (управляемом приложении) приводит к ошибке компиляции. Почему так происходит? В платформе 1С:Предприятие 8.3 для управляемых форм разработчики изменили объектную модель.
Разберем основные отличия:
ЭлементыФормы. Она содержит плоский список всех объектов, размещенных на форме.Элементы. Она имеет иерархическую структуру, где элементы могут быть вложены в группы, страницы и таблицы.Следовательно, для исправления ошибки в коде достаточно заменить ЭлементыФормы на Элементы. Рассмотрим правильный синтаксис обращения:
// Правильное обращение в управляемой форме
Для Каждого ЭлементФормы Из Элементы Цикл
// Ваш код обработки элемента
КонецЦикла;
Рассмотрим практическую задачу: нам необходимо программно запретить редактирование всех полей на форме, кроме одного конкретного реквизита (например, флажка, который снимает блокировку). Самый простой способ — перебрать коллекцию Элементы в цикле.
Посмотрим на пример процедуры, которая управляет доступностью:
&НаКлиенте
Процедура УстановитьДоступностьЭлементовФормы(ЗначениеДоступности)
Для Каждого ЭлементФормы Из Элементы Цикл
// Нам нужно пропустить группы и декорации, так как у них
// управление доступностью работает иначе или не требуется
ЭтоТехническийЭлемент = (ТипЗнч(ЭлементФормы) = Тип("ДекорацияФормы"))
ИЛИ (ТипЗнч(ЭлементФормы) = Тип("ГруппаФормы"))
ИЛИ (ТипЗнч(ЭлементФормы) = Тип("ДополнениеЭлементаФормы"));
Если НЕ ЭтоТехническийЭлемент Тогда
ЭлементФормы.Доступность = ЗначениеДоступности;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
В данном коде мы проанализируем типы объектов. Важно понимать, что если мы установим Доступность = Ложь для объекта типа ГруппаФормы, то все элементы внутри этой группы автоматически станут недоступными. Это мощный инструмент, который позволяет управлять интерфейсом целыми блоками.
Как мы уже упоминали, коллекция Элементы в управляемом приложении иерархична. Простой цикл Для каждого по коллекции Элементы увидит только объекты «верхнего уровня» (те, что не вложены в другие группы). Если ваша форма имеет сложную структуру со страницами и подгруппами, простой цикл может не сработать для глубоко вложенных полей.
Рассмотрим более продвинутый, рекурсивный метод обхода. Этот способ позволяет добраться до каждого «закоулка» формы, независимо от того, насколько глубоко спрятан элемент.
&НаКлиенте
Процедура УстановитьТолькоПросмотрРекурсивно(КоллекцияЭлементов, ЗначениеДоступности)
Для Каждого ТекущийЭлемент Из КоллекцияЭлементов Цикл
// Если это группа или таблица, заходим внутрь
Если ТипЗнч(ТекущийЭлемент) = Тип("ГруппаФормы")
ИЛИ ТипЗнч(ТекущийЭлемент) = Тип("ТаблицаФормы") Тогда
// Рекурсивный вызов для подчиненных элементов
УстановитьТолькоПросмотрРекурсивно(ТекущийЭлемент.ПодчиненныеЭлементы, ЗначениеДоступности);
ИначеЕсли ТипЗнч(ТекущийЭлемент) = Тип("ПолеФормы")
ИЛИ ТипЗнч(ТекущийЭлемент) = Тип("КнопкаФормы") Тогда
// Устанавливаем доступность только для значимых элементов
ТекущийЭлемент.Доступность = ЗначениеДоступности;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Проанализируем этот подход (который также полезен при доработке динамических списков). Использование свойства ПодчиненныеЭлементы позволяет нам «проваливаться» внутрь групп. Это гарантирует, что ни один элемент не будет пропущен.
В процессе решения задачи автор темы столкнулся с дилеммой: использовать ТолькоПросмотр или Доступность (также полезно изучить код создания условного оформления). Это важный архитектурный момент, который стоит разобрать подробнее.
Доступность (Enabled):
ТолькоПросмотр (ReadOnly):
КнопкаФормы нет свойства ТолькоПросмотр. Чтобы отключить кнопку, всегда используется Доступность.Если ваша задача — запретить редактирование документа, но оставить возможность копирования данных, лучше использовать свойство формы ЭтаФорма.ТолькоПросмотр = Истина;. Однако, если вам нужно оставить доступным один конкретный элемент (например, кнопку «Разблокировать»), то общая блокировка формы не подойдет, и придется использовать перебор элементов в цикле, как мы рассмотрели выше.
Разберем еще один нюанс, который часто упускают. В управляемых формах кнопки жестко связаны с Командами. Если вы хотите отключить кнопку, можно воздействовать не на саму кнопку (как элемент формы), а на её команду.
Например, если у вас есть кнопка, связанная с командой ЗаписатьИЗакрыть, вы можете выполнить следующий код:
ЭтаФорма.Команды.ЗаписатьИЗакрыть.Доступность = Ложь;
Это автоматически отключит все кнопки на форме, которые связаны с этой командой (например, и в командной панели, и где-нибудь внизу формы). Это более «чистый» и надежный способ управления логикой приложения.
Подводя итог нашему разбору, выделим ключевые правила работы с элементами формы в 1С 8.3:
Элементы вместо ЭлементыФормы в управляемом приложении.ПодчиненныеЭлементы.Доступность блокирует взаимодействие полностью, а ТолькоПросмотр позволяет просматривать и копировать данные.ДекорацияФормы, ГруппаФормы), чтобы избежать ошибок выполнения или нежелательного поведения интерфейса.Используя предложенные методики, вы сможете гибко управлять интерфейсом ваших решений, делая их удобными и защищенными от ошибочных действий пользователя.