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

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

Как найти сумму всех элементов массива в 1С

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

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

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

Как устроен массив в 1С и почему у него нет метода суммы

Массив создаётся конструктором Новый Массив и хранит произвольные значения: числа, строки, ссылки, структуры. Из-за такой универсальности платформа не может заранее знать, какие элементы складывать, поэтому методов вроде Сумма() у массива нет. Есть только базовые операции: Количество(), Добавить(), Найти(), ВГраница().

Это значит, что ответственность за корректность суммирования лежит на разработчике: нужно самостоятельно перебрать элементы, убедиться, что они числовые, и накопить результат. Если в массиве окажется строка или Неопределено, попытка сложения вызовет ошибку выполнения «Преобразование значения к типу Число не может быть выполнено».

Базовый способ: суммирование в цикле «Для Каждого»

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

Функция СуммаМассива(Массив) Экспорт

Сумма = 0;

Для Каждого Элемент Из Массив Цикл

Сумма = Сумма + Элемент;

КонецЦикла;

Возврат Сумма;

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

Вызов выглядит так:

Цены = Новый Массив;

Цены.Добавить(150.50);

Цены.Добавить(200);

Цены.Добавить(49.50);

Итого = СуммаМассива(Цены); // 400

Цикл Для Каждого подходит, когда индекс элемента не нужен. Если по логике задачи требуется знать позицию элемента (например, суммировать только элементы с чётными индексами), используйте классический цикл со счётчиком: Для Индекс = 0 По Массив.ВГраница() Цикл.

bsl
Сумма = 0;
Для Каждого Элемент Из Массив Цикл
	Сумма = Сумма + Элемент;
КонецЦикла;

Сумма по полю структур внутри массива

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

// Массив структур с полями Товар и Сумма

ИтоговаяСумма = 0;

Для Каждого СтрокаДанных Из МассивСтрок Цикл

ИтоговаяСумма = ИтоговаяСумма + СтрокаДанных.Сумма;

КонецЦикла;

Здесь критично убедиться, что поле существует у каждой структуры. Если структуры формируются в разных местах кода, безопаснее проверять наличие ключа через СтрокаДанных.Свойство("Сумма", ЗначениеПоля) — метод вернёт Ложь, если ключа нет, и код не упадёт с ошибкой.

Для числовых полей, которые могут быть не заполнены, добавляйте защиту от Неопределено:

ЗначениеПоля = ?(СтрокаДанных.Сумма = Неопределено, 0, СтрокаДанных.Сумма);

ИтоговаяСумма = ИтоговаяСумма + ЗначениеПоля;

Суммирование с условием и фильтрацией

Частая задача — сложить не все элементы, а только удовлетворяющие условию: положительные значения, суммы по конкретному контрагенту, числа больше порога. Условие помещают прямо внутрь цикла.

СуммаПоложительных = 0;

Для Каждого Элемент Из Массив Цикл

Если ТипЗнч(Элемент) = Тип("Число") И Элемент > 0 Тогда

СуммаПоложительных = СуммаПоложительных + Элемент;

КонецЕсли;

КонецЦикла;

Обратите внимание на проверку типа через ТипЗнч(). Если массив собирается из внешних данных (файл, HTTP-запрос, строка, введённая пользователем), элементы могут оказаться строками. Строку с числом можно преобразовать через Число(), но функция выбросит исключение на нечисловом значении, поэтому преобразование безопасно выполнять только после проверки или внутри Попытка...Исключение.

Альтернатива: таблица значений с методом Итог()

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

ТЗ = Новый ТаблицаЗначений;

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

Для Каждого Элемент Из Массив Цикл

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

НоваяСтрока.Сумма = Элемент;

КонецЦикла;

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

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

Что выбрать для суммирования

Цикл по массиву

Подходит для простого массива чисел или структур. Минимум кода, работает везде, включая тонкий клиент и веб-клиент.

Таблица значений + Итог()

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

Запрос с СУММА()

Лучший вариант, если данные уже лежат в базе: сумму считает СУБД, в память загружается только итог.

Сумма через запрос, если данные в базе

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

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

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

"ВЫБРАТЬ

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

|ИЗ

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

Выборка = Запрос.Выполнить().Выбрать();

ИтоговаяСумма = 0;

Если Выборка.Следующий() Тогда

ИтоговаяСумма = ?(Выборка.ИтоговаяСумма = NULL, 0, Выборка.ИтоговаяСумма);

КонецЕсли;

Важный нюанс: если в выборке нет ни одной строки, СУММА() возвращает NULL, а не ноль. Поэтому результат всегда проверяют на NULL и заменяют нулём — иначе последующие вычисления с этим значением дадут ошибку.

Куда поместить функцию и как проверить результат

Функцию суммирования, которая нужна в нескольких местах конфигурации, помещают в общий модуль. Для вызова с клиента модуль должен иметь флажки «Клиент (обычное приложение)» и/или «Клиент (управляемое приложение)»; для серверных вычислений — флажок «Сервер». Клиент-серверный вызов из цикла делать нельзя: функцию вызывают один раз, передавая массив целиком.

Проверка корректности простая: на тестовом массиве с заранее известной суммой (например, 10 + 20 + 30 = 60) функция должна вернуть ожидаемое число. Дополнительно проверьте граничные случаи: пустой массив должен дать 0, массив из одного элемента — сам элемент, массив с отрицательными числами — алгебраическую сумму.

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

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

Пустой массив
Норма

Функция возвращает 0

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

Ошибка или Неопределено — значит, переменная суммы не инициализирована

Массив 10, 20, 30
Норма

Результат ровно 60

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

Другое число — проверьте, не суммируется ли элемент дважды

Массив с NULL/Неопределено
Норма

Такие элементы пропускаются или заменяются нулём

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

Ошибка преобразования типа — нет защиты в цикле

Типичные ошибки
01
Переменная суммы не обнуляется перед циклом — при повторном вызове в одной процедуре итог накапливается поверх старого значения.
02
Сложение без проверки типа — строка или Неопределено в массиве прерывает выполнение с ошибкой преобразования.
03
Использование ВГраница() с циклом от 1 — индексация массива начинается с 0, первый элемент теряется или возникает выход за границы.
04
Ожидание нуля от СУММА() в запросе — при пустой выборке возвращается NULL, что ломает дальнейшие вычисления.

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

Есть ли в 1С встроенная функция суммы массива, как в других языках?

Нет. Во встроенном языке 1С у массива нет агрегатных методов. Сумму вычисляют перебором в цикле либо переносят данные в таблицу значений и используют метод Итог().

Как посчитать сумму только числовых элементов, если в массиве смешанные типы?

Внутри цикла проверяйте тип: Если ТипЗнч(Элемент) = Тип("Число") Тогда Сумма = Сумма + Элемент; КонецЕсли. Нечисловые элементы будут проигнорированы без ошибки.

Что вернёт суммирование пустого массива?

Если переменная суммы инициализирована нулём до цикла, цикл просто не выполнится ни разу, и функция вернёт 0. Если переменную не инициализировать, получите ошибку или Неопределено — поэтому обнуление обязательно.

Можно ли суммировать массив на клиенте в управляемом приложении?

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

Что быстрее: цикл по массиву или запрос с СУММА()?

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

Как сложить элементы двумерного массива?

Двумерного массива в 1С нет — используют массив массивов. Суммируют двумя вложенными циклами: внешний перебирает строки (вложенные массивы), внутренний — элементы каждой строки.

Итог

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

Сумма массива в 1С считается циклом с накоплением в обнулённой переменной. Проверяйте типы элементов из внешних источников, помните про NULL у СУММА() в запросах, а для группировок используйте таблицу значений с методами Итог() и Свернуть().