Разработка и Конфигурация · 10 мин
Как сложить числа в 1С: оператор, запросы, итоги и отчёты
Как сложить числа в 1С: оператор сложения в коде, сумма в табличной части, итоги в запросе СУММА, группировки в отчётах СКД и типичные ошибки.
Сложение чисел — базовая операция, которая в 1С встречается сразу в нескольких контекстах: в коде на встроенном языке, в запросах к базе данных, в табличных частях документов и в отчётах на СКД. У каждого сценария свой синтаксис и свои подводные камни: где-то важен тип данных, где-то — обработка NULL, а где-то — настройка итогов.
Материал охватывает все основные способы суммирования: от простого оператора «+» до агрегатной функции СУММА в запросе и ресурсов в схеме компоновки данных. Примеры применимы к типовым конфигурациям на управляемых формах (1С:ERP, 1С:Бухгалтерия, 1С:Управление торговлей) и к самостоятельным разработкам.
Сложение чисел в коде на встроенном языке
Самый простой случай — сложение двух числовых переменных оператором «+». Результат можно присвоить переменной, вывести пользователю или использовать в дальнейших вычислениях:
Число1 = 10;
Число2 = 25.5;
Сумма = Число1 + Число2; // 35.5
Оператор «+» работает и с датами (прибавление секунд), и со строками — но там он выполняет конкатенацию, то есть склеивание. Если хотя бы один операнд — строка, а второй — число, платформа попытается выполнить преобразование, и при невозможности выдаст ошибку «Преобразование значения к типу Число не может быть выполнено». Поэтому перед сложением значений из реквизитов с составным типом или из пользовательского ввода стоит явно приводить их к числу.
Для суммирования элементов коллекции — массива, таблицы значений, колонки — удобно использовать цикл либо встроенный метод Итог() у таблицы значений:
// Сумма колонки таблицы значений
ИтогоСумма = ТаблицаТоваров.Итог("Сумма");
// Сумма массива через цикл
Итого = 0;
Для Каждого Элемент Из МассивЧисел Цикл
Итого = Итого + Элемент;
КонецЦикла;
Сумма в табличной части документа
Типовая задача — посчитать итог по табличной части документа, например общую сумму по строкам товаров. В модуле объекта или формы обращение к табличной части идёт по её имени, а суммирование выполняется тем же методом Итог():
// В модуле объекта документа
СуммаДокумента = Товары.Итог("Сумма");
// На форме — через объект
ИтогоПоДокументу = Объект.Товары.Итог("Сумма");
Если нужен пересчёт суммы строки при изменении количества или цены, код размещают в обработчике события ПриИзменении соответствующего поля на форме. В типовых конфигурациях для этого обычно есть готовые процедуры пересчёта — дублировать их своей логикой не стоит, лучше вызывать существующие механизмы, чтобы не нарушить расчёт НДС, скидок и округления.
- 1Откройте форму документа в конфигураторе
- 2Найдите поле Количество табличной части и создайте обработчик ПриИзменении
- 3В обработчике получите текущую строку: Строка = Элементы.Товары.ТекущиеДанные
- 4Запишите расчёт: Строка.Сумма = Строка.Количество * Строка.Цена
- 5Повторите для поля Цена и проверьте результат на тестовом документе
Суммирование в запросе: функция СУММА
Когда данные нужно сложить по большому объёму записей, правильный инструмент — запрос с агрегатной функцией СУММА. Она суммирует значения поля по группе или по всей выборке:
ВЫБРАТЬ
Продажи.Номенклатура КАК Номенклатура,
СУММА(Продажи.СуммаОборот) КАК СуммаПродаж
ИЗ
РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, , ) КАК Продажи
СГРУППИРОВАТЬ ПО
Продажи.Номенклатура
Ключевой нюанс — функция СУММА игнорирует значения NULL. Если поле может быть NULL (например, после левого соединения), итог по группе может оказаться NULL или заниженным. Стандартное решение — обернуть поле в ЕСТЬNULL:
СУММА(ЕСТЬNULL(Таблица.Сумма, 0)) КАК Сумма
Для суммирования с условием используют конструкцию ВЫБОР внутри агрегатной функции — так можно в одном запросе получить несколько разных сумм, например отдельно по видам операций:
СУММА(ВЫБОР
КОГДА Операции.ВидОперации = &Продажа
ТОГДА Операции.Сумма
ИНАЧЕ 0
КОНЕЦ) КАК СуммаПродаж
Итоги по регистрам накопления
Если данные хранятся в регистре накопления, суммировать движения вручную обычно не нужно — платформа умеет получать готовые итоги через виртуальные таблицы. Для регистра остатков это таблица Остатки, для оборотного регистра или оборотов по остаточному — Обороты с указанием периода.
Обращение к виртуальной таблице не только короче, но и быстрее: итоги хранятся в предрассчитанном виде, если у регистра включено использование итогов. Проверить это можно в свойствах регистра в конфигураторе. При отключённых итогах (так иногда делают для ускорения записи) запрос к виртуальной таблице будет считать сумму по всем записям, что заметно медленнее.
Для регистра сведений и справочников виртуальных таблиц итогов нет — там суммирование выполняется только агрегатной функцией СУММА с группировкой по нужным измерениям.
Как выбрать способ суммирования
Сумма в отчётах на СКД
В схеме компоновки данных суммирование настраивается на вкладке «Ресурсы». Ресурс — это поле, которое система будет агрегировать при группировке. Для числового поля указывают выражение Сумма(СуммаДокумента) и перечисляют группировки, по которым ресурс рассчитывается (или оставляют «Общий итог»).
Распространённая ситуация: поле добавлено в запрос набора данных, но в отчёте итог пустой или равен нулю. Причина почти всегда в том, что поле не добавлено в ресурсы либо для него не указаны группировки расчёта. Вторая частая причина — в выражении ресурса используется агрегат, а в настройках отчёта поле выведено в детальных записях без группировки: тогда СКД не покажет итог выше уровня детальных строк.
Если сумма должна считаться нестандартно — например, сумма максимумов по группам — используют вложенные агрегаты в выражении ресурса: Сумма(Максимум(Поле)). Порядок агрегатов важен: сначала вычисляется внутренний по нижнему уровню группировки.
Особые случаи: округление, составные типы, валютные суммы
При сложении дробных чисел с последующим выводом в документ или отчёт важно округление. Функция Окр(Значение, 2) округляет до копеек, причём округлять следует итоговую сумму, а не каждое слагаемое по отдельности — иначе накапливается погрешность, и итог по строкам не сойдётся с суммой документа.
Реквизиты составного типа (например, «Число, Строка») перед сложением нужно проверять функцией ТипЗнч() и приводить к числу. Попытка сложить значение нечислового экземпляра приведёт к ошибке исполнения, которая прервёт обработку.
Валютные суммы складывать напрямую между собой нельзя: сначала каждую сумму пересчитывают в валюту учёта по курсу на нужную дату, и только потом суммируют. В типовых конфигурациях для этого есть функции работы с курсами валют в общих модулях.
Как проверить результат
Сумма документа совпадает с суммой по строкам с точностью до копеек
Расхождение на копейки — округляли промежуточные значения
Итог по группе числовой и совпадает с ручной проверкой по отбору
NULL или заниженная сумма — не обработаны NULL-значения
Общий итог равен сумме по группировкам верхнего уровня
Пустые итоги — поле не добавлено в ресурсы
Каждая сумма пересчитана по курсу до сложения
Складываются суммы в разных валютах напрямую
Контроль результата и границы самостоятельной работы
Любой расчёт суммы стоит проверять на контрольном примере: взять два-три документа с известными значениями, сложить вручную и сравнить с результатом программы. Для запросов удобно использовать консоль запросов, для кода — отладчик с просмотром значений переменных на каждом шаге.
Все изменения в коде и схемах отчётов выполняйте сначала на копии базы. Ошибка в процедуре пересчёта сумм документа может некорректно записать уже проведённые документы, а восстановление потребует перепроведения или восстановления из резервной копии. Перед изменением типовых модулей убедитесь, что конфигурация поддерживает расширения — доработку через расширение откатить значительно проще, чем прямое изменение конфигурации.
Что важно запомнить
В коде числа складываются оператором «+», колонки таблиц — методом Итог(), данные базы — функцией СУММА в запросе с обработкой NULL через ЕСТЬNULL, а в отчётах СКД — через ресурсы. Округляйте только итог, проверяйте типы операндов и тестируйте расчёт на копии базы.
Частые вопросы
Почему при сложении чисел получается строка?
Значит, хотя бы один операнд имеет строковый тип — оператор «+» выполняет конкатенацию. Проверьте типы через ТипЗнч() и приведите значения к числу функцией Число() или настройкой типа реквизита.
СУММА в запросе возвращает NULL, хотя записи есть. Что делать?
Это происходит, когда все суммируемые значения в группе равны NULL — типично после левого соединения без совпадений. Оберните поле в ЕСТЬNULL(Поле, 0) внутри функции СУММА.
Как сложить суммы только по отмеченным строкам табличной части?
Метод Итог() так не умеет. Либо пройдите циклом по строкам с проверкой признака и накапливайте сумму в переменной, либо выгрузите табличную часть в таблицу значений, отберите строки через НайтиСтроки() и просуммируйте их.
Можно ли сложить числа в отчёте без изменения конфигурации?
Да, если отчёт построен на СКД: в пользовательском режиме доступны настройки группировок и выводимых ресурсов. Если нужного ресурса нет, потребуется доработка схемы в конфигураторе или через расширение.
Почему итог документа не сходится с суммой строк на копейку?
Причина — округление промежуточных значений: цены с НДС, скидки или пересчёты валют округлялись на каждой строке. Округляйте только итоговую сумму либо используйте механизм распределения копеек, встроенный в типовые конфигурации.
Что быстрее: цикл по выборке или СУММА в запросе?
Агрегатная функция СУММА в запросе всегда предпочтительнее: она выполняется на стороне СУБД одной операцией. Цикл по выборке требует передачи всех записей на сервер 1С и обрабатывается интерпретатором, что на больших объёмах работает в разы медленнее.