Как консолидировать итоги в табличном поле управляемой формы 1С при многострочном заголовке?

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

При работе с табличными полями в управляемых формах 1С мы часто сталкиваемся с необходимостью отображения итогов. Однако, когда заголовок табличного поля имеет сложную структуру, например, состоит из нескольких строк или содержит объединенные группы по вертикали, стандартные механизмы отображения итогов могут вести себя не так, как нам хотелось бы. Часто итоги "разъезжаются" по группам заголовка, занимая несколько строк, тогда как требуется вывести их в одну консолидированную строку, возможно, только по определенным колонкам. Давайте разберем, как решить эту задачу, взяв под полный контроль процесс расчета и отображения итогов.

Программное управление итогами: Основной подход

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

  1. Отключение штатных итогов для нежелательных колонок

    Прежде всего, убедимся, что автоматическое отображение итогов для колонок, по которым мы не хотим видеть итоги, отключено. Для этого необходимо проверить свойство ОтображатьВПодвале у соответствующих элементов формы (колонок табличного поля) и установить его в значение "Ложь" (False), если оно присутствует. Также убедитесь, что свойства ТекстПодвала и ПутьКДаннымПодвала у этих колонок пусты.

    Важно: У самого табличного поля должно быть включено свойство Подвал. Без этого итоги отображаться не будут, даже если настроены для отдельных колонок.

  2. Создание реквизитов формы для хранения итогов

    Для того чтобы хранить рассчитанные программно итоги и затем выводить их, мы создадим на форме дополнительные реквизиты. Эти реквизиты будут служить "переменными" для наших итоговых значений. Создайте реквизиты с типом Число или Строка (в зависимости от того, как вы планируете выводить их). Например:

    • ИтогКоличество (Тип: Число)
    • ИтогСумма (Тип: Число)
    • ИтогОбщий (Тип: Строка, если нужно форматирование или объединение нескольких значений)

    Например, в конфигураторе на форме перейдите в раздел "Реквизиты", нажмите "Добавить" и укажите имя и тип нового реквизита.

  3. Вычисление итогов

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

    • ПриСозданииНаСервере: для первоначального расчета при открытии формы.
    • ПриЧтенииНаСервере: если форма работает с объектом базы данных.
    • ПриИзменении: для событий, связанных с изменением данных в табличной части на форме.
    • ПриОбновленииОтображения: для динамических списков, когда требуется учесть отборы или другие изменения в отображаемых данных.
    • При изменении отборов или других параметров, влияющих на данные.

    Для расчета итогов мы можем использовать несколько подходов:

    Расчет итогов по табличной части объекта

    Если табличное поле отображает данные табличной части какого-либо объекта (например, документа), мы можем воспользоваться встроенным методом Итог("ИмяКолонки") у самой табличной части. Этот метод быстро суммирует значения в указанной колонке.

    
    // Предположим, у нас есть табличная часть "Товары"
    // и нам нужен итог по колонке "Количество" и "Сумма"
    ИтогКоличество = Объект.Товары.Итог("Количество");
    ИтогСумма = Объект.Товары.Итог("Сумма");
    

    Расчет итогов по данным табличного поля (без учета отборов)

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

    
    ИтогКоличество = 0;
    ИтогСумма = 0;
    
    Для Каждого СтрокаТП Из ЭлементыФормы.МоеТабличноеПоле.ТекущиеДанные Цикл
        ИтогКоличество = ИтогКоличество + СтрокаТП.Количество;
        ИтогСумма = ИтогСумма + СтрокаТП.Сумма;
    КонецЦикла;
    

    Этот способ подходит для небольших объемов данных. Для больших объемов он может быть медленным, особенно если выполняется на клиенте.

    Расчет итогов для динамического списка (с учетом отборов и группировок)

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

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

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

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

    Производительность: Для очень больших объемов данных или сложных расчетов рассмотрите возможность выполнения вычислений в фоновом задании, чтобы не блокировать интерфейс пользователя.

  4. Вывод итогов в подвал табличного поля

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

    • Использование ПутьКДаннымПодвала: Этот способ наиболее прост, если вы создали реквизиты формы для каждого итога. Просто укажите имя реквизита в свойстве ПутьКДаннымПодвала нужной колонки. Например, для колонки "Количество" в свойстве ПутьКДаннымПодвала укажите "ИтогКоличество". Платформа автоматически будет брать значение из этого реквизита и отображать его.

      
      // Пример настройки в конфигураторе:
      // Выберите табличное поле на форме, затем нужную колонку.
      // В окне свойств колонки найдите "ПутьКДаннымПодвала" и укажите: ИтогКоличество
      
    • Использование ТекстПодвала: Этот способ дает больше контроля над форматированием и объединением текста. Вы можете программно присваивать значение свойству ТекстПодвала колонок. Это особенно полезно, если вам нужно отобразить несколько итогов в одной ячейке подвала или применить сложное форматирование (хотя для простого форматирования чисел лучше использовать свойство Формат у реквизита или колонки).

      
      // В обработчике, где рассчитываются итоги (например, после выполнения запроса)
      // После расчета ИтогКоличество и ИтогСумма
      ЭлементыФормы.МоеТабличноеПоле.Колонки.Количество.ТекстПодвала = Формат(ИтогКоличество, "ЧЦ=15; ЧДЦ=2; ЧРД=,");
      ЭлементыФормы.МоеТабличноеПоле.Колонки.Сумма.ТекстПодвала = Формат(ИтогСумма, "ЧЦ=15; ЧДЦ=2; ЧРД=,");
      
      // Если нужно объединить несколько итогов в одну ячейку (например, в колонке "Комментарий")
      ЭлементыФормы.МоеТабличноеПоле.Колонки.Комментарий.ТекстПодвала = "Всего: " + Формат(ИтогОбщий, "ЧЦ=15; ЧДЦ=2; ЧРД=,") + " руб.";
      

      Не забывайте вызывать ЭлементыФормы.МоеТабличноеПоле.Обновить(); или ЭлементыФормы.ОбновитьОтображениеДанных(), если изменения не отображаются автоматически, особенно если присвоение значений происходит в серверных процедурах.

    Таким образом, мы добиваемся вывода итогов в одну строку, контролируя, какие именно колонки их содержат, и как они форматируются, независимо от сложности заголовка.

Общие рекомендации по работе с итогами в табличных полях

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

  1. Свойство "Подвал" табличного поля: Убедитесь, что у самого табличного поля включено свойство Подвал. Это базовое условие для отображения любых итогов.

  2. Свойства "ТекстПодвала" и "ПутьКДаннымПодвала": Понимайте разницу. ПутьКДаннымПодвала удобен для привязки к реквизиту формы, значение которого автоматически отображается. ТекстПодвала предоставляет полный программный контроль над содержимым ячейки подвала, включая форматирование и объединение нескольких значений.

  3. Автоматические итоги и "ОтображатьВПодвале": Для стандартных случаев (простая табличная часть, одна строка заголовка) можно использовать автоматические итоги, устанавливая для нужных колонок свойство ОтображатьВПодвале в "Истина". Однако в нашем случае с многострочными заголовками этот механизм оказался недостаточным или не позволял добиться нужной консолидации.

  4. Обновление итогов при изменении данных: Крайне важно, чтобы рассчитанные программно итоги всегда были актуальными. Поэтому после любых действий, которые могут изменить данные в табличном поле (добавление/удаление строк, изменение значений, изменение отборов), необходимо повторно вызывать процедуру расчета и обновления итогов.

  5. Использование запросов для расчетов: Для сложных агрегаций, фильтрации по множеству условий или при работе с динамическими списками, всегда предпочтительнее использовать язык запросов 1С. Это позволяет эффективно выполнять расчеты на сервере и получать точные данные, соответствующие текущему контексту (например, установленным отборам).

  6. Производительность: Если таблица содержит очень много строк (тысячи и более), прямой перебор строк на клиенте может замедлять работу формы. В таких случаях всегда старайтесь выполнять расчеты на сервере, используя запросы. Для особенно тяжелых расчетов рассмотрите асинхронное выполнение в фоновых заданиях, чтобы не блокировать интерфейс пользователя.

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

  8. Система стандартов и методик разработки 1С: В документации 1С:ИТС рекомендуется располагать итоговые значения в подвалах таблиц, особенно если количество итоговых колонок велико и они не помещаются в одну строку в виде отдельных полей ввода. Также подчеркивается необходимость актуализации итогов при изменении данных в документе или других источниках.

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

← На главную