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

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

Как объединить два массива в 1С: практическое руководство

Как объединить два массива в 1С: методы Добавить, ОбщегоНазначения, удаление дублей, работа с таблицами значений. Примеры кода, ошибки и проверка результата.

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

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

Отдельно рассмотрим частую сопутствующую задачу — объединение массивов без повторяющихся значений, а также типичные ошибки, из-за которых объединённый массив оказывается пустым или содержит неожиданные данные.

Базовый способ: цикл с методом Добавить()

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

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

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

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

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

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

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

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

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

КонецЦикла;

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

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

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

Готовая функция из БСП: ДополнитьМассив

В типовых конфигурациях (УТ, ERP, БП, ЗУП и других на базе Библиотеки стандартных подсистем) есть готовая процедура ОбщегоНазначенияКлиентСервер.ДополнитьМассив(МассивПриемник, МассивИсточник, ТолькоУникальныеЗначения). Она делает ровно то же самое, но избавляет от написания цикла вручную и поддерживает режим добавления только уникальных значений.

ОбщегоНазначенияКлиентСервер.ДополнитьМассив(Массив1, Массив2);

// С третьим параметром — без дублей:

ОбщегоНазначенияКлиентСервер.ДополнитьМассив(Массив1, Массив2, Истина);

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

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

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

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

Функция ОбъединитьМассивы(Массив1, Массив2) Экспорт

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

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

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

КонецЦикла;

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

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

КонецЦикла;

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

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

Альтернатива — скопировать первый массив штатными средствами и дополнить копию. В новых версиях платформы доступно копирование через конструктор: Новый Массив(Новый ФиксированныйМассив(Массив1)), но универсальный и читаемый способ — всё тот же цикл.

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

Объединение массивов без дублей

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

Через соответствие — быстрый способ

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

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

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

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

КонецЦикла;

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

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

КонецЦикла;

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

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

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

КонецЦикла;

Через таблицу значений со свёрткой

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

ТЗ = Новый ТаблицаЗначений;

ТЗ.Колонки.Добавить("Значение");

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

ТЗ.Добавить().Значение = Элемент;

КонецЦикла;

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

ТЗ.Добавить().Значение = Элемент;

КонецЦикла;

ТЗ.Свернуть("Значение");

Результат = ТЗ.ВыгрузитьКолонку("Значение");

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

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

Работает везде, сохраняет дубли и порядок. Подходит для простого слияния без требований к уникальности.

БСП: ДополнитьМассив()

Удобно в типовых конфигурациях, есть режим уникальности. Медленный на больших массивах из-за поиска Найти().

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

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

Через таблицу значений

Надёжный классический приём, можно дополнительно сортировать. Требует создания промежуточного объекта.

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

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

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

// Что-то пошло не так при простом слиянии

КонецЕсли;

Для отладки используйте вывод содержимого через цикл с Сообщить() или смотрите значения в табло при остановке отладчика. Если массивы содержат ссылки, убедитесь, что в обоих массивах ссылки одного типа — смешение, например, «ДокументСсылка.РеализацияТоваровУслуг» и «СправочникСсылка.Номенклатура» в одном массиве часто приводит к ошибкам при передаче в запрос или СКД.

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

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

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

Равно сумме длин исходных массивов (при простом слиянии)

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

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

Типы элементов
Норма

Все элементы одного ожидаемого типа (например, только ссылки нужного вида)

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

В массиве Неопределено или значения другого типа — ошибка при передаче в запрос

Дубли
Норма

Повторы отсутствуют, если требовалась уникальность

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

Одинаковые ссылки встречаются несколько раз — уникальность не обеспечена

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

Самая частая проблема — попытка объединить массив с Неопределено. Если функция, формирующая один из массивов, вернула Неопределено вместо пустого массива, цикл Для Каждого завершится ошибкой «Итератор для значения не определен». Перед объединением проверяйте: Если Массив2 = Неопределено Тогда Массив2 = Новый Массив; КонецЕсли; — или используйте функцию, которая гарантированно возвращает массив.

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

Третья распространённая ситуация — попытка «сложить» массивы оператором +. В языке 1С оператор сложения для массивов не определён, такой код вызовет ошибку. Объединение возможно только перебором элементов или готовыми процедурами.

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

Когда массивы не нужны: объединение на уровне запроса

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

ВЫБРАТЬ Ссылка ИЗ Документ.РеализацияТоваровУслуг

ГДЕ Дата МЕЖДУ &Начало И &Конец

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ Ссылка ИЗ Документ.ВозвратТоваровОтПокупателя

ГДЕ Дата МЕЖДУ &Начало И &Конец

Такой подход особенно выгоден при больших объёмах: выборка и объединение выполняются на стороне СУБД, а не в клиентском или серверном коде 1С. Массив же остаётся оправданным, когда данные приходят из разнородных источников — например, часть из запроса, часть из файла или веб-сервиса.

Итог

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

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

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

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

Нет, оператор сложения для массивов в языке 1С не определён — попытка вызовет ошибку исполнения. Объединение выполняется только перебором элементов второго массива с добавлением в первый или готовыми процедурами вроде ДополнитьМассив из БСП.

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

Создайте третий массив и последовательно добавьте в него элементы обоих массивов двумя циклами. Либо скопируйте первый массив и дополните копию элементами второго. Исходные коллекции при этом останутся нетронутыми.

Почему после ДополнитьМассив изменился массив, который я передавал в функцию?

Массивы в 1С передаются по ссылке, а не по значению. Процедура, дополняющая массив-приёмник, изменяет тот же объект, что виден и в вызывающем коде. Чтобы избежать побочного эффекта, передавайте в функцию копию массива.

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

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

Что делать, если один из массивов равен Неопределено?

Перед объединением добавьте проверку: если переменная равна Неопределено, присвойте ей Новый Массив. Иначе цикл Для Каждого завершится ошибкой «Итератор для значения не определен». Хорошая практика — чтобы функции всегда возвращали массив, хотя бы пустой.

Влияют ли дубли в объединённом массиве на запрос с условием В?

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