Разработка и Конфигурация · 11 мин
Как преобразовать массив в таблицу значений в 1С
Практическое руководство: как преобразовать массив в таблицу значений в 1С через цикл, ЗагрузитьКолонку и запрос. Примеры кода, ошибки и проверка результата.
Массив в 1С удобен для временного хранения однотипных данных, но он не поддерживает сортировку, поиск по колонкам, свёртку и вывод в табличное поле формы. Как только данные нужно показать пользователю, отфильтровать или передать в запрос, массив преобразуют в таблицу значений — универсальный объект с именованными колонками и типизированными ячейками.
Прямого метода «массив в таблицу» во встроенном языке нет, поэтому преобразование выполняется одним из трёх способов: перебором массива в цикле с добавлением строк, методом ЗагрузитьКолонку() для одноколоночных данных или через временную таблицу в запросе. Выбор зависит от того, что лежит в массиве: простые значения, структуры или ссылки.
Ниже разобраны все три подхода с готовым кодом, типичными ошибками типизации и способами проверить, что таблица заполнилась корректно.
Создание таблицы значений с нужной структурой колонок
Перед заполнением таблицу нужно объявить и описать её колонки. Колонки добавляются методом Колонки.Добавить() с указанием имени, типа и, при необходимости, заголовка. Тип задаётся объектом ОписаниеТипов — это важно, потому что без явной типизации колонка примет любые значения, что позже вызовет ошибки при сортировке, свёртке и выгрузке.
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Номенклатура", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));
ТЗ.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 3)));
ТЗ.Колонки.Добавить("Комментарий", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(200)));
Имена колонок должны соответствовать правилам идентификаторов: без пробелов, без начала с цифры. Если имя колонки совпадёт с именем служебного метода (например, «Колонки»), обращение к ней через точку станет невозможным — придётся обращаться через квадратные скобки Строка["Колонки"], что затрудняет чтение кода.
Базовый способ: перебор массива в цикле
Самый универсальный вариант — цикл Для Каждого с добавлением новой строки на каждой итерации. Он работает с любым содержимым массива: примитивами, структурами, ссылками и даже другими массивами.
Для Каждого Элемент Из МассивТоваров Цикл
НоваяСтрока = ТЗ.Добавить();
НоваяСтрока.Номенклатура = Элемент;
КонецЦикла;
Если массив содержит структуры, поля распределяются по колонкам по именам. Здесь удобен метод ЗаполнитьЗначенияСвойств() — он копирует значения из структуры в строку таблицы по совпадающим именам и игнорирует лишние ключи структуры:
Для Каждого СтруктураСтроки Из МассивСтруктур Цикл
НоваяСтрока = ТЗ.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураСтроки);
КонецЦикла;
Условие корректной работы ЗаполнитьЗначенияСвойств: каждый ключ структуры, который нужно перенести, должен совпадать с именем колонки. Если в структуре есть ключ, которого нет среди колонок, возникнет ошибка «Недопустимое значение свойства» — поэтому либо заранее создавайте все нужные колонки, либо фильтруйте структуру перед заполнением.
- 1Создайте таблицу: ТЗ = Новый ТаблицаЗначений
- 2Опишите колонки через Колонки.Добавить() с типами
- 3Переберите массив циклом Для Каждого
- 4На каждой итерации вызовите ТЗ.Добавить() и заполните поля строки
- 5Проверьте результат: ТЗ.Количество() должно равняться Массив.Количество()
Быстрый способ для простых значений: ЗагрузитьКолонку
Если массив содержит однотипные простые значения (числа, строки, ссылки) и нужна таблица с одной заполненной колонкой, цикл не требуется. Метод ЗагрузитьКолонку() принимает массив и имя колонки, создаёт столько строк, сколько элементов в массиве, и заполняет указанную колонку:
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Ссылка", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));
ТЗ.ЗагрузитьКолонку(МассивСсылок, "Ссылка");
Этот способ короче и быстрее цикла на больших объёмах. Обратная операция — ВыгрузитьКолонку("Ссылка") — превращает колонку таблицы обратно в массив, что удобно для передачи списка ссылок в параметр запроса.
Ограничение метода: он заполняет только одну колонку. Если из массива структур нужно разложить данные по нескольким колонкам, ЗагрузитьКолонку не подойдёт — используйте цикл с ЗаполнитьЗначенияСвойств.
Сравнение вариантов
Универсален: подходит для структур, вычисляемых полей и сложной логики. Минус — многословный код.
Самый быстрый для массива простых значений в одну колонку. Не работает с многоколоночными данными.
Оптимален, если цель — отбор в запросе или соединение с данными СУБД. Требует написания текста запроса.
Преобразование через запрос и временную таблицу
Когда массив нужен не сам по себе, а для отбора данных из базы, преобразование в таблицу значений можно совместить с запросом. Массив передаётся в запрос как параметр и разворачивается во временную таблицу конструкцией ВЫБРАТЬ ... ИЗ &Массив — точнее, через помещение таблицы значений или условие В (&Массив).
Типовой сценарий: сначала массив преобразуют в таблицу значений любым способом выше, затем эту таблицу передают параметром в запрос и помещают во временную таблицу для соединения с реальными данными:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Т.Номенклатура КАК Номенклатура
|ПОМЕСТИТЬ ВТ_Товары
|ИЗ &ТЗ КАК Т
|;
|ВЫБРАТЬ
| Товары.Номенклатура,
| Цены.Цена
|ИЗ ВТ_Товары КАК Товары
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК Цены
| ПО Товары.Номенклатура = Цены.Номенклатура";
Запрос.УстановитьПараметр("ТЗ", ТЗ);
Результат = Запрос.Выполнить().Выгрузить();
Такой подход выигрывает, когда по списку из массива нужно получить связанные данные (цены, остатки, реквизиты) одним обращением к базе вместо обхода в цикле с точечными запросами. Соединение с реальными таблицами в запросе выполняется на стороне СУБД и работает заметно быстрее перебора.
Типичные ошибки при преобразовании
Большинство проблем при переносе массива в таблицу связаны не с синтаксисом, а с типами и структурой данных. Ниже — ошибки, которые встречаются чаще всего.
Отдельного внимания заслуживает приведение типов. Если колонка объявлена как СправочникСсылка.Номенклатура, а в массиве оказалась строка с наименованием, значение в ячейке станет пустой ссылкой без какого-либо предупреждения. Перед заполнением стоит проверять тип элемента через ТипЗнч(), если состав массива не гарантирован.
Ещё одна тонкость: метод Добавить() возвращает новую строку, и именно её нужно заполнять. Обращение ТЗ[ТЗ.Количество()-1] после добавления работает, но медленнее и хуже читается.
Как проверить результат преобразования
После заполнения таблицы убедитесь, что данные перенеслись полностью и без искажений. Минимальный набор проверок занимает несколько строк кода и выполняется в отладчике или через Сообщить().
Сообщить("Строк в таблице: " + ТЗ.Количество());
Сообщить("Элементов в массиве: " + Массив.Количество());
Для Каждого СтрокаТЗ Из ТЗ Цикл
Если Не ЗначениеЗаполнено(СтрокаТЗ.Номенклатура) Тогда
Сообщить("Пустая ссылка в строке " + ТЗ.Индекс(СтрокаТЗ));
КонецЕсли;
КонецЦикла;
Если таблица выводится на форму, дополнительно проверьте, что реквизит формы имеет тип «ТаблицаЗначений» и колонки реквизита совпадают по именам с колонками заполняемой таблицы — иначе данные просто не отобразятся.
Как проверить результат
ТЗ.Количество() равно числу элементов массива
Строк меньше — часть элементов потеряна в цикле или отфильтрована
Все ячейки содержат ожидаемые значения нужного типа
Пустые ссылки или пустые строки там, где были данные — признак несовпадения типов
Имена колонок совпадают с ключами структур или реквизитом формы
Данные не отображаются на форме или ЗаполнитьЗначенияСвойств выдаёт ошибку
Ограничения и альтернативы
Таблица значений существует только в памяти сеанса: она не сохраняется в базе данных и не передаётся между сеансами. Если результат нужен постоянно, итоговую таблицу записывают в регистр сведений, документ с табличной частью или сериализуют через ЗначениеВСтрокуВнутр() для хранения в хранилище значения.
При передаче таблицы между клиентом и сервером в управляемых формах помните: таблица значений сериализуется целиком, и на больших объёмах (десятки тысяч строк) вызовы сервера замедляются. В таких случаях данные лучше формировать и обрабатывать полностью на сервере, а на клиент возвращать только итог.
Если задача — только отбор по списку значений в запросе, таблицу значений можно вообще не создавать: условие ГДЕ Ссылка В (&Массив) принимает массив напрямую. Преобразование оправдано, когда нужны колонки, сортировка, группировка или вывод на форму.
Что важно запомнить
Массив преобразуется в таблицу значений циклом с Добавить() для любых данных или ЗагрузитьКолонку() для простых значений в одну колонку. Всегда типизируйте колонки, проверяйте совпадение имён ключей структур и колонок, а для выборки связанных данных передавайте таблицу параметром в запрос вместо обращений к базе в цикле.
Частые вопросы
Можно ли преобразовать массив в таблицу значений одной командой?
Нет, отдельного метода для этого во встроенном языке нет. Ближайший вариант — ЗагрузитьКолонку(), который заполняет одну колонку из массива без цикла. Для многоколоночных данных цикл с Добавить() обязателен.
Как перенести массив структур в таблицу значений?
Создайте колонки с именами, совпадающими с ключами структур, затем в цикле вызывайте ТЗ.Добавить() и ЗаполнитьЗначенияСвойств(НоваяСтрока, Структура). Ключи структуры без одноимённых колонок вызовут ошибку, поэтому лишние ключи нужно исключить заранее.
Почему после заполнения в ячейках пустые ссылки?
Чаще всего причина в несовпадении типов: колонка типизирована под ссылку, а в массиве лежат строки или значения другого типа. Платформа молча приводит их к пустому значению. Проверьте состав массива через ТипЗнч() до заполнения.
Как получить массив обратно из таблицы значений?
Используйте метод ВыгрузитьКолонку("ИмяКолонки") — он возвращает массив значений указанной колонки. Для полного снимка строк можно обойти таблицу циклом и собрать массив структур вручную.
Что быстрее: цикл с запросом внутри или таблица значений с одним запросом?
Однозначно второй вариант. Запрос в цикле обращается к базе на каждой итерации, тогда как передача таблицы значений параметром и соединение во временной таблице выполняется одним обращением к СУБД и масштабируется на большие объёмы.
Можно ли передать таблицу значений на клиент в управляемой форме?
Можно, но таблица сериализуется целиком при каждом серверном вызове. На больших объёмах это замедляет работу, поэтому тяжёлую обработку выполняйте на сервере, а на клиент возвращайте только результат, необходимый для отображения.