Как преобразовать массив в список значений и обратно в 1С?

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

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

Зачем преобразовывать массив в список значений и обратно?

Прежде чем перейти к коду, давайте ответим на вопрос: почему вообще возникает такая необходимость? Каждая коллекция в 1С имеет свое уникальное предназначение:

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

Из-за этих различий нам регулярно приходится конвертировать данные: например, мы получили массив значений из запроса, но хотим красиво показать его пользователю на форме с возможностью выбора (нужен список значений). Или наоборот: пользователь отметил галочками элементы в списке на форме, и теперь нам нужно передать эти «чистые» значения в запрос для проведения расчетов (нужен массив).

Преобразование из списка значений в массив

Давайте подробно разберем, как получить массив из списка значений. Для этого в платформе 1С предусмотрен штатный метод ВыгрузитьЗначения(), принадлежащий объекту СписокЗначений. Этот метод создает новый массив и автоматически копирует в него все значения из элементов списка.

Рассмотрим практический пример использования этого метода:


// Создадим и заполним тестовый список значений
СписокТоваров = Новый СписокЗначений;
СписокТоваров.Добавить(Справочники.Номенклатура.НайтиПоКоду("00000001"), "Товар 1");
СписокТоваров.Добавить(Справочники.Номенклатура.НайтиПоКоду("00000002"), "Товар 2");

// Преобразуем список значений в массив одной строкой кода
МассивТоваров = СписокТоваров.ВыгрузитьЗначения();

// Теперь в переменной МассивТоваров находится стандартный Массив
// Мы можем передать его, например, в параметры запроса

Важное примечание: при выгрузке значений из списка в массив полностью теряются сопутствующие метаданные элементов списка. Будут проигнорированы свойства Представление, Пометка и Картинка. В массив попадут исключительно «чистые» данные, содержащиеся в свойстве Значение каждого элемента списка.

Преобразование из массива в список значений

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

Решение кроется в методе ЗагрузитьЗначения(), который принадлежит самому объекту СписокЗначений. Давайте посмотрим, как это выглядит на практике:


// Предположим, у нас есть исходный массив с какими-то данными
МассивИмен = Новый Массив;
МассивИмен.Добавить("Александр");
МассивИмен.Добавить("Мария");
МассивИмен.Добавить("Иван");

// Создаем новый список значений
СписокИмен = Новый СписокЗначений;

// Загружаем данные из массива в список
СписокИмен.ЗагрузитьЗначения(МассивИмен);

Что происходит «под капотом» платформы при вызове этого метода? Платформа автоматически обходит переданный массив, создает для каждого элемента объект типа ЭлементСпискаЗначений и заполняет его свойства по умолчанию:

Архитектурная асимметрия: почему у массива нет метода выгрузки?

Давайте проанализируем, почему разработчики платформы спроектировали эту связь именно так. Почему у списка значений есть оба метода (ЗагрузитьЗначения и ВыгрузитьЗначения), а у массива — ни одного?

В объектно-ориентированном программировании существует правило минимизации зависимостей. Массив — это системный, универсальный тип данных, который живет на всех уровнях платформы, включая самые глубокие серверные процессы и внешние соединения. Он должен оставаться максимально простым и производительным. СписокЗначений — это прикладной объект, тесно связанный с интерфейсом пользователя. Если бы мы добавили в Массив метод преобразования в СписокЗначений, нам пришлось бы связать базовый тип данных с интерфейсными библиотеками, что усложнило бы и утяжелило бы платформу.

Поэтому управление конвертацией полностью делегировано объекту СписокЗначений. Это красивое и логичное архитектурное решение.

Главный лайфхак разработчиков: быстрая сортировка массива

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

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


// Наш неотсортированный массив чисел
МассивЧисел = Новый Массив;
МассивЧисел.Добавить(15);
МассивЧисел.Добавить(3);
МассивЧисел.Добавить(42);
МассивЧисел.Добавить(8);

// Шаг 1. Переносим данные в список значений
ТранзитныйСписок = Новый СписокЗначений;
ТранзитныйСписок.ЗагрузитьЗначения(МассивЧисел);

// Шаг 2. Сортируем список значений средствами платформы
ТранзитныйСписок.СортироватьПоЗначению(НаправлениеСортировки.Возр);

// Шаг 3. Выгружаем отсортированные данные обратно в массив
МассивЧисел = ТранзитныйСписок.ВыгрузитьЗначения();

// Теперь МассивЧисел содержит элементы: 3, 8, 15, 42

Почему это работает быстро? Сортировка внутри объекта СписокЗначений выполняется на уровне платформы, написанной на C++. Это происходит в десятки и сотни раз быстрее, чем аналогичные алгоритмы сортировки, написанные разработчиком вручную на встроенном языке 1С.

Альтернатива: использование Таблицы значений

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

У таблиц значений также есть встроенные оптимизированные методы для работы с массивами. Мы можем загружать данные в колонку таблицы и выгружать их обратно без использования циклов:


// Создаем таблицу значений с одной колонкой
Таблица = Новый ТаблицаЗначений;
Таблица.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка"));

// Загружаем массив прямо в колонку таблицы значений
МассивИмен = Новый Массив;
МассивИмен.Добавить("Анна");
МассивИмен.Добавить("Сергей");

Таблица.Колонки.Имя.ЗагрузитьКолонку(МассивИмен);

// Выгружаем колонку таблицы значений обратно в массив
НовыйМассив = Таблица.ВыгрузитьКолонку("Имя");

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

Оптимизация производительности и правила хорошего тона

Давайте сформулируем несколько важных правил по работе с коллекциями, которые уберегут вашу базу данных от падения производительности:

  1. Откажитесь от циклов для конвертации: Всегда используйте методы ЗагрузитьЗначения() и ВыгрузитьЗначения() вместо ручного обхода коллекций в цикле Для Каждого. Системные методы выполняются на уровне ядра платформы и экономят процессорное время.
  2. Оптимизируйте клиент-серверный трафик: Помните, что Массив — это очень легкий сериализуемый тип, а СписокЗначений нагружен метаданными интерфейса. Никогда не передавайте тяжелые списки значений с сервера на клиент без острой необходимости. Если вам нужно передать данные, выгрузите список значений в массив на сервере, передайте массив на клиент и там, если требуется, загрузите его обратно в локальный список значений.
  3. Использование в запросах: При передаче параметров в запрос для конструкции В (&Параметр) используйте именно массивы. Передача списков значений в запросы в старых версиях платформы могла вызывать ошибки, а в новых — просто создает лишнюю нагрузку на сериализацию данных. Предварительная выгрузка списка в массив перед установкой параметра запроса считается стандартом качественной разработки.

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

← На главную