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