|
![]() |
#1 |
Участник
|
Цитата:
![]() ![]() Ошибка времени выполнения в ComExcelDocument_RU.findRange() Ошибка чтения файлов XLS под Windows 7 - тут предложено решение: переписать взаимодействие с Excel на использование .NET вместо COM. К слову, тут вот предлагают запускать клиента на терминальном сервере, так я по своему скромному опыту скажу, что это лишь усугубит ситуацию, потому что на настольном компе у вас несколько десятков процессов и 300-800 потоков, и все вылетает из-за этих <censored> таймаутов, а на терминальном сервере будет несколько сотен процессов и эдак под 4-5 тысяч потоков, так что вылетать будет куда чаще. Цитата:
Сообщение от gl00mie
![]() Переписал семейство классов SysExcel на .NET, по ходу дела пришлось добавить несколько новых оберток для интерфейсов Excel, чтобы избавиться от необходимости работать напрямую через COM. Пока повсеместно включать не решился, но результат превзошел все ожидания! При запуске на терминальном сервере с полусотней параллельно работающих пользовательских сессий импорт из Excel через .NET несмотря на нещадные переключения между окнами (которые раньше валили импорт на раз) не только стабильно завершался без ошибок, но и отрабатывал при этом достаточно шустро - в отличие от "залатанного" импорта через COM, где за счет дополнительных try/catch/retry ошибки вроде как маскировались, но приводили к очень ощутимому замедлению работы.
|
|
![]() |
#2 |
Участник
|
2 gl00mie
Можете поподробней рассказать, что значить переписать на .NET ? Проблема взаимодействия Axapta c com-объектами под Windows7 и Winserver 2008 общеизвестна и на сколько я знаю в Microsofte пытаются ее решить, но как то не очень удачно (заплатки с периодическим обращением к объектами и т.д.) |
|
![]() |
#3 |
Участник
|
Взять классы-обертки для работы с Excel и переделать их как-то так (на примере SysExcelCells):
X++: public static client SysExcelCells construct(MSOfficeVersion _version, COM _cells, Microsoft.Office.Interop.Excel.Range _cells_net = null) { if (_cells_net) { return SysExcelCells_NET::construct( _version, _cells_net ); } return new SysExcelCells(_cells, _version); } /////////////////////////////////////////////////////////////////////////////// // реализация обертки для работы с Excel через Microsoft.Office.Interop.Excel class SysExcelCells_NET extends SysExcelCells { Microsoft.Office.Interop.Excel.Range cells_net; } // возвращает ClrObject из пространства имен Microsoft.Office.Interop.Excel, оберткой для которого является экземпляр класса // это часть внутренней инфраструктуры семейства классов SysExcel*, реализующих работу через .NET protected CLRObject clrObject() { return cells_net; } public final COM comObject() { // copy-paste кода метода-обработчика comObject(), общего для классов SysExcel*, реализующих работу через .NET str methodName = strfmt( '%1.%2', classid2name( classidget( this ) ), methodstr(SysExcel, comObject) ); throw error( strfmt( "@SYS75628", methodName, "@SYS95798" ) ); } // способ, которым класс взаимодействует с Excel // это часть внутренней инфраструктуры семейства классов SysExcel* для реализации кое-каких проверок protected final InteropKind getXlInteropKind() { return InteropKind::ClrInterop; } public SysExcelCell item(int _row, int _column) { // предполагаем, что класс может работать и на сервере, при этом вызывающий код не должен знать детали взаимодействия с Excel new InteropPermission( InteropKind::ClrInterop ).assert(); // BP deviation documented return SysExcelCell::construct( version, null, cells_net.get_Item( _row, _column ) ); } protected void new(Microsoft.Office.Interop.Excel.Range _cells_net, MSOfficeVersion _version) { super( null, _version ); cells_net = _cells_net; } public SysExcelRange range(str _range = '') { SysExcelRange ret; ; if (_range != '') { new InteropPermission( InteropKind::ClrInterop ).assert(); // BP deviation documented ret = SysExcelRange::construct( version, null, cells_net.get_Range( _range, this.getClrMissingArg() ) ); } else { ret = SysExcelRange::construct( version, null, cells_net ); } return ret; } public static SysExcelCells_NET construct(MSOfficeVersion _version, Microsoft.Office.Interop.Excel.Range _cells_net) { return new SysExcelCells_NET( _cells_net, _version ); } ![]() Последний раз редактировалось gl00mie; 25.08.2011 в 14:20. Причина: очепятки |
|
|
За это сообщение автора поблагодарили: Stainless (1). |
![]() |
#4 |
Участник
|
Да уж, тема грустная для АХ2009, на АХ4 не было таких явных проблем при шевелении мышкой или кликом на запуск другой проги в момент построения Ехель отчетов.
Мы переписали на .НЕТ проблема снялась, но возникла несовместимость с разными офисами на клиентских местах - решение обсуждалось в какой-то теме, нужно ДЛЛ от офиса 2007 засунуть в БИН на клиенте, тогда на Офис2003 заработает. А тут начала сбоить даже стандартная выгрузка формы (фича АХ2009) в Ехель по кнопочке на форме или Ctrl-E Она ж тоже СОМ и ее наш перепис не коснулся.... и чинят это в МС, судя по году возникновения темы, давно... точнее вообще не чинят, тк потуги try-catch 4 раза - это бутафория, пробовали, фигня-с Вторая панацея помимо .НЕТ, это запуск в потоках (для Ворда решили именно так, так на .Нет он не пошел, лезли неисправимые баги). С потоками все ок, там никто мышкой не пошевелит и не поломает хрупкую конструкцию СОМ вызова. Минус - проблемы с выводом инфолога, тк строится все это "где-то там". |
|
![]() |
#5 |
Участник
|
Вроде в отдельном потоке можно "вырезать" выведенные в нем сообщения через infolog.cut(), вернуть его через Thread.setErrorLog(), и потом вывести это все в основном потоке через infolog.view(). По-моему, куда больше проблем в случае отдельного потока с созданием "обертки" для запуска куска функционала в отдельном потоке, передачи нужных ему данных, etc...
|
|
![]() |
#6 |
Administrator
|
Это скажем так - не проблема. Это особенность, про которую не нужно забывать и выводить надо через Thread.setoutputParm()
Эта проблема одноразовая - один раз сделал, а потом забыл. Правда один раз сделать надо.
__________________
Возможно сделать все. Вопрос времени |
|
Теги |
ax2009, excel |
|
Опции темы | Поиск в этой теме |
Опции просмотра | |
|