08.04.2010, 11:00 | #1 |
Участник
|
Ошибка чтения файлов XLS под Windows 7
Такая ситуация. Может кто встречался. Аксапта версии 4.0 SP2. Есть у нас несколько функций по загрузке в Аксапту чего-либо из файлов Excel. Например, накладных поставщиков. Все эти файлы присылаются в версиях Excel не выше 2003. Все эти загрузки великолепно работают на компах под WinXP. И вот стали у нас ставить новые компы с предустановленной Windows 7. Поставили мы туда 2007 офис. И стала в этих загрузках появляться плавающая ошибка:
Код: Error Сообщение (13:28:19) Ошибка времени выполнения: Метод был вызван с недопустимым числом параметров. Причем, в том же 2007 офисе, установленном на WinXP, ошибки нет. А на Windows 7 ошибка есть. Установка 2003 офиса на тот же Windows 7 не помогает, дает ту же ошибку. Чего-то значит сломалось в Windows 7, похоже в каких-то библиотеках по работе с com-объектами. Стек вызовов такой (название нашего класса опускаю, даю стек начиная со стандартных классов по работе с excel: Код: Трассировка стека (C)\Classes\COM\value (C)\Classes\SysExcelCell_XP\value - line 12 (C)\Classes\SysDataExcelCOMFree\readRow - line 38 (C)\Classes\SysDataExcelCOM\read - line 11 (C)\Classes\SysDataImportExcel\read - line 3 (C)\Classes\SysDataImportDefBase\importFilename - line 38 (C)\Classes\SysDataImportExcel\importFilename - line 6 (C)\Classes\SysDataImportDefBase\import - line 23 (C)\Classes\SysDataImportExcel\import - line 10 (C)\Classes\SysDataImportDefBase\run - line 5 Код метода, где появляется ошибка: X++: public COMVariant value(anytype _value = COMArgument::NoValue) { COMVariant ret; ; if (!prmisdefault(_value)) { ret = cell.value(#xlRangeValueDefault,_value); } else { ret = cell.value(#xlRangeValueDefault); // ВОТ В ЭТОЙ СТРОКЕ ПОЯВЛЯЕТСЯ ОШИБКА } return ret; } Последний раз редактировалось Zabr; 08.04.2010 в 11:05. |
|
|
За это сообщение автора поблагодарили: Logger (1). |
08.04.2010, 11:58 | #2 |
Участник
|
Полно подобных ошибок при работе с любой версией MS Office в любой Windows. Правда, у меня они возникали при работе через терминал c Word, но, думаю, с Excel все то же самое. Посмотри вот эту тему
Ошибки Word 2003 при работе в терминальном режиме там в конце я написал что надо и чего не надо делать при работе с MS Office. Например, не очень корректное открытие файла может вызвать ошибку при разборе содержимого этого файла. Пройдись по всем используемым методам, на предмет корректного обрачивания параметров, передаваемых в Excel в ComVariant. |
|
08.04.2010, 12:29 | #3 |
Участник
|
Предлагаю попробовать переписать методы заменив вызовы COM на CLR.
Пример кода создающий csv файл: X++: protected FileName excel2csv(FileName _excelFileName) { Microsoft.Office.Interop.Excel._Application excel; Microsoft.Office.Interop.Excel.Workbooks workbooks; Microsoft.Office.Interop.Excel._Workbook workbook; System.Type type; System.Reflection.FieldInfo fieldInfo; System.Object missing; Microsoft.Office.Interop.Excel.XlFileFormat fileFormat; Microsoft.Office.Interop.Excel.XlSaveAsAccessMode saveAsAccessMode; FileName textFileName; FileName path; FileName name; FileName extention; ; new InteropPermission(InteropKind::ClrInterop).assert(); [path, name, extention] = fileNameSplit(_excelFileName); textFileName = path + name + '.csv'; if (System.IO.File::Exists(textFileName)) System.IO.File::Delete(textFileName); type = System.Type::GetType('System.Reflection.Missing'); fieldInfo = type.GetField('Value'); missing = fieldInfo.GetValue(null); fileFormat = ClrInterop::parseClrEnum('Microsoft.Office.Interop.Excel.XlFileFormat', 'xlTextWindows'); saveAsAccessMode = ClrInterop::parseClrEnum('Microsoft.Office.Interop.Excel.XlSaveAsAccessMode', 'xlNoChange'); excel = new Microsoft.Office.Interop.Excel.ApplicationClass(); workbooks = excel.get_Workbooks(); workbook = workbooks._Open(_excelFileName, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing); workbook.SaveAs(textFileName, fileFormat, missing, missing, missing, missing, saveAsAccessMode, missing, missing, missing, missing, missing); workbook.Close(false, _excelFileName, null); CodeAccessPermission::revertAssert(); return textFileName; } |
|
|
За это сообщение автора поблагодарили: Logger (4), gl00mie (5), Batuev Artem (0). |
08.04.2010, 15:21 | #4 |
Участник
|
|
|
08.04.2010, 16:23 | #5 |
Участник
|
Цитата:
Procedure - Reference a New Assembly in the AOT Use the following procedure to reference a new assembly in the AOT: 1. Right-click AOT > References. 2. Select Add Reference. 3. The Add Reference form appears. 4. The Add reference form contains all the assemblies that have been registered in the Global Assembly Cache (GAC). However, you are not restricted to just these assemblies. Click the Browse… button to select an assembly from another location. |
|
|
За это сообщение автора поблагодарили: Zabr (4). |
14.01.2011, 01:05 | #6 |
Участник
|
X++: fileFormat = ClrInterop::parseClrEnum('Microsoft.Office.Interop.Excel.XlFileFormat', 'xlTextWindows'); saveAsAccessMode = ClrInterop::parseClrEnum('Microsoft.Office.Interop.Excel.XlSaveAsAccessMode', 'xlNoChange'); |
|
14.01.2011, 10:08 | #7 |
Участник
|
А разве так нельзя?
Microsoft.Office.Interop.Excel.XlFileFormat::xlTextWindows
__________________
Axapta v.3.0 sp5 kr2 |
|
|
За это сообщение автора поблагодарили: Logger (2). |
09.03.2011, 11:22 | #8 |
Участник
|
Тут вопрос возник, какой вообще смысл в такой операции. Внутренее то все равно будет работать COM
Т.е. методы COM заменяются на те же методы COM, которые вызываются не прямо, а через еще одно звено в виде CLR. Или я где-то не прав? |
|
10.03.2011, 15:14 | #9 |
Участник
|
Цитата:
У всех так ? Может надо что-то ещё вызывать для завершения работы с Excel.
__________________
Дмитрий |
|
10.03.2011, 18:11 | #10 |
Участник
|
Как обычно, нужно вызвать Application.Quit()
|
|
11.03.2011, 10:16 | #11 |
Участник
|
Не помогает, эффекта от quit() никакого.
И сразу следующий вопрос - работает ли у кого-нибудь весь этот код в пакетном режиме на 64-битном АОСе ?
__________________
Дмитрий |
|
11.03.2011, 11:33 | #12 |
Участник
|
Я бы предложил попробовать использовать класс ComDispFunction вместо прямого вызова методов.
У меня были подобные проблемы при использовании стороннего Com-класса под Win7 и Win2008R2 (кстати, в DAX3.0) Вылечилось переписыванием всех вызовов.
__________________
Axapta v.3.0 sp5 kr2 |
|
|
За это сообщение автора поблагодарили: Logger (5). |
06.05.2011, 11:03 | #13 |
Участник
|
to Damn:
Прибить эксель из памяти поможет Garbage Collector: ... new InteropPermission(InteropKind::ClrInterop).assert(); excel = null; System.GC::Collect(); System.GC::WaitForPendingFinalizers(); CodeAccessPermission::revertAssert(); |
|
|
За это сообщение автора поблагодарили: sukhanchik (4). |
23.08.2011, 19:05 | #14 |
Участник
|
Подстава с чтением значений типа дата из ячеек при использовании свойства Range.Value2()
Сегодня столкнулся с откровенной подставой со стороны Excel. Исходные данные:
|
|
|
За это сообщение автора поблагодарили: Logger (6). |
05.09.2011, 12:52 | #15 |
Участник
|
Выложил семейство классов SysExcel, переписанное на работу через .NET, см. Взаимодействие с Excel через .NET (семейство классов SysExcel)
|
|
Теги |
.net, ax2009, ax4.0, com-объект, excel, импорт данных, импорт файла |
|
|