К статье
Практический материал

Разработка и Конфигурация · 11 мин

1С: как добавить итоги в таблицу значений

Как посчитать итоги по таблице значений в 1С: методы Итог(), Свернуть(), группировка через запрос и построитель отчёта. Примеры кода, ошибки и проверка результата.

Таблица значений в 1С — основной инструмент промежуточного хранения данных: в неё загружаются результаты запросов, движения документов, выборки из справочников. Когда нужно получить сумму по колонке или сгруппировать строки с подсчётом итогов, у разработчика есть несколько штатных механизмов, и выбор между ними влияет на скорость работы и объём кода.

Чаще всего применяются методы Итог() и Свернуть() объекта «ТаблицаЗначений», а также свёртка через запрос с итогами. У каждого подхода есть ограничения: Итог() считает только одну колонку за вызов, Свернуть() необратимо изменяет таблицу, а запрос требует переноса логики на язык запросов.

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

Метод Итог() — сумма по одной колонке

Самый простой способ получить итог — вызвать метод Итог() с именем числовой колонки. Метод не меняет таблицу, а возвращает число, которое можно вывести в сообщение, записать в реквизит или использовать в расчёте.

ТЗ = ПолучитьТаблицуТоваров();

ИтогоСумма = ТЗ.Итог("Сумма");

ИтогоКоличество = ТЗ.Итог("Количество");

Сообщить("Итого по документу: " + ИтогоСумма);

Метод суммирует только значения, которые приводятся к числу. Если в колонке встречаются NULL или строки, они будут проигнорированы или вызовут ошибку в зависимости от типа колонки. Поэтому перед вызовом убедитесь, что колонка описана как число в Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число")) или получена из запроса с числовым типом.

Каждый вызов Итог() выполняет полный проход по таблице. Если нужно посчитать пять колонок в таблице на сотни тысяч строк, это пять полных проходов — в такой ситуации выгоднее свёртка или запрос.

Метод Свернуть() — группировка строк с итогами

Метод Свернуть(КолонкиГруппировки, КолонкиСуммирования) преобразует таблицу: строки с одинаковыми значениями в колонках группировки объединяются в одну, а числовые колонки суммируются. Это аналог конструкции GROUP BY в SQL.

// Исходная таблица: Контрагент, Договор, Сумма

ТЗ.Свернуть("Контрагент", "Сумма");

// Теперь в таблице по одной строке на контрагента,

// колонка Договор удалена, Сумма — итог по контрагенту

Ключевые правила, которые нужно помнить при работе со свёрткой:

  • Колонки, не указанные ни в группировке, ни в суммировании, удаляются из таблицы без предупреждения.
  • Метод изменяет исходную таблицу. Если она ещё нужна, заранее сделайте копию: ТЗИтоги = ТЗ.Скопировать().
  • Колонки суммирования должны иметь числовой тип, иначе получите ошибку или нулевые значения.
  • Чтобы свернуть всю таблицу в одну строку с общими итогами, передайте пустую строку группировки: ТЗ.Свернуть("", "Сумма, Количество").

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

Итоги на этапе запроса — ИТОГИ ПО и СУММА()

Если таблица значений заполняется из запроса, считать итоги эффективнее сразу на уровне СУБД. Два варианта: агрегатная функция СУММА() с группировкой или секция ИТОГИ ПО с иерархическим результатом.

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Продажи.Контрагент КАК Контрагент,

| СУММА(Продажи.СуммаОборот) КАК Сумма

|ИЗ

| РегистрНакопления.Продажи.Обороты(&Начало, &Конец, , ) КАК Продажи

|СГРУППИРОВАТЬ ПО

| Продажи.Контрагент

|ИТОГИ

| СУММА(Сумма)

|ПО

| ОБЩИЕ";

При обходе результата с ИТОГИ ПО ОБЩИЕ общий итог доступен через выборку по группировке ОбходРезультатаЗапроса.ПоГруппировкам. Если итог нужен единственный и без детальных строк, проще выполнить запрос без ИТОГИ, сгруппировать по пустому набору или выгрузить результат и вызвать Итог().

Перенос агрегации в запрос снижает объём данных, передаваемых с сервера СУБД, и обычно работает быстрее, чем свёртка большой таблицы в памяти. Ограничение: запрос не поможет, если таблица собрана программно из разных источников или получена извне (например, загружена из файла).

Сравнение вариантов

Итог()

Одна сумма по одной колонке, таблица не меняется. Не подходит, когда нужно много итогов или группировка.

Свернуть()

Группировка с несколькими итоговыми колонками в памяти. Уничтожает лишние колонки, нужна копия таблицы.

Запрос с СУММА() и ИТОГИ

Самый быстрый для данных из базы. Не работает для таблиц, собранных программно или загруженных извне.

Добавление строки итогов в таблицу

Иногда требуется не свернуть таблицу, а дописать в конец строку «Итого» — например, для выгрузки в Excel или вывода в табличный документ. Здесь метод Свернуть() не подходит, строку добавляют вручную.

СтрокаИтог = ТЗ.Добавить();

СтрокаИтог.Номенклатура = "Итого:";

СтрокаИтог.Количество = ТЗ.Итог("Количество");

СтрокаИтог.Сумма = ТЗ.Итог("Сумма");

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

Для промежуточных итогов по группам (например, по каждому складу) логика сложнее: перед сменой значения группировочного поля вставляется строка с накопленной суммой, счётчики обнуляются. Такой подход требует, чтобы таблица была заранее отсортирована по колонке группировки — иначе промежуточные итоги окажутся разорванными.

Добавление строки «Итого» в таблицу
  1. 1
    Убедитесь, что таблица полностью заполнена детальными строками
  2. 2
    Вызовите ТЗ.Итог("ИмяКолонки") для каждой суммируемой колонки
  3. 3
    Добавьте новую строку методом ТЗ.Добавить() и заполните её полученными значениями
  4. 4
    Пометьте строку текстом «Итого» в первой колонке для читаемости
  5. 5
    Проверьте, что сумма итоговой строки совпадает с контрольным значением из источника данных

Итоги в дереве значений и иерархических данных

Если данные иерархические, таблицу значений часто преобразуют в дерево значений. Метод Свернуть() у дерева отсутствует, а Итог() у строк дерева работает только по непосредственным подчинённым строкам, поэтому итоги считают рекурсивным обходом.

Функция ПосчитатьИтогиВетки(СтрокаДерева)

Если СтрокаДерева.Строки.Количество() = 0 Тогда

Возврат СтрокаДерева.Сумма;

КонецЕсли;

Итог = 0;

Для Каждого ПодСтрока Из СтрокаДерева.Строки Цикл

Итог = Итог + ПосчитатьИтогиВетки(ПодСтрока);

КонецЦикла;

СтрокаДерева.Сумма = Итог;

Возврат Итог;

КонецФункции

Альтернатива без рекурсии — запрос с ИТОГИ ПО и выгрузкой в дерево: Запрос.Выполнить().Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией). Платформа сама заполнит итоги в строках-группах, и ручной обход не понадобится.

Риск рекурсивного подхода — переполнение стека на очень глубоких иерархиях и двойной счёт, если листья уже содержат итоговые суммы. Перед выбором способа убедитесь, что суммы хранятся только в листьях либо только в группах, но не в обоих уровнях одновременно.

Проверка результата и типичные ошибки

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

Контрольные точки

Как проверить результат

Сумма после Свернуть()
Норма

Совпадает с Итог() по исходной таблице до свёртки

Тревожный признак

Расходится — вероятно, часть строк потеряна из-за NULL в колонках группировки

Количество строк после свёртки
Норма

Равно числу уникальных комбинаций колонок группировки

Тревожный признак

Строк больше ожидаемого — в группировке есть поля с разным представлением (лишние пробелы, регистр)

Итог() по числовой колонке
Норма

Возвращает число без ошибок

Тревожный признак

Ошибка преобразования или ноль — колонка нечисловая или пустая

Типичные ошибки
01
Вызов Свернуть() для исходной таблицы без копии — теряются колонки и детальные строки, нужные дальше по коду
02
Суммирование колонки со строковым типом — Итог() вернёт ноль или ошибку вместо суммы
03
Подсчёт итога по таблице с уже добавленной строкой «Итого» — сумма удваивается
04
Игнорирование NULL в колонках группировки при Свернуть() — строки с NULL объединяются в отдельную группу и искажают картину
05
Повторный вызов Свернуть() по уже свёрнутой таблице с другими колонками — часть данных безвозвратно потеряна на первом шаге

Отдельная ловушка — отладка: в конфигураторе таблицу значений удобно смотреть через «Вычислить выражение» с выводом в табло, но на больших таблицах это медленно. Практичнее временно вывести итог и число строк через Сообщить() и сравнить с ожидаемыми.

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

Частые вопросы

Можно ли посчитать итог сразу по нескольким колонкам одним вызовом?

Методом Итог() — нет, он принимает одну колонку. Для нескольких колонок вызовите Итог() для каждой или используйте Свернуть("", "Сумма, Количество") на копии таблицы: после свёртки с пустой группировкой в таблице останется одна строка со всеми итогами.

Почему после Свернуть() пропали нужные колонки?

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

Как посчитать итог только по части строк, а не по всей таблице?

Отберите нужные строки через ТЗ.НайтиСтроки(Отбор) и просуммируйте в цикле, либо скопируйте отобранные строки в новую таблицу через Скопировать(МассивСтрок) и вызовите Итог() уже для неё. Второй способ удобнее, когда итогов нужно несколько.

Что быстрее: Свернуть() или группировка в запросе?

Для данных, которые ещё не выбраны из базы, быстрее запрос — агрегация выполняется на сервере СУБД и в память попадает уже сгруппированный результат. Свернуть() оправдан, когда таблица собрана программно, получена из файла или уже находится в памяти по другим причинам.

Как вывести итоги в табличное поле на форме?

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

Почему Итог() возвращает ноль, хотя в таблице есть суммы?

Чаще всего колонка имеет нечисловой тип — например, суммы загружены как строки из файла. Проверьте тип колонки и при необходимости пересоздайте её с числовым описанием типов, заполнив значения через Число(). Вторая причина — неверное имя колонки, но в этом случае обычно возникает ошибка, а не ноль.

Итог

Что важно запомнить

Итог() — для одной суммы без изменения таблицы, Свернуть() — для группировки с обязательной копией исходных данных, запрос с СУММА() и ИТОГИ — самый быстрый вариант для данных из базы. Перед использованием результата сверяйте итог с контрольным значением и следите за типами колонок.