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

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

Как заполнить массив структурой в 1С

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

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

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

Ниже разобраны синтаксис создания структур, способы добавления их в массив, заполнение в цикле, обход и чтение данных, а также типичные ошибки и способы проверить результат. Примеры приведены на встроенном языке платформы 1С:Предприятие 8.3 и работают как в толстом, так и в тонком клиенте.

Создание массива и структуры: базовый синтаксис

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

Структура создаётся конструктором Новый Структура. В простейшем виде передаётся строка с именами ключей через запятую, а затем — значения в том же порядке: Новый Структура("Номенклатура, Количество", ТекТовар, 5). Если значения опускаются, ключи получают значение Неопределено.

Минимальный пример заполнения массива одной структурой выглядит так:

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

СтрокаТовара = Новый Структура;

СтрокаТовара.Вставить("Номенклатура", Справочники.Номенклатура.НайтиПоКоду("000001"));

СтрокаТовара.Вставить("Количество", 3);

СтрокаТовара.Вставить("Цена", 1500);

МассивТоваров.Добавить(СтрокаТовара);

Метод Вставить() добавляет ключ или перезаписывает существующий. Альтернатива — передать всё в конструктор одной строкой, что короче, но менее читаемо при большом числе полей. Выбор зависит от количества ключей и стиля кода конфигурации.

Заполнение массива структурами в цикле

Самый частый сценарий — обход выборки из запроса или табличной части с добавлением структуры на каждой итерации. Ключевое правило: конструктор Новый Структура должен находиться внутри цикла. Тогда каждая итерация создаёт независимый объект.

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Товары.Номенклатура КАК Номенклатура,

| Товары.Количество КАК Количество

|ИЗ

| Документ.РеализацияТоваровУслуг.Товары КАК Товары

|ГДЕ

| Товары.Ссылка = &Ссылка";

Запрос.УстановитьПараметр("Ссылка", ДокументСсылка);

МассивСтрок = Новый Массив;

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

СтрокаДанных = Новый Структура("Номенклатура, Количество");

СтрокаДанных.Номенклатура = Выборка.Номенклатура;

СтрокаДанных.Количество = Выборка.Количество;

МассивСтрок.Добавить(СтрокаДанных);

КонецЦикла;

Обратите внимание: доступ к полям структуры возможен и через точку (СтрокаДанных.Количество), если ключ объявлен при создании. Это удобно, но работает только для заранее известных ключей. Для динамических имён используйте Вставить() и Свойство().

Добавление элементов: Добавить, Вставить и Установить

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

Проверить текущее число элементов можно через Количество(). Индексация массива начинается с нуля, поэтому последний элемент имеет индекс Массив.Количество() - 1. Обращение за границы массива вызывает ошибку исполнения, поэтому перед чтением по индексу проверяйте размер.

Копирование структуры перед добавлением

Иногда нужно добавить в массив изменённую копию уже существующей структуры. Простое присваивание переменной не копирует объект — обе переменные будут указывать на одну структуру. Для копии создайте новую структуру и перенесите ключи:

Функция СкопироватьСтруктуру(Источник)

Копия = Новый Структура;

Для Каждого КлючЗначение Из Источник Цикл

Копия.Вставить(КлючЗначение.Ключ, КлючЗначение.Значение);

КонецЦикла;

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

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

Такая функция полезна, когда массив заполняется однотипными записями, у которых меняется одно-два поля: создаётся шаблон, а в цикле копируется и дозаполняется.

bsl
Массив = Новый Массив;
Для Сч = 1 По 5 Цикл
	Элемент = Новый Структура("Номер, Наименование");
	Элемент.Номер = Сч;
	Элемент.Наименование = "Строка " + Сч;
	Массив.Добавить(Элемент);
КонецЦикла;

Обход массива и чтение данных из структур

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

Для Каждого СтрокаТовара Из МассивСтрок Цикл

Сообщить(СтрокаТовара.Номенклатура);

Количество = 0;

Если СтрокаТовара.Свойство("Количество", Количество) Тогда

Сообщить("Количество: " + Количество);

КонецЕсли;

КонецЦикла;

Метод Свойство(ИмяКлюча, НайденноеЗначение) возвращает Истина, если ключ существует, и помещает значение во второй параметр. Это безопасный способ чтения, когда набор ключей у структур в массиве может различаться. Прямое обращение к несуществующему полю через точку вызовет ошибку «Поле объекта не обнаружено».

Для поиска нужной структуры в массиве перебирайте элементы с условием. Метод Найти() массива сравнивает ссылки на объекты, а не содержимое структур, поэтому для поиска по значению поля он не подходит — нужен явный цикл с проверкой.

Порядок заполнения массива структурами
  1. 1
    Создайте пустой массив: Массив = Новый Массив
  2. 2
    Определите единый набор ключей для всех структур
  3. 3
    Внутри цикла создавайте Новый Структура на каждой итерации
  4. 4
    Заполните значения ключей через точку или Вставить()
  5. 5
    Добавьте структуру: Массив.Добавить(Элемент)
  6. 6
    Проверьте результат: Массив.Количество() и содержимое первого элемента

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

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

Массив структур оправдан для передачи параметров между процедурами, формирования данных для HTTP-запросов и JSON, небольших промежуточных наборов до нескольких сотен записей. Для выгрузки в JSON структуры сериализуются штатно через ЗаписьJSON, что делает этот формат удобным для интеграций.

Массив структур или таблица значений

Массив структур

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

Таблица значений

Подходит для больших объёмов, сортировки, свёртки, передачи в запрос. Тяжелее в создании, не сериализуется в JSON напрямую.

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

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

Типичные ошибки и как их избежать

Первая и самая массовая ошибка — создание структуры вне цикла, из-за чего все элементы массива ссылаются на один объект. Вторая — обращение к полю через точку без проверки его существования. Третья — путаница между Найти() массива и поиском по значению поля структуры.

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

Типичные ошибки
01
Структура создана до цикла — все элементы массива содержат данные последней итерации
02
Обращение к несуществующему ключу через точку — ошибка «Поле объекта не обнаружено», используйте Свойство()
03
Поиск через Массив.Найти(Структура) — сравниваются ссылки, а не содержимое, нужен перебор с условием
04
Разный набор ключей у элементов массива — усложняет обход и вызывает ошибки чтения
05
Обращение к элементу по индексу без проверки Количество() — выход за границы массива

Проверка результата заполнения

После заполнения убедитесь, что массив содержит ожидаемое число элементов и что данные в структурах корректны. Быстрый способ — вывести количество и содержимое первого и последнего элемента через Сообщить() в отладочном режиме или воспользоваться табло переменных в конфигураторе при точке останова.

Если МассивСтрок.Количество() = 0 Тогда

ВызватьИсключение "Массив не заполнен: проверьте отбор запроса";

КонецЕсли;

Полезно проверять не только количество, но и состав ключей: вызовите Свойство() для обязательных полей первого элемента. Если массив передаётся между серверными процедурами, помните, что структуры сериализуются при передаче с клиента на сервер — вложенные мутабельные объекты вроде других массивов переносятся корректно, но ссылки на объекты базы сохраняют тип.

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

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

Количество элементов
Норма

Массив.Количество() равно числу обработанных строк

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

Ноль или меньше ожидаемого — проверьте условия отбора и цикл

Содержимое элементов
Норма

Каждый элемент имеет свои значения полей

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

Все элементы одинаковые — структура создана вне цикла

Наличие ключей
Норма

Свойство() возвращает Истина для всех обязательных полей

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

Ключ отсутствует — не задан при создании структуры

Часто задаваемые вопросы

Можно ли добавить одну и ту же структуру в массив дважды?

Технически да, но в массив попадут две ссылки на один объект: изменение поля через один элемент отразится и на втором. Если нужны независимые копии, создавайте новую структуру или копируйте существующую перебором ключей.

Как отсортировать массив структур по значению поля?

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

Как передать массив структур в запрос?

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

Чем структура отличается от соответствия при заполнении массива?

Структура имеет фиксированный набор ключей, заданный при создании, и поддерживает доступ через точку. Соответствие допускает ключи любого типа и динамическое добавление без объявления. Для однотипных записей с известными полями удобнее структура, для произвольных ключей — соответствие.

Можно ли выгрузить массив структур в JSON?

Да. Используйте ЗаписьJSON и ЗаписатьJSON: структуры преобразуются в объекты, массив — в JSON-массив. Ключи структуры станут именами свойств, поэтому задавайте их латиницей, если JSON предназначен для внешней системы.

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

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

Итог

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

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