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

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

1С: как работать с массивом встроенного языка

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

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

Массивы применяются повсюду: при передаче списка документов в процедуру печати, при накоплении строк табличной части перед записью, при построении параметров запроса (оператор «В» принимает массив), при обмене данными между подсистемами. Умение правильно создать массив, обойти его и не выйти за границы индексов — базовый навык разработчика 1С.

Ниже разобраны создание массива, основные методы, перебор элементов, поиск и сортировка, а также типичные ошибки — от обращения по несуществующему индексу до модификации массива во время обхода. Все примеры приведены на встроенном языке 1С и работают как на сервере, так и на клиенте, если не указано иное.

Создание массива и добавление элементов

Массив создаётся конструктором Новый Массив. Без параметров получается пустой массив; если передать число — создаётся массив заданной размерности, заполненный значениями Неопределено. Также можно передать несколько измерений через запятую для многомерного массива.

ПустойМассив = Новый Массив;          // пустой

МассивНа10 = Новый Массив(10); // 10 элементов = Неопределено

Матрица = Новый Массив(3, 4); // двумерный массив 3x4

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

Товары = Новый Массив;

Товары.Добавить("Номенклатура1");

Товары.Добавить("Номенклатура2");

Товары.Вставить(0, "Первый элемент"); // в начало

Товары[1] = "Заменённое значение";

Проверить текущий размер помогает метод Количество() (синоним — ВГраница() возвращает индекс последнего элемента, то есть Количество() − 1). Помните: индексация начинается с нуля, поэтому последний допустимый индекс — Массив.ВГраница(), а не Массив.Количество().

Доступ к элементам и перебор в цикле

Доступ к элементу выполняется оператором квадратных скобок: Значение = Массив[0]. Попытка чтения по индексу вне диапазона вызывает исключение, которое прерывает выполнение кода, поэтому при работе с массивами переменной длины сначала проверяйте границы.

Для полного обхода удобнее всего цикл Для Каждого — он не требует контроля индексов и читается проще:

Для Каждого Элемент Из Товары Цикл

Сообщить(Элемент);

КонецЦикла;

Если внутри цикла нужен номер элемента или требуется изменять значения по индексу, используйте классический цикл Для:

Для Индекс = 0 По Товары.ВГраница() Цикл

Товары[Индекс] = СокрЛП(Товары[Индекс]);

КонецЦикла;

Обход в обратном порядке делается циклом с шагом −1: Для Индекс = Товары.ВГраница() По 0 Цикл не сработает — нужен явный отрицательный шаг через конструкцию Пока или вычисление индекса вручную. Обратный обход особенно важен при удалении элементов внутри цикла, о чём ниже.

Безопасный обход массива
  1. 1
    Проверьте, что массив инициализирован и не равен Неопределено
  2. 2
    Используйте Для Каждого, если индекс не нужен
  3. 3
    Если нужен индекс — цикл Для от 0 до ВГраница()
  4. 4
    При удалении элементов обходите массив с конца
  5. 5
    После цикла проверьте результат через Количество()

Поиск элементов и проверка наличия значения

Метод Найти(Значение) возвращает индекс первого найденного элемента или Неопределено, если значения нет. Сравнение идёт по равенству: для строк регистр учитывается, для ссылок сравниваются сами ссылки, а не представления.

Позиция = Товары.Найти("Номенклатура2");

Если Позиция <> Неопределено Тогда

Сообщить("Найдено на позиции " + Позиция);

КонецЕсли;

Ограничение метода Найти — он ищет только точное совпадение. Если нужен поиск по части строки, по условию или по свойству объекта, придётся перебирать массив вручную с проверкой внутри цикла. Для частого поиска по большим наборам массив неэффективен: используйте Соответствие (ключ-значение) или ТаблицуЗначений с индексом.

Что выбрать для поиска

Массив + Найти()

Подходит для редкого поиска в небольшом списке простых значений. Поиск линейный, на больших объёмах медленный.

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

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

Таблица значений с индексом

Когда ищете по нескольким полям или нужна сортировка. Требует больше кода на подготовку.

Удаление элементов и очистка массива

Метод Удалить(Индекс) убирает элемент по позиции, сдвигая остальные влево. Метод Очистить() удаляет все элементы, оставляя пустой массив. Отдельного метода «удалить по значению» нет — сначала найдите индекс через Найти(), затем удалите.

Индекс = Товары.Найти("Номенклатура2");

Если Индекс <> Неопределено Тогда

Товары.Удалить(Индекс);

КонецЕсли;

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

Для Индекс = -Товары.ВГраница() По 0 Цикл

РеальныйИндекс = -Индекс;

Если ПустаяСтрока(Товары[РеальныйИндекс]) Тогда

Товары.Удалить(РеальныйИндекс);

КонецЕсли;

КонецЦикла;

Сортировка и обмен данными с другими коллекциями

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

Список = Новый СписокЗначений;

Список.ЗагрузитьЗначения(Товары);

Список.СортироватьПоЗначению();

Товары = Список.ВыгрузитьЗначения();

Массив тесно связан с другими коллекциями: ТаблицаЗначений.ВыгрузитьКолонку() возвращает массив, запрос ВЫБРАТЬ ... В (&Массив) принимает массив как параметр для фильтрации, а Запрос.Выполнить().Выгрузить() позволяет быстро получить массив значений одной колонки. Это самый частый сценарий: собрать массив ссылок и передать его в запрос одним параметром вместо цикла обращений к базе.

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

Многомерные массивы и типичные ошибки

Многомерный массив создаётся конструктором с несколькими измерениями: Новый Массив(3, 4). Обращение идёт через цепочку индексов: Матрица[0][1] или Матрица[0][1] = 5. На практике многомерные массивы в 1С применяются редко — для табличных данных почти всегда удобнее ТаблицаЗначений с именованными колонками.

Ещё одна тонкость: присваивание Массив2 = Массив1 не копирует данные, а создаёт вторую ссылку на тот же объект. Изменение через одну переменную видно через другую. Для независимой копии создайте новый массив и скопируйте элементы в цикле или через ЗагрузитьЗначения/ВыгрузитьЗначения списка значений.

Типичные ошибки
01
Обращение к Массив[Количество()] вместо Массив[ВГраница()] — индексация с нуля, получите выход за границы
02
Удаление элементов в прямом цикле — пропуск элементов из-за сдвига индексов
03
Ожидание, что Массив2 = Массив1 создаст копию — меняются оба, это один объект
04
Поиск подстроки методом Найти() — метод ищет только точное равенство
05
Использование массива для миллионов проверок наличия — линейный поиск, нужно Соответствие

Проверка результата и отладка

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

Признаки корректной работы: количество элементов совпадает с ожидаемым после добавлений и удалений, Найти() возвращает ожидаемый индекс, запрос с параметром-массивом возвращает непустой результат. Если массив пришёл извне (из функции, из формы), проверяйте его на Неопределено перед использованием — обращение к методам Неопределено даёт ошибку «Значение не является значением объектного типа».

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

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

Размер массива после операций
Норма

Количество() совпадает с числом добавленных минус удалённые

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

Размер больше или меньше ожидаемого — где-то лишний Добавить или пропущенное Удалить

Результат Найти()
Норма

Возвращён индекс от 0 до ВГраница()

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

Неопределено при заведомо существующем значении — проверьте регистр строк и тип сравниваемого значения

Запрос с параметром-массивом
Норма

Выборка содержит записи по всем ссылкам массива

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

Пустой результат — массив пуст или типы параметра и поля не совпадают

Частые вопросы

Как объединить два массива в один?

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

Можно ли хранить в массиве значения разных типов?

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

Как передать массив с клиента на сервер?

Массив сериализуется платформой автоматически: просто объявите параметр в серверной процедуре и передайте массив при вызове. Ограничение — элементы должны быть сериализуемыми (ссылки, примитивы, структуры); объекты типа ТабличныйДокумент или COM-объекты передать нельзя.

Чем массив отличается от фиксированного массива?

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

Как быстро проверить, пуст ли массив?

Сравните Количество() с нулём: Если Массив.Количество() = 0 Тогда. Перед этим убедитесь, что переменная вообще содержит массив, а не Неопределено — иначе получите ошибку обращения к методу.

Есть ли ограничение на размер массива?

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

Итог

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

Массив создаётся через Новый Массив, индексация с нуля, последний индекс — ВГраница(). Обходите циклом Для Каждого, удаляйте с конца, ищите через Найти() только точные совпадения. Для частого поиска берите Соответствие, для сортировки — СписокЗначений или запрос. Присваивание массива не копирует данные, а передаёт ссылку на тот же объект.