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