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