AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 08.04.2010, 11:00   #1  
Zabr is offline
Zabr
Участник
Axapta Retail User
 
1,202 / 345 (14) ++++++
Регистрация: 26.06.2002
Адрес: Москва
Ошибка чтения файлов XLS под Windows 7
Такая ситуация. Может кто встречался. Аксапта версии 4.0 SP2. Есть у нас несколько функций по загрузке в Аксапту чего-либо из файлов Excel. Например, накладных поставщиков. Все эти файлы присылаются в версиях Excel не выше 2003. Все эти загрузки великолепно работают на компах под WinXP. И вот стали у нас ставить новые компы с предустановленной Windows 7. Поставили мы туда 2007 офис. И стала в этих загрузках появляться плавающая ошибка:
Код:
Error Сообщение (13:28:19) Ошибка времени выполнения: Метод был вызван с недопустимым числом параметров.
Плавающая в том смысле, что один и тот же файл может загрузиться без ошибки, а потом с ошибкой в ячейке Х, а потом с ошибкой в ячейке Y, а потом опять без ошибки, а потом с ошибкой в ячейке Z.. И т.д.
Причем, в том же 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
Все эти классы на слое sys, то есть модификаций в них не было.

Код метода, где появляется ошибка:

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;
}
Не наблюдалось у кого то глюков в Windows 7 при стыковке Аксапты с MS Office ?

Последний раз редактировалось Zabr; 08.04.2010 в 11:05.
За это сообщение автора поблагодарили: Logger (1).
Старый 08.04.2010, 11:58   #2  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,701 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Полно подобных ошибок при работе с любой версией MS Office в любой Windows. Правда, у меня они возникали при работе через терминал c Word, но, думаю, с Excel все то же самое. Посмотри вот эту тему

Ошибки Word 2003 при работе в терминальном режиме

там в конце я написал что надо и чего не надо делать при работе с MS Office.

Например, не очень корректное открытие файла может вызвать ошибку при разборе содержимого этого файла. Пройдись по всем используемым методам, на предмет корректного обрачивания параметров, передаваемых в Excel в ComVariant.
Старый 08.04.2010, 12:29   #3  
Morpheus is offline
Morpheus
Участник
Аватар для Morpheus
Соотечественники
 
602 / 167 (7) ++++++
Регистрация: 30.03.2005
Адрес: Київ-København-Düsseldorf
Предлагаю попробовать переписать методы заменив вызовы 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  
Zabr is offline
Zabr
Участник
Axapta Retail User
 
1,202 / 345 (14) ++++++
Регистрация: 26.06.2002
Адрес: Москва
Цитата:
Сообщение от Morpheus Посмотреть сообщение
Пример кода создающий csv файл:
У меня Ax 4.0 (было написано выше). А это для какой версии? Не компилируется такое в четверке.
Старый 08.04.2010, 16:23   #5  
Morpheus is offline
Morpheus
Участник
Аватар для Morpheus
Соотечественники
 
602 / 167 (7) ++++++
Регистрация: 30.03.2005
Адрес: Київ-København-Düsseldorf
Цитата:
Сообщение от Zabr Посмотреть сообщение
У меня Ax 4.0 (было написано выше). А это для какой версии? Не компилируется такое в четверке.
Необходимо Microsoft.Office.Interop.Excel добавить в узел References:

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  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,953 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
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  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
А разве так нельзя?
Microsoft.Office.Interop.Excel.XlFileFormat::xlTextWindows
__________________
Axapta v.3.0 sp5 kr2
За это сообщение автора поблагодарили: Logger (2).
Старый 09.03.2011, 11:22   #8  
trud is offline
trud
Участник
Лучший по профессии 2017
 
1,039 / 1633 (57) ++++++++
Регистрация: 07.06.2003
Записей в блоге: 1
Цитата:
Сообщение от Morpheus Посмотреть сообщение
Предлагаю попробовать переписать методы заменив вызовы COM на CLR.
Тут вопрос возник, какой вообще смысл в такой операции. Внутренее то все равно будет работать COM
Т.е. методы COM заменяются на те же методы COM, которые вызываются не прямо, а через еще одно звено в виде CLR. Или я где-то не прав?
Старый 10.03.2011, 15:14   #9  
Damn is offline
Damn
Участник
 
436 / 154 (6) ++++++
Регистрация: 28.05.2003
Адрес: в глуши
Цитата:
Сообщение от Morpheus Посмотреть сообщение
Предлагаю попробовать переписать методы заменив вызовы COM на CLR.

Пример кода создающий csv файл:
А у меня почему-то после обращения к Excel через Microsoft.Office.Interop.Excel (вызов workBooks.open(), workBook.saveas() и затем workBook.close()) в системе всё равно остаётся висеть процесс Excel. Со временем этих процессов становится всё больше и больше. Но оперирую я не csv, а xls-файлами. Использую Win Server 2008.
У всех так ? Может надо что-то ещё вызывать для завершения работы с Excel.
__________________
Дмитрий
Старый 10.03.2011, 18:11   #10  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Как обычно, нужно вызвать Application.Quit()
Старый 11.03.2011, 10:16   #11  
Damn is offline
Damn
Участник
 
436 / 154 (6) ++++++
Регистрация: 28.05.2003
Адрес: в глуши
Не помогает, эффекта от quit() никакого.
И сразу следующий вопрос - работает ли у кого-нибудь весь этот код в пакетном режиме на 64-битном АОСе ?
__________________
Дмитрий
Старый 11.03.2011, 11:33   #12  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
Я бы предложил попробовать использовать класс ComDispFunction вместо прямого вызова методов.

У меня были подобные проблемы при использовании стороннего Com-класса под Win7 и Win2008R2 (кстати, в DAX3.0)
Вылечилось переписыванием всех вызовов.
__________________
Axapta v.3.0 sp5 kr2
За это сообщение автора поблагодарили: Logger (5).
Старый 06.05.2011, 11:03   #13  
gogen600 is offline
gogen600
Участник
 
1 / 14 (1) ++
Регистрация: 24.04.2007
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  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Angry Подстава с чтением значений типа дата из ячеек при использовании свойства Range.Value2()
Сегодня столкнулся с откровенной подставой со стороны Excel. Исходные данные:
  • файл в формате Excel 2003, полученный извне, в нем несколько колонок с датами и установленным форматом ячеек "Дата" (дд.мм.гггг)
  • Excel 2010 версии 14.0.6024.1000
  • переписанное на .NET семейство классов SysExcel, с помощью которого читаются данные
  • в SysExcelRange для удобства добавлен метод, который читает значение ячейки с помощью get_Value2() и возвращает его сконвертированным в желаемый базовый аксаптовский тип.
Так вот, оказалось, что для этих ячеек типа "Дата" методы get_Value(Microsoft.Office.Interop.Excel.XlRangeValueDataType::xlRangeValueDefault) и get_Value2() возвращают значения разных типов: первый - типа System.DateTime с нормальной датой/временем (той, которую я вижу в файле), а второй - типа System.Double со значением числа дней от начала "эпохи", НО! когда это значение скармливаешь аксаптовской функции num2date(), получается дата на 2 дня позже, чем в файле! Я в принципе наслышан про "особенности" Excel в плане работы с датами, но вот чтоб такие подставы... В общем, я переделал SysExcelRange на использование get_Value(), и все рассосалось.
За это сообщение автора поблагодарили: Logger (6).
Старый 05.09.2011, 12:52   #15  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Выложил семейство классов SysExcel, переписанное на работу через .NET, см. Взаимодействие с Excel через .NET (семейство классов SysExcel)
Теги
.net, ax2009, ax4.0, com-объект, excel, импорт данных, импорт файла

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Установка DAX 4.0 под локальным пользователем на Windows XP shogel DAX: База знаний и проекты 81 07.04.2010 16:42
emeadaxsupport: Group policy setting "System Objects: Default owner for objects created by members of the administrators group" is missing on Windows Server 2008 Blog bot DAX Blogs 2 28.08.2009 02:14
axaptafreak: Running Dynamics AX 2009 on Windows 7 using Windows Virtual XP Blog bot DAX Blogs 3 24.07.2009 11:20
Client Axapta 3.0 SP4 и Linux. Как запустить? Daiver DAX: Администрирование 10 28.06.2007 15:59
Русская локализация Axapta 3 ? SlavaK DAX: Администрирование 59 01.07.2003 22:38

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 19:40.