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

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

Коллекция в 1С: что это и как с ней работать

Что такое коллекция в 1С: массив, структура, соответствие, список значений и таблица значений. Как выбрать тип, перебрать элементы и избежать типичных ошибок.

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

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

Материал ориентирован на тех, кто изучает встроенный язык 1С или настраивает типовые конфигурации через расширения и внешние обработки. Разберём основные типы коллекций, способы перебора, типичные ошибки и критерии выбора.

Что такое коллекция во встроенном языке 1С

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

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

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

Основные типы коллекций и когда их применять

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

Тип коллекцииДоступ к элементамТипичное применение
МассивПо индексу (с нуля)Упорядоченные однотипные данные, передача списков между процедурами
СтруктураПо имени ключаПередача именованных параметров, временное хранение разнородных значений
СоответствиеПо произвольному ключуБыстрый поиск по ключу любого типа, кэширование, сопоставление кодов
Список значенийПо индексуСписки с представлениями для пользователя, пометки, сортировка на форме
Таблица значенийПо номеру строки и имени колонкиТабличные данные: итоги расчётов, загрузка из файлов, свёртка и группировка
Табличная частьПо номеру строкиСтроки документов и справочников, хранятся в базе вместе с объектом

Массив

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

Структура и соответствие

Структура адресуется строковыми ключами, которые должны быть допустимыми идентификаторами. Соответствие допускает ключ любого типа — число, ссылку, дату. Оба типа ищут элемент по ключу быстро, поэтому соответствие — стандартный инструмент для кэшей и словарей «код → объект».

Таблица значений

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

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

Массив

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

Соответствие

Подходит для быстрого поиска по ключу любого типа и кэширования. Ограничение: нет гарантированного порядка обхода.

Таблица значений

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

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

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

Как перебрать элементы коллекции

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

Для Каждого СтрокаТовара Из ТаблицаТоваров Цикл

Сумма = Сумма + СтрокаТовара.Цена * СтрокаТовара.Количество;

КонецЦикла;

Для массива и таблицы значений доступен и обход по индексу через цикл «Для … По … Цикл» — он нужен, когда требуется номер элемента или обход в обратном порядке. Для структуры и соответствия индексного доступа нет.

Внутри цикла нельзя удалять элементы из той же коллекции, по которой идёт обход «Для Каждого», — поведение становится непредсказуемым. Для удаления используют обратный обход по индексу либо собирают элементы на удаление в отдельный массив и удаляют после цикла.

bsl
Для Индекс = 1 - ТаблицаТоваров.Количество() По 0 Цикл
    Строка = ТаблицаТоваров[-Индекс];
    Если Строка.Количество = 0 Тогда
        ТаблицаТоваров.Удалить(Строка);
    КонецЕсли;
КонецЦикла;

Прикладные коллекции: табличные части, выборки, наборы записей

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

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

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

Как выбрать тип коллекции под задачу

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

Отдельный случай — передача параметров в процедуры. Здесь стандарт де-факто: структура с именованными ключами. Она читается в месте вызова без подсказок и легко расширяется новыми параметрами без изменения сигнатуры.

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

Как выбрать действие

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

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

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

Отдельный источник сбоев — обращение к несуществующему ключу структуры. Оператор Структура.Ключ вызывает исключение, если ключа нет. Безопасный вариант — метод Свойство("Ключ", Значение), который вернёт значение или оставит переменную неопределённой.

Типичные ошибки
01
Удаление элементов внутри цикла «Для Каждого» — часть элементов пропускается, итоговый результат непредсказуем
02
Поиск значения в большом массиве внутри цикла — квадратичная сложность, код «зависает» на больших данных; замените массив соответствием
03
Повторный обход выборки запроса — вторая итерация возвращает пустоту; выгружайте результат в таблицу значений
04
Обращение к отсутствующему ключу структуры напрямую — исключение; используйте метод Свойство()
05
Передача таблицы значений с клиента на сервер и обратно без необходимости — лишний трафик сериализации

Как проверить, что код с коллекцией работает правильно

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

Для отладки удобно выводить размер коллекции через Количество() до и после операций. Если после фильтрации число элементов не совпадает с ожиданием — ищите ошибку в условии отбора, а не в цикле.

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

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

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

Совпадает с ожидаемым числом по исходным данным

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

Меньше ожидаемого — вероятно, удаление внутри цикла или неверный фильтр

Обход структуры или соответствия
Норма

Все добавленные ключи присутствуют в цикле

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

Ключ «теряется» — проверьте тип ключа и регистр строковых ключей

Повторное использование выборки запроса
Норма

Данные выгружены в таблицу значений и доступны многократно

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

Второй проход по выборке возвращает пустоту

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

Поиск по ключу соответствия выполняется мгновенно

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

Линейный поиск по массиву внутри цикла — время растёт квадратично

Порядок действий
  1. 1
    Определите, как будет выполняться доступ к элементам: по индексу, по ключу или построчно
  2. 2
    Выберите тип коллекции по критериям из таблицы сравнения
  3. 3
    Создайте коллекцию и заполните тестовыми данными, включая пустой и граничный случай
  4. 4
    Реализуйте обход циклом «Для Каждого», не изменяя состав коллекции внутри цикла
  5. 5
    Проверьте результат на пустой коллекции, одном элементе и дубликатах ключей
  6. 6
    Замерьте время на объёме, близком к реальному, и при необходимости замените массив соответствием
Если в цикле по таблице значений нужно найти строки по значению одной колонки, сначала добавьте индекс: Таблица.Индексы.Добавить("Номенклатура"). После этого метод НайтиСтроки() отработает заметно быстрее, особенно на больших таблицах.
ПЗ
Практическое замечание

Частые вопросы о коллекциях в 1С

Чем структура отличается от соответствия?

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

Можно ли отсортировать массив в 1С?

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

Почему цикл пропускает элементы при удалении строк?

При удалении элемента внутри цикла «Для Каждого» нарушается внутренний порядок обхода, и часть элементов пропускается. Решение — обход по индексу в обратном порядке или сбор удаляемых элементов в отдельный массив с последующим удалением после цикла.

Что быстрее для поиска: массив или соответствие?

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

Как передать таблицу значений между сервером и клиентом?

Таблица значений не передаётся напрямую в тонком клиенте. Её преобразуют в массив структур, помещают в хранилище значений или используют реквизит формы типа «ТаблицаЗначений». Для больших объёмов предпочтительна обработка целиком на сервере без передачи на клиента.

Табличная часть документа — это тоже коллекция?

Да. Табличная часть поддерживает перебор в цикле «Для Каждого», методы Количество(), Добавить(), Удалить(), Итог() по числовой колонке. Отличие от таблицы значений в том, что её строки хранятся в базе данных вместе с документом и записываются вместе с ним.

Итог

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

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