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

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

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

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

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

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

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

Любой способ добавления начинается с подготовки таблицы: нужно создать объект и описать колонки с типами. Если тип колонки не задан или задан неверно, при загрузке массива значения будут приведены к нежелательному типу либо возникнет ошибка преобразования.

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

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

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

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

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

Загрузка массива как колонки через ЗагрузитьКолонку

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

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

МассивТоваров.Добавить(Справочники.Номенклатура.НайтиПоКоду("0000001"));

МассивТоваров.Добавить(Справочники.Номенклатура.НайтиПоКоду("0000002"));

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

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

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

bsl
ТЗ.Очистить();
ТЗ.ЗагрузитьКолонку(МассивТоваров, "Номенклатура");
// Проверка: количество строк должно совпасть с размером массива
Если ТЗ.Количество() <> МассивТоваров.Количество() Тогда
    ВызватьИсключение "Размеры не совпадают";
КонецЕсли;

Построчное добавление элементов массива через цикл

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

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

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

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

НоваяСтрока.Количество = 1;

НоваяСтрока.Комментарий = "Добавлено из массива";

КонецЦикла;

Если элементы массива — структуры или соответствия (типичный случай после разбора JSON или строки файла), значения берутся из свойств элемента. Перед присваиванием полезно проверять наличие свойства, потому что обращение к отсутствующему свойству структуры вызывает исключение.

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

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

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

НоваяСтрока.Количество = Элемент.Количество;

КонецЕсли;

КонецЦикла;

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

Размещение массива в одной ячейке таблицы

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

ТЗ.Колонки.Добавить("СвязанныеДокументы"); // без ограничения типа

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

НоваяСтрока.СвязанныеДокументы = МассивДокументов;

У этого приёма есть ограничения. Такую колонку нельзя передать в запрос как параметр таблицы значений для соединения — запрос не умеет работать с массивами внутри ячеек. Сортировка и свёртка по этой колонке также бессмысленны. Используйте вложенный массив только как транспорт внутри одного алгоритма, а для постоянного хранения и выборок раскладывайте данные по строкам.

Добавление массива как одной строки таблицы

Обратная задача: элементы массива должны стать значениями колонок одной строки — например, массив получен разбором строки CSV через СтрРазделить(). Здесь порядок элементов массива жёстко привязан к порядку колонок, и заполнение идёт по индексу.

Части = СтрРазделить(СтрокаФайла, ";");

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

НоваяСтрока.Номенклатура = Справочники.Номенклатура.НайтиПоКоду(Части[0]);

НоваяСтрока.Количество = Число(Части[1]);

НоваяСтрока.Комментарий = Части[2];

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

Сравнение способов и выбор под задачу

Выбор метода зависит от формы исходных данных и того, что должно получиться на выходе. Краткая ориентировка:

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

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

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

Цикл с Добавить()

Нужно заполнить несколько колонок или обработать каждый элемент. Универсально, чуть больше кода.

Массив в ячейке

Список нужно хранить как единое целое внутри строки. Не совместим с запросами и свёрткой.

Массив как строка по индексам

Разбор строк файлов и CSV. Требует строгого порядка колонок и проверки размера массива.

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

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

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

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

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

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

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

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

Строк больше или меньше — остались старые данные или массив не полон

Типы значений
Норма

Ссылки остаются ссылками, числа — числами

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

Ссылки превратились в строки — колонка объявлена строковой

Ключевые колонки
Норма

Нет пустых значений в обязательных полях

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

Пустые ячейки — элементы массива не соответствуют колонкам

Наиболее частые ошибки при этой задаче собраны ниже — почти каждая встречается в реальных доработках.

Типичные ошибки
01
Вызов ЗагрузитьКолонку для несуществующей колонки — исключение «Колонка не найдена». Сначала добавьте колонку.
02
Загрузка в таблицу со старыми строками без Очистить() — данные смешиваются, строки дублируются.
03
Несовпадение типов: загрузка строк в колонку ссылочного типа даёт пустые значения без явной ошибки.
04
Обращение к элементу массива по индексу без проверки размера — обрыв обработки на «битой» строке файла.
05
Передача таблицы с массивами в ячейках в запрос — ошибка неверного типа параметра.

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

Итог

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

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

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

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

Да, если массив должен стать одной колонкой — используйте ТЗ.ЗагрузитьКолонку(Массив, "ИмяКолонки"). Для заполнения нескольких колонок одной командой штатного метода нет, потребуется цикл.

Почему после ЗагрузитьКолонку в таблице оказалось больше строк, чем в массиве?

Метод не удаляет существующие строки: если таблица уже содержала данные, а массив короче, «лишние» старые строки остаются. Вызовите ТЗ.Очистить() перед загрузкой, если прежние данные не нужны.

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

Обходите массив циклом, создавайте строку через ТЗ.Добавить() и присваивайте поля из свойств структуры, предварительно проверяя их наличие методом Свойство(). Альтернатива — обработка через JSON с чтением в соответствие, но цикл остаётся самым прозрачным вариантом.

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

Нет. Запрос требует, чтобы колонки таблицы-параметра имели допустимые для СУБД типы. Вложенный массив нужно предварительно развернуть в отдельные строки таблицы.

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

У реквизита формы типа «ТаблицаЗначений» нет метода ЗагрузитьКолонку. Либо заполняйте коллекцию циклом с Добавить(), либо преобразуйте реквизит в объект ТаблицаЗначений через РеквизитФормыВЗначение(), выполните загрузку и верните данные через ЗначениеВРеквизитФормы().

Что быстрее: ЗагрузитьКолонку или цикл с Добавить()?

На типовых объёмах разница практически незаметна. ЗагрузитьКолонку короче в записи, цикл гибче. Реальный прирост производительности даёт замена всей связки «массив → таблица» на прямую выгрузку результата запроса, если данные изначально лежат в базе.