Сумма по ячейкам в 1С: от выделения мышью до итогов в СКД
Содержание
Чтобы быстро суммировать ячейки в 1С, выделите их мышью в сформированном отчёте: в типовых конфигурациях на платформе 8.3 сумма выделенного сразу появляется в поле над табличным документом, справа. В коде сумму колонки таблицы считает метод Итог("Сумма"), в запросе — агрегатная функция СУММА(), в схеме компоновки — ресурс.
Типичная ситуация: главбух просит «сколько всего отгрузили Ромашке за квартал», а в отчёте 140 строк. Пересчитывать на калькуляторе не нужно: пользователь справится выделением, а разработчику хватит одной строки в коде, запросе или схеме компоновки.
Сумма выделенных ячеек в режиме пользователя
Для бухгалтера это самый частый сценарий. Ничего настраивать не нужно.
- Сформируйте отчёт, например оборотно-сальдовую ведомость.
- Выделите мышью нужные ячейки с числами. Несмежные ячейки добавляйте с зажатым
Ctrl, диапазон — сShift. - Посмотрите в поле справа над отчётом: там появится сумма выделенного.
- Нажмите на стрелку рядом с этим полем — можно переключить показатель на количество, среднее, минимум или максимум.
Поле считает только ячейки, где действительно стоит число. Заголовки, пустые ячейки и текст вроде «Итого» в сумму не попадают, поэтому выделять колонку можно вместе с шапкой.
Если нужен итог по списку документов
Журналы и списки справочников — это не отчёт, выделить в них ячейки как в таблице нельзя. Порядок такой:
- Откройте список, например
Продажи → Реализация (акты, накладные, УПД)в 1С:Бухгалтерии 3.0. - Отберите нужное: по контрагенту, организации, периоду.
- Выполните
Ещё → Вывести список..., отметьте нужные колонки и нажмитеОК. - Список откроется как табличный документ. Выделите колонку «Сумма» — итог появится так же, как в отчёте.
Из этого же окна список удобно сохранить в Excel, если сумму нужно разложить по формулам.
Калькулятор платформы
Для пары чисел, которых нет рядом в одной таблице, подойдёт встроенный калькулятор: Ctrl+F2. Результат копируется в любое числовое поле документа.
| Задача | Чем пользоваться |
|---|---|
| Сумма части строк отчёта | Выделение мышью, поле суммы над отчётом |
| Итог по журналу документов | Ещё → Вывести список... + выделение |
| Сложить 2–3 числа из разных мест | Калькулятор Ctrl+F2 |
| Регулярный итог по одной и той же выборке | Настройка отчёта: группировки и итоги |
Суммирование в цикле на встроенном языке
Когда сумма нужна внутри обработки, документа или печатной формы, считают программно. Самый прямой способ — обойти строки и накопить значение в переменной.
ИтогоСумма = 0;
ИтогоКоличество = 0;
Для Каждого СтрокаТЧ Из Объект.Товары Цикл
ИтогоСумма = ИтогоСумма + СтрокаТЧ.Сумма;
ИтогоКоличество = ИтогоКоличество + СтрокаТЧ.Количество;
КонецЦикла;
Цикл нужен, когда есть условие: сложить только строки с положительной суммой, только определённый склад, только услуги. Если условия нет, проще встроенный метод.
Метод Итог() для табличной части и таблицы значений
ИтогоСумма = Объект.Товары.Итог("Сумма");
Метод есть у табличной части и у таблицы значений. Он работает с колонкой числового типа. Если таблицу значений вы строите сами, сразу задайте колонке тип, иначе итог по колонке без типа может вести себя непредсказуемо:
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Номенклатура");
ТЗ.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2)));
Свернуть() — сумма по группам
Нужна сумма не одной цифрой, а по каждой номенклатуре? Используйте Свернуть():
ТЗ = Объект.Товары.Выгрузить();
ТЗ.Свернуть("Номенклатура", "Количество, Сумма");
Первый параметр — колонки группировки, второй — колонки, которые суммируются. Остальные колонки метод удалит. Он меняет саму таблицу, поэтому сворачивайте копию, полученную через Выгрузить(), а не табличную часть объекта.
Не суммируйте в цикле тысячи строк, которые сначала получили из базы по одной. Если данные лежат в базе, считать нужно в запросе: это быстрее на порядок и не грузит клиент.
Итог в подвале табличной части формы
Пользователи часто просят «показать сумму под колонкой». В управляемой форме это делается без кода:
- В свойствах таблицы формы включите
Подвал. - У поля колонки заполните
ПутьКДаннымПодвала, напримерОбъект.Товары.ИтогСумма.
Платформа сама пересчитывает значение при изменении строк. Для колонки «Количество» путь будет Объект.Товары.ИтогКоличество.
Агрегация данных средствами языка запросов
Запрос — основной способ суммировать данные, которые уже записаны в базу. Для этого есть агрегатная функция СУММА() и группировка СГРУППИРОВАТЬ ПО.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Товары.Номенклатура КАК Номенклатура,
| СУММА(Товары.Количество) КАК Количество,
| СУММА(Товары.Сумма) КАК Сумма
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК Товары
|ГДЕ
| Товары.Ссылка.Проведен
| И Товары.Ссылка.Дата МЕЖДУ &НачалоПериода И &КонецПериода
|СГРУППИРОВАТЬ ПО
| Товары.Номенклатура";
Запрос.УстановитьПараметр("НачалоПериода", НачалоКвартала(ТекущаяДатаСеанса()));
Запрос.УстановитьПараметр("КонецПериода", КонецКвартала(ТекущаяДатаСеанса()));
Результат = Запрос.Выполнить().Выгрузить();
Каждое поле в ВЫБРАТЬ должно быть либо под агрегатной функцией, либо в СГРУППИРОВАТЬ ПО. Иначе запрос не выполнится с ошибкой про поле, которое не входит в группу.
Одна общая сумма
Если нужна одна цифра, группировка не нужна. Но учтите: если подходящих строк нет, СУММА() вернёт NULL, а не ноль.
"ВЫБРАТЬ
| ЕСТЬNULL(СУММА(Товары.Сумма), 0) КАК Сумма
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК Товары
|ГДЕ
| Товары.Ссылка = &Документ"
Условная сумма в одном запросе
Чтобы получить в одной строке и продажи, и возвраты, используйте ВЫБОР внутри СУММА:
СУММА(ВЫБОР КОГДА Т.Сумма > 0 ТОГДА Т.Сумма ИНАЧЕ 0 КОНЕЦ) КАК Приход,
СУММА(ВЫБОР КОГДА Т.Сумма < 0 ТОГДА -Т.Сумма ИНАЧЕ 0 КОНЕЦ) КАК Расход
Отбор по уже посчитанной сумме ставят в ИМЕЮЩИЕ, а не в ГДЕ: например, ИМЕЮЩИЕ СУММА(Товары.Сумма) > 100000.
ИТОГИ — подытоги прямо в результате
Секция ИТОГИ добавляет в результат строки с суммами по группировкам и общий итог:
|ИТОГИ
| СУММА(Количество),
| СУММА(Сумма)
|ПО
| ОБЩИЕ,
| Номенклатура"
Такой результат обходят через Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам). Для остатков и оборотов регистров не суммируйте движения вручную: виртуальные таблицы Остатки и Обороты уже отдают готовые суммы за период.
Итоги в табличном документе
Здесь два разных случая: вы сами выводите отчёт из макета или читаете числа из уже готового табличного документа.
Итог при выводе из макета
Самый надёжный вариант — копить сумму в момент вывода строк. Тогда итог берётся из исходных чисел, а не из отформатированного текста ячеек.
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
ОбластьИтого = Макет.ПолучитьОбласть("Итого");
ИтогСумма = 0;
Для Каждого Строка Из Данные Цикл
ОбластьСтрока.Параметры.Заполнить(Строка);
ТабДок.Вывести(ОбластьСтрока);
ИтогСумма = ИтогСумма + Строка.Сумма;
КонецЦикла;
ОбластьИтого.Параметры.ИтогСумма = ИтогСумма;
ТабДок.Вывести(ОбластьИтого);
В макете в области «Итого» должна быть ячейка с параметром ИтогСумма. Формат числа задайте в свойствах ячейки, например ЧДЦ=2.
Сумма выделенных ячеек готового документа
Если нужно повторить «поле суммы» в своей форме, обойдите выделенные области. Код выполняется на клиенте: выделение существует только там.
&НаКлиенте
Функция СуммаВыделенныхЯчеек(ТабДок)
Итого = 0;
Для Каждого Область Из ТабДок.ВыделенныеОбласти Цикл
Если ТипЗнч(Область) <> Тип("ОбластьЯчеекТабличногоДокумента") Тогда
Продолжить;
КонецЕсли;
Верх = Макс(Область.Верх, 1);
Низ = ?(Область.Низ = 0, ТабДок.ВысотаТаблицы, Мин(Область.Низ, ТабДок.ВысотаТаблицы));
Лево = Макс(Область.Лево, 1);
Право = ?(Область.Право = 0, ТабДок.ШиринаТаблицы, Мин(Область.Право, ТабДок.ШиринаТаблицы));
Для НомерСтроки = Верх По Низ Цикл
Для НомерКолонки = Лево По Право Цикл
Текст = ТабДок.Область(НомерСтроки, НомерКолонки, НомерСтроки, НомерКолонки).Текст;
Итого = Итого + ЧислоИзТекста(Текст);
КонецЦикла;
КонецЦикла;
КонецЦикла;
Возврат Итого;
КонецФункции
&НаКлиенте
Функция ЧислоИзТекста(Знач Текст)
Текст = СтрЗаменить(Текст, Символы.НПП, "");
Текст = СтрЗаменить(Текст, " ", "");
Текст = СтрЗаменить(Текст, ",", ".");
Если ПустаяСтрока(Текст) Тогда
Возврат 0;
КонецЕсли;
Попытка
Возврат Число(Текст);
Исключение
Возврат 0;
КонецПопытки;
КонецФункции
Ограничение по высоте и ширине таблицы нужно на случай, когда пользователь выделил колонку целиком: без него цикл уйдёт далеко за последнюю заполненную строку.
Разделитель разрядов в отчётах 1С — неразрывный пробел, а не обычный. Поэтому Число("1 250,00") без чистки текста падает с ошибкой преобразования.
Группировки и итоги в схеме компоновки данных
В СКД сумма по колонке появляется не сама по себе: поле нужно объявить ресурсом.
- Откройте схему компоновки в конструкторе отчёта.
- Перейдите на вкладку
Ресурсы. - Перенесите туда числовые поля: «Количество», «Сумма». По умолчанию выражение —
Сумма(Сумма). - На вкладке
Настройкидобавьте группировку, например по контрагенту, а внутри — детальные записи или вложенную группировку по номенклатуре.
После этого отчёт выведет подытог в каждой группировке и общий итог внизу.
Что настраивается дальше
- 📊 Расположение общих итогов. На вкладке
Другие настройкизадаётся, где выводить общий итог: внизу, вверху или нигде. - 🧮 Итог не суммой. Для цены сумма бессмысленна. Задайте ресурсу выражение
Сумма(Сумма) / Сумма(Количество)— получится средневзвешенная цена в каждой группе. - 🔢 Ресурс только на нужных уровнях. В свойствах ресурса можно указать группировки, по которым он рассчитывается. Это убирает нули и мусор в строках, где итог не нужен.
- 📐 Доля от общего итога. В вычисляемых полях и ресурсах доступна функция
ВычислитьВыражение, напримерВычислитьВыражение("Сумма(Сумма)", "ОбщийИтог").
В пользовательском режиме те же группировки и итоги меняют через кнопку Настройки... отчёта на закладке со структурой, если вариант отчёта это позволяет.
Поле, которое не объявлено ресурсом, в группировках выводится пустым. Если «сумма по контрагенту» не появилась — первым делом проверьте вкладку Ресурсы.
Отладка: как проверить, что сумма посчитана верно
Когда итог в документе не совпадает с отчётом, удобнее смотреть значения прямо в отладчике.
- Поставьте точку останова на строку после расчёта суммы (
F9в конфигураторе). - Запустите отладку и дойдите до точки.
- Откройте окно вычисления выражения (
Shift+F9) и введите, например,Объект.Товары.Итог("Сумма")илиРезультат.Итог("Сумма"). - Сравните с переменной, в которую вы копили сумму в цикле.
Для запроса полезно открыть его в консоли запросов и выполнить отдельно: сразу видно, есть ли задвоенные строки и NULL в числовых полях. Таблицу значений в отладчике можно раскрыть и посмотреть построчно.
Ошибки точности и «разъехавшиеся» суммы
Большинство вопросов «почему сумма не бьётся» сводится к нескольким причинам.
Почему 0,1 + 0,2 в 1С равно 0,3
Тип Число во встроенном языке десятичный, а не двоичный с плавающей точкой, как в Excel или JavaScript. Поэтому знакомой по Excel ошибки «0,30000000000000004» в 1С нет. Расхождения возникают только там, где вы сами округляете промежуточные значения или ограничиваете точность реквизита.
Правило простое: округляйте один раз и в конце. Если считать цену с округлением до копеек, а потом умножать на количество, ошибка вырастет пропорционально количеству.