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