Грамотная загрузка из Excel в 1С

Многим 1сникам не понятен единственно верный путь чтения Excel-файлов.
Если файл Excel содержит только одну страницу, то его можно прочитать методом Прочитать табличного документа. И записать в Excel файл табличный документ тоже можно из 1С.
Файлы Excel, пользователь, кстати, может открыть и посмотреть в 1С.
Но у метода Прочитать есть недостаток - он криво воспринимает некоторые даты, как ни читай - текстом или значениями. Будем надеяться, со временем эти банальные глюки 1с все же починят. А пока надо применять свои руки, т.е. читать через старый добрый Excel.Application, методика позволяет также читать книги с несколькими листами.
Важно, что читать нужно на клиенте. На сервере Excel запускается от имени пользователя, под которым работает служба 1С-сервера, на практике в 50% случаев админы не могут корректно настроить работу COM-приложения. Поэтому лучше прочитать весь файл на клиенте и передать его в виде массива структур.
Привожу пример чтения обычного файла, содержащего 12 листов с накладными среднего размера. 6 409 ячеек прочитались за 25 секунд. 256 ячеек в секунду - не быстро, но все же быстрее чем ручками?
Для ускорения можно использовать чтение методом COMSafeArray, данные считываются практически мгновенно, но об этом в другой раз. Поэкспериментируйте сами. Правда, первое измерение двухмерного массива получаются колонки, потом строки. Учитывая, что 1С не умеет быстро транспонировать массивы, нужно так и обрабатывать данные.
Ну и еще один штрих - многие пользователи работают в терминале и не ставят на сервер Excel по лицензионным соображениям. С файлами Excel может работать и Open Office, в том числе и по COM-объекту. Так что в планах написать функцию загрузки для Open Office.
Текст функции под катом:
Функция ЗагрузитьExcelФайлВМассивЛистов(ИмяФайла, ЗНАЧ
СоответствиеФильтраЛистов = Неопределено)
//СоответствиеФильтраЛистов - соответствие содержащее
числа с номерами листа (начиная с единицы)
//Или названия листов в виде строки.
//Возвращается массив структур с полями:
// Номер - номер листа с единицы
// Имя - имя листа строкой
// Строк - количество строк
// Колонок - количество колонок
// Ячейки - двумерный массив колонок, первое
измерение - строка, второе - колонка
Перем МассивЛистов;
МассивЛистов = Новый Массив(); //Это масс
Эксель = New
COMObject("Excel.Application");
Эксель.visible = false;
Книга = Эксель.Workbooks.Open(ИмяФайла);
Для НомерЛиста = 1 To Книга.Sheets.Count Цикл
Лист = Книга.Sheets(НомерЛиста);
ИмяЛиста = Лист.Name;
Если СоответствиеФильтраЛистов <>
Неопределено Тогда
Если
СоответствиеФильтраЛистов[НомерЛиста] = Неопределено
И
СоответствиеФильтраЛистов[ИмяЛиста] = Неопределено
Тогда
Продолжить;
//Если лист грузить не надо
КонецЕсли;
КонецЕсли;
КоличествоСтрок =
Лист.UsedRange.Rows.Count;
КоличествоКолонок =
Лист.UsedRange.Columns.Count;
Ячейки = Новый Массив(КоличествоСтрок,
КоличествоКолонок);
Для Строка = 1 По КоличествоСтрок
Цикл
Для Колонка = 1 По
КоличествоКолонок Цикл
Ячейки[Строка - 1][Колонка - 1] = Лист.Cells(Строка,
Колонка).Value;
КонецЦикла;
КонецЦикла;
СтруктураЛиста = Новый Структура();
СтруктураЛиста.Вставить("Строк",
КоличествоСтрок);
СтруктураЛиста.Вставить("Колонок",
КоличествоКолонок);
СтруктураЛиста.Вставить("Ячейки",
Ячейки);
СтруктураЛиста.Вставить("Номер",
НомерЛиста);
СтруктураЛиста.Вставить("Имя",
ИмяЛиста);
МассивЛистов.Добавить(СтруктураЛиста);
КонецЦикла;
Книга.Close();
Возврат МассивЛистов;
КонецФункции
|
</> |