Написана обработка печати этикеток для склада с товарной накладной,которая приходит от поставщика в формате 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Обьект надо подключать?
ЗначИдТовара = СтрЗаменить(Формат(ЯчТовар.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");
спрЗначСертификат.Наименование = ЗначСертификат;
спрЗначСертификат.Записать();
СсылкаСертификат = спрЗначСертификат.Ссылка;
Конецесли;
тСвойство = глПоНаименованию("СвойстваОбъектов","Сертификат");
Запись = лкПолучитьЗаписьНабора(Набор, НайденнаяСсылка, тСвойство);//Набор.Добавить();
Запись.Объект = НайденнаяСсылка;
Запись.Свойство = тСвойство;//глПоНаименованию("СвойстваОбъектов","Сертификат");
Запись.Значение = СсылкаСертификат;
Набор.Записать();
КонецЕсли;
// КУ
если ЗначениеЗаполнено(ЗначКУ) Тогда
тСвойство = глПоНаименованию("СвойстваОбъектов","Качественное удостоверение");
Запись = лкПолучитьЗаписьНабора(Набор, НайденнаяСсылка, тСвойство);//Набор.Добавить();
Запись.Объект = НайденнаяСсылка;
Запись.Свойство = тСвойство;
Запись.Значение = ЗначКУ;
Набор.Записать();
КонецЕсли;
// Дата реализации
если ЗначениеЗаполнено(ЗначДР) Тогда
тСвойство = глПоНаименованию("СвойстваОбъектов","Дата реализации");
Запись = лкПолучитьЗаписьНабора(Набор, НайденнаяСсылка, тСвойство);//Набор.Добавить();
Запись.Объект = НайденнаяСсылка;
Запись.Свойство = тСвойство;//глПоНаименованию("СвойстваОбъектов","Дата реализации");
Запись.Значение = ЗначДР;
Набор.Записать();
КонецЕсли;
// Дата выработки
если ЗначениеЗаполнено(ЗначДВ) Тогда
тСвойство = глПоНаименованию("СвойстваОбъектов","Дата выработки");
Запись = лкПолучитьЗаписьНабора(Набор, НайденнаяСсылка, тСвойство);//Набор.Добавить();
Запись.Объект = НайденнаяСсылка;
Запись.Свойство = тСвойство;
Запись.Значение = ЗначДВ;
Набор.Записать();
КонецЕсли;
Andrewks,спасибо Вам. Очень интересно через ADODB. Пробую по Вашему примеру и,конечно,много вопросов появляется. Как задать в запросе область ячеек? Делаю,например,так:СтрЗапроса="select * from [B11:F99]",
ожидая в результате прямоугольник ячеек B11-F99.
В RecordSet же выводится область состоящая из 5 ячеек с B11 по F11 (привожу табличный документ,выведенный в отладке). Имена (Name)у них идут с F1 по F5. Поле OriginalValue = Произошла исключительная ситуация (ADODB.Field): Текущий объект Recordset не поддерживает обновление. Это связано с ограничением поставщика или с выбранным типом блокировки.
Поле UnderlyingValue = Произошла исключительная ситуация (ADODB.Field): Текущий проводник не поддерживает обновление связанных значений.
Если можно,подскажите,может что не недоустановлено,или область ячеек не так надо задавать? Хотелось бы освоить ADODB. Спасибо.
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 (которое появляется,если его просто запускать).
Можно ли эту засаду убрать,может кто подскажет?