Какие существуют способы скопировать один массив в другой в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В практике разработки на платформе 1С:Предприятие 8 часто возникает задача создания копии массива. На первый взгляд задача кажется тривиальной, однако начинающие разработчики часто сталкиваются с проблемой передачи ссылки на объект вместо создания его физической копии. Если мы просто напишем НовыйМассив = СтарыйМассив;, то обе переменные будут указывать на один и тот же объект в памяти. Изменение одного массива неизбежно приведет к изменению другого. Рассмотрим подробнее, как правильно выполнять копирование в различных ситуациях.

Способ 1: Поэлементное копирование в цикле

Это классический и самый прозрачный метод. Мы создаем новый объект Массив и последовательно добавляем в него элементы из исходной коллекции. Разберем этот процесс по шагам:


КопияМассива = Новый Массив;
Для Каждого Элемент Из ИсходныйМассив Цикл
    КопияМассива.Добавить(Элемент);
КонецЦикла;

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

Способ 2: Использование методов БСП (Библиотеки стандартных подсистем)

Если ваша конфигурация построена на базе БСП (что является стандартом для современных решений 1С), нам доступны готовые инструменты. В модуле ОбщегоНазначения существуют функции, которые берут на себя рутину по обходу коллекции.

Ранее широко использовалась функция:

ОбщегоНазначения.СкопироватьУниверсальнуюКоллекцию(КоллекцияИсходная)

В актуальных версиях БСП (начиная с 2024 года и ранее) рекомендуется использовать более мощный инструмент для создания полной копии:


// Создает глубокую копию массива или другой коллекции
МассивКопия = ОбщегоНазначения.СкопироватьРекурсивно(ИсходныйМассив);

Преимущество этого метода в том, что он умеет обрабатывать вложенные структуры, создавая новые экземпляры для каждого уровня вложенности.

Способ 3: Копирование через СписокЗначений

Существует элегантный и лаконичный способ копирования через промежуточный объект СписокЗначений. Этот метод часто используется в типовых конфигурациях для быстрого «перекладывания» данных.


Список = Новый СписокЗначений;
Список.ЗагрузитьЗначения(ИсходныйМассив);
КопияМассива = Список.ВыгрузитьЗначения();

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

Способ 4: Глубокое копирование через внутреннюю строку

Если нам необходимо гарантированно получить независимую копию со всеми вложенными данными (структурами, соответствиями, массивами), можно прибегнуть к механизму сериализации. Платформа 1С имеет встроенные функции для преобразования объекта в специальную внутреннюю строку формата 1С.

КопияМассива = ЗначениеИзСтрокиВнутр(ЗначениеВСтрокуВнутр(ИсходныйМассив));

Важный нюанс: хотя этот метод работает быстро и эффективно, формат ЗначениеВСтрокуВнутр считается устаревшим и не рекомендуется для использования в кроссплатформенных решениях (например, если планируется работа на Linux-серверах с определенными настройками). Однако для большинства задач внутри Windows-окружения он остается «выручалочкой» для создания клонов сложных структур.

Способ 5: Использование ФиксированногоМассива

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


// Сначала создаем фиксированную копию, затем на ее основе — новый массив
КопияМассива = Новый Массив(Новый ФиксированныйМассив(ИсходныйМассив));

Здесь конструктор Новый Массив() принимает на вход другую коллекцию и создает на ее основе новый независимый объект.

Способ 6: Копирование через временное хранилище

Для максимально надежного «глубокого» копирования, которое гарантированно разрывает связи между объектами, можно использовать механизмы передачи данных между клиентом и сервером. Помещение во временное хранилище фактически сериализует объект в двоичные данные.


Адрес = ПоместитьВоВременноеХранилище(ИсходныйМассив);
КопияМассива = ПолучитьИзВременногоХранилища(Адрес);

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

Разбор ситуации: зачем вообще копировать массив?

Рассмотрим пример из практики. Представьте, что вы работаете с формой, где пользователь выбирает строки в списке (Элементы.Список.ВыделенныеСтроки). Вам нужно обработать этот массив дважды, но в каждом случае по разным правилам (например, для разных структур документов). Если вы начнете удалять элементы из оригинального массива ВыделенныеСтроки, они пропадут и из интерфейса, и для последующей обработки. В таких случаях создание копии — единственный верный путь.

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

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

  1. Цикл или СписокЗначений: Быстро, просто, но копирование поверхностное (ссылочное для вложенных объектов).
  2. ЗначениеВСтрокуВнутр / Временное хранилище: Медленнее, но создают полную (глубокую) копию всех вложенных данных.
  3. Методы БСП: Самый «цивилизованный» способ, рекомендуемый стандартами разработки 1С.

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

← На главную