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

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

Как соединить два массива в 1С

Как объединить два массива в 1С: добавление элементов циклом, удаление дубликатов, сортировка результата. Примеры кода, типичные ошибки и проверка результата.

Массив в 1С — это универсальная коллекция, которая хранит произвольные значения в определённом порядке. Задача объединения двух массивов возникает постоянно: при сборке списка документов из разных отборов, при объединении результатов нескольких запросов, при формировании параметров печатных форм. Встроенной функции «склеить массивы» в платформе нет, поэтому объединение делается перебором элементов.

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

Базовое соединение массивов циклом

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

Массив1 = Новый Массив;

Массив1.Добавить("А");

Массив1.Добавить("Б");

Массив2 = Новый Массив;

Массив2.Добавить("В");

Массив2.Добавить("Г");

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

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

КонецЦикла;

// Массив1 теперь содержит: А, Б, В, Г

Обратите внимание: первый массив изменяется «на месте». Если исходные данные нужны дальше в неизменном виде, создайте третий массив и скопируйте в него оба источника. Это особенно важно в общих модулях, где массив может передаваться в несколько процедур.

Объединение в новый массив без изменения исходных

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

Функция СоединитьМассивы(Массив1, Массив2)

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

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

Результат.Добавить(Элемент);

КонецЦикла;

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

Результат.Добавить(Элемент);

КонецЦикла;

Возврат Результат;

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

Такую функцию удобно вынести в общий модуль, чтобы не дублировать код в прикладных объектах. Назовите её понятно — например, ОбъединитьМассивы — и задокументируйте, изменяет ли она параметры или возвращает новую коллекцию.

Соединение массивов без дубликатов

Частая задача — объединить списки так, чтобы повторяющиеся значения вошли в результат только один раз. Для этого перед добавлением проверяйте наличие элемента методом Найти(): он возвращает индекс элемента или Неопределено, если значение не найдено.

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

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

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

КонецЕсли;

КонецЦикла;

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

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

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

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

КонецЦикла;

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

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

КонецЦикла;

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

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

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

КонецЦикла;

Сравнение вариантов

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

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

Цикл с проверкой Найти()

Даёт уникальные значения без лишних структур. Минус — медленно на больших массивах.

Через Соответствие

Быстрое удаление дубликатов на больших объёмах. Минус — порядок элементов не гарантирован.

Вставка элементов в произвольную позицию

Если нужно не просто дописать второй массив в конец, а вставить его в середину первого, используйте метод Вставить(Индекс, Значение). Учтите, что после каждой вставки индексы последующих элементов сдвигаются, поэтому начальный индекс нужно увеличивать в цикле.

Позиция = 2; // вставляем начиная с третьего элемента

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

Массив1.Вставить(Позиция, Элемент);

Позиция = Позиция + 1;

КонецЦикла;

Проверяйте, что стартовая позиция не превышает количество элементов в первом массиве (его можно получить через Количество()), иначе платформа выдаст ошибку выхода за границы индекса.

Сортировка и обработка результата после объединения

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

Список = Новый СписокЗначений;

Список.ЗагрузитьЗначения(Результат);

Список.СортироватьПоЗначению();

Результат = Список.ВыгрузитьЗначения();

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

Порядок действий
  1. 1
    Определите, должны ли исходные массивы остаться неизменными
  2. 2
    Выберите способ: простое добавление, с проверкой дубликатов или через соответствие
  3. 3
    Реализуйте цикл объединения и протестируйте на малом наборе данных
  4. 4
    Проверьте количество элементов и наличие дублей в результате
  5. 5
    При необходимости отсортируйте итоговый массив

Типичные ошибки при объединении массивов

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

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

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

Типичные ошибки
01
Добавление элементов в массив, который перебирается в том же цикле — бесконечный цикл или пропуск данных
02
Сравнение значений разных типов при поиске дублей — дубликаты не отфильтровываются
03
Перебор переменной со значением Неопределено вместо массива — ошибка выполнения
04
Использование Найти() на массивах в сотни тысяч элементов — заметное падение производительности

Проверка результата объединения

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

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

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

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

Количество элементов
Норма

Равно сумме размеров исходных массивов (или меньше при удалении дублей)

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

Меньше ожидаемого без причины или равно нулю

Порядок элементов
Норма

Сначала элементы первого массива, затем второго

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

Элементы перемешаны или часть потеряна

Дубликаты
Норма

При объединении без дублей каждое значение встречается один раз

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

Повторы остались — проверка Найти() не сработала из-за типов

Итог

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

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

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

Есть ли в 1С встроенная функция объединения массивов?

Нет, отдельной функции «склеить массивы» в платформе не предусмотрено. Объединение выполняется перебором элементов с методом Добавить() либо через промежуточные коллекции — список значений или соответствие.

Как объединить три и больше массивов?

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

Что быстрее: Найти() или соответствие для удаления дублей?

На маленьких массивах разница незаметна, и проще использовать Найти(). На больших объёмах соответствие работает значительно быстрее, потому что поиск ключа в нём не требует полного перебора. Минус соответствия — порядок элементов при выгрузке не гарантирован.

Можно ли соединить массивы разных типов значений?

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

Как объединить массивы в запросе 1С?

В языке запросов массивы не объединяются напрямую, но можно объединить выборки оператором ОБЪЕДИНИТЬ (или ОБЪЕДИНИТЬ ВСЕ, если дубликаты допустимы), а затем выгрузить результат в таблицу значений и получить нужную колонку методом ВыгрузитьКолонку().

Как скопировать массив, чтобы изменения копии не затрагивали оригинал?

Присваивание переменных не копирует массив — обе переменные будут указывать на один объект. Для независимой копии создайте новый массив и перенесите элементы циклом, либо используйте ЗагрузитьЗначения/ВыгрузитьЗначения через список значений.