26.05.2015, 14:55 | #1 |
Участник
|
Как правильно обернуть в ComVariant метод getWorkSheets() класса ComExcelDocument_RU
Здравствуйте.
Подскажите пожалуйста как правильно обернуть в ComVariant стандартный метод getWorkSheets() private COM getWorkSheets() { if (!comWorkSheets && m_comDocument) { try { comWorkSheets = m_comDocument.worksheets(); } catch (Exception::Error) { throw error("@GEE6043"); } } return comWorkSheets; } |
|
26.05.2015, 15:58 | #2 |
Участник
|
COMVariant::createFromCOM() не подходит?
__________________
Axapta v.3.0 sp5 kr2 |
|
27.05.2015, 08:38 | #3 |
Участник
|
нет не подходит. пишет что не то формат
|
|
27.05.2015, 08:44 | #4 |
Участник
|
Вы бы код привели, который ошибку генерирует
__________________
Axapta v.3.0 sp5 kr2 |
|
27.05.2015, 08:57 | #5 |
Участник
|
просто меняю строчку
comWorkSheets = m_comDocument.worksheets(); на comWorkSheets = COMVariant::createFromCOM(m_comDocument.worksheets()); перепробовал все COMVariant::createFrom... Тут явно надо как то иначе) Все время пишет "Типы операнда не совместимы с оператором." |
|
27.05.2015, 09:03 | #6 |
Участник
|
Вы тип comWorkSheets не меняли?
Иначе, получается, что вы в переменную типа COM пытаетесь записать переменную типа COMVariant
__________________
Axapta v.3.0 sp5 kr2 |
|
27.05.2015, 09:26 | #7 |
Участник
|
Сделал так.Но не аукнется ли это в другом месте?
private COMVariant getWorkSheets() { Comvariant f; if (!comWorkSheets && m_comDocument) { try { f=COMVariant::createFromCOM(m_comDocument.worksheets()); } catch (Exception::Error) { throw error("@GEE6043"); } } return f; } |
|
27.05.2015, 09:34 | #8 |
Участник
|
Конечно, аукнется)
Вы бы написали, чего именно этим хотите добиться А вообще, правильнее было бы добавить свой метод, а не ломать существующий
__________________
Axapta v.3.0 sp5 kr2 |
|
27.05.2015, 09:51 | #9 |
Участник
|
Все это я делаю чтоб избавиться от знаменитой ошибки работы класса ComExcelDocument_RU на терминалах. как то раз поправил метод getworkrsheet :
COM getWorkSheet(anytype _workSheetID) { COM comRet; Comvariant f; ; if (m_comDocument) { try { this.getWorkSheets(); if (typeof(_workSheetID) == Types::Class && classidget(_workSheetID) == classnum(COMVariant)) { f = _workSheetID; comRet = comWorkSheets.item(f); } else { comRet = comWorkSheets.item(_workSheetID); } } catch (Exception::Error) { throw error("@GEE6043"); } } return comRet; } Прошло время и сейчас уже ругается на getWorkSheets [IMG][/IMG] |
|
27.05.2015, 10:36 | #10 |
Участник
|
Замена на COMVariant ничем эту ошибку не исправит
Смотрите в сторону COMDispFunction
__________________
Axapta v.3.0 sp5 kr2 |
|
27.05.2015, 15:28 | #11 |
Участник
|
Вы бы сделали хотя бы поиск по данному форуму по ключевому слову "ComDispFunction". Есть масса примеров его использования.
В данном конкретном случае решение будет выглядеть так: Сначала коллекция листов (рабочая книга. Файл Excel) X++: // Метод getWorkSheets() private COM getWorkSheets() { ComVariant varRet; ComDispFunction funcGet; ; if (!comWorkSheets && m_comDocument) { try { /* comWorkSheets = m_comDocument.worksheets(); */ funcGet = new ComDispFunction(m_comDocument, "worksheets", COMDispContext::PropertyGet); varRet = new COMVariant(COMVariantInOut::OUT_RETVAL, COMVariantType::VT_DISPATCH); funcGet.call(varRet); comWorkSheets = COM::createFromInterface(varRet.iDispatch()); } catch (Exception::Error) { throw error("@GEE6043"); } } return comWorkSheets; } X++: private COM getWorkSheet(anytype _workSheetID) { COM comRet; ComVariant varRet; ComDispFunction funcGet; COMVariant varArgStr; COMVariant varArgInt; ; if (m_comDocument) { try { this.getWorkSheets(); /* comRet = comWorkSheets.item(_workSheetID); */ funcGet = new ComDispFunction(comWorkSheets, "item", COMDispContext::PropertyGet); varRet = new COMVariant(COMVariantInOut::OUT_RETVAL, COMVariantType::VT_DISPATCH); switch (typeOf(_workSheetID)) { case types::String : varArgStr = new COMVariant(COMVariantInOut::In, COMVariantType::VT_BSTR); varArgStr.bStr(_workSheetID); funcGet.call(varArgStr, varRet); break; case types::Integer : varArgInt = new COMVariant(COMVariantInOut::In, COMVariantType::VT_INT); varArgInt.int(_workSheetID); funcGet.call(varArgInt, varRet); break; default : throw error('Не корректный тип параметра'); break; } // switch (typeOf(_workSheetID)) comRet = COM::createFromInterface(varRet.iDispatch()); } catch (Exception::Error) { throw error("@GEE6043"); } } return comRet; }
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
|
За это сообщение автора поблагодарили: AlGol (2), NeveB (1), Logger (7), Ace of Database (5), ena_ax (1), Sergey Petrov (1), at5454 (1). |
26.08.2015, 19:33 | #12 |
Участник
|
По такому принципу пытаюсь переделать форматирование шрифта в ячейке, который был написан так:
X++: void bold(MSOfficeBookMark_RU _bookMark, int _workSheet = 1) { Com MultiRange; Com ComApplication; Com Font; ; if (m_comDocument) { comApplication = m_comDocument.application(); if (comApplication) { MultiRange = this.findRange(_bookMark, _workSheet); Font = MultiRange.Font(); Font.Bold(1); } } } При написании такой конструкции X++: funcGet = new ComDispFunction(Font, "Bold", COMDispContext::PropertyGet); varRet = new COMVariant(COMVariantInOut::OUT_RETVAL, COMVariantType::VT_DISPATCH); varArgInt = new COMVariant(COMVariantInOut::In, COMVariantType::VT_INT); varArgInt.int(1); funcGet.call(varArgInt); //-------------- //Font.Bold(1); -------------------- Метод "Bold" в COM-объекте класса "Font" возвратил код ошибки 0x8002000E (DISP_E_BADPARAMCOUNT), который означает: Число аргументов, указанных в вызове функции, отличается от числа аргументов в объявлении метода. -------------------- При вызове без аргументов funcGet.call(); работает отлично. Каким образом сделать шрифт болдом?
__________________
Ален ноби, ностра алис. Что означает - если один человек построил, другой завсегда разобрать может. |
|
|
За это сообщение автора поблагодарили: NeveB (1). |
26.08.2015, 20:33 | #13 |
Участник
|
ProprtyPut надо использовать
__________________
Axapta v.3.0 sp5 kr2 |
|
|
За это сообщение автора поблагодарили: AlGol (2). |
26.08.2015, 20:51 | #14 |
Участник
|
Спасибо!
Работает. X++: ComDispFunction funcGet, funcPut; COMVariant varArgInt, varArgBool; ; ... funcPut = new ComDispFunction(Font, "Bold", COMDispContext::PropertyPut); varArgBool = new COMVariant(COMVariantInOut::In, COMVariantType::VT_BOOL); varArgBool.boolean(true); funcPut.call(varArgBool);
__________________
Ален ноби, ностра алис. Что означает - если один человек построил, другой завсегда разобрать может. |
|
26.07.2018, 09:16 | #15 |
Участник
|
Цитата:
Сообщение от Владимир Максимов
Вы бы сделали хотя бы поиск по данному форуму по ключевому слову "ComDispFunction". Есть масса примеров его использования.
В данном конкретном случае решение будет выглядеть так: Сначала коллекция листов (рабочая книга. Файл Excel) X++: // Метод getWorkSheets() private COM getWorkSheets() { ComVariant varRet; ComDispFunction funcGet; ; if (!comWorkSheets && m_comDocument) { try { /* comWorkSheets = m_comDocument.worksheets(); */ funcGet = new ComDispFunction(m_comDocument, "worksheets", COMDispContext::PropertyGet); varRet = new COMVariant(COMVariantInOut::OUT_RETVAL, COMVariantType::VT_DISPATCH); funcGet.call(varRet); comWorkSheets = COM::createFromInterface(varRet.iDispatch()); } catch (Exception::Error) { throw error("@GEE6043"); } } return comWorkSheets; } X++: private COM getWorkSheet(anytype _workSheetID) { COM comRet; ComVariant varRet; ComDispFunction funcGet; COMVariant varArgStr; COMVariant varArgInt; ; if (m_comDocument) { try { this.getWorkSheets(); /* comRet = comWorkSheets.item(_workSheetID); */ funcGet = new ComDispFunction(comWorkSheets, "item", COMDispContext::PropertyGet); varRet = new COMVariant(COMVariantInOut::OUT_RETVAL, COMVariantType::VT_DISPATCH); switch (typeOf(_workSheetID)) { case types::String : varArgStr = new COMVariant(COMVariantInOut::In, COMVariantType::VT_BSTR); varArgStr.bStr(_workSheetID); funcGet.call(varArgStr, varRet); break; case types::Integer : varArgInt = new COMVariant(COMVariantInOut::In, COMVariantType::VT_INT); varArgInt.int(_workSheetID); funcGet.call(varArgInt, varRet); break; default : throw error('Не корректный тип параметра'); break; } // switch (typeOf(_workSheetID)) comRet = COM::createFromInterface(varRet.iDispatch()); } catch (Exception::Error) { throw error("@GEE6043"); } } return comRet; } Коллеги, данный изменение методов решило проблему timeout при работе отчетов модуля "Генератор Российских отчетов". см мою ссылку по теме Axapta 2009. str2IntOk Есть два вопроса: 1. На сколько это решение является универсальным? Какие могут быть исключения? 2. Почему данный подход не реализован в стандартном функционале? |
|
27.07.2018, 05:53 | #16 |
NavAx
|
Оно не решило, на самом деле.
Оно уменьшило его вероятность. Все равно - на тысячах строк будет иногда вылезать. Еще выжать вероятности поможет - написать в catch пару раз retry при COM ошибке после небольшой задержки миллисекунд в 100-300.. Тема уже исхожена эта вдоль и поперек. Радикально решает - доступ через .NET - искать здесь же на форуме.
__________________
Жизнь прекрасна! Если, конечно, правильно подобрать антидепрессанты... Последний раз редактировалось Maximin; 27.07.2018 в 05:58. |
|
27.07.2018, 09:31 | #17 |
Участник
|
Цитата:
Сообщение от Maximin
Оно не решило, на самом деле.
Оно уменьшило его вероятность. Все равно - на тысячах строк будет иногда вылезать. Еще выжать вероятности поможет - написать в catch пару раз retry при COM ошибке после небольшой задержки миллисекунд в 100-300.. Тема уже исхожена эта вдоль и поперек. Радикально решает - доступ через .NET - искать здесь же на форуме. В новой версии я так понимаю уже через NET реализовано? |
|
Теги |
com-объект, comdispfunction, excel, excel com формат, законченный пример, полезное |
|
|