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

Разработка и Конфигурация · 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. 1
    Определите, можно ли изменять первый массив, или нужен новый
  2. 2
    Переберите элементы второго массива циклом Для Каждого
  3. 3
    Добавьте каждый элемент методом Добавить()
  4. 4
    Проверьте итоговое количество: оно должно равняться сумме длин исходных массивов

Объединение с удалением дубликатов

Когда в обоих массивах могут встречаться одинаковые значения (коды товаров, ссылки на документы, номера строк), простое добавление даст повторы. Для отсечения дублей удобно использовать Соответствие: ключи в нём уникальны, а проверка существования ключа работает быстро.

Уникальные = Новый Соответствие;

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

Уникальные.Вставить(Элемент, Истина);

КонецЦикла;

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

Уникальные.Вставить(Элемент, Истина);

КонецЦикла;

Результат = Новый Массив;

Для Каждого КлючЗначение Из Уникальные Цикл

Результат.Добавить(КлючЗначение.Ключ);

КонецЦикла;

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

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

Если Массив1.Найти(Элемент) = Неопределено Тогда

Массив1.Добавить(Элемент);

КонецЕсли;

КонецЦикла;

Поэлементное суммирование числовых массивов

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

Если Массив1.Количество() <> Массив2.Количество() Тогда

ВызватьИсключение "Массивы имеют разную длину";

КонецЕсли;

Сумма = Новый Массив;

Для Индекс = 0 По Массив1.ВГраница() Цикл

Сумма.Добавить(Массив1[Индекс] + Массив2[Индекс]);

КонецЦикла;

Проверка равенства длин обязательна. Если второй массив короче, обращение по несуществующему индексу вызовет ошибку «Индекс находится за границами массива» и прервёт выполнение кода. В прикладной логике иногда допустимо складывать по длине меньшего массива, а недостающие элементы считать нулями — это нужно оговорить в условии задачи явно.

Если элементы могут быть нечисловыми (строки, Неопределено), перед сложением проверяйте тип через ТипЗнч() или приводите значения функцией Число() внутри попытки — иначе получите ошибку преобразования.

Сложение массивов со ссылками и структурами

Когда массив содержит ссылки на документы или элементы справочников, объединение работает так же — ссылки копируются как значения, сам объект в базе не дублируется. Дубликаты ссылок отсекаются тем же способом через Соответствие: ссылки сравниваются корректно.

Осторожность нужна с массивами структур. Метод Добавить() помещает в массив ссылку на ту же структуру: если потом изменить её поля, изменения отразятся во всех массивах, куда структура была добавлена. Чтобы получить независимые копии, создавайте новую структуру и копируйте свойства явно.

Типичные ошибки и проверка результата

Ошибки при работе с массивами в 1С повторяются из проекта в проект. Ниже — те, что встречаются чаще всего, и способы их избежать.

Типичные ошибки
01
Цикл от 1 вместо 0: индексация массивов начинается с нуля, первый элемент пропускается, а обращение к Массив[Количество()] даёт ошибку выхода за границы
02
Изменение входного массива-параметра: вызывающий код продолжает работать с уже изменённой коллекцией, что приводит к задвоению данных при повторном вызове
03
Отсутствие проверки длин при поэлементном сложении: на разнородных данных код падает с ошибкой индекса
04
Использование Найти() внутри большого цикла: на больших объёмах обработка замедляется в разы, лучше Соответствие
05
Ожидание, что оператор + склеит массивы: во встроенном языке такой операции нет, сложение массивов вызовет ошибку преобразования типов

После объединения полезно проверить результат простыми контрольными точками: количество элементов, наличие ключевых значений и отсутствие нежелательных дублей.

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

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

Количество элементов после простого объединения
Норма

Равно сумме длин исходных массивов

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

Меньше или больше — часть элементов потеряна или добавлена дважды

Количество после объединения без дублей
Норма

Не превышает сумму длин, повторяющихся значений нет

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

Длина равна сумме исходных, хотя дубли заведомо были — фильтрация не сработала

Первый и последний элементы
Норма

Соответствуют началу первого и концу второго массива

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

Порядок нарушен — возможно, использовался цикл с неверными границами

Исходные массивы после операции
Норма

Не изменились, если это требовалось

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

Входной массив содержит лишние элементы — он был изменён по ссылке

Производительность и границы применения

Для массивов в несколько тысяч элементов любой из описанных способов отработает мгновенно. Проблемы начинаются на сотнях тысяч элементов: поиск через Найти() внутри цикла даёт квадратичную сложность, и обработка может занять минуты. В таких случаях используйте Соответствие для уникальности или выгрузите данные в таблицу значений и сверните её методом Свернуть().

Если массивы формируются из запроса к базе, часто рациональнее объединить данные на уровне самого запроса через ОБЪЕДИНИТЬ или ОБЪЕДИНИТЬ ВСЕ, чем собирать два массива и склеивать их в коде. Это переносит работу на сервер СУБД и уменьшает объём передаваемых данных.

Сравнение вариантов объединения

Цикл с Добавить()

Простейший вариант для склейки; сохраняет порядок и дубли, не подходит для уникализации

Соответствие как фильтр

Быстрая уникализация на больших объёмах; порядок итогового массива не гарантирован

Найти() перед добавлением

Короткий код для малых массивов; медленно на больших объёмах

ОБЪЕДИНИТЬ в запросе

Оптимально, если данные берутся из базы; требует переписывания логики на языке запросов

Часто задаваемые вопросы

Можно ли сложить два массива оператором «+» в 1С?

Нет. Оператор сложения для массивов во встроенном языке не определён — попытка выполнить Массив1 + Массив2 завершится ошибкой преобразования типов. Объединение выполняется только программно: циклом с методом Добавить() или через промежуточные коллекции.

С какого индекса начинается массив в 1С?

Индексация начинается с нуля. Первый элемент — Массив[0], последний — Массив[Массив.Количество() - 1] или Массив[Массив.ВГраница()]. Цикл вида «Для Индекс = 1 По Количество» — типичная ошибка, приводящая к пропуску первого элемента и выходу за границу массива.

Как объединить массивы, чтобы порядок элементов сохранился?

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

Что делать, если массивы разной длины, а нужно поэлементное сложение?

Определите правило заранее: либо считать недостающие элементы нулями и идти по длине большего массива, либо обрабатывать только общую часть по длине меньшего. Перед обращением по индексу проверяйте условие Индекс <= Массив.ВГраница(), чтобы не получить ошибку выхода за границы.

Как быстро убрать дубликаты после объединения больших массивов?

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

Изменится ли исходный массив, если добавить в него элементы второго?

Да, если вы добавляете элементы непосредственно в первый массив — он изменится, и все места кода, где он используется, увидят новое содержимое, потому что массив передаётся по ссылке. Если исходные данные нужно сохранить, создавайте новый массив и заполняйте его элементами из обоих источников.

Итог

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

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