Разработка и Конфигурация · 12 мин
Коллекция в 1С: что это и как с ней работать
Что такое коллекция в 1С: массив, структура, соответствие, список значений и таблица значений. Как выбрать тип, перебрать элементы и избежать типичных ошибок.
Коллекция в 1С — это объект встроенного языка, который хранит набор связанных элементов и позволяет работать с ними как с единым целым: добавлять, удалять, искать и перебирать значения в цикле. К коллекциям относятся массив, структура, соответствие, список значений, таблица значений, а также прикладные коллекции вроде табличных частей документов и списков строк динамических списков.
Без коллекций не обходится практически ни один алгоритм: выборка из запроса — это коллекция, движения документа — коллекция записей, параметры процедуры часто передаются структурой. Понимание того, какой тип коллекции выбрать и как с ним работать, напрямую влияет на скорость кода и количество ошибок.
Материал ориентирован на тех, кто изучает встроенный язык 1С или настраивает типовые конфигурации через расширения и внешние обработки. Разберём основные типы коллекций, способы перебора, типичные ошибки и критерии выбора.
Что такое коллекция во встроенном языке 1С
В терминологии платформы 1С коллекцией называют любой объект, допускающий обход элементов в цикле «Для Каждого». Это объединяет как универсальные типы данных (массив, структура), так и специализированные прикладные объекты: табличные части, наборы записей регистров, выборки из результата запроса, коллекции строк дерева значений.
Общее свойство всех коллекций — наличие внутреннего механизма перебора. Различаются они способом адресации элементов: по индексу (массив), по имени ключа (структура, соответствие), по номеру строки (таблица значений, табличная часть). От способа адресации зависит, какие операции выполняются быстро, а какие — медленно.
Важно не путать коллекцию со ссылкой на объект базы данных. Справочник «Номенклатура» — это не коллекция, а вот выборка из справочника или список его элементов в форме — уже коллекция. Эта граница определяет, какие методы доступны: у коллекции есть «Количество()», «Добавить()», «Найти()», у ссылки — нет.
Основные типы коллекций и когда их применять
Выбор типа коллекции — первое решение, которое принимает разработчик. Неправильный выбор приводит к медленному поиску, лишним преобразованиям и громоздкому коду.
| Тип коллекции | Доступ к элементам | Типичное применение |
|---|---|---|
| Массив | По индексу (с нуля) | Упорядоченные однотипные данные, передача списков между процедурами |
| Структура | По имени ключа | Передача именованных параметров, временное хранение разнородных значений |
| Соответствие | По произвольному ключу | Быстрый поиск по ключу любого типа, кэширование, сопоставление кодов |
| Список значений | По индексу | Списки с представлениями для пользователя, пометки, сортировка на форме |
| Таблица значений | По номеру строки и имени колонки | Табличные данные: итоги расчётов, загрузка из файлов, свёртка и группировка |
| Табличная часть | По номеру строки | Строки документов и справочников, хранятся в базе вместе с объектом |
Массив
Массив — самая простая коллекция: элементы хранятся подряд, обращение по индексу выполняется мгновенно. Создаётся конструктором Новый Массив или литералом. Поиск значения методом Найти() идёт линейным перебором, поэтому для частого поиска в больших наборах массив не подходит.
Структура и соответствие
Структура адресуется строковыми ключами, которые должны быть допустимыми идентификаторами. Соответствие допускает ключ любого типа — число, ссылку, дату. Оба типа ищут элемент по ключу быстро, поэтому соответствие — стандартный инструмент для кэшей и словарей «код → объект».
Таблица значений
Таблица значений — коллекция строк с типизированными колонками. Поддерживает сортировку, свёртку (группировку с суммированием), поиск по значению колонки и построение индексов. Это основной тип для промежуточных расчётов вне запроса.
Сравнение вариантов
Подходит для упорядоченных списков и передачи данных между процедурами. Ограничение: поиск значения — линейный перебор.
Подходит для быстрого поиска по ключу любого типа и кэширования. Ограничение: нет гарантированного порядка обхода.
Подходит для табличных данных, группировок и сортировок. Ограничение: тяжелее массива по памяти, требует описания колонок.
Подходит для списков, отображаемых пользователю, с представлениями и пометками. Ограничение: избыточен для чисто служебных данных.
Как перебрать элементы коллекции
Стандартный способ обхода — цикл «Для Каждого». Переменная цикла на каждой итерации получает очередной элемент: для массива — значение, для структуры и соответствия — объект «КлючИЗначение», для таблицы значений — строку.
Для Каждого СтрокаТовара Из ТаблицаТоваров Цикл
Сумма = Сумма + СтрокаТовара.Цена * СтрокаТовара.Количество;
КонецЦикла;
Для массива и таблицы значений доступен и обход по индексу через цикл «Для … По … Цикл» — он нужен, когда требуется номер элемента или обход в обратном порядке. Для структуры и соответствия индексного доступа нет.
Внутри цикла нельзя удалять элементы из той же коллекции, по которой идёт обход «Для Каждого», — поведение становится непредсказуемым. Для удаления используют обратный обход по индексу либо собирают элементы на удаление в отдельный массив и удаляют после цикла.
Для Индекс = 1 - ТаблицаТоваров.Количество() По 0 Цикл
Строка = ТаблицаТоваров[-Индекс];
Если Строка.Количество = 0 Тогда
ТаблицаТоваров.Удалить(Строка);
КонецЕсли;
КонецЦикла;Прикладные коллекции: табличные части, выборки, наборы записей
Помимо универсальных типов, разработчик постоянно встречает коллекции, встроенные в прикладные объекты. Табличная часть документа — коллекция строк, которая хранится в базе вместе с документом и проводится вместе с ним. Набор записей регистра — коллекция записей, которую можно прочитать, изменить и записать целиком.
Выборка из результата запроса — коллекция особого рода: она однопроходная. После обхода выборку нельзя перебрать заново без повторного выполнения запроса. Если данные нужны несколько раз, результат выгружают в таблицу значений методом Выгрузить().
Динамический список на форме и данные формы в виде таблицы — тоже коллекции, но с ограничениями: часть методов (например, свёртка) в них недоступна, а состав колонок определяется запросом или реквизитами объекта.
Как выбрать тип коллекции под задачу
Критерии выбора сводятся к трём вопросам: как будет выполняться доступ к элементам, нужен ли порядок, куда данные пойдут дальше. Если нужен быстрый поиск по уникальному ключу — соответствие. Если важен порядок и доступ по номеру — массив. Если данные табличные и требуют группировки — таблица значений. Если список показывается пользователю с представлениями — список значений.
Отдельный случай — передача параметров в процедуры. Здесь стандарт де-факто: структура с именованными ключами. Она читается в месте вызова без подсказок и легко расширяется новыми параметрами без изменения сигнатуры.
Как выбрать действие
Типичные ошибки при работе с коллекциями
Большинство проблем с коллекциями — не синтаксические, а алгоритмические: неверно выбранный тип, удаление внутри цикла, повторный обход выборки. Эти ошибки либо замедляют код в десятки раз, либо приводят к пропуску элементов без каких-либо сообщений.
Отдельный источник сбоев — обращение к несуществующему ключу структуры. Оператор Структура.Ключ вызывает исключение, если ключа нет. Безопасный вариант — метод Свойство("Ключ", Значение), который вернёт значение или оставит переменную неопределённой.
Как проверить, что код с коллекцией работает правильно
Проверка начинается с граничных случаев: пустая коллекция, один элемент, дублирующиеся ключи. Цикл по пустой коллекции просто не выполняется — это норма, но код после цикла должен корректно работать с нулевым итогом.
Для отладки удобно выводить размер коллекции через Количество() до и после операций. Если после фильтрации число элементов не совпадает с ожиданием — ищите ошибку в условии отбора, а не в цикле.
Как проверить результат
Совпадает с ожидаемым числом по исходным данным
Меньше ожидаемого — вероятно, удаление внутри цикла или неверный фильтр
Все добавленные ключи присутствуют в цикле
Ключ «теряется» — проверьте тип ключа и регистр строковых ключей
Данные выгружены в таблицу значений и доступны многократно
Второй проход по выборке возвращает пустоту
Поиск по ключу соответствия выполняется мгновенно
Линейный поиск по массиву внутри цикла — время растёт квадратично
- 1Определите, как будет выполняться доступ к элементам: по индексу, по ключу или построчно
- 2Выберите тип коллекции по критериям из таблицы сравнения
- 3Создайте коллекцию и заполните тестовыми данными, включая пустой и граничный случай
- 4Реализуйте обход циклом «Для Каждого», не изменяя состав коллекции внутри цикла
- 5Проверьте результат на пустой коллекции, одном элементе и дубликатах ключей
- 6Замерьте время на объёме, близком к реальному, и при необходимости замените массив соответствием
Если в цикле по таблице значений нужно найти строки по значению одной колонки, сначала добавьте индекс: Таблица.Индексы.Добавить("Номенклатура"). После этого метод НайтиСтроки() отработает заметно быстрее, особенно на больших таблицах.
Частые вопросы о коллекциях в 1С
Чем структура отличается от соответствия?
Структура адресуется только строковыми ключами, которые должны быть допустимыми идентификаторами (без пробелов и спецсимволов). Соответствие принимает ключ любого типа — число, дату, ссылку. Для словарей с нестроковыми ключами подходит только соответствие, для передачи именованных параметров обычно используют структуру.
Можно ли отсортировать массив в 1С?
У массива нет собственного метода сортировки. Стандартный приём — скопировать элементы в список значений, вызвать метод СортироватьПоЗначению() и выгрузить обратно через ВыгрузитьЗначения(). Таблицу значений можно сортировать напрямую методом Сортировать().
Почему цикл пропускает элементы при удалении строк?
При удалении элемента внутри цикла «Для Каждого» нарушается внутренний порядок обхода, и часть элементов пропускается. Решение — обход по индексу в обратном порядке или сбор удаляемых элементов в отдельный массив с последующим удалением после цикла.
Что быстрее для поиска: массив или соответствие?
Метод Найти() массива перебирает элементы по очереди — время растёт пропорционально размеру. Соответствие ищет по ключу практически мгновенно независимо от объёма. Если поиск выполняется внутри цикла, соответствие выигрывает на больших данных в разы и десятки раз.
Как передать таблицу значений между сервером и клиентом?
Таблица значений не передаётся напрямую в тонком клиенте. Её преобразуют в массив структур, помещают в хранилище значений или используют реквизит формы типа «ТаблицаЗначений». Для больших объёмов предпочтительна обработка целиком на сервере без передачи на клиента.
Табличная часть документа — это тоже коллекция?
Да. Табличная часть поддерживает перебор в цикле «Для Каждого», методы Количество(), Добавить(), Удалить(), Итог() по числовой колонке. Отличие от таблицы значений в том, что её строки хранятся в базе данных вместе с документом и записываются вместе с ним.
Что важно запомнить
Коллекция в 1С — любой объект с перебираемыми элементами: массив, структура, соответствие, список значений, таблица значений, табличная часть, выборка запроса. Тип выбирают по способу доступа к данным, обход выполняют циклом «Для Каждого», а состав коллекции внутри цикла не изменяют. Для поиска по ключу используйте соответствие, для табличных данных — таблицу значений.