Добавление элементов в массив на встроенном языке 1С:Предприятия 8.3

· 9 мин

Содержание

Чтобы добавить значение в массив 1С, вызовите Массив.Добавить(Значение) — элемент встанет в конец, размер вырастет на единицу. Если элемент нужен в начале или в середине, используйте Массив.Вставить(Индекс, Значение). А Массив.Установить(Индекс, Значение) или запись Массив[Индекс] = Значение ничего не добавляют: они заменяют уже существующий элемент.

Выбор простой. Добавление в конец — основной и самый быстрый путь. Вставка по индексу нужна, когда важен порядок. Замена — когда размер массива задан заранее. Все три метода есть в платформе 8.3 и не зависят от конфигурации: код одинаково работает в Бухгалтерии, ЗУП, УТ и в своих разработках.

Как создать массив перед добавлением значений

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

Есть три способа создать массив.

📌 Пустой массив — самый частый вариант, дальше элементы добавляют по одному:

Товары = Новый Массив;
Товары.Добавить("Бумага А4");
Товары.Добавить("Тонер");
// Товары.Количество() = 2

📌 Массив заданного размера — все элементы сразу получают значение Неопределено:

Остатки = Новый Массив(3);
// Остатки[0], Остатки[1], Остатки[2] = Неопределено
Остатки[0] = 120;
Остатки[1] = 45;
Остатки[2] = 0;

📌 Массив из другой коллекции — платформа и типовые конфигурации умеют отдавать готовые массивы:

// Из строки с разделителем (платформа 8.3.6 и новее)
Коды = СтрРазделить("001;002;003", ";", Ложь);

// Из колонки таблицы значений
Номенклатура = ТаблицаТоваров.ВыгрузитьКолонку("Номенклатура");

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

// Копия фиксированного массива — уже изменяемая
Изменяемый = Новый Массив(ФиксМассив);

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

Многомерный массив создают конструктором с несколькими размерами: Новый Массив(3, 2) — три строки по два элемента. Каждая «строка» — вложенный массив, к ней обращаются так: Матрица[1][0]. Когда размеры строк разные, проще собрать массив массивов вручную — через Добавить на каждом уровне.

Метод Добавить: значение в конец массива

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

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

Суммы = Новый Массив;
Суммы.Добавить(1500);
Суммы.Добавить(2300);
Суммы.Добавить(800);

ИндексПоследнего = Суммы.ВГраница(); // 2
Итого = 0;
Для Каждого Сумма Из Суммы Цикл
	Итого = Итого + Сумма;
КонецЦикла;
// Итого = 4600

Добавление значений в массив в цикле

Типичная задача — собрать массив ссылок из результата запроса или из табличной части документа.

МассивКонтрагентов = Новый Массив;
Для Каждого Строка Из Объект.Товары Цикл
	Если Строка.Количество > 0 Тогда
		МассивКонтрагентов.Добавить(Строка.Поставщик);
	КонецЕсли;
КонецЦикла;

Если фильтр не нужен и нужна вся колонка, цикл лишний: Объект.Товары.ВыгрузитьКолонку("Поставщик") вернёт тот же массив одной строкой.

Как добавить значение без дублей

В массиве нет встроенной проверки уникальности. Перед добавлением ищите значение методом Найти — он вернёт индекс или Неопределено:

Если Склады.Найти(Склад) = Неопределено Тогда
	Склады.Добавить(Склад);
КонецЕсли;

Для нескольких сотен элементов это нормально. На десятках тысяч Найти начинает тормозить — об этом в разделе про производительность.

Добавить один массив в другой

Встроенного метода «склеить массивы» у платформы нет. Пишут цикл:

Для Каждого Элемент Из МассивИсточник Цикл
	МассивПриемник.Добавить(Элемент);
КонецЦикла;

В типовых конфигурациях на БСП (Бухгалтерия 3.0, ЗУП 3.1, УТ 11) есть готовая процедура ОбщегоНазначенияКлиентСервер.ДополнитьМассив(Приемник, Источник, ТолькоУникальные). Третий параметр Истина пропускает значения, которые уже есть в приёмнике. В своей конфигурации без БСП этой процедуры нет — оставьте цикл.

Вставка значения в начало или середину массива

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

Этапы = Новый Массив;
Этапы.Добавить("Поступление");
Этапы.Добавить("Реализация");

Этапы.Вставить(1, "Перемещение");
// Поступление, Перемещение, Реализация

Этапы.Вставить(0, "Заказ");
// Заказ, Поступление, Перемещение, Реализация

Что будет, если индекс больше размера

Вставить с индексом, равным Количество(), работает как Добавить — значение уходит в конец.

Если индекс ещё больше, платформа расширяет массив: промежуточные позиции заполняются Неопределено, а переданное значение встаёт по указанному индексу.

Список = Новый Массив;
Список.Добавить("А");          // [0] = "А"
Список.Вставить(3, "Г");       // [0] = "А", [1] и [2] = Неопределено, [3] = "Г"
// Список.Количество() = 4

Такие «дыры» потом ломают обход: код, который ждёт строку или ссылку, получит Неопределено. Если вставляете по вычисленному индексу, проверяйте его до вызова.

Замена элемента: Установить и квадратные скобки

Массив.Установить(Индекс, Значение) и Массив[Индекс] = Значение делают одно и то же — меняют значение существующего элемента. Размер массива не меняется.

Цены = Новый Массив(2);
Цены[0] = 100;
Цены.Установить(1, 250);

Индекс должен быть в диапазоне от 0 до ВГраница(). Выход за границу — ошибка выполнения, расширения массива здесь не будет.

Сравнение методов: Добавить, Вставить, Установить

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

Сопутствующие методы, которые нужны при работе с добавлением:

  • 🔢 Количество() — сколько элементов;
  • 📍 ВГраница() — индекс последнего элемента, у пустого массива равен -1;
  • 🔍 Найти(Значение) — индекс первого совпадения или Неопределено;
  • ✂️ Удалить(Индекс) — удаляет элемент, хвост сдвигается влево;
  • 🧹 Очистить() — удаляет все элементы.

Ошибки при добавлении в массив и как их обойти

Платформа сообщает об ошибках массива короткими фразами. Вот что стоит за самыми частыми.

Диагностика: выберите симптом

Удаление и добавление в одном проходе

Если в цикле нужно и удалять элементы, идите с конца — индексы ещё не пройденных элементов при этом не сдвигаются:

Всего = Строки.Количество();
Для Сч = 1 По Всего Цикл
	Индекс = Всего - Сч;
	Если ПустаяСтрока(Строки[Индекс]) Тогда
		Строки.Удалить(Индекс);
	КонецЕсли;
КонецЦикла;

Граница цикла Всего вычислена один раз до начала. Пересчитывать Строки.Количество() внутри цикла нельзя: после удаления индекс уедет за границу.

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

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

Добавление в массив сложных значений: структуры и вложенные массивы

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

Ошибки = Новый Массив;

Для Каждого Строка Из Объект.Товары Цикл
	Если Строка.Цена = 0 Тогда
		Описание = Новый Структура;
		Описание.Вставить("НомерСтроки", Строка.НомерСтроки);
		Описание.Вставить("Текст", "Не заполнена цена");
		Ошибки.Добавить(Описание);
	КонецЕсли;
КонецЦикла;

Для Каждого Ошибка Из Ошибки Цикл
	Сообщить(СтрШаблон("Строка %1: %2", Ошибка.НомерСтроки, Ошибка.Текст));
КонецЦикла;

СтрШаблон сам приводит номер строки к тексту, поэтому склеивать число со строкой вручную не нужно.

Структура кладётся по ссылке

Одна тонкость ловит многих. Если создать структуру один раз до цикла и в цикле только менять её поля, массив заполнится ссылками на один и тот же объект. В итоге все элементы покажут значения последней итерации.

// Неправильно: все элементы массива — одна и та же структура
Описание = Новый Структура("Код");
Для Каждого Код Из Коды Цикл
	Описание.Код = Код;
	Результат.Добавить(Описание);
КонецЦикла;

Создавайте Новый Структура внутри цикла — как в примере выше. То же правило действует для вложенных массивов и соответствий.

Массив массивов

Для табличных данных без таблицы значений собирают массив, каждый элемент которого — тоже массив:

Строки = Новый Массив;
Строка1 = Новый Массив;
Строка1.Добавить("Бумага");
Строка1.Добавить(250);
Строки.Добавить(Строка1);
// Строки[0][1] = 250

Производительность: как быстро добавлять тысячи значений

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

Добавляйте в конец, а не в начало

Добавить не трогает существующие элементы. Вставить(0, …) сдвигает весь массив на каждом вызове. Вставка 50 000 значений в начало в цикле означает сотни миллионов сдвигов — код, который с Добавить работает доли секунды, начинает работать заметно дольше.

Если нужен обратный порядок, добавляйте в конец, а потом соберите перевёрнутую копию одним проходом:

Обратный = Новый Массив;
Всего = Исходный.Количество();
Для Сч = 1 По Всего Цикл
	Обратный.Добавить(Исходный[Всего - Сч]);
КонецЦикла;

Уникальность через Соответствие

Найти перебирает массив от начала. При 20 000 элементах проверка «есть ли уже» на каждом шаге превращает сбор в квадратичный алгоритм. Держите рядом Соответствие как индекс:

Уникальные = Новый Массив;
Встречались = Новый Соответствие;

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

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

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

Не собирайте в цикле то, что отдаёт запрос

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

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

Обратная задача — получить из запроса готовый массив: Результат.ВыгрузитьКолонку("Ссылка").

Короткие правила

  • ✅ Создавайте массив до цикла, а не внутри него.
  • ✅ Если размер известен заранее — Новый Массив(N) и заполнение по индексу.
  • ✅ Для проверки «уже есть» на больших объёмах — Соответствие, а не Найти.
  • ✅ Готовые выгрузки (ВыгрузитьКолонку, СтрРазделить, ВыгрузитьЗначения) вместо ручного цикла.
  • ❌ Не вставляйте в начало в цикле.
  • ❌ Не меняйте массив внутри Для Каждого по нему же.

Частые вопросы о добавлении значений в массив

Можно ли добавить в массив значение другого типа?
Да. Массив не типизирован: в одном массиве могут лежать число, строка, дата и ссылка. Проверить тип элемента при обходе можно через ТипЗнч(Элемент) = Тип("Число").
Как добавить в массив сразу несколько значений одной строкой?
Для строк — СтрРазделить("а,б,в", ","). Для значений других типов конструктора со списком значений нет: вызывайте Добавить несколько раз или используйте цикл по другой коллекции.
Как сделать копию массива, чтобы добавление не меняло оригинал?
Присваивание Копия = Оригинал копирует ссылку, а не данные: добавление в копию изменит оригинал. Независимую копию дают цикл с Добавить или конструкция Новый Массив(Новый ФиксированныйМассив(Оригинал)).
Чем массив отличается от списка значений при добавлении?
У списка значений метод Добавить(Значение, Представление) принимает ещё и представление, есть пометка и картинка. Список удобен для форм и выбора пользователем, массив — для обработки данных в коде и передачи в запрос.
Сколько элементов можно добавить в массив?
Жёсткого лимита в документации нет, ограничивает объём памяти процесса. Массивы на сотни тысяч элементов на сервере работают, но такие объёмы обычно лучше обрабатывать запросом или порциями.