В практике программирования на платформе 1С:Предприятие часто возникает задача математического сложения числовых данных, которые хранятся в массиве. Особенно часто это встречается при парсинге входящих строк, получении данных из внешних источников или обработке табличных частей. Разберем подробно, как реализовать суммирование элементов массива, начиная от простейших алгоритмов и заканчивая профессиональными методами обработки данных.
Предположим, у нас есть исходные данные в виде строк, которые мы уже успешно преобразовали в массивы с помощью функции СтрРазделить:
СтрокаТоваров = "Тумба, Шкаф, Стол, Стул";
СтрокаЦен = "5000, 7000, 6000, 2000";
МассивТоваров = СтрРазделить(СтрокаТоваров, ",", Ложь);
МассивЦен = СтрРазделить(СтрокаЦен, ",", Ложь);
Наша цель — получить переменную ИтоговаяСумма, которая будет содержать результат сложения всех цен из МассивЦен.
Рассмотрим самый базовый способ, который подходит для понимания логики работы индексов массива. Мы перебираем элементы по их порядковому номеру (индексу) от 0 до верхней границы массива.
Сумма = 0;
Для Индекс = 0 По МассивЦен.ВГраница() Цикл
// Складываем текущее значение с накопленной суммой
Сумма = Сумма + МассивЦен[Индекс];
КонецЦикла;
Сообщить("Итоговая сумма: " + Сумма);
Важный нюанс: В данном примере происходит неявное преобразование типов. Поскольку массив был получен из строки, его элементы имеют тип Строка. 1С пытается автоматически преобразовать строку в число, так как переменная Сумма инициализирована нулем (числом). Однако полагаться на неявное преобразование — плохая практика.
Проанализируем более элегантный способ перебора элементов. Цикл Для каждого работает быстрее в написании и читается легче, так как нам не нужно управлять индексами и следить за границами массива.
Сумма = 0;
Для каждого ЭлементЦена Из МассивЦен Цикл
// Используем явное преобразование для надежности
Сумма = Сумма + Число(ЭлементЦена);
КонецЦикла;
Этот метод считается стандартным для большинства задач в 1С. Он безопасен и понятен коллегам по разработке.
Существует "хакерский" способ сложить все элементы массива буквально в одну строку, не используя явные циклы. Мы можем соединить все элементы массива в одну длинную математическую строку (например, "5000+7000+6000") и попросить платформу вычислить её значение.
МассивЦен = СтрРазделить("5000, 7000, 6000", ",", Ложь);
Результат = Вычислить(СтрСоединить(МассивЦен, "+"));
Сообщить("Итог: " + Результат);
Выясним причины, почему этот метод стоит использовать с осторожностью:
Вычислить исполняет любой переданный код. Если в массив попадет вредоносная инструкция, она будет выполнена.СтрСоединить создаст некорректное выражение (например, "5000++6000"), что приведет к аварийному завершению программы.Проанализируем ситуацию, когда входные данные могут быть "грязными" (содержать пробелы, буквы или спецсимволы). Если мы попытаемся выполнить Число(" 5000 "), 1С справится, но если там будет Число("5000 руб."), программа выдаст критическую ошибку.
Разберем по шагам, как написать максимально защищенный код:
ПривестиЗначение.
ТипЧисло = Новый ОписаниеТипов("Число");
ИтоговаяСумма = 0;
Для каждого ЗначениеИзМассива Из МассивЦен Цикл
// СократитьЛП убирает пробелы слева и справа
ОчищенноеЗначение = СократитьЛП(ЗначениеИзМассива);
// ПривестиЗначение превратит любой мусор в 0, а числовую строку — в Число
ЧисловоеЗначение = ТипЧисло.ПривестиЗначение(ОчищенноеЗначение);
ИтоговаяСумма = ИтоговаяСумма + ЧисловоеЗначение;
КонецЦикла;
Посмотрим на пример, который часто ставит в тупик новичков. При копировании данных из Excel или веб-страниц в числах часто встречаются "неразрывные пробелы" (символ с кодом 160). Обычная функция СократитьЛП их не удаляет, и Число() выдает ошибку.
Чтобы решить эту проблему, проанализируем следующий прием:
// Символы.НПП — это неразрывный пробел
ЧистаяСтрока = СтрЗаменить(ЗначениеИзМассива, Символы.НПП, "");
ЧистаяСтрока = СтрЗаменить(ЧистаяСтрока, " ", ""); // Убираем обычные пробелы
Сумма = Сумма + Число(ЧистаяСтрока);
В контексте нашей задачи, вычисления лучше всего оформлять в виде Функции. Выясним почему:
Процедура просто выполняет действия (например, выводит сообщение на экран). Функция же выполняет расчет и возвращает результат в то место, где её вызвали.
// Пример вызова функции
ОбщийИтог = ПосчитатьСуммуМассива(МассивЦен);
Функция ПосчитатьСуммуМассива(ВходящийМассив)
Результат = 0;
Для каждого Элемент Из ВходящийМассив Цикл
Результат = Результат + Число(Элемент);
КонецЦикла;
Возврат Результат; // Возвращаем число вызывающей программе
КонецФункции
Если вам нужно не просто сложить элементы, а выполнять сложные расчеты (например, сумма с учетом скидки или фильтрация), профессиональнее использовать объект ТаблицаЗначений. У него есть встроенный метод Итог, который работает крайне быстро.
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Цена", Новый ОписаниеТипов("Число"));
// Заполняем таблицу из массива
Для каждого Значение Из МассивЦен Цикл
НоваяСтрока = ТЗ.Добавить();
НоваяСтрока.Цена = Число(Значение);
КонецЦикла;
// Получаем сумму одной командой без циклов
ИтоговаяСумма = ТЗ.Итог("Цена");
В современных конфигурациях (на базе БСП) вместо старого метода Сообщить() рекомендуется использовать объект СообщениеПользователю. Это позволяет привязать сообщение к конкретному полю на форме или объекту в базе данных.
Также для формирования красивых строк используйте СтрШаблон. Это защитит ваш код от ошибок при сложении строк и чисел (конкатенации):
ТекстИтога = СтрШаблон("Расчет окончен. Всего товаров на сумму: %1 руб.", Формат(ИтоговаяСумма, "ЧДЦ=2"));
Сообщить(ТекстИтога);
Рассмотренные методы позволяют не только решить задачу сложения элементов массива, но и сделать код устойчивым к ошибкам во входящих данных. Выбирайте метод исходя из сложности вашей задачи: для простых тестов подойдет Вычислить, для типовых задач — цикл Для каждого с явным приведением типов, а для сложных расчетов — ТаблицаЗначений.