Как сделать одну командную панель для нескольких таблиц на управляемой форме?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке сложных интерфейсов на управляемых формах 1С часто возникает задача разместить несколько таблиц (например, динамически создаваемых на разных страницах формы) и привязать к ним единую командную панель. Главная проблема заключается в том, что свойство ИсточникКоманд элемента управления КоманднаяПанель доступно для настройки только в режиме конфигуратора. В объектной модели управляемой формы на этапе выполнения переназначить источник команд программно невозможно.

Разберем детально варианты решения этой задачи, их преимущества, ограничения и особенности реализации.

Ограничения платформы и суть проблемы

Рассмотрим, почему стандартный подход не работает «из коробки». В 1С:Предприятие 8.3 элемент формы КоманднаяПанель связывается с конкретной таблицей формы через свойство ИсточникКоманд. Если динамически генерировать таблицы значений в реквизитах формы и выводить их на разные страницы панели, платформа не позволит одной общей командной панели автоматически менять свой контекст на текущую активную таблицу при переключении страниц.

Кроме того, при выполнении контекстных серверных вызовов и изменении структуры элементов формы платформа может сбрасывать динамически созданные кнопки в автозаполняемых панелях. Поэтому потребуется выбрать один из рабочих архитектурных подходов.

Способ 1. Создание общих кнопок и вызов программных методов таблицы

Проанализируем первый подход: создание собственной командной панели над группой страниц с пользовательскими кнопками, которые обращаются к текущему активному элементу формы.

В управляемом приложении объект ТаблицаФормы имеет встроенные клиентские методы для выполнения стандартных операций над строками:

  1. ДобавитьСтроку() — создает новую строку в активной таблице;
  2. ИзменитьСтроку() — переводит выбранную строку в режим редактирования;
  3. СкопироватьСтроку() — дублирует выделенную строку;
  4. УдалитьСтроку() — удаляет текущую или выделенные строки;
  5. СдвинутьВверх() и СдвинутьВниз() — меняют порядок строк.

Посмотрим на пример клиентского обработчика команды добавления строки:


&НаКлиенте
Процедура КомандаДобавитьСтроку(Команда)
    
    ТекущийЭл = ЭтаФорма.ТекущийЭлемент;
    
    Если ТипЗнч(ТекущийЭл) = Тип("ТаблицаФормы") Тогда
        // При необходимости возвращаем фокус на таблицу
        ТекущийЭл.ДобавитьСтроку();
    КонецЕсли;

КонецПроцедуры

Аналогично реализуются обработчики для удаления, копирования и перемещения строк. Чтобы кнопки общей панели корректно блокировались (например, кнопка «Удалить» должна быть недоступна, если в таблице нет строк), в событиях таблиц ПриАктивизацииСтроки или ПриАктивизацииЯчейки следует динамически управлять свойством Доступность соответствующих кнопок формы.

Способ 2. Добавление пользовательских команд в командные панели самих таблиц

Выясним особенности второго подхожда. Если отказаться от идеи единой панели над закладками, можно использовать свойства самих таблиц. Каждая таблица формы имеет свойство КоманднаяПанель, в которое программно можно добавлять кастомные кнопки при создании таблицы или при первой активизации страницы.

В этом случае стандартные системные кнопки (добавление, удаление, поиск) формируются платформой автоматически благодаря автозаполнению командной панели таблицы, а специфические общие команды добавляются программно:


&НаКлиенте
Процедура ПриАктивизацииСтраницыТаблицы(Элемент)
    
    // Проверяем, были ли уже добавлены пользовательские кнопки
    // и добавляем их в элемент ТаблицаФормы.КоманднаяПанель
    
КонецПроцедуры

Этот способ удобен тем, что стандартные действия таблицы не приходится переписывать вручную, так как каждая таблица имеет свой собственный автозаполняемый источник команд.

Способ 3. Оптимизация формы: использование одной таблицы с перезагрузкой данных

Если таблиц на форме планируется много (десятки штук), динамическое создание сотен элементов формы и реквизитов приводит к значительному увеличению объема контекста, передаваемого между клиентом и сервером. В таких случаях выгодно пересмотреть структуру формы.

Рассмотрим альтернативный алгоритм:

  1. На форме размещается всего одна визуальная ТаблицаФормы и одна автозаполняемая командная панель над ней.
  2. Для переключения между наборами данных используется группа страниц без отображения содержимого самими элементами (или переключатель/закладки).
  3. Исходные данные таблиц хранятся на сервере в структуре или массиве.
  4. При переключении закладки на сервере выполняется заполнение реквизита формы через процедуру ЗначениеВРеквизитФормы().

Посмотрим на пример серверной перезагрузки данных:


&НаСервере
Процедура ЗагрузитьДанныеВТаблицуФормы(ИмяВкладки)
    
    ТаблицаИзХранилища = ПолучитьТаблицуПоИмени(ИмяВкладки);
    ЗначениеВРеквизитФормы(ТаблицаИзХранилища, "ОбъектнаяТаблицаФормы");

КонецПроцедуры

При таком подходе командная панель всегда жестко привязана к единственной таблице на форме, стандартные команды работают без написания дополнительного кода, а клиент-серверный обмен остается минимальным.

Итоги и рекомендации

Проанализировав все способы, выделим главное:

← На главную