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