Как получить массив данных из табличного документа без обхода каждой ячейки

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Метод 1: Использование Построителя отчета для конвертации в таблицу значений

Это самый быстрый и эффективный способ «превратить» ТабличныйДокумент в ТаблицаЗначений. Основная идея заключается в том, что платформа умеет рассматривать область ячеек как источник данных. Мы проанализируем, как работает связка объектов ОписаниеИсточникаДанных и ПостроительОтчета.

Рассмотрим пример кода, который позволяет выполнить это преобразование:


Функция ПреобразоватьТабличныйДокументВТаблицуЗначений(Знач ТабДок) Экспорт
    
    ПоследняяСтрока = ТабДок.ВысотаТаблицы;
    ПоследняяКолонка = ТабДок.ШиринаТаблицы;
    
    // Выделяем всю заполненную область документа
    ОбластьЯчеек = ТабДок.Область(1, 1, ПоследняяСтрока, ПоследняяКолонка); 
    
    // Создаем описание источника на основании области
    ИсточникДанных = Новый ОписаниеИсточникаДанных(ОбластьЯчеек);  
    
    // Используем построитель для выгрузки данных
    ПостроительОтчета = Новый ПостроительОтчета; 
    ПостроительОтчета.ИсточникДанных = ИсточникДанных;
    ПостроительОтчета.Выполнить();
    
    // Получаем готовую таблицу значений
    ТЗ = ПостроительОтчета.Результат.Выгрузить();
    
    Возврат ТЗ;
    
КонецФункции

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

Метод 2: Получение массива строк через НайтиСтроки

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


// Добавим вспомогательную колонку, если нужно выбрать все строки
ТЗ.Колонки.Добавить("Вспомогательная");
// Создаем пустой отбор, который вернет все строки
МассивСтрок = ТЗ.НайтиСтроки(Новый Структура("Вспомогательная", Неопределено));

Однако стоит помнить, что объекты типа СтрокаТаблицыЗначений не могут быть переданы с сервера на клиент. В этом случае нам все равно придется сформировать массив простых структур или значений.

Метод 3: Оптимизация через промежуточные форматы (CSV/Текст)

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

Алгоритм действий выглядит следующим образом:

  1. Сохраняем ТабличныйДокумент во временный файл формата .txt или .csv с помощью метода Записать().
  2. Используем объект ЧтениеТекста для потокового чтения данных.
  3. Разбираем строки текста и помещаем их в массив.

Такой способ работает крайне быстро, так как платформа выполняет выгрузку данных в файл на низком уровне, минуя тяжеловесные объекты ОбластьЯчеек.

Почему прямой обход ячеек считается медленным?

Выясним причину, по которой классический цикл Для по ВысотаТаблицы часто критикуют. Проблема не в самом цикле, а в обращении к ячейкам через метод Область(). Каждый раз, когда вы вызываете ТабДок.Область(Ряд, Колонка), платформа создает в памяти новый объект типа «Область», который содержит в себе множество свойств (шрифт, цвет, рамки, текст, значение и т.д.). Создание и уничтожение тысяч таких объектов создает колоссальную нагрузку на процессор и память.

Практический совет: Если вы все же вынуждены использовать обход в цикле, старайтесь минимизировать количество обращений к свойствам. Например, чтение Ячейка.Значение обычно быстрее, чем чтение Ячейка.Текст, так как не требует форматирования значения в строку согласно маске.

Анализ производительности и типичные ошибки

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

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

Итоги

Мы рассмотрели несколько способов ускорения работы с данными табличного документа. Самым универсальным и «чистым» с точки зрения кода 1С является использование Построителя отчета. Он позволяет избежать создания лишних объектов в памяти и предоставляет данные в удобном формате ТаблицаЗначений. Однако всегда помните о золотом правиле оптимизации: прежде чем менять алгоритм, убедитесь с помощью замера производительности, что именно этот участок кода является «узким местом» вашей системы.

← На главную