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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 14.03.2016, 08:33   #1  
terraByteG is offline
terraByteG
Участник
 
15 / 17 (1) ++
Регистрация: 10.03.2016
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Я не в курсе, но разве после того, как макрос Excel завершил свою работу, созданные в этом макросе переменные не освобождаются? Или как организована работа с этим Com-объектом в Excel?
Как там внутри устроено - науке не известно. Как я понял, авторы заверяют - что у них все отрабатывает на 100%, а значит проблемы индейцев шерифа не волнуют.

Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
В данном случае, предположительно, происходит не корректная выгрузка объекта из памяти. Какие-то следы остаются. Причем ошибка не Axapta, а именно самого объекта. Вот это и надо проверить перезапустив Excel с этим Com-объектом.
Поддерживаю. Самое забавное, что в библиотеке отсутствует метод завершения всего этого действа (или нет, например, Close()?). Хотя бы handle возвращал, можно было бы аварийно excel бахать.
Старый 14.03.2016, 15:39   #2  
vikuss2006 is offline
vikuss2006
Участник
 
42 / 10 (1) +
Регистрация: 22.11.2013
Никакого закрытия в библиотеке нет, только Login и получение данных, к сожалению

Последний раз редактировалось vikuss2006; 14.03.2016 в 15:55.
Старый 15.03.2016, 19:57   #3  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,715 / 1204 (44) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Если обернуть вызов в ComDispFunction() не поможет?

X++:
static void test_Com(Args _args)
{
    Com     comApplication;
    str     ret;
    str     s;

    ComDispFunction funcGet;
    COMVariant      varArgStr1;
    COMVariant      varArgStr2;
    COMVariant      varArgStr3;
    COMVariant      varArgStr4;
    ComVariant      varRet;

    ;
    
    try
    {
        comApplication = new COM("iDocIntegrator.DocOperation");
        if(!comApplication)
        {
            info("error");
            return;
        }

        // Вместо прямого вызова, сделать вызов через ComDispFunction
        //ret = comApplication.Login("login", "pass", "pass", "D:\key");

        // Функция
        funcGet = new ComDispFunction(comApplication, "Login", COMDispContext::PropertyGet);

        // Параметры
        varArgStr1 = COMVariant::createFromStr("login");
        varArgStr2 = COMVariant::createFromStr("pass");
        varArgStr3 = COMVariant::createFromStr("pass");
        varArgStr4 = COMVariant::createFromStr("D:\key");
 
        // Возвращаемое значение
        varRet  = new COMVariant(COMVariantInOut::OUT_RETVAL, COMVariantType::VT_BSTR);

        // Выполнение
        funcGet.call(varArgStr1, varArgStr2, varArgStr3, varArgStr4, varRet);
 
        // Результат выполнения
        ret = varRet.bStr();
 
        
        if(!ret)
        {
            // Вместо прямого вызова, сделать вызов через ComDispFunction
            //s = comApplication.GetDocInfoList("20160218", "20160218");

            // Функция
            funcGet = new ComDispFunction(comApplication, "GetDocInfoList", COMDispContext::PropertyGet);

            // Параметры
            varArgStr1 = COMVariant::createFromStr("20160218");
            varArgStr2 = COMVariant::createFromStr("20160218");
            
            // Возвращаемое значение
            varRet  = new COMVariant(COMVariantInOut::OUT_RETVAL, COMVariantType::VT_BSTR);

            // Выполнение
            funcGet.call(varArgStr1, varArgStr2, varRet);
            
            // Результат выполнения
            s = varRet.bStr();
            info(s);
        }
        else
        {
            info(ret);
        }
        comApplication = null;
    }
    catch(Exception::Error)
    {
        comApplication = null;
        throw error("Обработка отменена!");
    }

    comApplication = null;
    
    info('end');
}
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 17.03.2016, 12:56   #4  
vikuss2006 is offline
vikuss2006
Участник
 
42 / 10 (1) +
Регистрация: 22.11.2013
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Если обернуть вызов в ComDispFunction() не поможет?

X++:
static void test_Com(Args _args)
{
    Com     comApplication;
    str     ret;
    str     s;

    ComDispFunction funcGet;
    COMVariant      varArgStr1;
    COMVariant      varArgStr2;
    COMVariant      varArgStr3;
    COMVariant      varArgStr4;
    ComVariant      varRet;

    ;
    
    try
    {
        comApplication = new COM("iDocIntegrator.DocOperation");
        if(!comApplication)
        {
            info("error");
            return;
        }

        // Вместо прямого вызова, сделать вызов через ComDispFunction
        //ret = comApplication.Login("login", "pass", "pass", "D:\key");

        // Функция
        funcGet = new ComDispFunction(comApplication, "Login", COMDispContext::PropertyGet);

        // Параметры
        varArgStr1 = COMVariant::createFromStr("login");
        varArgStr2 = COMVariant::createFromStr("pass");
        varArgStr3 = COMVariant::createFromStr("pass");
        varArgStr4 = COMVariant::createFromStr("D:\key");
 
        // Возвращаемое значение
        varRet  = new COMVariant(COMVariantInOut::OUT_RETVAL, COMVariantType::VT_BSTR);

        // Выполнение
        funcGet.call(varArgStr1, varArgStr2, varArgStr3, varArgStr4, varRet);
 
        // Результат выполнения
        ret = varRet.bStr();
 
        
        if(!ret)
        {
            // Вместо прямого вызова, сделать вызов через ComDispFunction
            //s = comApplication.GetDocInfoList("20160218", "20160218");

            // Функция
            funcGet = new ComDispFunction(comApplication, "GetDocInfoList", COMDispContext::PropertyGet);

            // Параметры
            varArgStr1 = COMVariant::createFromStr("20160218");
            varArgStr2 = COMVariant::createFromStr("20160218");
            
            // Возвращаемое значение
            varRet  = new COMVariant(COMVariantInOut::OUT_RETVAL, COMVariantType::VT_BSTR);

            // Выполнение
            funcGet.call(varArgStr1, varArgStr2, varRet);
            
            // Результат выполнения
            s = varRet.bStr();
            info(s);
        }
        else
        {
            info(ret);
        }
        comApplication = null;
    }
    catch(Exception::Error)
    {
        comApplication = null;
        throw error("Обработка отменена!");
    }

    comApplication = null;
    
    info('end');
}
Опять ошибка:
<?xml version="1.0" encoding="windows-1251"?><ERROR>Access violation at address 1105C5CF in module 'libeay32.dll'. Write of address 0889E338</ERROR>
Старый 18.03.2016, 16:04   #5  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,715 / 1204 (44) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от vikuss2006 Посмотреть сообщение
Опять ошибка:
<?xml version="1.0" encoding="windows-1251"?><ERROR>Access violation at address 1105C5CF in module 'libeay32.dll'. Write of address 0889E338</ERROR>
А Вы не могли бы на время тестирования отключить антивирус, если он у Вас есть? Может быть, он блокирует библиотеку?

И еще, думаю, не принципиально, но все-таки, первой командой в примере Excel идет выборка списка документов.

X++:
MsgBox "Получение списка архивных документов за период"
Call testGetDocInfoList(o)
И только потом конкретный документ. Может, Вам сделать то же самое?

X++:
XML xml;

(...)

xml = comApplication.GetDocInfoList()
info(xml)
PS: А Вы не узнавали у разработчиков, почему их библиотека не выгружается из памяти при работе с Excel? Вроде бы прямое обнуление идет

Set o = Nothing
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 21.03.2016, 10:43   #6  
vikuss2006 is offline
vikuss2006
Участник
 
42 / 10 (1) +
Регистрация: 22.11.2013
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
А Вы не могли бы на время тестирования отключить антивирус, если он у Вас есть? Может быть, он блокирует библиотеку?

И еще, думаю, не принципиально, но все-таки, первой командой в примере Excel идет выборка списка документов.

X++:
MsgBox "Получение списка архивных документов за период"
Call testGetDocInfoList(o)
И только потом конкретный документ. Может, Вам сделать то же самое?

X++:
XML xml;

(...)

xml = comApplication.GetDocInfoList()
info(xml)
PS: А Вы не узнавали у разработчиков, почему их библиотека не выгружается из памяти при работе с Excel? Вроде бы прямое обнуление идет

Set o = Nothing
Попробовала отключать антивирус, и получать список документов после Login, но все равно выскакивает та же ошибка:
Метод 'GetDocInfoList' в COM-объекте класса '{A6103CA4-D33A-48A5-BB08-7893A12BE5D8}' возвратил код ошибки 0x8000FFFF (<неизвестно>), который означает: Вы не вошли в систему!.
Старый 21.03.2016, 10:48   #7  
vikuss2006 is offline
vikuss2006
Участник
 
42 / 10 (1) +
Регистрация: 22.11.2013
И еще, у разработчиков я узнавала, почему библиотека выгружается из памяти, ничего не ответили, единственное, что сказали, и то не разработчики,а техническая поддержка банка, что они не знают, как будет вести себя библиотека при одновременных запусках.
Старый 23.03.2016, 08:39   #8  
terraByteG is offline
terraByteG
Участник
 
15 / 17 (1) ++
Регистрация: 10.03.2016
Так понимаю, что run - не объявлен как статический...
X++:
t = new Thread();
//t.removeOnComplete(true);
t.run(classnum(FCH_ThreadDemo), staticmethodstr(FCH_ThreadDemo, run));
Старый 23.03.2016, 08:53   #9  
vikuss2006 is offline
vikuss2006
Участник
 
42 / 10 (1) +
Регистрация: 22.11.2013
Цитата:
Сообщение от terraByteG Посмотреть сообщение
Так понимаю, что run - не объявлен как статический...
X++:
t = new Thread();
//t.removeOnComplete(true);
t.run(classnum(FCH_ThreadDemo), staticmethodstr(FCH_ThreadDemo, run));
class FCH_ThreadDemo
{
}
static client void main()
{
Thread t;
;
t = new Thread();
//t.removeOnComplete(true);
t.run(classnum(FCH_ThreadDemo), staticmethodstr(FCH_ThreadDemo, run));

}
static client void run(Thread t)
{
;
//sleep(2000);
info("hello");
}

вызов
FCH_ThreadDemo::main();
Старый 23.03.2016, 10:10   #10  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,448 / 1792 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
По-моему в тройке были какие-то проблемы с использованием infologa в потоке.
Threads
Цитата:
Сообщение от db Посмотреть сообщение
... Ошибка связана с попыткой создать формочку для инфолога в потоке. ...
Попробуйте без интерактивных функций
Вывести сообщение сгенерированное в отдельном потоке (thread) в окно инфо?
Старый 23.03.2016, 10:25   #11  
terraByteG is offline
terraByteG
Участник
 
15 / 17 (1) ++
Регистрация: 10.03.2016
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
По-моему в тройке были какие-то проблемы с использованием infologa в потоке.
В AX 2009 - с этим тоже беда.
Старый 23.03.2016, 10:27   #12  
vikuss2006 is offline
vikuss2006
Участник
 
42 / 10 (1) +
Регистрация: 22.11.2013
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
По-моему в тройке были какие-то проблемы с использованием infologa в потоке.
Threads


Попробуйте без интерактивных функций
Вывести сообщение сгенерированное в отдельном потоке (thread) в окно инфо?
Я работаю в АX3.0, убрала info, делаю просто
static client void run(Thread t)
{
int i = 1;
;
i++;
}
Но самое интересное, что в run() ставлю точку останова, и туда вообще не попадаю.
Старый 23.03.2016, 10:18   #13  
terraByteG is offline
terraByteG
Участник
 
15 / 17 (1) ++
Регистрация: 10.03.2016
X++:
class FCH_ThreadDemo
{
}

static client void main(Args args)
{
Thread t;
container           con;
    ;
    t = new Thread();
    t.run(classnum(FCH_ThreadDemo), staticmethodstr(FCH_ThreadDemo, run));
    sleep(500);
    info(conPeek(t.getOutputParm(), 1));
    t.removeOnComplete(true);
}

static client void run(Thread t)
{
    t.setOutputParm(['Hello']);
}
Старый 23.03.2016, 10:36   #14  
vikuss2006 is offline
vikuss2006
Участник
 
42 / 10 (1) +
Регистрация: 22.11.2013
Цитата:
Сообщение от terraByteG Посмотреть сообщение
X++:
class FCH_ThreadDemo
{
}

static client void main(Args args)
{
Thread t;
container           con;
    ;
    t = new Thread();
    t.run(classnum(FCH_ThreadDemo), staticmethodstr(FCH_ThreadDemo, run));
    sleep(500);
    info(conPeek(t.getOutputParm(), 1));
    t.removeOnComplete(true);
}

static client void run(Thread t)
{
    t.setOutputParm(['Hello']);
}
Выдало Информация 0
Старый 23.03.2016, 11:08   #15  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,448 / 1792 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от vikuss2006 Посмотреть сообщение
Выдало Информация 0
выше я еже приводил ссылку Вывести сообщение сгенерированное в отдельном потоке (thread) в окно инфо?
Цитата:
Сообщение от Perc Посмотреть сообщение
После thread.run(, нужно было вставить ожидание thread.waitUntilSignaled(); А то получалось соответственно, что заполнял инфолог позже того как пытался посмотреть в нем данные.
Старый 23.03.2016, 11:14   #16  
terraByteG is offline
terraByteG
Участник
 
15 / 17 (1) ++
Регистрация: 10.03.2016
vikuss2006 Странно. Должно работать. AX 2009 отрабатывает.
Про точку останова - глюк. Breakpoint в помощь... Только учтите, что основное приложение поток с таким кодом ждать не будет... Тут надо использовать waitUntilSignaled.
Старый 24.03.2016, 13:30   #17  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,715 / 1204 (44) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
X++:
class FCH_ThreadDemo
{
}

static client void main(Args args)
{
    Thread      thread;
    ;

    thread = new Thread();
    //thread.setInputParm([...]);           // Передать параметры в контейнере, если необходимо
    thread.removeOnComplete(true);          // По завершении работы выгрузить поток
    
    thread.run(classnum(FCH_ThreadDemo), staticmethodstr(FCH_ThreadDemo, run));     // Выполнение
    
    thread.waitUntilSignaled();             // Ожидаем получение ответа из потока
    infolog.import(thread.getOutputParm()); // Выводит в инфолог полученный выходной параметр
}

static client void run(Thread _thread)
{
    container   packedArgs;
    ;
    
    //Получение параметров, переданных в потоке
    //packedArgs = _thread.getInputParm(); 
 
    // Выполнение метода обычными командами Axapta
    info('Hello');

    // Последней командой метода, скопировать infolog в выходной параметр потока
    _thread.setOutputParm(infolog.copy(1,infolog.num()));   
}
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 25.03.2016, 12:56   #18  
vikuss2006 is offline
vikuss2006
Участник
 
42 / 10 (1) +
Регистрация: 22.11.2013
У меня Аксапта 2003 года, так что наверное, не будет работать
Старый 25.03.2016, 14:36   #19  
vikuss2006 is offline
vikuss2006
Участник
 
42 / 10 (1) +
Регистрация: 22.11.2013
t.waitUntilSignaled() - Класс Thread не содержит эту функцию.
Старый 25.03.2016, 15:44   #20  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,448 / 1792 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от vikuss2006 Посмотреть сообщение
t.waitUntilSignaled() - Класс Thread не содержит эту функцию.
Тогда в родительском потоке в цикле опрашивать статус дочернего, пока не выполниться.
Метод thread.status есть?

X++:
thread = new Thread();
thread.run(classnum(FCH_ThreadDemo), staticmethodstr(FCH_ThreadDemo, run));

while (thread.status() != 2)
{
   sleep(500);
}
[result] = thread.getOutputParm();

Последний раз редактировалось S.Kuskov; 25.03.2016 в 15:46.
Теги
com connector, com-объект, thread

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
axmfg: Lean manufacturing: Picking activities and kanban line events Blog bot DAX Blogs 0 26.08.2014 21:13
atinkerersnotebook: Using Vendor Requests to Manage On-boarding New Vendors Blog bot DAX Blogs 1 22.10.2013 02:24
atinkerersnotebook: Using Service Management to Track Service Orders Blog bot DAX Blogs 1 25.08.2013 19:16
atinkerersnotebook: Configuring Lean Manufacturing in Dynamics AX 2012 Blog bot DAX Blogs 1 12.08.2013 00:15
dynamicsaxtraining: Vendor returns Blog bot DAX Blogs 0 11.10.2012 00:11

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

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

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