В процессе разработки часто возникает задача трансформации данных из одной структуры в другую. Одной из классических ситуаций является перенос данных из двухмерного массива (или массива массивов), полученного, например, при чтении файла Excel, в объект ТаблицаЗначений. Несмотря на кажущуюся простоту, здесь легко допустить логическую ошибку, которая приведет к избыточному количеству строк или некорректному заполнению ячеек.
В этой статье мы разберем, как правильно реализовать этот переход, проанализируем типичные ошибки начинающих разработчиков и рассмотрим наиболее производительные методы платформы 1С.
Рассмотрим ситуацию: у нас есть массив, содержащий 4 вложенных массива, в каждом из которых находится по 31 элементу (представим это как 4 колонки и 31 строку данных). Наша задача — программно создать ТаблицаЗначений с соответствующей структурой и заполнить её этими данными.
Типичная ошибка заключается в попытке добавлять строки внутри цикла по колонкам. Проанализируем, к чему это приводит: если мы в цикле по каждой из 4 колонок будем добавлять по 31 строке, в итоге мы получим таблицу из 124 строк (4 * 31), где данные будут распределены «лесенкой» или дублироваться, вместо ожидаемых 31 строки.
Для того чтобы эффективно заполнить таблицу значений из массива массивов, необходимо четко разделить процесс на три этапа: подготовка объекта, создание нужного количества пустых строк и наполнение данными каждой колонки. Выясним причину, почему такой подход является оптимальным: метод ЗагрузитьКолонку работает пакетно на уровне платформы, что значительно быстрее, чем построчный обход в цикле.
Разберем по шагам правильную реализацию:
ТаблицаЗначений.Добавить().Рассмотрим пример кода, который решает эту задачу:
// Предположим, что "Данные" — это массив массивов (Данные[ИндексКолонки][ИндексСтроки])
ТаблицаЗначенийИзЭксель = Новый ТаблицаЗначений;
// Шаг 1: Создаем пустые строки в таблице значений.
// Количество итераций соответствует количеству элементов во вложенном массиве (количество будущих строк).
Для Индекс = 0 По Данные[0].ВГраница() Цикл
ТаблицаЗначенийИзЭксель.Добавить();
КонецЦикла;
// Шаг 2: Добавляем колонки и заполняем их данными из массива.
Для Счет = 0 по Данные.ВГраница() Цикл
ИмяКолонки = "Колонка" + Строка(Счет);
ТаблицаЗначенийИзЭксель.Колонки.Добавить(ИмяКолонки);
// Метод ЗагрузитьКолонку заполняет созданную колонку значениями из массива Данные[Счет]
ТаблицаЗначенийИзЭксель.ЗагрузитьКолонку(Данные[Счет], ИмяКолонки);
КонецЦикла;
При использовании метода ЗагрузитьКолонку крайне важно помнить о соответствии размерностей. Если количество элементов в передаваемом массиве меньше, чем количество строк в ТаблицаЗначений, то оставшиеся строки в данной колонке будут очищены (установлено значение Неопределено или по умолчанию для типа). Если элементов в массиве больше — возникнет ошибка времени выполнения.
Рекомендация по типизации: В приведенном выше примере колонки создаются без указания типа. Для повышения стабильности работы программы, особенно если данные далее будут выгружаться в ТабличнаяЧасть документа, рекомендуется указывать ОписаниеТипов при вызове метода Добавить() для коллекции Колонки.
Проанализируем ситуацию, когда необходимо задать типы данных:
МассивТиповЧисло = Новый Массив;
МассивТиповЧисло.Добавить(Тип("Число"));
ОписаниеТипаЧисло = Новый ОписаниеТипов(МассивТиповЧисло);
// При добавлении колонки указываем описание типов
ТаблицаЗначенийИзЭксель.Колонки.Добавить(ИмяКолонки, ОписаниеТипаЧисло);
Если структура вашего массива иная (например, массив содержит строки, где каждая строка — это отдельный массив значений), то метод ЗагрузитьКолонку не подойдет. В таком случае мы используем классический обход вложенными циклами.
Посмотрим на пример такого кода:
// Вариант, когда Данные[ИндексСтроки][ИндексКолонки]
Для Каждого МассивСтроки Из Данные Цикл
НоваяСтрока = ТаблицаЗначений.Добавить();
Для ИндексКол = 0 По МассивСтроки.ВГраница() Цикл
НоваяСтрока[ИндексКол] = МассивСтроки[ИндексКол];
КонецЦикла;
КонецЦикла;
Хотя этот метод кажется более привычным, он уступает в производительности методу ЗагрузитьКолонку при работе с большими объемами данных. Поэтому, если у вас есть возможность подготовить массив данных «поколоночно», всегда отдавайте предпочтение первому варианту.
Если ваша конечная цель — загрузка данных из Excel, стоит рассмотреть возможность использования объекта ТабличныйДокумент. Метод Прочитать() этого объекта позволяет загрузить файл напрямую, после чего данные можно перенести в ТаблицаЗначений, обращаясь к ячейкам через метод Область(). Это избавит вас от необходимости строить промежуточные многомерные массивы и сэкономит оперативную память сервера или клиентского приложения.
Таким образом, мы выяснили, что ключ к правильному заполнению таблицы значений из массива — это строгое соблюдение последовательности действий: сначала формирование «скелета» таблицы (строк), а затем направленное заполнение данными (колонок). Это исключает логические ошибки с размерностью и обеспечивает высокую скорость обработки данных.