При загрузке файлов Excel (особенно формата .xlsx) в объект 1С ТабличныйДокумент с помощью метода Прочитать() разработчики часто сталкиваются с неожиданным behavior: свойства ШиринаТаблицы и ВысотаТаблицы возвращают огромные значения (например, 16 384 колонки и 9 806 строк), хотя реальных данных в файле всего 10–20 колонок.
Рассмотрим по шагам, почему возникает эта проблема и какими способами можно определить фактические границы таблицы для обхода ячеек.
Проанализируем ситуации, из-за которых ТабличныйДокумент определяет размер таблицы со значительным запасом:
dimension, определяющий максимальный рабочий диапазон листа. Сторонние генераторы файлов или сам MS Excel при сохранении могут прописывать в этот тег предельное количество колонок (до 16 384). Метод Прочитать() считывает этот диапазон целиком.Если загружаемый файл имеет четкую структуру с шапкой (строкой заголовков колонок), разберем самый простой вариант определения количества колонок: выполнение цикла по строке шапки до первой незаполненной ячейки.
Рассмотрим пример кода на сервере:
&НаСервере
Функция ПрочитатьExcelФайл(ПутьКФайлу)
ТабДок = Новый ТабличныйДокумент;
ТабДок.Прочитать(ПутьКФайлу);
// Определим реальное количество колонок по строке шапки (например, строка 3)
СтрокаШапки = 3;
МаксКолонок = ТабДок.ШиринаТаблицы;
РеальноеКоличествоКолонок = 0;
Для НомерКолонки = 1 По МаксКолонок Цикл
ТекстЯчейки = СокрЛП(ТабДок.ПолучитьОбласть(СтрокаШапки, НомерКолонки).ТекущаяОбласть.Текст);
Если ПустаяСтрока(ТекстЯчейки) Тогда
Прервать;
КонецЕсли;
РеальноеКоличествоКолонок = РеальноеКоличествоКолонок + 1;
КонецЦикла;
Возврат РеальноеКоличествоКолонок;
КонецФункции
В случаях, когда шапка содержит объединенные ячейки или пустые значения, надежнее искать границы с конца таблицы. Выполним обратный цикл от значений ВысотаТаблицы и ШиринаТаблицы к началу, проверяя заполненность ячеек.
Посмотрим на реализацию поиска последней заполненной строки и колонки:
&НаСервере
Процедура ОпределитьГраницыТаблицы(ТабДок, ПоследняяСтрока, ПоследняяКолонка)
ПоследняяСтрока = 0;
ПоследняяКолонка = 0;
ВсегоСтрок = ТабДок.ВысотаТаблицы;
ВсегоКолонок = ТабДок.ШиринаТаблицы;
// Поиск последней строки с данными
Для Стр = Наоборот ВсегоСтрок По 1 Цикл
ФлагЗаполнена = Ложь;
Для Кол = 1 По Мин(ВсегоКолонок, 100) Цикл // проверяем первые 100 колонок
Текст = СокрЛП(ТабДок.Область(Стр, Кол).Текст);
Если Не ПустаяСтрока(Текст) Тогда
ФлагЗаполнена = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если ФлагЗаполнена Тогда
ПоследняяСтрока = Стр;
Прервать;
КонецЕсли;
КонецЦикла;
// Поиск последней колонки с данными
Для Кол = Наоборот ВсегоКолонок По 1 Цикл
ФлагЗаполнена = Ложь;
Для Стр = 1 По ПоследняяСтрока Цикл
Текст = СокрЛП(ТабДок.Область(Стр, Кол).Текст);
Если Не ПустаяСтрока(Текст) Тогда
ФлагЗаполнена = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если ФлагЗаполнена Тогда
ПоследняяКолонка = Кол;
Прервать;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Существует эффективный прием очистки пустых областей с помощью объекта ПостроительЗапроса. Передача области табличного документа в описание источника данных позволяет отсечь пустые строки и колонки и сразу получить объект ТаблицаЗначений.
Проанализируем этот подход на примере:
&НаСервере
Функция ПреобразоватьТабДокВТаблицуЗначений(ТабДок)
Построитель = Новый ПостроительЗапроса;
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабДок.Область());
// Выгрузка автоматизирует обрезку пустых строк и колонок по краям
ТаблицаРезультирующая = Построитель.Результат.Выгрузить();
Возврат ТаблицаРезультирующая;
КонецФункции
Если стандартный метод ТабличныйДокумент.Прочитать() работает медленно из-за большого объема пустых отформатированных ячеек, воспользуемся альтернативными инструментами интеграции:
Excel.Application: Позволяет обращаться к свойству UsedRange файла MS Excel, которое точнее определяет границы фактически используемых ячеек..xlsx представляет собой ZIP-архив. Распаковав его с помощью объекта ЧтениеZipФайла и прочитав XML-структуру через ЧтениеXML, можно быстро извлечь данные без загрузки графического представления таблицы.ADODB.Connection): Выполнение SQL-запроса к файлу Excel возвращает только строки с данными, полностью игнорируя пустое форматирование за пределами таблицы.