Разработка и Конфигурация · 11 мин
Как создать массив структур в 1С
Как создать массив структур в 1С: добавление элементов, обход в цикле, поиск, типичные ошибки и готовые примеры кода для разработчика.
Массив структур — один из самых востребованных приёмов во встроенном языке 1С. Он нужен, когда требуется хранить набор однотипных записей с именованными полями: список товаров с ценой и количеством, параметры отбора, строки будущего документа, настройки обмена. В отличие от таблицы значений, массив структур создаётся без явного описания колонок и удобен для временных данных внутри процедуры или функции.
Конструкция строится из двух базовых объектов платформы: Массив хранит упорядоченную последовательность элементов, а Структура — пары «ключ-значение». Объединяя их, разработчик получает гибкий список записей, к полям которых можно обращаться по имени: Элемент.Номенклатура, Элемент.Цена. Ниже разобраны способы создания, наполнения, обхода и поиска, а также ограничения и типичные ошибки.
Что такое массив и структура во встроенном языке 1С
Объект Массив — это упорядоченная коллекция произвольных значений с доступом по индексу, начиная с нуля. Элементы добавляются методом Добавить(), вставляются методом Вставить(), удаляются методом Удалить(). Количество элементов возвращает метод Количество().
Объект Структура — коллекция пар «ключ-значение», где ключом выступает строка, удовлетворяющая правилам именования переменных (без пробелов, не начинается с цифры). Структура создаётся конструктором Новый Структура("Ключ1, Ключ2", Значение1, Значение2), причём список значений можно опустить — тогда поля получат значение Неопределено.
Когда структуры помещаются в массив, каждый элемент массива становится самостоятельной записью. Важно понимать: структура передаётся по ссылке, поэтому одна и та же структура, добавленная в массив дважды, даст два указателя на один объект — изменение поля отразится в обоих элементах.
Базовое создание массива структур: пошаговый пример
Минимальный рабочий пример выглядит так: сначала создаётся пустой массив, затем в цикле или напрямую в него добавляются структуры с нужным набором полей. Ниже полный фрагмент кода, который можно выполнить в любой процедуре.
МассивТоваров = Новый Массив;
СтрокаТовара = Новый Структура;
СтрокаТовара.Вставить("Номенклатура", "Товар А");
СтрокаТовара.Вставить("Цена", 1500);
СтрокаТовара.Вставить("Количество", 2);
МассивТоваров.Добавить(СтрокаТовара);
// Краткая форма — через конструктор
МассивТоваров.Добавить(Новый Структура("Номенклатура, Цена, Количество", "Товар Б", 2300, 1));
Обе формы равнозначны. Метод Вставить() удобен, когда поля добавляются по условию или в разных местах кода. Конструктор Новый Структура(...) компактнее, но требует, чтобы все значения были известны в момент вызова.
- 1Объявите переменную и присвойте ей Новый Массив
- 2Определите состав полей записи — имена ключей структуры
- 3Создайте структуру через Новый Структура или метод Вставить
- 4Добавьте структуру в массив методом Добавить
- 5Повторите для каждой записи, обычно внутри цикла
- 6Проверьте результат через Массив.Количество() и обращение к полям первого элемента
Наполнение массива в цикле
На практике массив структур чаще всего заполняется из выборки запроса, табличной части документа или другого источника данных. Типичный сценарий — пройтись по строкам табличной части и собрать нужные поля в отдельные структуры.
МассивСтрок = Новый Массив;
Для Каждого СтрокаТЧ Из Документ.Товары Цикл
Запись = Новый Структура;
Запись.Вставить("Номенклатура", СтрокаТЧ.Номенклатура);
Запись.Вставить("Сумма", СтрокаТЧ.Сумма);
МассивСтрок.Добавить(Запись);
КонецЦикла;
Критически важный момент: структура должна создаваться заново на каждой итерации цикла. Если объявить структуру один раз до цикла и только менять значения полей, в массиве окажется несколько ссылок на один и тот же объект — все элементы будут показывать данные последней итерации. Это одна из самых частых ошибок начинающих разработчиков.
Если записи нужны не все, а по условию, добавляйте проверку внутри цикла: Если СтрокаТЧ.Количество > 0 Тогда ... КонецЕсли;. Это избавляет от последующей фильтрации готового массива.
Обход массива и доступ к полям структур
Для перебора элементов удобнее всего цикл Для Каждого — он не требует работы с индексами и защищает от выхода за границы массива. Обращение к полю выполняется через точку: Элемент.Цена.
Для Каждого Элемент Из МассивТоваров Цикл
Сообщить(Элемент.Номенклатура + " — " + Элемент.Цена);
КонецЦикла;
Если поле может отсутствовать в части структур (например, записи формировались в разных ветках логики), безопасное чтение выполняется через метод Свойство():
ЗначениеСкидки = Неопределено;
Если Элемент.Свойство("Скидка", ЗначениеСкидки) Тогда
// поле есть, работаем со значением
КонецЕсли;
Прямое обращение к несуществующему ключу вызывает исключение и прерывает выполнение. Поэтому при неоднородном составе записей либо выравнивайте набор полей при создании, либо всегда проверяйте наличие ключа.
Поиск и фильтрация элементов в массиве структур
У массива нет встроенного поиска по значениям полей структур — метод Найти() сравнивает сами элементы (ссылки на структуры), а не их содержимое. Поэтому поиск выполняется перебором с условием.
Функция НайтиПоНоменклатуре(Массив, ИскомоеЗначение)
Для Каждого Элемент Из Массив Цикл
Если Элемент.Номенклатура = ИскомоеЗначение Тогда
Возврат Элемент;
КонецЕсли;
КонецЦикла;
Возврат Неопределено;
КонецФункции
Когда поиск выполняется многократно в большом массиве, перебор становится узким местом. В этом случае эффективнее построить Соответствие, где ключ — значение поля поиска, а значение — сама структура или её индекс. Доступ по ключу в соответствии выполняется быстро и без перебора.
Когда массив структур не подходит: альтернативы
Массив структур — не универсальный контейнер. Если данные требуется сортировать, сворачивать по группам, искать по нескольким колонкам или передавать в СКД и запросы, правильный выбор — таблица значений. Она хранит типизированные колонки и имеет богатый встроенный API: Найти(), НайтиСтроки(), Сортировать(), Свернуть().
Также массив структур не сериализуется напрямую во всех механизмах платформы. Для передачи между сеансами, через хранилище значений или в фоновое задание данные надёжнее упаковать в таблицу значений либо преобразовать в JSON штатными средствами (ЗаписатьJSON).
Сравнение вариантов
Подходит для временных данных внутри процедуры, простого обхода и передачи в параметрах. Ограничение: нет встроенной сортировки, свёртки и поиска по полям
Подходит для сортировки, свёртки, поиска по колонкам, передачи в запрос и СКД. Ограничение: требует описания колонок, чуть более громоздкий код создания
Подходит для быстрого доступа по ключу. Ограничение: нет порядка обхода по индексу и дублирующихся ключей
Проверка результата и контрольные точки
После наполнения массива проверьте три вещи: количество элементов соответствует ожиданию, поля доступны по имени, значения не «склеились» из-за общей ссылки на одну структуру. Быстрая проверка выполняется через Сообщить() или отладчик — точка останова после цикла наполнения покажет содержимое каждого элемента.
При передаче массива структур между клиентом и сервером помните: структура и массив сериализуются платформой штатно, но значения полей должны быть сериализуемых типов (примитивы, ссылки, другие структуры и массивы). Вложенные COM-объекты или результаты запросов вызовут ошибку передачи.
Как проверить результат
Массив.Количество() равно числу ожидаемых записей
Количество меньше или больше — проверьте условия добавления в цикле
Изменение поля одного элемента не влияет на остальные
Все элементы меняются вместе — структура создавалась один раз вне цикла
Обращение Элемент.Ключ не вызывает исключения
Ошибка «Поле объекта не обнаружено» — набор полей неоднороден, нужна проверка через Свойство()
Пример комплексной задачи
Соберём типовой сценарий целиком: из табличной части документа отобрать строки с ненулевым количеством, сформировать массив структур, найти в нём запись с максимальной суммой.
МассивСтрок = Новый Массив;
Для Каждого СтрокаТЧ Из Товары Цикл
Если СтрокаТЧ.Количество = 0 Тогда
Продолжить;
КонецЕсли;
МассивСтрок.Добавить(Новый Структура("Номенклатура, Сумма",
СтрокаТЧ.Номенклатура, СтрокаТЧ.Сумма));
КонецЦикла;
Максимум = Неопределено;
Для Каждого Элемент Из МассивСтрок Цикл
Если Максимум = Неопределено Или Элемент.Сумма > Максимум.Сумма Тогда
Максимум = Элемент;
КонецЕсли;
КонецЦикла;
Обратите внимание на защиту от пустого массива: если ни одна строка не прошла отбор, переменная Максимум останется равной Неопределено, и дальнейший код должен это учитывать. Пропуск такой проверки — частый источник ошибок «Значение не является значением объектного типа».
Что важно запомнить
Массив структур создаётся через Новый Массив и Добавить(Новый Структура(...)). Структуру создавайте заново на каждой итерации цикла, проверяйте наличие полей через Свойство(), а для сортировки, свёртки и поиска по нескольким полям переходите на таблицу значений.
Частые вопросы
Можно ли добавить поле в структуру после её создания?
Да, методом Вставить("ИмяКлюча", Значение) структуру можно расширять в любой момент. Однако если массив должен содержать однородные записи, лучше сразу задавать одинаковый набор полей — это упрощает обход и исключает ошибки обращения к отсутствующим ключам.
Как отсортировать массив структур по значению поля?
Встроенной сортировки по полям у массива нет. Варианты: написать собственный алгоритм сравнения с обменом элементов, либо перенести данные в таблицу значений, вызвать Сортировать("ИмяКолонки") и при необходимости обойти результат. Для разовой задачи обычно проще второй путь.
Можно ли передать массив структур в фоновое задание?
Да, массивы и структуры сериализуются платформой и допустимы в параметрах фонового задания, если все значения полей — сериализуемых типов: примитивы, ссылки, даты, вложенные массивы и структуры. Результаты запросов, COM-объекты и подобные объекты передавать нельзя.
Чем структура отличается от соответствия при хранении пар «ключ-значение»?
У структуры ключи — строки-идентификаторы, а доступ возможен через точку, как к свойству. Соответствие допускает ключи любого типа, включая ссылки и числа, но обращение идёт только через квадратные скобки. Для записей с фиксированными именованными полями принято использовать структуру.
Почему все элементы массива показывают одинаковые данные?
Почти всегда причина в том, что структура создана один раз до цикла, а внутри цикла только меняются значения её полей. В массив добавляются ссылки на один и тот же объект. Решение — создавать Новый Структура внутри тела цикла на каждой итерации.
Как проверить, есть ли в массиве структура с нужным значением поля?
Переберите массив циклом Для Каждого с условием по полю и прервите его командой Прервать при первом совпадении. Если таких проверок много, постройте соответствие «значение поля → структура» один раз и проверяйте наличие ключа через соответствие — это заметно быстрее повторных переборов.