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