При разработке в 1С часто возникает необходимость сформировать или скопировать данные из объекта Массив в ТаблицаЗначений. Начинающие разработчики нередко сталкиваются с ситуацией, когда цикл добавления строк и функция ЗаполнитьЗначенияСвойств не приносят ожидаемого результата: новая таблица остается пустой или содержащиеся в ней строки не заполняются данными.
Рассмотрим причины возникновения такой проблемы, проанализируем устройство объектов коллекции и разберем проверенные способы решения задачи для разных типов исходных данных.
Выясним причину, по которой стандартный код копирования не производит запись данных:
ТЗ = Новый ТаблицаЗначений;
Для Каждого СтрокаИзМассива Из ИсходныйМассив Цикл
НовСтр = ТЗ.Добавить();
ЗаполнитьЗначенияСвойств(НовСтр, СтрокаИзМассива);
КонецЦикла;
Системная процедура ЗаполнитьЗначенияСвойств копирует значения только между свойствами с совпадающими именами. У объекта ТаблицаЗначений при его создании через Новый ТаблицаЗначений коллекция Колонки совершенно пуста. Следовательно, у добавляемой строки НовСтр еще нет никаких колонок (свойств), куда процедура могла бы записать значения.
Чтобы зафиксировать данные, в приемнике предварительно должны быть созданы соответствующие колонки с необходимыми именами.
Если элементов массива является объект типа СтрокаТаблицыЗначений, это означает, что исходные строки привязаны к своей родительской таблице-владельцу. В 1С получить исходную таблицу можно с помощью метода Владелец().
Способ А. Использование метода Скопировать()
Если необходимо получить новую таблицу значений, содержащую только строки из массива, самый простой и быстрый способ — использовать метод Скопировать() исходной таблицы:
Если ИсходныйМассив.Количество() > 0 Тогда
ИсходнаяТЗ = ИсходныйМассив[0].Владелец();
НоваяТЗ = ИсходнаяТЗ.Скопировать(ИсходныйМассив);
КонецЕсли;
Способ Б. Копирование структуры колонок
Если требуется скопировать колонки и затем поочередно обработать или добавить строки:
Если ИсходныйМассив.Количество() > 0 Тогда
ИсходнаяТЗ = ИсходныйМассив[0].Владелец();
НоваяТЗ = ИсходнаяТЗ.СкопироватьКолонки();
Для Каждого СтрокаИзМассива Из ИсходныйМассив Цикл
НоваяСтрока = НоваяТЗ.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаИзМассива);
КонецЦикла;
КонецЕсли;
При передаче данных между клиентом и сервером или при работе с веб-сервисами часто используется массив структур. Попытка обойти СтрокаТаблицыЗначений в цикле как парную коллекцию КлючИЗначение приведет к ошибке «Поле объекта не обнаружено (Ключ)», однако для элементов типа Структура данный подход работает корректно.
Рассмотрим универсальные функции для двустороннего преобразования массива структур в таблицу значений и наоборот.
Преобразование массива структур в ТаблицуЗначений:
Функция ПреобразоватьМассивВТаблицуЗначений(мсДанные) Экспорт
тзДанные = Новый ТаблицаЗначений;
Для Каждого ЭлементМассива Из мсДанные Цикл
// Формируем колонки по ключам первой структуры
Если тзДанные.Колонки.Количество() = 0 Тогда
Для Каждого ЗначениеСтруктуры Из ЭлементМассива Цикл
тзДанные.Колонки.Добавить(ЗначениеСтруктуры.Ключ);
КонецЦикла;
КонецЕсли;
// Заполняем новую строку данными
НоваяСтрока = тзДанные.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, ЭлементМассива);
КонецЦикла;
Возврат тзДанные;
КонецФункции
Преобразование ТаблицыЗначений в массив структур:
Функция ПреобразоватьТаблицуЗначенийВМассив(тзДанные) Экспорт
мсДанные = Новый Массив;
Для Каждого СтрокаТЗ Из тзДанные Цикл
стСтрокаТаблицы = Новый Структура;
Для Каждого Колонка Из тзДанные.Колонки Цикл
стСтрокаТаблицы.Вставить(Колонка.Имя, СтрокаТЗ[Колонка.Имя]);
КонецЦикла;
мсДанные.Добавить(стСтрокаТаблицы);
КонецЦикла;
Возврат мсДанные;
КонецФункции
Если исходный массив содержит примитивные значения (например, строки или числа) и их требуется поместить в конкретную колонку таблицы значений, разберем следующий алгоритм:
ТаблицаЗначений.ТЗ.Колонки.Добавить("ИмяКолонки").ЗагрузитьКолонку().
ИсходныйМассив = Новый Массив;
ИсходныйМассив.Добавить("Значение 1");
ИсходныйМассив.Добавить("Значение 2");
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("МояКолонка");
Для Каждого Элемент Из ИсходныйМассив Цикл
ТЗ.Добавить();
КонецЦикла;
ТЗ.ЗагрузитьКолонку(ИсходныйМассив, "МояКолонка");
Для успешного переноса данных всегда учитывайте тип элементов в исходном массиве:
СтрокаТаблицыЗначений, используйте метод Владелец().Скопировать(Массив).Структура, создавайте колонки по ключам структуры перед вызовом ЗаполнитьЗначенияСвойств.ЗагрузитьКолонку() предварительно создав нужную колонку и строки.