Массив в 1С 8.3: создание, добавление, получение по индексу

Дата: 19.09.2026 04:23:52
Массив
Коллекции значений
Встроенный язык
Циклы
Клиент-сервер
Комментарий:
0
Платформа:
8.3
Конфигурация:
Любая
Формы:
Любые

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

Массив доступен и на клиенте, и на сервере, примеры работают на платформе 8.3. Исключение — функции СтрРазделить и СтрСоединить: они есть в платформе с версии 8.3.6 и работают, только если режим совместимости конфигурации не ниже 8.3.6. В старых конфигурациях используйте СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок из БСП или цикл с функциями Найти и Сред (СтрНайти тоже появилась только в 8.3.6).

Где встречается массив

  • Элементы.Список.ВыделенныеСтроки — массив выделенных строк таблицы формы. В списке справочника или документа это ссылки.
  • ТаблицаЗначений.ВыгрузитьКолонку() возвращает массив значений колонки, НайтиСтроки() — массив найденных строк.
  • СтрРазделить() разбивает строку на массив подстрок: артикулы через точку с запятой, колонки строки CSV.
  • Параметр запроса для условия В (&Список) чаще всего передают массивом.
  • Многие функции БСП принимают и возвращают массивы: объекты для обработки, пользователей, файлы.

Если к данным нужен доступ не по номеру, а по ключу, возьмите соответствие или структуру. Если у каждой записи несколько полей — таблицу значений.

Как создать массив в 1С 8.3

Конструктор Новый Массив вызывают без параметров, с количеством элементов или с фиксированным массивом. Число в параметре создаёт массив заданного размера, заполненный значениями Неопределено. Несколько чисел дают многомерный массив — массив, элементы которого тоже массивы.

// Пустой массив — самый частый вариант
Товары = Новый Массив;

// Три элемента, каждый равен Неопределено
Коды = Новый Массив(3);
Коды[0] = "К-01";

// Двумерный массив 2 x 3: два вложенных массива по три элемента
Матрица = Новый Массив(2, 3);
Матрица[1][2] = 150;

// Из строки с разделителем (8.3.6+, режим совместимости не ниже 8.3.6)
Артикулы = СтрРазделить("А-100;А-200;;А-300", ";", Ложь); // 3 элемента, пустой пропущен

// Изменяемый массив из фиксированного
Фиксированный = Новый ФиксированныйМассив(Артикулы);
Изменяемый = Новый Массив(Фиксированный);
Изменяемый.Добавить("А-400");

Массив в 1С не типизирован: в одном массиве могут лежать строка, число и ссылка. Но код, который обходит такой массив, придётся обвешивать проверками ТипЗнч, поэтому держите в одном массиве значения одного типа.

Все методы массива в одной таблице

МетодЧто делаетЧто возвращаетЕсли индекса нет
Добавить(Значение)Добавляет элемент в конец
Вставить(Индекс, Значение)Вставляет элемент, остальные сдвигаются вправоМассив дополняется значениями Неопределено до нужного индекса
Получить(Индекс) или [Индекс]Читает элементЗначение элементаОшибка
Установить(Индекс, Значение) или [Индекс] =Заменяет элементОшибка
Найти(Значение)Ищет первое вхождение значенияИндекс или Неопределено
Удалить(Индекс)Удаляет элемент, остальные сдвигаются влевоОшибка
Количество()Считает элементыЧисло, у пустого массива 0
ВГраница()Даёт индекс последнего элементаЧисло, у пустого массива −1
Очистить()Удаляет все элементы

Пример, в котором задействованы все методы: добавить в массив два склада, вставить третий между ними, прочитать, заменить, найти и удалить. Процедура оформлена как обработчик команды формы, но тот же код без изменений выполнится и на сервере.

&НаКлиенте
Процедура ПоказатьМетодыМассива(Команда)

    Склады = Новый Массив;
    Склады.Добавить("Основной");            // [Основной]
    Склады.Добавить("Розница");             // [Основной, Розница]
    Склады.Вставить(1, "Транзит");          // [Основной, Транзит, Розница]

    Сообщить(Склады[0] + " / " + Склады.Получить(1)); // Основной / Транзит

    Склады.Установить(2, "Магазин");        // [Основной, Транзит, Магазин]
    Склады[0] = "Центральный";              // то же, что Установить(0, ...)

    Индекс = Склады.Найти("Транзит");       // 1, если не найдено — Неопределено
    Если Индекс <> Неопределено Тогда
        Склады.Удалить(Индекс);             // [Центральный, Магазин]
    КонецЕсли;

    Сообщить("Элементов: " + Склады.Количество()
        + ", индекс последнего: " + Склады.ВГраница()); // 2 и 1

    Склады.Очистить();                      // Количество() = 0, ВГраница() = -1

КонецПроцедуры

Элемент массива по индексу: Получить и квадратные скобки

Индексы начинаются с нуля. В массиве из трёх элементов есть индексы 0, 1 и 2, а обращение к элементу с индексом 3 заканчивается ошибкой «Индекс находится за границами массива». Запись Массив[Индекс] и вызов Массив.Получить(Индекс) равнозначны, так же как присваивание Массив[Индекс] = Значение и Массив.Установить(Индекс, Значение). Скобки короче, поэтому в типовых конфигурациях встречаются чаще.

Путаницу чаще всего вызывают два «размера». Количество() — сколько элементов в массиве, ВГраница() — индекс последнего из них, на единицу меньше. У пустого массива количество равно 0, а верхняя граница равна −1. Отсюда правило для цикла по индексу: от 0 до ВГраница().

// Индексы от 0 до ВГраница()
Для Индекс = 0 По Артикулы.ВГраница() Цикл
    Сообщить(Строка(Индекс) + ": " + Артикулы[Индекс]);
КонецЦикла;

// Так нельзя: на последнем шаге индекс равен Количество() и выходит за границу
// Для Индекс = 0 По Артикулы.Количество() Цикл

// Индекс не нужен — Для Каждого
Для Каждого Артикул Из Артикулы Цикл
    Сообщить(Артикул);
КонецЦикла;

// Последний элемент — только для непустого массива
Если Артикулы.Количество() > 0 Тогда
    Последний = Артикулы[Артикулы.ВГраница()];
КонецЕсли;

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

Обход и удаление элементов

Для чтения удобнее всего Для Каждого: не нужно думать об индексах. Но переменная цикла получает значение элемента, а не связь с ним. Присваивание ей нового значения массив не меняет. Чтобы заменить элементы, нужен цикл по индексу и запись Массив[Индекс] = ....

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

// Удаляем незаполненные элементы, двигаясь с конца массива
Индекс = Артикулы.ВГраница();
Пока Индекс >= 0 Цикл
    Если Не ЗначениеЗаполнено(Артикулы[Индекс]) Тогда
        Артикулы.Удалить(Индекс);
    КонецЕсли;
    Индекс = Индекс - 1;
КонецЦикла;

При обходе с конца сдвигаются только уже проверенные элементы, поэтому ничего не теряется и индекс не выходит за границы.

Массив на клиенте и на сервере

Массив можно передать с клиента на сервер и обратно, если все его элементы тоже передаются между клиентом и сервером: примитивные типы, ссылки, структуры, соответствия, вложенные массивы. Таблицу значений или объект справочника внутри массива на клиент не передать. Типичный сценарий — пользователь выделил строки в списке, клиент отправляет массив ссылок на сервер, сервер отвечает массивом строк:

// Модуль формы списка справочника Номенклатура

&НаКлиенте
Процедура ПоказатьНаименования(Команда)

    Выделенные = Элементы.Список.ВыделенныеСтроки; // Массив ссылок
    Если Выделенные.Количество() = 0 Тогда
        Возврат;
    КонецЕсли;

    Наименования = НаименованияПоСсылкам(Выделенные);
    Сообщить(СтрСоединить(Наименования, ", "));

КонецПроцедуры

&НаСервереБезКонтекста
Функция НаименованияПоСсылкам(Знач Ссылки)

    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    |    Номенклатура.Наименование КАК Наименование
    |ИЗ
    |    Справочник.Номенклатура КАК Номенклатура
    |ГДЕ
    |    Номенклатура.Ссылка В (&Ссылки)
    |
    |УПОРЯДОЧИТЬ ПО
    |    Наименование";
    Запрос.УстановитьПараметр("Ссылки", Ссылки);

    // ВыгрузитьКолонку возвращает Массив строк — его можно вернуть на клиент
    Возврат Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Наименование");

КонецФункции

Параметр серверной функции объявлен как Знач. Без этого слова платформа после вызова вернула бы массив обратно на клиент — это лишний трафик. Обратная сторона: если серверная процедура изменит массив, клиент этих изменений не увидит, поэтому результат возвращайте из функции явно.

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

Готовый модуль для работы с массивами

У массива нет методов сортировки, удаления дублей, копирования и сравнения — их приходится писать самому. Создайте общий модуль РаботаСМассивамиКлиентСервер, включите флажки «Клиент (управляемое приложение)», «Сервер» и «Внешнее соединение» и вставьте код. Вызов из любого места: РаботаСМассивамиКлиентСервер.УникальныеЗначения(Артикулы).

// Общий модуль РаботаСМассивамиКлиентСервер
// Флажки: Клиент (управляемое приложение), Сервер, Внешнее соединение.
// Директивы компиляции не нужны: функции доступны везде, где скомпилирован модуль.

// Возвращает элемент по индексу или ЗначениеПоУмолчанию, если индекса в массиве нет.
Функция ЭлементМассива(Массив, Индекс, ЗначениеПоУмолчанию = Неопределено) Экспорт

    Если ТипЗнч(Индекс) <> Тип("Число")
        Или Индекс < 0
        Или Индекс <> Цел(Индекс)
        Или Индекс > Массив.ВГраница() Тогда
        Возврат ЗначениеПоУмолчанию;
    КонецЕсли;

    Возврат Массив[Индекс];

КонецФункции

// Удаляет все вхождения значения. Возвращает количество удалённых элементов.
Функция УдалитьВсеВхождения(Массив, Значение) Экспорт

    Удалено = 0;
    Индекс = Массив.ВГраница();
    Пока Индекс >= 0 Цикл
        Если Массив[Индекс] = Значение Тогда
            Массив.Удалить(Индекс);
            Удалено = Удалено + 1;
        КонецЕсли;
        Индекс = Индекс - 1;
    КонецЦикла;

    Возврат Удалено;

КонецФункции

// Возвращает новый массив без повторов, порядок первых вхождений сохраняется.
Функция УникальныеЗначения(Массив) Экспорт

    Результат = Новый Массив;
    Встречались = Новый Соответствие;

    Для Каждого Элемент Из Массив Цикл
        Если Встречались[Элемент] = Неопределено Тогда
            Встречались.Вставить(Элемент, Истина);
            Результат.Добавить(Элемент);
        КонецЕсли;
    КонецЦикла;

    Возврат Результат;

КонецФункции

// Поверхностная копия: новый массив с теми же элементами.
Функция КопияМассива(Массив) Экспорт

    Копия = Новый Массив;
    Для Каждого Элемент Из Массив Цикл
        Копия.Добавить(Элемент);
    КонецЦикла;

    Возврат Копия;

КонецФункции

// Сравнивает массивы поэлементно с учётом порядка.
Функция МассивыРавны(Массив1, Массив2) Экспорт

    Если Массив1.Количество() <> Массив2.Количество() Тогда
        Возврат Ложь;
    КонецЕсли;

    Для Индекс = 0 По Массив1.ВГраница() Цикл
        Если Массив1[Индекс] <> Массив2[Индекс] Тогда
            Возврат Ложь;
        КонецЕсли;
    КонецЦикла;

    Возврат Истина;

КонецФункции

// Возвращает новый массив, отсортированный по значению (числа, строки, даты).
Функция ОтсортированныйМассив(Массив, ПоУбыванию = Ложь) Экспорт

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

    Если ПоУбыванию Тогда
        Список.СортироватьПоЗначению(НаправлениеСортировки.Убыв);
    Иначе
        Список.СортироватьПоЗначению(НаправлениеСортировки.Возр);
    КонецЕсли;

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

КонецФункции

Разбор ключевых строк

  • ЭлементМассива проверяет тип индекса, его целочисленность и диапазон и вместо исключения возвращает значение по умолчанию. Пригодится при разборе строк из файла, где колонок может оказаться меньше, чем ожидалось: Цена = РаботаСМассивамиКлиентСервер.ЭлементМассива(Колонки, 3, "0"). Условия в Если вычисляются слева направо и до первого истинного, поэтому сравнение с нулём не выполнится, если индекс не число.
  • УдалитьВсеВхождения идёт с конца по той же причине, что и пример выше. Вызывать Найти() в цикле тоже можно, но каждый вызов перебирает массив с начала.
  • УникальныеЗначения запоминает встреченные значения в соответствии. Поиск по ключу соответствия быстрый, а Массив.Найти() перебирает элементы подряд. На массиве в десятки тысяч элементов вариант с Найти() для каждого элемента заметно медленнее.
  • КопияМассива делает поверхностную копию. Если в массиве лежат структуры или другие массивы, копия будет ссылаться на те же самые объекты, и изменение структуры в копии отразится в исходном массиве.
  • МассивыРавны сравнивает поэлементно с учётом порядка. Оператор = для двух разных массивов с одинаковым содержимым вернёт Ложь: он сравнивает сами объекты, а не их содержимое.

Типичные ошибки

  • «Индекс находится за границами массива». Цикл до Количество() вместо ВГраница(), обращение к [0] в пустом массиве, счёт индексов с единицы, удаление элементов в прямом цикле.
  • Лишние Неопределено в начале массива. Новый Массив(3) уже содержит три элемента, и Добавить() допишет четвёртый. Если размер заранее не нужен, создавайте пустой массив. Если нужен — заполняйте элементы через [Индекс], а не через Добавить().
  • «Метод объекта не обнаружен (Добавить)». В переменной лежит ФиксированныйМассив: так часто возвращают данные параметры сеанса и кэширующие функции типовых конфигураций. Фиксированный массив только читается. Сделайте изменяемую копию: Новый Массив(ФиксированныйМассив).
  • Присвоили значение переменной цикла. Строка Элемент = СокрЛП(Элемент) внутри Для Каждого ничего не меняет в массиве. Нужен цикл по индексу.
  • Найти не находит структуру. Для структур, массивов и других объектов Найти() ищет тот же самый объект, а не объект с таким же содержимым. Две структуры с одинаковыми полями — два разных значения.
  • «Процедура или функция с указанным именем не определена (СтрРазделить)». Платформа новая, но режим совместимости конфигурации 8.3.5 или ниже. Замените вызов на функцию БСП из начала статьи или на цикл.
  • Изменения на сервере «пропали». Параметр с Знач при серверном вызове на клиент не возвращается. Возвращайте массив результатом функции.

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

Как проверить, что массив пустой?

Сравнить Массив.Количество() с нулём. Если в переменной может оказаться не массив, а, например, Неопределено из необязательного параметра, сначала проверьте тип: ТипЗнч(Значение) = Тип("Массив").

Как получить последний элемент массива?

Выражением Массив[Массив.ВГраница()] — после проверки, что массив не пустой. У пустого массива верхняя граница равна −1, и обращение закончится ошибкой.

Как убрать дубли из массива?

Функцией УникальныеЗначения из модуля выше. В конфигурациях на БСП есть готовая функция ОбщегоНазначенияКлиентСервер.СвернутьМассив(Массив), которая возвращает новый массив без повторов. Её наличие и параметры сверьте с версией библиотеки в вашей конфигурации.

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

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

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

СтрСоединить(Массив, ",") склеивает элементы через разделитель, СтрРазделить(Строка, ",") разбивает строку обратно. Используйте один и тот же разделитель в обе стороны. Второй параметр СтрРазделить — не подстрока, а набор символов: при ", " строка режется и по запятой, и по каждому пробелу внутри значений. Если строку склеили через ", ", разбейте её по "," и обрежьте пробелы:

Части = СтрРазделить(Строка, ",", Ложь);
Для Индекс = 0 По Части.ВГраница() Цикл
    Части[Индекс] = СокрЛП(Части[Индекс]);
КонецЦикла;

Третий параметр Ложь отбрасывает пустые подстроки, поэтому пустые элементы исходного массива при обратном преобразовании пропадут. Если запятая встречается в самих значениях, склеивайте через символ, которого в данных нет, например Символы.Таб. СтрСоединить рассчитана на массив строк: числа, даты и ссылки заранее преобразуйте функцией Строка() или Формат().

Когда проще заказать

Массивы — строительный материал почти любой обработки: выгрузок, загрузок, групповой перепроводки и заполнения документов. Если нужна готовая обработка или отчёт под вашу задачу, а не разбор синтаксиса, посмотрите услугу отчёты и обработки 1С или разместите задачу на площадке: оценка бесплатная, ответ — в течение рабочего дня.

По теме

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

Станьте частью сообщества!
Войдите или зарегистрируйтесь, и вы сможете участвовать в обсуждениях.


1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.