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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 09.07.2010, 16:43   #1  
Toto is offline
Toto
Участник
 
2 / 10 (1) +
Регистрация: 09.07.2010
Ошибка времени выполнения в ComExcelDocument_RU.findRange()
DAX 2009 и Excel 2007.

При вызове метода insertRows класса ComExcelDocument_RU, по непонятным мне причинам, на одних и тех же данных время от времени вываливается ошибка времени выполнения "неправильные типы аргументов в операции присвоения значения переменной" на 18 строке метода findRange
X++:
comApplication = m_comDocument.application();
. Если пошагово под отладчиком пройти данные методы, то ошибки не возникает, но стоит запустить на выполнение в нормальном режиме - может возникнуть ошибка.

метод insertRows
X++:
void insertRows(int _fromRow,
                int _toRow,
                int _fromWorkSheet = 1,
                int _offset        = 1,
                int _numOfCopies   = 1,
                // CIT_MSOfficeReport, kirp -->
                /*
                int _toWorkSheet   = 1)
                */
                int                 _toWorkSheet        = 1,
                MSOfficeBookMark_RU _copyFromBookmark   = "")
                // CIT_MSOfficeReport, kirp <--
{
    COM         comRows,
                comWorkSheet,
                comRow, comRowTarget, selection;
    COMVariant  comRowVariant, selVariant;
    ;

    if (_numOfCopies <= 0)
        return;

    if (! m_comDocument)
        throw error(strfmt("@GEE6401", this.getApplicationName()));

    // CIT_MSOfficeReport, kirp -->
    if (_copyFromBookmark)
    {
        comRow = this.findRange(_copyFromBookmark, _fromWorkSheet);
        comRow.copy();
    }
    else
    {
    // CIT_MSOfficeReport, kirp <--

        comRow = this.findRange(strFmt("%1:%2", _fromRow, _toRow), _fromWorkSheet);
        comRow.copy();
    // CIT_MSOfficeReport, kirp -->
    }
    // CIT_MSOfficeReport, kirp <--

    comRowTarget = this.findRange(strFmt("%1:%2", _fromRow + _offset, _fromRow + _offset + (_toRow - _fromRow + 1) * _numOfCopies - 1), _toWorkSheet);
    comRowTarget.select();
    comRowTarget.insert();

    comWorkSheet  = this.getWorkSheet(_toWorkSheet);
    comRows = comWorkSheet.cells();
    comRows = COM::createFromVariant(comRows.item(1));
    comRows.select();
    m_comApplication.cutCopyMode(false);
}
метод findRange
X++:
// Creates object range type named the same way as Excel bookmark
// bookMark -> Excel bookmark name
// CIT_MSOfficeReport, ilso -->
/*
protected COM findRange(MSOfficeBookMark_RU bookMark, int _workSheet = 1)
*/
public COM findRange(MSOfficeBookMark_RU bookMark, int _workSheet = 1)
// CIT_MSOfficeReport, ilso <--
{
    COM comRange,
        comWorkSheet;
    COM comApplication;
    ;

    if (m_comDocument)
    {
        comWorkSheet   = this.getWorkSheet(_workSheet);
        comApplication = m_comDocument.application();
        comWorkSheet.activate();

        if (comWorkSheet && comApplication)
        {
            comRange = comApplication.range(bookMark);
        }
    }
    return comRange;
}
insertRows вызывается с первыми 5 параметрами.
Подскажите, пожалуйста, в чем может быть дело.

PS. В поиске ничего не нашел.
Старый 09.07.2010, 17:30   #2  
AlexSD is offline
AlexSD
Microsoft Dynamics
Сотрудники Microsoft Dynamics
 
257 / 302 (11) ++++++
Регистрация: 14.10.2003
В таймаутах. В РУ4 или РУ5 были добавлены пара макросов StartSafeCall_RU и EndSafeCall_RU. Пример их использования можно посмотреть в методах класса LedgerRRGRunReport_RU. Например, в addWorksheets(...), outputValue(...) и removeWorksheets(...).
Это должно Вам помочь.
За это сообщение автора поблагодарили: alexbn (1), Logger (4), Daiver (1), AlexArh (1), alex55 (1), Андрей К. (1).
Старый 12.07.2010, 18:16   #3  
Toto is offline
Toto
Участник
 
2 / 10 (1) +
Регистрация: 09.07.2010
Спасибо, буду разбираться.
Старый 13.01.2011, 20:45   #4  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
А может кто-нить разъяснить, что за таймауты такие появились, где про них написано, и в чем суть макроса EndSafeCall_RU? Я так понимаю, он просто при возникновении ошибки пытается повторно вызвать обрамленный макросами код указанное число раз, делая небольшие паузы между повторами. Зачем для этого используется такая конструкция?
X++:
#define.safeCallTimeOut(250)
#define.safeCallNotifyMethod('notify')
infolog.addTimeOut(infolog, #safeCallNotifyMethod, #safeCallTimeOut);
infolog.wait();
retry;
Почему просто не использовать какой-нить sleep?
Старый 13.01.2011, 22:29   #5  
Zabr is offline
Zabr
Участник
Axapta Retail User
 
1,202 / 345 (14) ++++++
Регистрация: 26.06.2002
Адрес: Москва
Это из той же оперы ? Ошибка чтения файлов XLS под Windows 7
Но это в АХ.4sp2. Так и не победили пока.
Старый 13.01.2011, 23:23   #6  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
А фиг знает, может, и из той же. Сейчас вот вылечился экспорт данных в Excel через ComExcelDocument_RU, который, зараза, валился буквально от любого чиха: мышкой не туда ткнешь - и привет. Вылечилось обрамлением шаманскими макросами вызовов методов COM-объектов в методах findRange, getWorkSheet, insertValueInRange.
Старый 13.01.2011, 23:57   #7  
AlexSD is offline
AlexSD
Microsoft Dynamics
Сотрудники Microsoft Dynamics
 
257 / 302 (11) ++++++
Регистрация: 14.10.2003
Я этот прием подсмотрел в функции выгрузки данных таблицы в ексель. Немного причесал для своих целей и оформил для удобства ввиде пары макросов.
Почему не sleep? Не помню. Может, потому что sleep замораживал бы систему. А может, по какой-то другой причине.
Старый 14.01.2011, 12:00   #8  
kashperuk is offline
kashperuk
Участник
Аватар для kashperuk
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,361 / 2084 (78) +++++++++
Регистрация: 30.05.2004
Адрес: Atlanta, GA, USA
Видимо не такой уж он был и safe, этот timeout
Старый 14.01.2011, 13:09   #9  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,941 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от kashperuk Посмотреть сообщение
Видимо не такой уж он был и safe, этот timeout
Да тут не до смеха.
Нам тут рекламируют везде, что в каждой следующей версии улучшается интеграция DAX со всем чем можно на свете, а с офисом и подавно. Но что-то не очень на это похоже. По крайней мере в 3-ке таких проблем не было, либо они было крайне редкими. Неужели уж такие баги нельзя закрыть ?
Старый 14.01.2011, 13:19   #10  
AlexSD is offline
AlexSD
Microsoft Dynamics
Сотрудники Microsoft Dynamics
 
257 / 302 (11) ++++++
Регистрация: 14.10.2003
Цитата:
Сообщение от Logger Посмотреть сообщение
Да тут не до смеха.
По крайней мере в 3-ке таких проблем не было, либо они было крайне редкими. Неужели уж такие баги нельзя закрыть ?
По моему мнению проблема таймаутов заключается не в Аксапте, а в новых офисах.

У вас какой офис был, когда вы в трешке работали? Попробуйте с ним же поработать в 2009-ой.

По поводу багов, что вы имеете ввиду?
Старый 14.01.2011, 13:22   #11  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,941 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Если бы в новых офисах !
У нас используются терминальные сервера, на которых стоит 2003-й офис и при переходе на с трешки на 2009-ю Аксапту мы их не меняли. Просто доустановили клиента DAX 2009 на терминальные сервера и все.
Старый 14.01.2011, 13:24   #12  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,941 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от AlexSD Посмотреть сообщение
По поводу багов, что вы имеете ввиду?
Считаю что такая нестабильная работа с офисом - это баг. По сути каждый чих вынужден обрабатывать программист из кода X++.
Если все правильно делать, то этим должно заниматься ядро.

Есть и друге баги. Чуть попозже выложу описание.
Старый 14.01.2011, 17:00   #13  
AlexSD is offline
AlexSD
Microsoft Dynamics
Сотрудники Microsoft Dynamics
 
257 / 302 (11) ++++++
Регистрация: 14.10.2003
Ну, не в офисе, так не в офисе. У меня сложилось такое мнение, поскольку новые проблемы приходили после установки нового офиса.

По поводу, чем должно заниматься ядро, чем нет. Я не думаю, что именно ядро ответственно за то, каким образом вы решаете свои функциональные задачи. Не нравится как работает COM, пользуйтесь XML, буфером обмена или другими вариантами.

Кстати, я сам не проверял, но если вызывать офисные COM объекты из какой-нибудь другой среды,скажем из программы на .net, то там все проходит гладко? Без необходимости использования таймаутов? Или те же самые грабли?
Старый 14.01.2011, 17:17   #14  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,941 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Про другие системы я тоже не проверял.
Если 3-ку считать другой системой - то в ней работало.

Вам кстати отдельное спасибо за
Ошибка времени выполнения в ComExcelDocument_RU.findRange()
сами мы еще долго могли бы ковыряться в поисках решения проблемы.
Старый 17.01.2011, 13:54   #15  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Таймауты и повтор кода - это не решение проблемы. Это временная "затычка", чтобы "отвязались". Но рано или поздно это все равно "выйдет боком". Т.е. возникнет ситуация когда даже многократный повтор ничем не поможет. Я с этим уже много раз и в разных ситуациях сталкивался.

Как мне кажется, в данном случае, проблема носит общий характер. Здесь "виноваты" все 3 участника: Windows, Excel и Axapta. В разной степени и по разным причинам, но именно все вместе.

Со стороны ядра Axapta - явно не вполне корректная работа с COM-объектами. Начиная с конвертации переменных и кончая работой с "многочленами". Все время приходится "пальцем придерживать"

Со стороны Excel - какая-то проблема с загрузкой COM-интерфейса. Иногда как следствие каких-либо системных сообщений, которые при работе через Com-интерфейс не видны, но сам факт их появления блокирует дальнейшую работу

Ну, а собственно Windows, вероятно, может являться причиной проблем загрузки COM-интерфейса. Разумеется, это лишь мое предположение.
Старый 28.02.2011, 14:04   #16  
AndreyStar is offline
AndreyStar
Участник
 
11 / 23 (1) +++
Регистрация: 01.04.2004
Тоже столкнулись с этой проблемой, идея сделать как в российском функционале, с макросами на try catch очень не понравилась, да и объем переписывания немалый

Проблема возникала только на системах с Win7, XP + Office 2010 + dax 2009 работало без проблем

Когда искал причину, увидел что в других языках обращения к COM компилируются с атрибутом [STAThread] - однопоточное исполнение, ну и появилась мысль что многопоточность Win7 мешает жить. Попытка запустить dax2009 в режиме совместимости чуть улучшила ситуацию, но проблему не решила и тогда пришла идея запустить класс экспорта в отдельном потоке, и все заработало

Сейчас все протестировано в разных связках, в том числе и в 64-битной системе, все работает, и переписывать нужно только способ запуска класса
За это сообщение автора поблагодарили: Logger (5), Ace of Database (2), coolibin (1), vc (1), alex55 (1), someOne (1).
Старый 02.03.2011, 11:41   #17  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,438 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от gl00mie Посмотреть сообщение
Сейчас вот вылечился экспорт данных в Excel через ComExcelDocument_RU, который, зараза, валился буквально от любого чиха: мышкой не туда ткнешь - и привет. Вылечилось обрамлением шаманскими макросами вызовов методов COM-объектов в методах findRange, getWorkSheet, insertValueInRange.
gl00mie, а не могли бы вы разместить в этой теме коды этих макросов и переписанных методов ComExcelDocument_RU. Для тех у кого ещё нет спасительного rollup
Старый 02.03.2011, 12:58   #18  
someOne is offline
someOne
Участник
Аватар для someOne
 
174 / 429 (15) +++++++
Регистрация: 11.12.2008
Адрес: Москва
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
gl00mie, а не могли бы вы разместить в этой теме коды этих макросов и переписанных методов ComExcelDocument_RU. Для тех у кого ещё нет спасительного rollup
Пробовал "играть" с макросами. Они помогают не всегда либо не помогают вообще!!!

Вот код макроса EndSafeCall_RU :

X++:
// %1 retry count by default 4
// %2 time out by default 250
// %3 exception type by default Exception::Error

#ifnot.empty(%1)
    #define.safeCallRetryCount(%1)
#endif
#if.empty(%1)
    #define.safeCallRetryCount(4)
#endif

#ifnot.empty(%2)
    #define.safeCallTimeOut(%2)
#endif
#if.empty(%2)
    #define.safeCallTimeOut(250)
#endif

#ifnot.empty(%3)
    #define.safeCallExceptionType(%3)
#endif
#if.empty(%3)
    #define.safeCallExceptionType(Exception::Error)
#endif

catch (#safeCallExceptionType)
{
    if (xSession::currentRetryCount() >= #safeCallRetryCount)
    {
        throw #safeCallExceptionType;
    }
    else
    {
        #define.safeCallNotifyMethod('notify')
        infolog.clear(0);

        infolog.addTimeOut(infolog, #safeCallNotifyMethod, #safeCallTimeOut);
        infolog.wait();

        retry;
    }
}
И StartSafeCall_RU:
X++:
try
Только это как "мертвому припарки"

Может лучше копать в сторону "однопоточного" запуска, предложенного AndreyStar ?
Кто знает как это делать ?
Через thread ? Но это ведь тоже определенное извращение...
За это сообщение автора поблагодарили: S.Kuskov (1).
Старый 02.03.2011, 13:29   #19  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,941 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от AndreyStar Посмотреть сообщение
Когда искал причину, увидел что в других языках обращения к COM компилируются с атрибутом [STAThread] - однопоточное исполнение, ну и появилась мысль что многопоточность Win7 мешает жить. Попытка запустить dax2009 в режиме совместимости чуть улучшила ситуацию, но проблему не решила и тогда пришла идея запустить класс экспорта в отдельном потоке, и все заработало

Сейчас все протестировано в разных связках, в том числе и в 64-битной системе, все работает, и переписывать нужно только способ запуска класса
Не могли бы подробнее рассказать что нужно сделать ?
Старый 02.03.2011, 14:12   #20  
someOne is offline
someOne
Участник
Аватар для someOne
 
174 / 429 (15) +++++++
Регистрация: 11.12.2008
Адрес: Москва
Цитата:
Сообщение от AndreyStar Посмотреть сообщение
Тоже столкнулись с этой проблемой, идея сделать как в российском функционале, с макросами на try catch очень не понравилась, да и объем переписывания немалый

Проблема возникала только на системах с Win7, XP + Office 2010 + dax 2009 работало без проблем

Когда искал причину, увидел что в других языках обращения к COM компилируются с атрибутом [STAThread] - однопоточное исполнение, ну и появилась мысль что многопоточность Win7 мешает жить. Попытка запустить dax2009 в режиме совместимости чуть улучшила ситуацию, но проблему не решила и тогда пришла идея запустить класс экспорта в отдельном потоке, и все заработало

Сейчас все протестировано в разных связках, в том числе и в 64-битной системе, все работает, и переписывать нужно только способ запуска класса
Кажется понял как это работает.

Запускаем импорт из екселя, например, так
X++:
thread    thread = new thread();

     thread.setInputParm(["Т000081968", "c:\text.xlsx"]); // какие то параметры

     thread.run(classnum(TetImportClass), identifierstr(importFromExcel));
А сам метод импорта в классе TetImportClass
X++:
static client void importFromExcel(thread _thread)

ComExcelDocument_RU        document = new ComExcelDocument_RU();
str path;
str parm;
;
[parm, path] = _thread.getInputParm();

    document.open(path, false);

    .....
     ....
Думаю, так импорт не получится прервать передвиганием мыши или переключением окон, так как импорт проходит в отдельном потоке. И ошибок не будет.
Какое никакое, но все же решение.
Только теперь ряд других проблем имеется, например перехват ошибок и вывод их на экран - не тривиальная задача. Но решаемая.
За это сообщение автора поблагодарили: Logger (3), Ace of Database (5).
Теги
com-объект, excel, thread, асинхронный com, ошибка

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Ошибка времени выполнения DmitryS DAX: Администрирование 5 17.06.2010 13:14
Ошибка времени выполнения: В NumberSeqReference_Empl_RU (Объект), не найден исполнимый код метода "loadModule" Ksju DAX: Функционал 14 21.10.2009 13:00
Ошибка времени выполнения Stas[SNRC] DAX: Программирование 6 12.03.2008 12:21
Ошибка времени выполнения Didukh84 DAX: Программирование 19 06.03.2008 09:11
Ошибка времени выполнения: Binary (Объект), метод string вызван с недопустимыми параметрами. mmm DAX: Программирование 4 15.05.2007 16:00
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

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

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

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