Сумма по ячейкам в 1С: от выделения мышью до итогов в СКД

· 9 мин

Содержание

Чтобы быстро суммировать ячейки в 1С, выделите их мышью в сформированном отчёте: в типовых конфигурациях на платформе 8.3 сумма выделенного сразу появляется в поле над табличным документом, справа. В коде сумму колонки таблицы считает метод Итог("Сумма"), в запросе — агрегатная функция СУММА(), в схеме компоновки — ресурс.

Типичная ситуация: главбух просит «сколько всего отгрузили Ромашке за квартал», а в отчёте 140 строк. Пересчитывать на калькуляторе не нужно: пользователь справится выделением, а разработчику хватит одной строки в коде, запросе или схеме компоновки.

Сумма выделенных ячеек в режиме пользователя

Для бухгалтера это самый частый сценарий. Ничего настраивать не нужно.

  1. Сформируйте отчёт, например оборотно-сальдовую ведомость.
  2. Выделите мышью нужные ячейки с числами. Несмежные ячейки добавляйте с зажатым Ctrl, диапазон — с Shift.
  3. Посмотрите в поле справа над отчётом: там появится сумма выделенного.
  4. Нажмите на стрелку рядом с этим полем — можно переключить показатель на количество, среднее, минимум или максимум.

Поле считает только ячейки, где действительно стоит число. Заголовки, пустые ячейки и текст вроде «Итого» в сумму не попадают, поэтому выделять колонку можно вместе с шапкой.

Если нужен итог по списку документов

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

  1. Откройте список, например Продажи → Реализация (акты, накладные, УПД) в 1С:Бухгалтерии 3.0.
  2. Отберите нужное: по контрагенту, организации, периоду.
  3. Выполните Ещё → Вывести список..., отметьте нужные колонки и нажмите ОК.
  4. Список откроется как табличный документ. Выделите колонку «Сумма» — итог появится так же, как в отчёте.

Из этого же окна список удобно сохранить в Excel, если сумму нужно разложить по формулам.

Калькулятор платформы

Для пары чисел, которых нет рядом в одной таблице, подойдёт встроенный калькулятор: Ctrl+F2. Результат копируется в любое числовое поле документа.

ЗадачаЧем пользоваться
Сумма части строк отчётаВыделение мышью, поле суммы над отчётом
Итог по журналу документовЕщё → Вывести список... + выделение
Сложить 2–3 числа из разных местКалькулятор Ctrl+F2
Регулярный итог по одной и той же выборкеНастройка отчёта: группировки и итоги

Суммирование в цикле на встроенном языке

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

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

Цикл нужен, когда есть условие: сложить только строки с положительной суммой, только определённый склад, только услуги. Если условия нет, проще встроенный метод.

Метод Итог() для табличной части и таблицы значений

ИтогоСумма = Объект.Товары.Итог("Сумма");

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

ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Номенклатура");
ТЗ.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2)));

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

Нужна сумма не одной цифрой, а по каждой номенклатуре? Используйте Свернуть():

ТЗ = Объект.Товары.Выгрузить();
ТЗ.Свернуть("Номенклатура", "Количество, Сумма");

Первый параметр — колонки группировки, второй — колонки, которые суммируются. Остальные колонки метод удалит. Он меняет саму таблицу, поэтому сворачивайте копию, полученную через Выгрузить(), а не табличную часть объекта.

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

Итог в подвале табличной части формы

Пользователи часто просят «показать сумму под колонкой». В управляемой форме это делается без кода:

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

Платформа сама пересчитывает значение при изменении строк. Для колонки «Количество» путь будет Объект.Товары.ИтогКоличество.

Агрегация данных средствами языка запросов

Запрос — основной способ суммировать данные, которые уже записаны в базу. Для этого есть агрегатная функция СУММА() и группировка СГРУППИРОВАТЬ ПО.

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

Каждое поле в ВЫБРАТЬ должно быть либо под агрегатной функцией, либо в СГРУППИРОВАТЬ ПО. Иначе запрос не выполнится с ошибкой про поле, которое не входит в группу.

Одна общая сумма

Если нужна одна цифра, группировка не нужна. Но учтите: если подходящих строк нет, СУММА() вернёт NULL, а не ноль.

"ВЫБРАТЬ
|    ЕСТЬNULL(СУММА(Товары.Сумма), 0) КАК Сумма
|ИЗ
|    Документ.РеализацияТоваровУслуг.Товары КАК Товары
|ГДЕ
|    Товары.Ссылка = &Документ"

Условная сумма в одном запросе

Чтобы получить в одной строке и продажи, и возвраты, используйте ВЫБОР внутри СУММА:

СУММА(ВЫБОР КОГДА Т.Сумма > 0 ТОГДА Т.Сумма ИНАЧЕ 0 КОНЕЦ) КАК Приход,
СУММА(ВЫБОР КОГДА Т.Сумма < 0 ТОГДА -Т.Сумма ИНАЧЕ 0 КОНЕЦ) КАК Расход

Отбор по уже посчитанной сумме ставят в ИМЕЮЩИЕ, а не в ГДЕ: например, ИМЕЮЩИЕ СУММА(Товары.Сумма) > 100000.

ИТОГИ — подытоги прямо в результате

Секция ИТОГИ добавляет в результат строки с суммами по группировкам и общий итог:

|ИТОГИ
|    СУММА(Количество),
|    СУММА(Сумма)
|ПО
|    ОБЩИЕ,
|    Номенклатура"

Такой результат обходят через Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам). Для остатков и оборотов регистров не суммируйте движения вручную: виртуальные таблицы Остатки и Обороты уже отдают готовые суммы за период.

Итоги в табличном документе

Здесь два разных случая: вы сами выводите отчёт из макета или читаете числа из уже готового табличного документа.

Итог при выводе из макета

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

ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
ОбластьИтого = Макет.ПолучитьОбласть("Итого");
ИтогСумма = 0;
Для Каждого Строка Из Данные Цикл
    ОбластьСтрока.Параметры.Заполнить(Строка);
    ТабДок.Вывести(ОбластьСтрока);
    ИтогСумма = ИтогСумма + Строка.Сумма;
КонецЦикла;
ОбластьИтого.Параметры.ИтогСумма = ИтогСумма;
ТабДок.Вывести(ОбластьИтого);

В макете в области «Итого» должна быть ячейка с параметром ИтогСумма. Формат числа задайте в свойствах ячейки, например ЧДЦ=2.

Сумма выделенных ячеек готового документа

Если нужно повторить «поле суммы» в своей форме, обойдите выделенные области. Код выполняется на клиенте: выделение существует только там.

&НаКлиенте
Функция СуммаВыделенныхЯчеек(ТабДок)
    Итого = 0;
    Для Каждого Область Из ТабДок.ВыделенныеОбласти Цикл
        Если ТипЗнч(Область) <> Тип("ОбластьЯчеекТабличногоДокумента") Тогда
            Продолжить;
        КонецЕсли;
        Верх = Макс(Область.Верх, 1);
        Низ = ?(Область.Низ = 0, ТабДок.ВысотаТаблицы, Мин(Область.Низ, ТабДок.ВысотаТаблицы));
        Лево = Макс(Область.Лево, 1);
        Право = ?(Область.Право = 0, ТабДок.ШиринаТаблицы, Мин(Область.Право, ТабДок.ШиринаТаблицы));
        Для НомерСтроки = Верх По Низ Цикл
            Для НомерКолонки = Лево По Право Цикл
                Текст = ТабДок.Область(НомерСтроки, НомерКолонки, НомерСтроки, НомерКолонки).Текст;
                Итого = Итого + ЧислоИзТекста(Текст);
            КонецЦикла;
        КонецЦикла;
    КонецЦикла;
    Возврат Итого;
КонецФункции

&НаКлиенте
Функция ЧислоИзТекста(Знач Текст)
    Текст = СтрЗаменить(Текст, Символы.НПП, "");
    Текст = СтрЗаменить(Текст, " ", "");
    Текст = СтрЗаменить(Текст, ",", ".");
    Если ПустаяСтрока(Текст) Тогда
        Возврат 0;
    КонецЕсли;
    Попытка
        Возврат Число(Текст);
    Исключение
        Возврат 0;
    КонецПопытки;
КонецФункции

Ограничение по высоте и ширине таблицы нужно на случай, когда пользователь выделил колонку целиком: без него цикл уйдёт далеко за последнюю заполненную строку.

Разделитель разрядов в отчётах 1С — неразрывный пробел, а не обычный. Поэтому Число("1 250,00") без чистки текста падает с ошибкой преобразования.

Группировки и итоги в схеме компоновки данных

В СКД сумма по колонке появляется не сама по себе: поле нужно объявить ресурсом.

  1. Откройте схему компоновки в конструкторе отчёта.
  2. Перейдите на вкладку Ресурсы.
  3. Перенесите туда числовые поля: «Количество», «Сумма». По умолчанию выражение — Сумма(Сумма).
  4. На вкладке Настройки добавьте группировку, например по контрагенту, а внутри — детальные записи или вложенную группировку по номенклатуре.

После этого отчёт выведет подытог в каждой группировке и общий итог внизу.

Что настраивается дальше

  • 📊 Расположение общих итогов. На вкладке Другие настройки задаётся, где выводить общий итог: внизу, вверху или нигде.
  • 🧮 Итог не суммой. Для цены сумма бессмысленна. Задайте ресурсу выражение Сумма(Сумма) / Сумма(Количество) — получится средневзвешенная цена в каждой группе.
  • 🔢 Ресурс только на нужных уровнях. В свойствах ресурса можно указать группировки, по которым он рассчитывается. Это убирает нули и мусор в строках, где итог не нужен.
  • 📐 Доля от общего итога. В вычисляемых полях и ресурсах доступна функция ВычислитьВыражение, например ВычислитьВыражение("Сумма(Сумма)", "ОбщийИтог").

В пользовательском режиме те же группировки и итоги меняют через кнопку Настройки... отчёта на закладке со структурой, если вариант отчёта это позволяет.

Поле, которое не объявлено ресурсом, в группировках выводится пустым. Если «сумма по контрагенту» не появилась — первым делом проверьте вкладку Ресурсы.

Отладка: как проверить, что сумма посчитана верно

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

  1. Поставьте точку останова на строку после расчёта суммы (F9 в конфигураторе).
  2. Запустите отладку и дойдите до точки.
  3. Откройте окно вычисления выражения (Shift+F9) и введите, например, Объект.Товары.Итог("Сумма") или Результат.Итог("Сумма").
  4. Сравните с переменной, в которую вы копили сумму в цикле.

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

Ошибки точности и «разъехавшиеся» суммы

Большинство вопросов «почему сумма не бьётся» сводится к нескольким причинам.

Диагностика: выберите симптом

Почему 0,1 + 0,2 в 1С равно 0,3

Тип Число во встроенном языке десятичный, а не двоичный с плавающей точкой, как в Excel или JavaScript. Поэтому знакомой по Excel ошибки «0,30000000000000004» в 1С нет. Расхождения возникают только там, где вы сами округляете промежуточные значения или ограничиваете точность реквизита.

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

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

Можно ли в табличном документе 1С написать формулу, как в Excel?
Нет. Табличный документ не хранит формулы, ячейки содержат готовые значения. Итог считают кодом при выводе или выгружают документ в Excel и считают там.
Почему не видно суммы выделенных ячеек в отчёте?
Поле суммы есть в формах отчётов типовых конфигураций. В самописной обработке его нет, пока разработчик не добавит расчёт по выделенным областям сам.
Чем Итог() отличается от СУММА() в запросе?
Итог() считает уже загруженную в память таблицу. СУММА() считает на стороне базы данных и возвращает готовую цифру — для больших объёмов это быстрее.
Как посчитать сумму с отбором без цикла?
В запросе — условие в ГДЕ или ВЫБОР внутри СУММА. В таблице значений — НайтиСтроки() по структуре отбора, но саму сумму по найденным строкам всё равно складывают в цикле.
Где в СКД убрать общий итог внизу отчёта?
На вкладке «Другие настройки» схемы или в настройках варианта: параметр расположения общих итогов по вертикали ставят в «Нет».