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