Разработка и поддержка интерфейсов на обычных формах в 1С:Предприятии 8 нередко преподносит разработчикам сложные задачи. Одной из таких проблем является работа с большим количеством элементов типа Переключатель (RadioButton). Когда на форме размещено несколько десятков таких элементов, например, для выбора формата загрузки данных от различных поставщиков, визуальный поиск нужного элемента в конфигураторе превращается в рутину.
Особенно остро проблема встает, когда нужно найти конкретный переключатель по его внутреннему свойству Выбираемое значение, так как стандартный поиск по свойствам в конфигураторе не всегда удобен, а порядок обхода элементов на форме может быть нарушен. В этой статье мы подробно разберем, как решить эту проблему программным путем, как ориентироваться в элементах формы и какие интерфейсные альтернативы использовать, чтобы навсегда уйти от этой проблемы.
Прежде чем перейти к решению, проанализируем архитектуру переключателей в обычных формах. Элементы этой группы жестко связаны между собой свойством Порядок обхода (Tab Order). Первый элемент группы имеет признак ПервыйВГруппе = Истина и привязывается к реквизиту формы (свойство Данные). Все последующие переключатели этой группы должны следовать строго друг за другом в порядке обхода. Их связь с реквизитом определяется автоматически именно за счет этой последовательности.
Если в процессе доработки формы порядок обхода нарушается (например, между переключателями случайно вклинивается текстовое поле, кнопка или другой элемент), логика работы группы ломается. Переключатели перестают работать корректно, а свойство ВыбираемоеЗначение может стать недоступным для редактирования. Когда количество переключателей превышает 30-50 штук, ручная поддержка такого интерфейса и поиск нужного элемента отнимают колоссальное количество времени.
Наиболее быстрый и надежный способ найти нужный переключатель — выполнить программный обход коллекции элементов формы. Для этого не обязательно встраивать постоянный код в саму обработку. Достаточно открыть форму в режиме отладки или использовать внешнюю обработку (консоль кода) и выполнить следующий скрипт:
Для Каждого Элемент Из ЭлементыФормы Цикл
Если ТипЗнч(Элемент) = Тип("Переключатель") Тогда
Попытка
Значение = Элемент.ВыбираемоеЗначение;
Заголовок = Элемент.Заголовок;
ИмяЭлемента = Элемент.Имя;
Сообщить("Элемент: " + ИмяЭлемента + " | Заголовок: " + Заголовок + " | Значение: " + Значение);
Исключение
// Обработка исключения на случай непредвиденных типов данных в свойствах
КонецПопытки;
КонецЕсли;
КонецЦикла;
Разберем по шагам, как использовать этот метод на практике:
Переключатель43).Размещение огромного количества статических переключателей на форме считается плохой практикой (антипаттерном) проектирования. Это усложняет поддержку кода, увеличивает время загрузки формы и делает интерфейс неудобным для конечного пользователя. Рассмотрим более эффективные интерфейсные решения, которые избавят вас от необходимости искать и настраивать отдельные радиокнопки.
Вместо размещения 50 отдельных элементов управления мы можем использовать одно ТабличноеПоле, связанное с таблицей значений. В таблице будут всего две колонки: «Выбран» (тип Булево, отображается в виде флажка) и «Наименование формата».
Для того чтобы флажки вели себя как радиокнопки (то есть одновременно мог быть выбран только один формат), мы можем написать простой обработчик события при изменении флажка:
Процедура ТаблицаФорматовПриИзмененииФлажка(Элемент, Колонка)
ТекущаяСтрока = ЭлементыФормы.ТаблицаФорматов.ТекущиеДанные;
Если Колонка.Имя = "Выбран" И ТекущаяСтрока.Выбран Тогда
// Сбрасываем флажки у всех остальных строк
Для Каждого СтрокаФормата Из ТаблицаФорматов Цикл
Если СтрокаФормата <> ТекущаяСтрока Тогда
СтрокаФормата.Выбран = Ложь;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Преимущества этого подхода:
ТаблицаФорматов.Сортировать("Наименование формата Возр");.Если бизнес-требования или привычки пользователей жестко требуют наличия именно радиокнопок на форме, мы можем создавать их программно при инициализации формы. В этом случае мы полностью уходим от ручной настройки порядка обхода в конфигураторе.
Рассмотрим пример программного создания группы переключателей на панели с прокруткой:
Процедура СоздатьПереключателиДинамически()
// Список наших форматов (можно получить из базы данных, макета или массива)
СписокФорматов = ПолучитьСписокФорматовСортированный();
НачальнаяВысота = 20;
ТекущийY = 10;
ТекущийШаг = 25;
Для Каждого ФорматПоставщика Из СписокФорматов Цикл
Индекс = СписокФорматов.Индекс(ФорматПоставщика);
НовыйПереключатель = ЭлементыФормы.Добавить(Тип("Переключатель"), "ДинамПереключатель_" + Индекс, Истина, ЭлементыФормы.ПанельПереключателей);
НовыйПереключатель.Лево = 10;
НовыйПереключатель.Верх = ТекущийY;
НовыйПереключатель.Ширина = 300;
НовыйПереключатель.Высота = НачальнаяВысота;
НовыйПереключатель.Заголовок = ФорматПоставщика.Представление;
НовыйПереключатель.ВыбираемоеЗначение = ФорматПоставщика.Значение;
Если Индекс = 0 Тогда
// Первый элемент группы связываем с реквизитом формы
НовыйПереключатель.ПервыйВГруппе = Истина;
НовыйПереключатель.Данные = "ВыбранныйФорматЗагрузки";
Иначе
// Последующие элементы автоматически связываются по порядку обхода
НовыйПереключатель.ПервыйВГруппе = Ложь;
КонецЕсли;
ТекущийY = ТекущийY + ТекущийШаг;
КонецЦикла;
КонецПроцедуры
Этот метод гарантирует, что переключатели всегда будут идеально отсортированы по алфавиту, а порядок их обхода никогда не нарушится случайным действием программиста в конфигураторе.
Для максимально лаконичного интерфейса рекомендуем заменить группу радиокнопок на обычное поле ввода, у которого включена кнопка списка выбора. При открытии формы список выбора заполняется программно.
Пользователю будет доступен не только выбор кликом мыши, но и удобный автоподбор: при вводе первых букв имени поставщика с клавиатуры система мгновенно позиционируется на нужном значении, что значительно превосходит по удобству поиск глазами среди 50 переключателей на форме.