Разработка и Конфигурация · 10 мин
Как найти сумму всех элементов массива в 1С
Как посчитать сумму всех элементов массива в 1С: перебор в цикле, универсальная функция, свёртка таблицы значений, типичные ошибки и готовые примеры кода.
Массив в 1С — это простая коллекция значений без встроенного метода суммирования. В отличие от таблицы значений, у которой есть метод Итог(), для массива сумму приходится вычислять вручную: перебором элементов в цикле с накоплением результата. Это базовая задача, которая встречается при расчёте итогов по строкам документов, обработке данных обмена и агрегации показателей.
Способ решения зависит от того, что лежит в массиве: простые числа, строки с числами или структуры, из которых нужно взять конкретное поле. Ниже разобраны рабочие варианты кода для толстого и тонкого клиента, функция для повторного использования в общем модуле, а также альтернатива через таблицу значений, когда массив большой и требуется не только сумма.
Как устроен массив в 1С и почему у него нет метода суммы
Массив создаётся конструктором Новый Массив и хранит произвольные значения: числа, строки, ссылки, структуры. Из-за такой универсальности платформа не может заранее знать, какие элементы складывать, поэтому методов вроде Сумма() у массива нет. Есть только базовые операции: Количество(), Добавить(), Найти(), ВГраница().
Это значит, что ответственность за корректность суммирования лежит на разработчике: нужно самостоятельно перебрать элементы, убедиться, что они числовые, и накопить результат. Если в массиве окажется строка или Неопределено, попытка сложения вызовет ошибку выполнения «Преобразование значения к типу Число не может быть выполнено».
Базовый способ: суммирование в цикле «Для Каждого»
Самый читаемый вариант — перебор элементов с накоплением суммы в отдельной переменной. Переменную обязательно инициализируют нулём до цикла, иначе при первом сложении будет ошибка из-за неопределённого значения.
Функция СуммаМассива(Массив) Экспорт
Сумма = 0;
Для Каждого Элемент Из Массив Цикл
Сумма = Сумма + Элемент;
КонецЦикла;
Возврат Сумма;
КонецФункции
Вызов выглядит так:
Цены = Новый Массив;
Цены.Добавить(150.50);
Цены.Добавить(200);
Цены.Добавить(49.50);
Итого = СуммаМассива(Цены); // 400
Цикл Для Каждого подходит, когда индекс элемента не нужен. Если по логике задачи требуется знать позицию элемента (например, суммировать только элементы с чётными индексами), используйте классический цикл со счётчиком: Для Индекс = 0 По Массив.ВГраница() Цикл.
Сумма = 0;
Для Каждого Элемент Из Массив Цикл
Сумма = Сумма + Элемент;
КонецЦикла;Сумма по полю структур внутри массива
На практике массив часто содержит не числа, а структуры или строки таблицы значений — например, результат разбора JSON или выборка данных обмена. Тогда в цикле складывают конкретное поле каждого элемента.
// Массив структур с полями Товар и Сумма
ИтоговаяСумма = 0;
Для Каждого СтрокаДанных Из МассивСтрок Цикл
ИтоговаяСумма = ИтоговаяСумма + СтрокаДанных.Сумма;
КонецЦикла;
Здесь критично убедиться, что поле существует у каждой структуры. Если структуры формируются в разных местах кода, безопаснее проверять наличие ключа через СтрокаДанных.Свойство("Сумма", ЗначениеПоля) — метод вернёт Ложь, если ключа нет, и код не упадёт с ошибкой.
Для числовых полей, которые могут быть не заполнены, добавляйте защиту от Неопределено:
ЗначениеПоля = ?(СтрокаДанных.Сумма = Неопределено, 0, СтрокаДанных.Сумма);
ИтоговаяСумма = ИтоговаяСумма + ЗначениеПоля;
Суммирование с условием и фильтрацией
Частая задача — сложить не все элементы, а только удовлетворяющие условию: положительные значения, суммы по конкретному контрагенту, числа больше порога. Условие помещают прямо внутрь цикла.
СуммаПоложительных = 0;
Для Каждого Элемент Из Массив Цикл
Если ТипЗнч(Элемент) = Тип("Число") И Элемент > 0 Тогда
СуммаПоложительных = СуммаПоложительных + Элемент;
КонецЕсли;
КонецЦикла;
Обратите внимание на проверку типа через ТипЗнч(). Если массив собирается из внешних данных (файл, HTTP-запрос, строка, введённая пользователем), элементы могут оказаться строками. Строку с числом можно преобразовать через Число(), но функция выбросит исключение на нечисловом значении, поэтому преобразование безопасно выполнять только после проверки или внутри Попытка...Исключение.
Альтернатива: таблица значений с методом Итог()
Если данные удобно представить в виде таблицы, массив можно заменить таблицей значений — у неё есть встроенный метод Итог("ИмяКолонки"), который посчитает сумму по числовой колонке без цикла.
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число"));
Для Каждого Элемент Из Массив Цикл
НоваяСтрока = ТЗ.Добавить();
НоваяСтрока.Сумма = Элемент;
КонецЦикла;
Итого = ТЗ.Итог("Сумма");
Дополнительное преимущество — метод Свернуть(), который группирует строки и суммирует показатели одновременно. Это удобно, когда помимо общей суммы нужны итоги по измерениям: по контрагентам, складам, периодам. Для одноразового сложения простого числового массива таблица значений избыточна — цикл проще и быстрее написать.
Что выбрать для суммирования
Подходит для простого массива чисел или структур. Минимум кода, работает везде, включая тонкий клиент и веб-клиент.
Подходит, когда нужны ещё и группировки через Свернуть(). Избыточна для одноразового сложения, требует описания колонок.
Лучший вариант, если данные уже лежат в базе: сумму считает СУБД, в память загружается только итог.
Сумма через запрос, если данные в базе
Если массив формируется из данных информационной базы (например, выгрузкой результата запроса), эффективнее посчитать сумму прямо в запросе агрегатной функцией СУММА() и не перебирать массив вообще. Сервер базы данных выполнит агрегацию быстрее, чем цикл на встроенном языке, а в прикладной код вернётся одно число.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| СУММА(Продажи.СуммаОборот) КАК ИтоговаяСумма
|ИЗ
| РегистрНакопления.Продажи.Обороты(&Начало, &Конец, , ) КАК Продажи";
Выборка = Запрос.Выполнить().Выбрать();
ИтоговаяСумма = 0;
Если Выборка.Следующий() Тогда
ИтоговаяСумма = ?(Выборка.ИтоговаяСумма = NULL, 0, Выборка.ИтоговаяСумма);
КонецЕсли;
Важный нюанс: если в выборке нет ни одной строки, СУММА() возвращает NULL, а не ноль. Поэтому результат всегда проверяют на NULL и заменяют нулём — иначе последующие вычисления с этим значением дадут ошибку.
Куда поместить функцию и как проверить результат
Функцию суммирования, которая нужна в нескольких местах конфигурации, помещают в общий модуль. Для вызова с клиента модуль должен иметь флажки «Клиент (обычное приложение)» и/или «Клиент (управляемое приложение)»; для серверных вычислений — флажок «Сервер». Клиент-серверный вызов из цикла делать нельзя: функцию вызывают один раз, передавая массив целиком.
Проверка корректности простая: на тестовом массиве с заранее известной суммой (например, 10 + 20 + 30 = 60) функция должна вернуть ожидаемое число. Дополнительно проверьте граничные случаи: пустой массив должен дать 0, массив из одного элемента — сам элемент, массив с отрицательными числами — алгебраическую сумму.
Как проверить результат
Функция возвращает 0
Ошибка или Неопределено — значит, переменная суммы не инициализирована
Результат ровно 60
Другое число — проверьте, не суммируется ли элемент дважды
Такие элементы пропускаются или заменяются нулём
Ошибка преобразования типа — нет защиты в цикле
Частые вопросы
Есть ли в 1С встроенная функция суммы массива, как в других языках?
Нет. Во встроенном языке 1С у массива нет агрегатных методов. Сумму вычисляют перебором в цикле либо переносят данные в таблицу значений и используют метод Итог().
Как посчитать сумму только числовых элементов, если в массиве смешанные типы?
Внутри цикла проверяйте тип: Если ТипЗнч(Элемент) = Тип("Число") Тогда Сумма = Сумма + Элемент; КонецЕсли. Нечисловые элементы будут проигнорированы без ошибки.
Что вернёт суммирование пустого массива?
Если переменная суммы инициализирована нулём до цикла, цикл просто не выполнится ни разу, и функция вернёт 0. Если переменную не инициализировать, получите ошибку или Неопределено — поэтому обнуление обязательно.
Можно ли суммировать массив на клиенте в управляемом приложении?
Да, цикл перебора массива работает и на тонком, и на веб-клиенте, серверный вызов не требуется. Ограничение касается только таблиц значений — на тонком клиенте они недоступны, там вместо них используют массивы структур или данные формы.
Что быстрее: цикл по массиву или запрос с СУММА()?
Если данные уже в памяти в виде массива — цикл быстрее, так как не требует обращения к базе. Если данные ещё предстоит получить из базы, эффективнее сразу посчитать сумму запросом: СУБД выполнит агрегацию и передаст одно число вместо тысяч строк.
Как сложить элементы двумерного массива?
Двумерного массива в 1С нет — используют массив массивов. Суммируют двумя вложенными циклами: внешний перебирает строки (вложенные массивы), внутренний — элементы каждой строки.
Что важно запомнить
Сумма массива в 1С считается циклом с накоплением в обнулённой переменной. Проверяйте типы элементов из внешних источников, помните про NULL у СУММА() в запросах, а для группировок используйте таблицу значений с методами Итог() и Свернуть().