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