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

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

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

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

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

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

Что такое массив и структура во встроенном языке 1С

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

Объект Структура — коллекция пар «ключ-значение», где ключом выступает строка, удовлетворяющая правилам именования переменных (без пробелов, не начинается с цифры). Структура создаётся конструктором Новый Структура("Ключ1, Ключ2", Значение1, Значение2), причём список значений можно опустить — тогда поля получат значение Неопределено.

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

Базовое создание массива структур: пошаговый пример

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

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

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

СтрокаТовара.Вставить("Номенклатура", "Товар А");

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

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

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

// Краткая форма — через конструктор

МассивТоваров.Добавить(Новый Структура("Номенклатура, Цена, Количество", "Товар Б", 2300, 1));

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

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

Наполнение массива в цикле

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

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

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

Запись = Новый Структура;

Запись.Вставить("Номенклатура", СтрокаТЧ.Номенклатура);

Запись.Вставить("Сумма", СтрокаТЧ.Сумма);

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

КонецЦикла;

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

Если записи нужны не все, а по условию, добавляйте проверку внутри цикла: Если СтрокаТЧ.Количество > 0 Тогда ... КонецЕсли;. Это избавляет от последующей фильтрации готового массива.

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

Обход массива и доступ к полям структур

Для перебора элементов удобнее всего цикл Для Каждого — он не требует работы с индексами и защищает от выхода за границы массива. Обращение к полю выполняется через точку: Элемент.Цена.

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

Сообщить(Элемент.Номенклатура + " — " + Элемент.Цена);

КонецЦикла;

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

ЗначениеСкидки = Неопределено;

Если Элемент.Свойство("Скидка", ЗначениеСкидки) Тогда

// поле есть, работаем со значением

КонецЕсли;

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

Поиск и фильтрация элементов в массиве структур

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

Функция НайтиПоНоменклатуре(Массив, ИскомоеЗначение)

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

Если Элемент.Номенклатура = ИскомоеЗначение Тогда

Возврат Элемент;

КонецЕсли;

КонецЦикла;

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

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

Когда поиск выполняется многократно в большом массиве, перебор становится узким местом. В этом случае эффективнее построить Соответствие, где ключ — значение поля поиска, а значение — сама структура или её индекс. Доступ по ключу в соответствии выполняется быстро и без перебора.

Когда массив структур не подходит: альтернативы

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

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

Сравнение вариантов

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

Подходит для временных данных внутри процедуры, простого обхода и передачи в параметрах. Ограничение: нет встроенной сортировки, свёртки и поиска по полям

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

Подходит для сортировки, свёртки, поиска по колонкам, передачи в запрос и СКД. Ограничение: требует описания колонок, чуть более громоздкий код создания

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

Подходит для быстрого доступа по ключу. Ограничение: нет порядка обхода по индексу и дублирующихся ключей

Проверка результата и контрольные точки

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

При передаче массива структур между клиентом и сервером помните: структура и массив сериализуются платформой штатно, но значения полей должны быть сериализуемых типов (примитивы, ссылки, другие структуры и массивы). Вложенные COM-объекты или результаты запросов вызовут ошибку передачи.

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

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

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

Массив.Количество() равно числу ожидаемых записей

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

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

Независимость элементов
Норма

Изменение поля одного элемента не влияет на остальные

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

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

Доступ к полям
Норма

Обращение Элемент.Ключ не вызывает исключения

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

Ошибка «Поле объекта не обнаружено» — набор полей неоднороден, нужна проверка через Свойство()

Пример комплексной задачи

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

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

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

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

Продолжить;

КонецЕсли;

МассивСтрок.Добавить(Новый Структура("Номенклатура, Сумма",

СтрокаТЧ.Номенклатура, СтрокаТЧ.Сумма));

КонецЦикла;

Максимум = Неопределено;

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

Если Максимум = Неопределено Или Элемент.Сумма > Максимум.Сумма Тогда

Максимум = Элемент;

КонецЕсли;

КонецЦикла;

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

Итог

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

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

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

Можно ли добавить поле в структуру после её создания?

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

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

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

Можно ли передать массив структур в фоновое задание?

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

Чем структура отличается от соответствия при хранении пар «ключ-значение»?

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

Почему все элементы массива показывают одинаковые данные?

Почти всегда причина в том, что структура создана один раз до цикла, а внутри цикла только меняются значения её полей. В массив добавляются ссылки на один и тот же объект. Решение — создавать Новый Структура внутри тела цикла на каждой итерации.

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

Переберите массив циклом Для Каждого с условием по полю и прервите его командой Прервать при первом совпадении. Если таких проверок много, постройте соответствие «значение поля → структура» один раз и проверяйте наличие ключа через соответствие — это заметно быстрее повторных переборов.