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

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

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

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

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

Прямого метода «массив в таблицу» во встроенном языке нет, поэтому преобразование выполняется одним из трёх способов: перебором массива в цикле с добавлением строк, методом ЗагрузитьКолонку() для одноколоночных данных или через временную таблицу в запросе. Выбор зависит от того, что лежит в массиве: простые значения, структуры или ссылки.

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

Создание таблицы значений с нужной структурой колонок

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

ТЗ = Новый ТаблицаЗначений;

ТЗ.Колонки.Добавить("Номенклатура", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));

ТЗ.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 3)));

ТЗ.Колонки.Добавить("Комментарий", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(200)));

Имена колонок должны соответствовать правилам идентификаторов: без пробелов, без начала с цифры. Если имя колонки совпадёт с именем служебного метода (например, «Колонки»), обращение к ней через точку станет невозможным — придётся обращаться через квадратные скобки Строка["Колонки"], что затрудняет чтение кода.

Базовый способ: перебор массива в цикле

Самый универсальный вариант — цикл Для Каждого с добавлением новой строки на каждой итерации. Он работает с любым содержимым массива: примитивами, структурами, ссылками и даже другими массивами.

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

НоваяСтрока = ТЗ.Добавить();

НоваяСтрока.Номенклатура = Элемент;

КонецЦикла;

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

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

НоваяСтрока = ТЗ.Добавить();

ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураСтроки);

КонецЦикла;

Условие корректной работы ЗаполнитьЗначенияСвойств: каждый ключ структуры, который нужно перенести, должен совпадать с именем колонки. Если в структуре есть ключ, которого нет среди колонок, возникнет ошибка «Недопустимое значение свойства» — поэтому либо заранее создавайте все нужные колонки, либо фильтруйте структуру перед заполнением.

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

Быстрый способ для простых значений: ЗагрузитьКолонку

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

ТЗ = Новый ТаблицаЗначений;

ТЗ.Колонки.Добавить("Ссылка", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));

ТЗ.ЗагрузитьКолонку(МассивСсылок, "Ссылка");

Этот способ короче и быстрее цикла на больших объёмах. Обратная операция — ВыгрузитьКолонку("Ссылка") — превращает колонку таблицы обратно в массив, что удобно для передачи списка ссылок в параметр запроса.

Ограничение метода: он заполняет только одну колонку. Если из массива структур нужно разложить данные по нескольким колонкам, ЗагрузитьКолонку не подойдёт — используйте цикл с ЗаполнитьЗначенияСвойств.

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

Цикл Для Каждого + Добавить()

Универсален: подходит для структур, вычисляемых полей и сложной логики. Минус — многословный код.

ЗагрузитьКолонку()

Самый быстрый для массива простых значений в одну колонку. Не работает с многоколоночными данными.

Передача массива в запрос

Оптимален, если цель — отбор в запросе или соединение с данными СУБД. Требует написания текста запроса.

Преобразование через запрос и временную таблицу

Когда массив нужен не сам по себе, а для отбора данных из базы, преобразование в таблицу значений можно совместить с запросом. Массив передаётся в запрос как параметр и разворачивается во временную таблицу конструкцией ВЫБРАТЬ ... ИЗ &Массив — точнее, через помещение таблицы значений или условие В (&Массив).

Типовой сценарий: сначала массив преобразуют в таблицу значений любым способом выше, затем эту таблицу передают параметром в запрос и помещают во временную таблицу для соединения с реальными данными:

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

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

"ВЫБРАТЬ

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

|ПОМЕСТИТЬ ВТ_Товары

|ИЗ &ТЗ КАК Т

|;

|ВЫБРАТЬ

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

| Цены.Цена

|ИЗ ВТ_Товары КАК Товары

| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК Цены

| ПО Товары.Номенклатура = Цены.Номенклатура";

Запрос.УстановитьПараметр("ТЗ", ТЗ);

Результат = Запрос.Выполнить().Выгрузить();

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

Типичные ошибки при преобразовании

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

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

Отдельного внимания заслуживает приведение типов. Если колонка объявлена как СправочникСсылка.Номенклатура, а в массиве оказалась строка с наименованием, значение в ячейке станет пустой ссылкой без какого-либо предупреждения. Перед заполнением стоит проверять тип элемента через ТипЗнч(), если состав массива не гарантирован.

Ещё одна тонкость: метод Добавить() возвращает новую строку, и именно её нужно заполнять. Обращение ТЗ[ТЗ.Количество()-1] после добавления работает, но медленнее и хуже читается.

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

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

Сообщить("Строк в таблице: " + ТЗ.Количество());

Сообщить("Элементов в массиве: " + Массив.Количество());

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

Если Не ЗначениеЗаполнено(СтрокаТЗ.Номенклатура) Тогда

Сообщить("Пустая ссылка в строке " + ТЗ.Индекс(СтрокаТЗ));

КонецЕсли;

КонецЦикла;

Если таблица выводится на форму, дополнительно проверьте, что реквизит формы имеет тип «ТаблицаЗначений» и колонки реквизита совпадают по именам с колонками заполняемой таблицы — иначе данные просто не отобразятся.

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

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

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

ТЗ.Количество() равно числу элементов массива

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

Строк меньше — часть элементов потеряна в цикле или отфильтрована

Заполненность ключевых колонок
Норма

Все ячейки содержат ожидаемые значения нужного типа

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

Пустые ссылки или пустые строки там, где были данные — признак несовпадения типов

Состав колонок
Норма

Имена колонок совпадают с ключами структур или реквизитом формы

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

Данные не отображаются на форме или ЗаполнитьЗначенияСвойств выдаёт ошибку

Ограничения и альтернативы

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

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

Если задача — только отбор по списку значений в запросе, таблицу значений можно вообще не создавать: условие ГДЕ Ссылка В (&Массив) принимает массив напрямую. Преобразование оправдано, когда нужны колонки, сортировка, группировка или вывод на форму.

Итог

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

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

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

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

Нет, отдельного метода для этого во встроенном языке нет. Ближайший вариант — ЗагрузитьКолонку(), который заполняет одну колонку из массива без цикла. Для многоколоночных данных цикл с Добавить() обязателен.

Как перенести массив структур в таблицу значений?

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

Почему после заполнения в ячейках пустые ссылки?

Чаще всего причина в несовпадении типов: колонка типизирована под ссылку, а в массиве лежат строки или значения другого типа. Платформа молча приводит их к пустому значению. Проверьте состав массива через ТипЗнч() до заполнения.

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

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

Что быстрее: цикл с запросом внутри или таблица значений с одним запросом?

Однозначно второй вариант. Запрос в цикле обращается к базе на каждой итерации, тогда как передача таблицы значений параметром и соединение во временной таблице выполняется одним обращением к СУБД и масштабируется на большие объёмы.

Можно ли передать таблицу значений на клиент в управляемой форме?

Можно, но таблица сериализуется целиком при каждом серверном вызове. На больших объёмах это замедляет работу, поэтому тяжёлую обработку выполняйте на сервере, а на клиент возвращайте только результат, необходимый для отображения.