Так или иначе, но необходимость получить данные из книги MS Excel (далее просто
книга)время от времени возникает. Прайсы поставшиков, накладные,
отчеты и т.п. - очень часто хранятся в формате MS Excel.
Есть несколько способов добраться до данных, хранящихся в книге: можно сохранить
в другом формате, можно вытянуть посредством OLE, можно использовать, например,
ADO. Мы рассмотрим вариант с OLE.
Сразу к коду:
Эксель = СоздатьОбъект("Excel.Application");
Инициализируем OLE-объект. Если Excel не установлен, или в процессе инициализации
произошла ошибка, ни о какой дальнейшей работе речи быть не может, поэтому в
примере инициализация обернута конструкцией Попытка-Исключение, чтобы ползователь
не испытывал стресс от непонятных надписей в строке сообщений.
Т.к. часто производится пакетная обработка большого количества файлов без участия
пользователя, то имеет смысл отключить выдачу сообщений, которая останавливает
обработку:
Эксель.DisplayAlerts
= 0;
После выбора файла загружаем его:
Эксель.Workbooks.Open(Файл,0,1);
первый параметр - имя файла;
второй - флаг обновления ссылок. В таблицах могут присутствовать ссылки, например
на макросы, хранящиеся в отдельном файле, и т.п. При открытии такого документа
эксель интересуется, нужно ли обновлять ссылки. 1 - обновлять, 0 не обновлять.
В случае обработки чужих документов, не факт, что есть файл, на который указывает
ссылка, значения пересчитывать не требуется, поэтому у меня стоит 0;
третий - режим открытия. 0 - чтение\запись, 1 - только чтение. Чтобы избежать
ненужных вопросов при закрытии файла, открываем его в режиме "только чтение".
В моем примере, после открытия файла, загружается список листов книги:
КолЛист = Эксель.Worksheets.Count;
Спис.УдалитьВсе();
Для е = 1 По
КолЛист Цикл
Спис.ДобавитьЗначение(Эксель.Sheets(е).Name);
КонецЦикла;
Здесь мы получаем количество листов книги, очищаем список и органицуем цикл
заполнения списка значений.
В цикле добавляемое значение: Эксель.Sheets(е).Name,
где Эксель.Sheets(е)
- устанавливает активный лист, причем возвращает его (далее это будет
использоваться), а Name - это свойства листа, в
котором хранится имя листа книги.
После того как пользователь выбрал в списке нужный лист, загружаем его в таблицу
значений:
//***
01Процедура ПоказатьЛист(Номер)
02 ТЗ.Очистить();
03 Лист = Эксель.Sheets(Номер);
04 МаксСтр = Лист.Cells(1,1).SpecialCells(11).Row;
05 МаксКол = Лист.Cells(1,1).SpecialCells(11).Column;
06 ТЗ.КоличествоКолонок(МаксКол);
07 Для е =
1 По МаксСтр Цикл
08 ТЗ.НоваяСтрока();
09 Для у
= 1 По МаксКол
Цикл
10 ТЗ.УстановитьЗначение(е,у,Лист.Cells(е,у).Text);
11 КонецЦикла;
12 КонецЦикла;
13КонецПроцедуры
В строках 04 и 05 определяем размер области, занятьой данными - аналогично
назатию Ctrl+End в экселе.
Получение значения ячейки в цикла должно быть понятно. Небольшое примечание
- можно использовать свойство "Value" вместо "Text", но
при наличии ошибочной формулы в ячейке у меня намертво висла 1С.
Вот в принципе и вся кухня, надеюсь, что все понятно. Оригинал статьи лежит
здесь вместе с примером.
Данный метод имеет свои отрицательные стороны:
- необходим установленный MS Excel, что создает проблемы для пользователей
альтернативных офисных пакетов.
- скорость работы очень низкая. Для небольших объемов вполне приемлемо, но
дождаться обработки 3000 прайсов я не смог, терпения не хватило.
- некоторые проблемы могут возникнуть, если у пользователя открыт эксель
Основным источником информации является раздел справки MS Excel, описывающий
объектную модель экселя.
В качестве альтернативного варианта могу предложить класс
1с++ для доступа к данным книг MS Excel.
Вы можете обсудить эту статью на форуме
или непосредственно автору.
|