Как получить итоги по табличной части в шаблонах договоров 1С:УТ 11?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

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

Основные принципы работы с агрегатными функциями в шаблонах

Первоначально пользователь сталкивается с тем, что прямые попытки использования функций, таких как СуммаПоКолонке("Товары.Сумма") или КоличествоСтрок.[Товары], приводят к некорректному выводу: либо текст функции выводится как есть, либо итог повторяется для каждой строки табличной части. Это происходит из-за неправильного размещения этих функций в макете печатной формы.

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

  1. Шапка табличной части: Эта область выводится всего один раз перед началом вывода строк табличной части. Она содержит заголовки колонок и общую информацию.
  2. Строки табличной части: Эта область повторяется для каждой записи в табличной части. Именно здесь размещаются выражения для полей текущей строки, например, [Товары.Наименование], [Товары.Количество]. Если агрегатные функции, такие как СуммаПоКолонке([Товары.Сумма]), помещены в эту область, они будут вычислены для каждой отдельной строки, что приводит к ошибочному повторению итога на каждой строке.
  3. Подвал (или итоги) табличной части: Эта область выводится один раз после всех строк табличной части. Именно здесь и должны располагаться агрегатные функции для получения суммарных итогов по всей таблице.

Для правильной работы нам необходимо обеспечить, чтобы агрегатные функции находились именно в области "Подвала" или "Итогов", которая обрабатывается после всех строк.

Корректное использование агрегатных функций: готовые примеры

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


[КоличествоСтрок([Товары.Количество])] // Общее количество строк в табличной части
[МаксимумПоКолонке([Товары.Цена])]    // Максимальное значение в колонке "Цена"
[МинимумПоКолонке([Товары.Количество])] // Минимальное значение в колонке "Количество"
[СреднееПоКолонке([Товары.Количество])] // Среднее значение в колонке "Количество"
[СуммаПоКолонке([Товары.Сумма])]      // Сумма значений в колонке "Сумма"

Обратите внимание на синтаксис: квадратные скобки [] используются для обозначения выражений, а имя табличной части (например, Товары) указывается внутри функции перед именем колонки.

Расчет итогов по вычисляемым колонкам

Более сложная, но часто встречающаяся задача — это получение суммы по колонке, которая сама является результатом какого-либо вычисления. Например, требуется вычислить общую длительность работ, если в табличной части есть поля Начало и Окончание. Формула для одной строки может выглядеть так: ([Исполнители работ.Окончание] - [Исполнители работ.Начало]) / 3600 (для перевода секунд в часы). Как же просуммировать такие вычисляемые значения?

Мы рассмотрим несколько подходов к решению этой задачи.

Подход 1: Добавление реквизита в табличную часть

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

  1. Создание реквизита: В конфигураторе, для табличной части документа (например, ИсполнителиРабот), добавьте новый реквизит, например, ДлительностьВЧасах, с типом "Число".
  2. Расчет и заполнение реквизита: В модуле формы документа, или в модуле объекта, реализуйте процедуру, которая будет вычислять значение ДлительностьВЧасах при изменении полей Начало или Окончание в соответствующей строке табличной части.
  3. 
    // Пример кода в модуле формы документа (или объекта)
    // Для табличной части "ИсполнителиРабот"
                    
    &НаСервере
    Процедура ИсполнителиРаботНачалоПриИзменении(Элемент)
        // Вычисляем длительность при изменении поля Начало
        РассчитатьДлительностьСтроки(Элемент.ТекущиеДанные);
    КонецПроцедуры
                    
    &НаСервере
    Процедура ИсполнителиРаботОкончаниеПриИзменении(Элемент)
        // Вычисляем длительность при изменении поля Окончание
        РассчитатьДлительностьСтроки(Элемент.ТекущиеДанные);
    КонецПроцедуры
                    
    &НаСервере
    Процедура РассчитатьДлительностьСтроки(СтрокаТабличнойЧасти)
        Если СтрокаТабличнойЧасти.Начало <> Неопределено И СтрокаТабличнойЧасти.Окончание <> Неопределено Тогда
            Длительность = СтрокаТабличнойЧасти.Окончание - СтрокаТабличнойЧасти.Начало; // Разность в секундах
            СтрокаТабличнойЧасти.ДлительностьВЧасах = Длительность / 3600;
        Иначе
            СтрокаТабличнойЧасти.ДлительностьВЧасах = 0;
        КонецЕсли;
    КонецПроцедуры
    
  4. Получение итога: После того как реквизит ДлительностьВЧасах будет заполняться, вы сможете легко получить его сумму в шаблоне, используя уже знакомую нам функцию в области "Подвал" или "Итоги":
  5. 
    [СуммаПоКолонке([ИсполнителиРабот.ДлительностьВЧасах])]
    

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

Подход 2: Использование сложного выражения в агрегатной функции (если поддерживается)

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

Если бы такая возможность существовала, гипотетическая запись могла бы выглядеть так:


[СуммаПоКолонке(([ИсполнителиРабот.Окончание] - [ИсполнителиРабот.Начало]) / 3600)]

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

Подход 3: Предварительный расчет в коде

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

  1. Расчет суммы в модуле: В процедуре, которая отвечает за формирование печатной формы, мы можем пройтись по табличной части и рассчитать необходимую сумму.
  2. 
    // Пример кода в модуле объекта документа или в процедуре формирования печатной формы
                    
    ОбщаяДлительностьВЧасах = 0;
    Для Каждого СтрокаРабот Из ЭтотОбъект.ИсполнителиРабот Цикл
        Если СтрокаРабот.Начало <> Неопределено И СтрокаРабот.Окончание <> Неопределено Тогда
            Длительность = СтрокаРабот.Окончание - СтрокаРабот.Начало; // Разность в секундах
            ОбщаяДлительностьВЧасах = ОбщаяДлительностьВЧасах + (Длительность / 3600);
        КонецЕсли;
    КонецЦикла;
                    
    // Далее передаем ОбщаяДлительностьВЧасах в шаблон как параметр.
    // Например, если вы формируете через Макет.Область.Параметры.Вставить("ИтогДлительности", ОбщаяДлительностьВЧасах);
    
  3. Вывод параметра в шаблоне: В макете, в области "Подвал" или "Итоги", вы просто выводите этот параметр:
  4. 
    [ИтогДлительности]
    

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

Заключение

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

← На главную