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

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

Чем список отличается от массива в 1С

Разбираем отличия массива и списка значений в 1С: структура данных, методы, производительность, типичные задачи и примеры кода для разработчика.

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

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

Что такое массив в 1С и как он устроен

Массив создаётся конструктором Новый Массив() и представляет собой упорядоченный набор элементов, к которым обращаются по числовому индексу. Индексация начинается с нуля: первый элемент имеет индекс 0, последний — Количество() - 1. Элементом массива может быть значение любого типа, включая другие массивы, что позволяет строить многомерные структуры.

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

Что такое список значений и чем он отличается по структуре

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

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

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

Массив и список значений

Массив

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

Список значений

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

Сравнение методов и возможностей

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

ОперацияМассивСписок значений
Доступ по индексуДа, с нуляДа, с нуля
Хранение представления элементаНетДа
Пометка (флажок) у элементаНетДа
Сортировка штатным методомНетСортироватьПоЗначению()
Диалог выбора / отметкиНетВыбратьЭлемент(), ОтметитьЭлементы()
Использование в параметре запроса для В (&Список)ДаДа
Изменение размераДобавить/Вставить/УдалитьДобавить/Вставить/Удалить

Обратите внимание на различие методов поиска: Массив.Найти(Значение) возвращает индекс или Неопределено, а СписокЗначений.НайтиПоЗначению(Значение) возвращает сам элемент списка, через который доступны представление и пометка. Путаница между этими методами — частая причина ошибок «Метод объекта не обнаружен».

Производительность и расход памяти

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

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

Когда использовать массив, а когда список значений

Выбор определяется сценарием, а не привычкой. Ниже — типичные ситуации и рекомендуемый инструмент.

Маршрут решения

Как выбрать коллекцию

Нужно показать пользователю диалог выбора или отметки нескольких элементовИспользуйте список значений с методами ВыбратьЭлемент() или ОтметитьЭлементы()
Нужно накопить данные в цикле и обработать их программноИспользуйте массив — он легче и не хранит лишних атрибутов
Нужно передать набор значений в параметр запроса с условием В (&Параметр)Подойдут оба типа, выбирайте тот, что уже есть в коде
Нужно сохранить набор значений в хранилище или настройки с представлениямиИспользуйте список значений — он сохраняет представления элементов
Нужна сортировка значений без написания собственного алгоритмаИспользуйте список значений с методом СортироватьПоЗначению()

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

Примеры кода и преобразование между типами

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

// Собираем ссылки в массив

МассивКонтрагентов = Новый Массив;

Пока Выборка.Следующий() Цикл

МассивКонтрагентов.Добавить(Выборка.Ссылка);

КонецЦикла;

// Преобразуем в список для диалога отметки

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

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

Список.ЗаполнитьПометки(Истина);

Если Список.ОтметитьЭлементы("Выберите контрагентов") Тогда

// Возвращаем отмеченные обратно в массив

Выбранные = Новый Массив;

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

Если Элемент.Пометка Тогда

Выбранные.Добавить(Элемент.Значение);

КонецЕсли;

КонецЦикла;

КонецЕсли;

Обратное преобразование — Массив = Список.ВыгрузитьЗначения() — вернёт массив значений без представлений и пометок. Помните, что при загрузке через ЗагрузитьЗначения() представления элементов заполняются автоматически стандартным строковым представлением значения; если нужен свой текст, устанавливайте его вручную через второй параметр метода Добавить(Значение, Представление).

Порядок выбора и проверки
  1. 1
    Определите сценарий: программная обработка или взаимодействие с пользователем
  2. 2
    Для программной обработки создайте массив, для диалога — список значений
  3. 3
    При необходимости преобразуйте коллекции через ЗагрузитьЗначения() и ВыгрузитьЗначения()
  4. 4
    Проверьте в отладчике тип переменной и количество элементов перед передачей в запрос или диалог
  5. 5
    Убедитесь, что в цикле обращение к элементам соответствует типу: массив — по индексу, список — через Элемент.Значение

Типичные ошибки при работе с коллекциями

Типичные ошибки
01
Вызов метода списка у массива: СписокЗначений.НайтиПоЗначению() не существует у массива — получите ошибку «Метод объекта не обнаружен»
02
Обход списка как массива: в цикле Для Каждого по списку переменная содержит элемент списка, а не само значение — нужно обращаться к Элемент.Значение
03
Выход за границы массива: индексация с нуля, последний индекс равен Количество() - 1; обращение к Массив[Количество()] вызывает ошибку
04
Использование списка значений для больших объёмов без нужды: лишний расход памяти на представления и пометки при сотнях тысяч элементов
05
Ожидание, что ВыгрузитьЗначения() сохранит пометки: метод возвращает только значения, пометки и представления теряются

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

Альтернативы: соответствие, структура и таблица значений

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

Правильный выбор коллекции на этапе проектирования избавляет от последующих переделок: переделка кода с массива на соответствие в модуле с сотнями строк — это реальные трудозатраты, а не формальность.

Итог

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

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

Часто задаваемые вопросы

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

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

Почему в цикле по списку значений я получаю не значение, а какой-то объект?

Потому что переменная цикла Для Каждого ... Из Список содержит элемент списка — объект с полями Значение, Представление, Пометка и Картинка. Чтобы получить само значение, обращайтесь к свойству Элемент.Значение.

Что быстрее работает при большом количестве элементов?

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

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

У массива метода сортировки нет. Варианты: выгрузить значения в список значений, вызвать СортироватьПоЗначению() и загрузить обратно, либо использовать таблицу значений с сортировкой по колонке.

Сохраняются ли пометки при выгрузке списка в массив?

Нет. Метод ВыгрузитьЗначения() возвращает только значения элементов. Если пометки нужны дальше, собирайте отмеченные элементы в отдельный массив вручную в цикле с проверкой Элемент.Пометка.

Можно ли показать массив пользователю для выбора элемента?

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