Разработка и Конфигурация · 10 мин
Как добавить структуру в массив 1С
Как добавить структуру в массив 1С: метод Добавить(), обход коллекции, передача через параметры, сериализация в JSON, типичные ошибки и проверка результата.
Задача добавить структуру в массив возникает в 1С постоянно: при сборе строк табличной части для передачи в процедуру, при подготовке данных для HTTP-запроса, при формировании списка параметров отчёта. Механика простая — метод Добавить() помещает структуру как элемент массива, — но вокруг неё есть нюансы: структура передаётся по ссылке, ключи нельзя менять после создания, а при обмене данными массив структур нужно правильно сериализовать.
Ниже разобраны рабочие приёмы: создание и заполнение массива структур, обход и поиск, передача между клиентом и сервером, преобразование в JSON и обратно, а также типичные ошибки, из-за которых код падает или возвращает не те данные.
Базовый синтаксис: как создать массив и добавить структуру
Массив в 1С — универсальная коллекция, элементами которой могут быть значения любых типов, включая структуры. Создаётся массив конструктором Новый Массив, структура — конструктором Новый Структура. Добавление выполняется методом Добавить(), который помещает элемент в конец массива и возвращает добавленный элемент.
МассивТоваров = Новый Массив;
СтрокаТовара = Новый Структура;
СтрокаТовара.Вставить("Номенклатура", ТоварСсылка);
СтрокаТовара.Вставить("Количество", 5);
СтрокаТовара.Вставить("Цена", 1200);
МассивТоваров.Добавить(СтрокаТовара);
Тот же результат короче — ключи и значения можно задать прямо в конструкторе. Первый параметр — строка с именами ключей через запятую, дальше идут значения в том же порядке:
СтрокаТовара = Новый Структура("Номенклатура, Количество, Цена", ТоварСсылка, 5, 1200);
МассивТоваров.Добавить(СтрокаТовара);
Заполнение массива структурами в цикле
Самый частый сценарий — собрать данные из выборки запроса или табличной части в массив структур, чтобы передать их дальше одним параметром. Внутри цикла на каждой итерации создаётся новая структура и добавляется в массив.
Функция ПолучитьТоварыДокумента(ДокументСсылка) Экспорт
Результат = Новый Массив;
Для Каждого СтрокаТЧ Из ДокументСсылка.Товары Цикл
Элемент = Новый Структура;
Элемент.Вставить("Номенклатура", СтрокаТЧ.Номенклатура);
Элемент.Вставить("Количество", СтрокаТЧ.Количество);
Элемент.Вставить("Сумма", СтрокаТЧ.Сумма);
Результат.Добавить(Элемент);
КонецЦикла;
Возврат Результат;
КонецФункции
Критически важно создавать новую структуру на каждой итерации. Если объявить структуру один раз до цикла и только менять значения, в массиве окажется несколько ссылок на один и тот же объект — все элементы будут содержать данные последней итерации. Это одна из самых коварных ошибок, потому что код выполняется без исключений, просто результат неверный.
Если структура нужна фиксированного состава, удобно вынести её создание в отдельную функцию-конструктор. Это гарантирует одинаковый набор ключей у всех элементов массива:
Функция НоваяСтрокаТовара()
Возврат Новый Структура("Номенклатура, Количество, Сумма", Неопределено, 0, 0);
КонецФункции
Обход массива и чтение данных из структур
Обход выполняется циклом Для Каждого. Каждый элемент — структура, значения читаются через точку или методом Свойство(). Второй вариант безопаснее, если не уверены, что ключ существует: он возвращает Истина при наличии ключа и записывает значение в переменную, переданную вторым параметром.
Для Каждого Элемент Из МассивТоваров Цикл
Сумма = 0;
Если Элемент.Свойство("Сумма", Сумма) Тогда
ОбщаяСумма = ОбщаяСумма + Сумма;
КонецЕсли;
КонецЦикла;
Для поиска нужного элемента в массиве структур встроенного метода нет — ищите перебором с прерыванием по Прервать. Если поиск по ключу выполняется часто и массив большой, лучше на этапе проектирования заменить массив на соответствие, где ключом будет искомое значение, а значением — структура: поиск в соответствии работает быстрее линейного перебора.
НайденнаяСтрока = Неопределено;
Для Каждого Элемент Из МассивТоваров Цикл
Если Элемент.Номенклатура = ИскомыйТовар Тогда
НайденнаяСтрока = Элемент;
Прервать;
КонецЕсли;
КонецЦикла;
Передача массива структур между клиентом и сервером
Массив и структура доступны и на тонком клиенте, и на сервере, поэтому массив структур свободно передаётся в серверные вызовы и возвращается из них. Это стандартный способ передать пакет однотипных данных без создания временной таблицы значений.
Ограничения появляются в двух местах. Первое — в структуре нельзя хранить мутабельные объекты, недоступные на другой стороне (например, ссылки допустимы, а вот объекты типа ДокументОбъект при передаче сериализуются не всегда так, как ожидается). Второе — если данные нужны в форме между вызовами, массив структур нельзя напрямую сделать реквизитом формы: его конвертируют в таблицу значений формы или хранят во временном хранилище.
Сериализация массива структур в JSON
При обмене с внешними сервисами массив структур преобразуется в JSON штатными средствами платформы — через ЗаписьJSON с ЗаписатьЗначениеJSON(). Ключи структуры становятся именами полей JSON, массив — JSON-массивом объектов.
Запись = Новый ЗаписьJSON;
Запись.УстановитьСтроку();
ЗаписатьJSON(Запись, МассивТоваров);
СтрокаJSON = Запись.Закрыть();
При обратном чтении через ПрочитатьJSON() с флагом ПрочитатьВСоответствие = Ложь объекты JSON превращаются именно в структуры, а массив объектов — в массив структур. Учтите, что даты и ссылки в JSON не восстанавливаются автоматически: дату придётся парсить из строки, ссылку — искать по переданному идентификатору.
Если массив структур собирается только для отправки в JSON, заранее согласуйте имена ключей с контрактом API: переименовать ключ в существующей структуре нельзя, придётся пересоздавать все элементы. Удобно держать имена ключей в одной функции-конструкторе.
Альтернативы: когда массив структур — не лучший выбор
Массив структур хорош для небольших однотипных наборов данных, передаваемых между процедурами. Но в ряде случаев другие коллекции подходят лучше, и выбор стоит делать осознанно.
Сравнение вариантов
Передача параметров, обмен JSON, небольшие наборы. Ограничение: только линейный поиск, нет типизации колонок
Нужны сортировка, свёртка, итоги, поиск по индексам, выгрузка в запрос. Тяжелее, не передаётся с клиента на сервер в обе стороны без ограничений
Нужен быстрый поиск по произвольному ключу. Значением может быть структура. Нет гарантированного порядка обхода
Нужно показать данные пользователю для выбора или пометки. Избыточен для внутренней передачи данных
Если данные потом уйдут в запрос или понадобится группировка и итоги — сразу собирайте таблицу значений, а не конвертируйте массив структур постфактум. Если нужен только поиск по ключу — соответствие структур избавит от перебора.
Проверка результата и отладка
Убедиться, что массив заполнен правильно, проще всего в отладчике: поставьте точку останова после цикла и посмотрите содержимое массива в табло — платформа покажет вложенные структуры и их ключи. Проверяйте три вещи: количество элементов совпадает с ожидаемым, у каждого элемента полный набор ключей, значения соответствуют разным строкам источника, а не дублируют последнюю.
Как проверить результат
Равно числу обработанных строк источника
Меньше или больше — проверяйте условия внутри цикла и Добавить()
Каждый элемент содержит данные своей строки
Все элементы одинаковые — структура создана вне цикла
У всех элементов одинаковые ключи
Ключи различаются — обращение по отсутствующему ключу вызовет ошибку
В продуктивном коде без отладчика полезно временно выводить контрольные значения через Сообщить() или в журнал регистрации. Для массивов структур удобно сериализовать массив в JSON и вывести строку целиком — так видно и структуру, и данные одним снимком.
Что важно запомнить
Структура добавляется в массив методом Добавить(). В цикле создавайте новую структуру на каждой итерации — иначе все элементы будут ссылаться на один объект. Набор ключей структуры фиксируется при создании. Для обмена с внешними системами массив структур сериализуется в JSON штатными средствами платформы.
Частые вопросы
Как добавить структуру в начало массива, а не в конец?
Используйте метод Вставить(0, Структура) — он вставляет элемент по указанному индексу, сдвигая остальные. Метод Добавить() всегда помещает элемент в конец.
Можно ли изменить структуру после добавления в массив?
Да, значения существующих ключей меняются свободно, и изменения видны через массив, так как хранится ссылка. Но добавить новый ключ нельзя — набор ключей фиксируется в момент создания структуры.
Как скопировать структуру, чтобы изменения не затрагивали элемент массива?
Штатного метода копирования у структуры нет. Создайте новую структуру и перенесите значения перебором: Для Каждого КлючЗначение Из Исходная Цикл Новая.Вставить(КлючЗначение.Ключ, КлючЗначение.Значение) КонецЦикла. Это поверхностная копия — вложенные коллекции останутся общими.
Чем отличается структура от соответствия при работе в массиве?
У структуры фиксированный набор ключей и обращение через точку, у соответствия ключи добавляются и удаляются в любой момент, а обращение идёт через квадратные скобки. Для однотипных элементов массива обычно удобнее структура, для словаря с динамическими ключами — соответствие.
Можно ли передать массив структур в фоновое задание?
Да, массивы и структуры сериализуются при передаче в параметры фонового задания. Ограничение — значения внутри структур тоже должны быть сериализуемыми: ссылки, примитивы, даты и вложенные коллекции подходят, а объекты вроде ДокументОбъект — нет.
Как удалить из массива структуру по условию?
Найдите индекс элемента перебором и вызовите Массив.Удалить(Индекс). Удалять элементы внутри прямого цикла Для Каждого нельзя — обходите массив по индексам с конца или соберите индексы для удаления в отдельный список.