Как прочитать файл Excel,если установлен Libre Office

1. dentoma51 8 29.11.12 09:30 Сейчас в теме
Написана обработка печати этикеток для склада с товарной накладной,которая приходит от поставщика в формате Excel. В режиме тестирования все прошло успешно.
А при сдаче программы на склад выяснилось,что там не установлен Excel(нет лицензии),а установлен Libre Office.

И программа навернулась при попытке прочитать файл с расширением xls.
Вот фрагментф кода:
По кнопке открыть файл работает:
Процедура КоманднаяПанельТабличногоДокументаОткрыть(Кнопка)
ДиалогВыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);

ДиалогВыбораФайла.Заголовок = "Прочитать табличный документ из файла";
ДиалогВыбораФайла.Фильтр = "Лист Excel (*.xls)|*.xls|Табличный документ (*.mxl)|*.mxl|Текстовый документ (*.txt)|*.txt|dBase III (*.dbf)|*.dbf|";
Если ДиалогВыбораФайла.Выбрать() Тогда

ТабличныйДокумент1 = ЭлементыФормы.ТабличныйДокумент1;
ФайлНаДиске = Новый Файл(ДиалогВыбораФайла.ПолноеИмяФайла);
Если нРег(ФайлНаДиске.Расширение) = ".xls" Тогда
ПрочитатьТабличныйДокументИзExcel(ТабличныйДокумент1,ДиалогВыбораФайла.ПолноеИмяФайла);
==========================

Функция ПрочитатьТабличныйДокументИзExcel(ТабличныйДокумент, ИмяФайла, НомерЛистаExcel = 1) Экспорт
xlLastCell = 11;

ВыбФайл = Новый Файл(ИмяФайла);
Если НЕ ВыбФайл.Существует() Тогда
Сообщить("Файл не существует!");
Возврат Ложь;
КонецЕсли;

Excel = Новый COMОбъект("Excel.Application");

И здесь программа ломается с ругательством:

{ВнешняяОбработка.Альфа_ПечатьЭтикетокИЦенников(1337)}: Ошибка при вызове конструктора (COMОбъект): Недопустимая строка с указанием класса
Excel = Новый COMОбъект("Excel.Application");
по причине:
Недопустимая строка с указанием класса

Как же выйти из этой ситуации? Не хотелось бы ломать отработанную схему. Может другой COMОбьект надо подключать?
По теме из базы знаний
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. Guyer 20 29.11.12 09:41 Сейчас в теме
У меня есть обработка, читает Excel при установленном OpenOffice
В Модуле обработки


Процедура LoadDocument(HiddenMode, FileName) Экспорт
Если ПустаяСтрока(FileName) = 1 Тогда
FilePath = "private:factory/scalc";
Иначе
FilePath = convertToURL(FileName);
КонецЕсли;

MyStruct = ServiceManager.Bridge_GetStruct("com.sun.star.beans.PropertyValue");
VariantArray = Новый COMSafeArray("VT_VARIANT", 1);
MyStruct.name = "Hidden";
MyStruct.value = HiddenMode;
VariantArray.SetValue(0, MyStruct);

Document = Desktop.LoadComponentFromURL(FilePath, "_hidden", 0, VariantArray);
КонецПроцедуры // LoadDocument()

Процедура CloseDocument() Экспорт
Document.close(-1);
КонецПроцедуры

Функция convertToURL(FileName)
URL = СтрЗаменить(FileName," ","%20");
URL = СтрЗаменить(URL,"\","/");

Возврат "file://localhost/" + URL;
КонецФункции // convertToURL()


ServiceManager = Новый COMОбъект("com.sun.star.ServiceManager");
Desktop = ServiceManager.createInstance("com.sun.star.frame.Desktop");
Показать


В Форме обработки

Процедура КнопкаВыполнитьНажатие(Кнопка)
// Вставить содержимое обработчика.

LoadDocument(1, ИмяФайла);
Sheets = Document.getSheets();
Sheet = Sheets.getByName("Лист1");

Sh = Sheet.getCellRangeByName("A1:Z600");
//Здесь Мой Диапазон
НС = 0;
Док = Документы.ПоступлениеТоваровУслуг.СоздатьДокумент();
Док.Дата = ДатаДок;
Док.Записать();
ЗаполнениеДокументов.ЗаполнитьШапкуДокумента(Док.ЭтотОбъект, глТекущийПользователь, мВалютаРегламентированногоУчета, "Покупка");

Док.Организация = Организация;
Док.Контрагент = Поставщик;
Док.ДоговорКонтрагента = Договор;
Док.СкладОрдер = Склад;
Док.ДатаВходящегоДокумента = ДатаДок;
Док.Дата = ДатаДок;
Док.НомерВходящегоДокумента = НомерДок;
Док.ТипЦен = ТипЦен;
Док.РегистрироватьЦеныПоставщика = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(глТекущийПользователь, "РегистрироватьЦеныПоставщика");
Док.УстановитьНовыйНомер();

Док.ОтражатьВУправленческомУчете = Истина;
Док.ОтражатьВУправленческомУчете = Истина;
Док.ОтражатьВНалоговомУчете = Истина;

Для НС = НомерПервойСтроки По НомерПоследнейСтроки Цикл

ЯчТовар = Sh.getCellByPosition(НомерСтТовар-1, НС-1);
ЯчТоварНаим = Sh.getCellByPosition(НомерСтНаим-1, НС-1);
ЯчКоличество = Sh.getCellByPosition(НомерСтКоличество-1, НС-1);
ЯчСумма = Sh.getCellByPosition(НомерСтСумма-1, НС-1);
ЯчНДС = Sh.getCellByPosition(НомерСтНДС-1, НС-1);

ЗначИдТовара = СтрЗаменить(Формат(ЯчТовар.String,"ЧРГ = '+'"),"+","");
ЗначНаимТовара = Строка(ЯчТоварНаим.String);
НайденнаяСсылка = НайтиНоменклатуру(ЗначИдТовара); // Справочники.Номенклатура.НайтиПоРеквизиту("Артикул",ЗначИдТовара);
если НайденнаяСсылка.Пустая() ТОгда
// пробуем взять артикул из квадратных скобок наименования
Стр = ЗначНаимТовара;
ПозОткрСкобки = Найти(Стр,"[");
ПозЗакрСкобки = Найти(Стр,"]");
Если (ПозОткрСкобки>0) И (ПозЗакрСкобки > 0) И (ПозЗакрСкобки > ПозОткрСкобки) Тогда
Артикул2 = Сред(Стр,ПозОткрСкобки+1,(ПозЗакрСкобки-ПозОткрСкобки-1));
НайденнаяСсылка = НайтиНоменклатуру(Артикул2); //Справочники.Номенклатура.НайтиПоРеквизиту("Артикул",Артикул2);
ЗначИдТовара = Артикул2;
КонецЕсли;
КонецЕсли;

если НайденнаяСсылка.Пустая() ТОгда
ТекстВопроса = "Артикул: "+ЗначИдТовара+", наименование "+ЗначНаимТовара+":
|товар не найден в справочнике Номенклатура.
|Создать новый элемент? ДА - создать, НЕТ - выбрать из справочника.
|Если элемент не будет выбран, элемент будет создан автоматически.";
если Вопрос(ТекстВопроса,РежимДиалогаВопрос.ДаНет )=КодВозвратаДиалога.Нет Тогда
// выбираем
ВвестиЗначение(НайденнаяСсылка,""+ЗначИдТовара+" "+ЗначНаимТовара+"?",тип("СправочникСсылка.Номенклатура"));
КонецЕсли;

если НайденнаяСсылка.Пустая() ТОгда
СпрНоменклатура = Справочники.Номенклатура.СоздатьЭлемент();
СпрНоменклатура.Наименование = ЗначНаимТовара;
СпрНоменклатура.НаименованиеПолное = ЗначНаимТовара;
СпрНоменклатура.Артикул = ЗначИдТовара;
СпрНоменклатура.БазоваяЕдиницаИзмерения = Справочники.КлассификаторЕдиницИзмерения.НайтиПоКоду(1);
СпрНоменклатура.СтавкаНДС = Перечисления.СтавкиНДС.НДС18;
СпрНоменклатура.Записать();
ЕХО = Справочники.ЕдиницыИзмерения.СоздатьЭлемент();
ЕХО.Владелец = СпрНоменклатура.Ссылка;
ЕХО.Коэффициент = 1;
ЕХО.ЕдиницаПоКлассификатору = СпрНоменклатура.БазоваяЕдиницаИзмерения;
ЕХО.Наименование = ЕХО.ЕдиницаПоКлассификатору.Наименование;
ЕХО.Записать();
СпрНоменклатура.ЕдиницаХраненияОстатков = ЕХО.Ссылка;
СпрНоменклатура.Записать();
НайденнаяСсылка = СпрНоменклатура.Ссылка;
КонецЕсли;
Иначе
Если (НайденнаяСсылка.Родитель.Наименование="01") ИЛИ
(НайденнаяСсылка.Родитель.Наименование="02") ИЛИ
(НайденнаяСсылка.Родитель.Наименование="03") ИЛИ
(НайденнаяСсылка.Родитель.Наименование="04") ИЛИ
(НайденнаяСсылка.Родитель.Наименование="05") ИЛИ
(НайденнаяСсылка.Родитель.Наименование="06") ИЛИ
(НайденнаяСсылка.Родитель.Наименование="07") ИЛИ
(НайденнаяСсылка.Родитель.Наименование="08") ИЛИ
(НайденнаяСсылка.Родитель.Наименование="09") ИЛИ
ЛЕВ(НайденнаяСсылка.Родитель.Наименование,2)="10" ИЛИ
ЛЕВ(НайденнаяСсылка.Родитель.Наименование,2)="11" ИЛИ
(НайденнаяСсылка.Родитель.Наименование="12") ИЛИ
(НайденнаяСсылка.Родитель.Наименование="Детское питание") ИЛИ
(НайденнаяСсылка.Родитель.Наименование="Каша молочная") ИЛИ
(НайденнаяСсылка.Родитель.Наименование="15") ИЛИ
(НайденнаяСсылка.Родитель.Наименование="16") ИЛИ
(НайденнаяСсылка.Родитель.Наименование="17") ИЛИ
(НайденнаяСсылка.Родитель.Наименование="19") ИЛИ
(НайденнаяСсылка.Родитель.Наименование="18")
Тогда
Иначе
ТекстВопроса = ЗначНаимТовара+"
|совпадает с
|"+НайденнаяСсылка+"
|
|Да - Использовать найденное, НЕТ - выбрать из справочника.
|Если элемент не будет выбран, элемент будет выбран автоматически.";
если Вопрос(ТекстВопроса,РежимДиалогаВопрос.ДаНет )=КодВозвратаДиалога.Нет Тогда
// выбираем
ВвестиЗначение(НайденнаяСсылка,""+ЗначИдТовара+" "+ЗначНаимТовара+"?",тип("СправочникСсылка.Номенклатура"));
КонецЕсли;
КонецЕсли;
КонецЕсли;

// сертификат и № КУ
ЗначСертификат =0;
ЗначКУ = 0;
ЗначДР = 0;
ЗначДВ = 0;

если НомерСтолбцаСертификат>0 Тогда
ЯчСертификат = Sh.getCellByPosition(НомерСтолбцаСертификат-1, НС-1);
ЗначСертификат = Строка(ЯчСертификат.String);
КонецЕсли;
если НомерСтолбцаКУ >0 Тогда
ЯчКУ = Sh.getCellByPosition(НомерСтолбцаКУ-1, НС-1);
ЗначКУ = Строка(ЯчКУ.String);
КонецЕсли;
если НомерСтолбцаДР > 0 Тогда
ЯчДР = Sh.getCellByPosition(НомерСтолбцаДР-1, НС-1);
ЗначДР = Строка(ЯчДР.String);
КонецЕсли;

если НомерСтолбцаДВ > 0 Тогда
ЯчДВ = Sh.getCellByPosition(НомерСтолбцаДВ-1, НС-1);
ЗначДВ = Строка(ЯчДВ.String);
КонецЕсли;

Набор = РегистрыСведений.ЗначенияСвойствОбъектов.СоздатьНаборЗаписей();
Набор.Отбор.Объект.Установить(НайденнаяСсылка);
// сертификат
если ЗначениеЗаполнено(ЗначСертификат) Тогда
спрЗначСертификат = Справочники.ЗначенияСвойствОбъектов.НайтиПоНаименованию(ЗначСертификат);
СсылкаСертификат = спрЗначСертификат.Ссылка;
если спрЗначСертификат.Пустая() Тогда
спрЗначСертификат = Справочники.ЗначенияСвойствОбъектов.СоздатьЭлемент();
спрЗначСертификат.Владелец = ПланыВидовХарактеристик.СвойстваОбъектов.НайтиПоКоду("00112");
спрЗначСертификат.Наименование = ЗначСертификат;
спрЗначСертификат.Записать();
СсылкаСертификат = спрЗначСертификат.Ссылка;
Конецесли;
тСвойство = глПоНаименованию("СвойстваОбъектов","Сертификат");
Запись = лкПолучитьЗаписьНабора(Набор, НайденнаяСсылка, тСвойство);//Набор.Добавить();
Запись.Объект = НайденнаяСсылка;
Запись.Свойство = тСвойство;//глПоНаименованию("СвойстваОбъектов","Сертификат");
Запись.Значение = СсылкаСертификат;
Набор.Записать();
КонецЕсли;

// КУ
если ЗначениеЗаполнено(ЗначКУ) Тогда
тСвойство = глПоНаименованию("СвойстваОбъектов","Качественное удостоверение");
Запись = лкПолучитьЗаписьНабора(Набор, НайденнаяСсылка, тСвойство);//Набор.Добавить();
Запись.Объект = НайденнаяСсылка;
Запись.Свойство = тСвойство;
Запись.Значение = ЗначКУ;
Набор.Записать();
КонецЕсли;

// Дата реализации
если ЗначениеЗаполнено(ЗначДР) Тогда
тСвойство = глПоНаименованию("СвойстваОбъектов","Дата реализации");
Запись = лкПолучитьЗаписьНабора(Набор, НайденнаяСсылка, тСвойство);//Набор.Добавить();
Запись.Объект = НайденнаяСсылка;
Запись.Свойство = тСвойство;//глПоНаименованию("СвойстваОбъектов","Дата реализации");
Запись.Значение = ЗначДР;
Набор.Записать();
КонецЕсли;

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

ЗначКолво = Число(ЯчКоличество.Value);
ЗначСумма = ЯчСумма.Value;
ЗначНДС = ЯчНДС.Value;

СтрокаТабЧасти = Док.Товары.Добавить();
СтрокаТабЧасти.Номенклатура = НайденнаяСсылка;
СтрокаТабЧасти.ЕдиницаИзмерения = НайденнаяСсылка.ЕдиницаХраненияОстатков;
СтрокаТабЧасти.ЕдиницаИзмеренияМест = НайденнаяСсылка.ЕдиницаХраненияОстатков;
СтрокаТабЧасти.Коэффициент = НайденнаяСсылка.ЕдиницаХраненияОстатков.Коэффициент;
СтрокаТабЧасти.Количество = ЗначКолво;
СтрокаТабЧасти.Сумма = ЗначСумма;
СтрокаТабЧасти.СуммаНДС = ЗначНДС;
СтрокаТабЧасти.СтавкаНДС = НайденнаяСсылка.СтавкаНДС;
СтрокаТабЧасти.Склад = Склад;
ОбработкаТабличныхЧастей.ПриИзмененииСуммыТабЧасти(СтрокаТабЧасти, Док.ЭтотОбъект, глТекущийПользователь);
Сообщить("Загружена строка "+СтрокаТабЧасти.НомерСтроки);
КонецЦикла;

Док.Записать();
Сообщить("Записан документ "+Док.Ссылка);
CloseDocument();
КонецПроцедуры

Показать
4. andrewks 1370 29.11.12 11:00 Сейчас в теме
(1) dentoma51, для чтения xls, в общем случае, не нужен ни MS office, ни LibreOffice, а нужен всего лишь adodb
3. red80 29.11.12 09:52 Сейчас в теме
БСП не подходит, там нет чтения из OO.
5. andrewks 1370 29.11.12 11:01 Сейчас в теме
пример:

    СтрокаПодключения="
    |Provider=Microsoft.Jet.OLEDB.4.0;
    |Data Source="+ИмяФайла+";

    |Extended Properties=""Excel 8.0;IMEX=1;HDR=No"";";
    
    Попытка
        Connection.Open(СтрокаПодключения);
    Исключение
        ТекстОшибки=ОписаниеОшибки();
        ВывестиСообщение("Не удалось прочитать файл "+ИмяФайла+"
        |Возможно, файл заблокирован, или не установлен провайдер чтения файлов Microsoft Excel
        |Описание ошибки: "+ТекстОшибки);
        Возврат Адрес;
    КонецПопытки;
    
    СтрЗапроса="select * from [A1:A1]";
    Попытка
        RecordSet=Connection.Execute(СтрЗапроса);
    Исключение
        ТекстОшибки=ОписаниеОшибки();
        ВывестиСообщение("Не удалось произвести чтение из файла "+ИмяФайла+"
        |Описание ошибки: "+ТекстОшибки);
        Возврат Адрес;
    КонецПопытки;
    Если RecordSet.EOF=0 Тогда
        Данные=СокрЛП(RecordSet.Fields(0).Value);
    КонецЕсли;
    
    RecordSet.Close();
    
    Connection.Close();



Показать
6. dentoma51 8 29.11.12 16:00 Сейчас в теме
Andrewks,спасибо Вам. Очень интересно через ADODB. Пробую по Вашему примеру и,конечно,много вопросов появляется. Как задать в запросе область ячеек? Делаю,например,так:СтрЗапроса="select * from [B11:F99]",
ожидая в результате прямоугольник ячеек B11-F99.
В RecordSet же выводится область состоящая из 5 ячеек с B11 по F11 (привожу табличный документ,выведенный в отладке). Имена (Name)у них идут с F1 по F5. Поле OriginalValue = Произошла исключительная ситуация (ADODB.Field): Текущий объект Recordset не поддерживает обновление. Это связано с ограничением поставщика или с выбранным типом блокировки.
Поле UnderlyingValue = Произошла исключительная ситуация (ADODB.Field): Текущий проводник не поддерживает обновление связанных значений.
Если можно,подскажите,может что не недоустановлено,или область ячеек не так надо задавать? Хотелось бы освоить ADODB. Спасибо.
Прикрепленные файлы:
Новый1.mxl
7. andrewks 1370 29.11.12 16:12 Сейчас в теме
8. andrewks 1370 29.11.12 16:14 Сейчас в теме
если лист один, то: СтрЗапроса="select * from [$B11:F99]"
9. dentoma51 8 30.11.12 09:12 Сейчас в теме
Andrewks,еще раз спасибо за подсказку по ADODB.
А вот с Libre Office 3.6.3 есть засада,про которую много в инете жалоб.
Конкретно с версией Libre Office 3.6.3.
При попытке объявить
ServiceManager = Новый COMОбъект("com.sun.star.ServiceManager") вызывается исключение и появляется справка о программе.
На более ранних версиях,например,3.5.7,работает. И судя по отзывам в интернете работает до 3.6.2.

Есть только одна бяка.
При объявлении
ServiceManager = Новый COMОбъект("com.sun.star.ServiceManager")
появляется на мониторе стартовое окно Libre Office (которое появляется,если его просто запускать).
Можно ли эту засаду убрать,может кто подскажет?
10. andrewks 1370 30.11.12 17:26 Сейчас в теме
11. dentoma51 8 06.12.12 09:33 Сейчас в теме
(10) andrewks,с 3.6.4 rc1 не проходит.
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот