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