Как свернуть таблицу на управляемой форме в 1С 8.3?

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

При разработке интерфейсов на управляемых формах 1С часто возникает задача сгруппировать строки таблицы и просуммировать числовые показатели. В отличие от обычных форм, данные таблицы на клиенте представлены специальным типом ДанныеФормыКоллекция (или ДанныеФормыДерево), у которого отсутствует встроенный метод Свернуть(). Разберем по шагам, как правильно выполнить группировку строк таблицы формы на стороне сервера.

Особенности работы с таблицами на управляемой форме

Прежде чем приступать к коду, проанализируем ключевые ограничения платформы:

  1. Элемент формы «Таблица» визуализирует данные из реквизита формы, имеющего тип ДанныеФормыКоллекция.
  2. Все операции по группировке и агрегации данных выполняются исключительно на сервере.
  3. Для выполнения группировки данные реквизита формы необходимо преобразовать в прикладной объект ТаблицаЗначений, применить метод Свернуть() и загрузить результат обратно в реквизит формы.
  4. Суммируемые колонки в таблице значений обязательно должны иметь числовой тип данных. Если тип колонок составной или не определен, суммирование может выполниться некорректно.

Способ 1. Использование контекстных методов формы (&НаСервере)

Рассмотрим стандартный и наиболее распространенный вариант реализации с использованием процедур формы в контексте сервера. В этом случае мы обращаемся к методам РеквизитФормыВЗначение() и ЗначениеВРеквизитФормы().

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


&НаКлиенте
Процедура СвернутьТаблицу(Команда)
    СвернутьТаблицуНаСервере();
КонецПроцедуры

&НаСервере
Процедура СвернутьТаблицуНаСервере()
    // 1. Преобразуем реквизит формы в ТаблицуЗначений
    Таблица = РеквизитФормыВЗначение("ТаблицаНаФорме", Тип("ТаблицаЗначений"));
    
    // 2. Сворачиваем строки по колонкам группировки с подсчетом суммы
    Таблица.Свернуть("Номенклатура, Склад", "Количество, Сумма");
    
    // 3. Загружаем обработанные данные обратно в реквизит формы
    ЗначениеВРеквизитФормы(Таблица, "ТаблицаНаФорме");
КонецПроцедуры

Способ 2. Использование универсальных функций преобразования (&НаСервереБезКонтекста)

Если требуется вынести логику в неконтекстный вызов для оптимизации сетевого трафика или использовать общие модули, применяются универсальные функции ДанныеФормыВЗначение() и ЗначениеВДанныеФормы().

Разберем по шагам данный подход:


&НаКлиенте
Процедура СвернутьТаблицуБезКонтекста(Команда)
    СвернутьТаблицуНаСервереБезКонтекста(ТаблицаНаФорме);
КонецПроцедуры

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

Способ 3. Группировка через запрос во временную таблицу

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

Посмотрим на практический пример:


&НаСервере
Процедура СвернутьТаблицуЗапросом()
    Таблица = РеквизитФормыВЗначение("ТаблицаНаФорме", Тип("ТаблицаЗначений"));
    
    МенеджерВТ = Новый МенеджерВременныхТаблиц;
    Запрос = Новый Запрос;
    Запрос.МенеджерВременныхТаблиц = МенеджерВТ;
    
    Запрос.Текст = 
        "ВЫБРАТЬ
        |    ТЗ.Номенклатура КАК Номенклатура,
        |    ТЗ.Склад КАК Склад,
        |    ТЗ.Количество КАК Количество,
        |    ТЗ.Сумма КАК Сумма
        |ПОМЕСТИТЬ ВТ_ИсходныеДанные
        |ИЗ
        |    &ТаблицаИсходная КАК ТЗ
        |;
        |
        |////////////////////////////////////////////////////////////////////////////////
        |ВЫБРАТЬ
        |    ВТ.Номенклатура КАК Номенклатура,
        |    ВТ.Склад КАК Склад,
        |    СУММА(ВТ.Количество) КАК Количество,
        |    СУММА(ВТ.Сумма) КАК Сумма,
        |    СРЕДНЕЕ(ВТ.Сумма) КАК СредняяСумма
        |ИЗ
        |    ВТ_ИсходныеДанные КАК ВТ
        |СГРУППИРОВАТЬ ПО
        |    ВТ.Номенклатура,
        |    ВТ.Склад";
        
    Запрос.УстановитьПараметр("ТаблицаИсходная", Таблица);
    
    ТаблицаРезультат = Запрос.Выполнить().Выгрузить();
    ЗначениеВРеквизитФормы(ТаблицаРезультат, "ТаблицаНаФорме");
КонецПроцедуры

Важные нюансы при обновлении данных

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

  1. Сброс текущей строки: Методы ЗначениеВРеквизитФормы и ЗначениеВДанныеФормы полностью перезаполняют коллекцию, из-за чего активная позиция в таблице (Элементы.ИмяТаблицы.ТекущаяСтрока) сбрасывается. При необходимости сохраняйте идентификатор или ключевые поля строки до преобразования и восстанавливайте позиционирование после.
  2. Иерархия: Если пользователю требуется визуально сворачивать и разворачивать строки с сохранением детальных записей, используйте реквизит с типом ДанныеФормыДерево вместо плоской таблицы значений, рассчитывая итоги в родительских узлах.
← На главную