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