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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 26.05.2015, 14:55   #1  
at5454 is offline
at5454
Участник
 
61 / 10 (1) +
Регистрация: 29.05.2014
Как правильно обернуть в ComVariant метод getWorkSheets() класса ComExcelDocument_RU
Здравствуйте.
Подскажите пожалуйста как правильно обернуть в ComVariant
стандартный метод getWorkSheets()



private COM getWorkSheets()
{
if (!comWorkSheets && m_comDocument)
{
try
{
comWorkSheets = m_comDocument.worksheets();
}

catch (Exception::Error)
{
throw error("@GEE6043");
}
}

return comWorkSheets;
}
Старый 26.05.2015, 15:58   #2  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2476 (88) +++++++++
Регистрация: 20.08.2005
COMVariant::createFromCOM() не подходит?
__________________
Axapta v.3.0 sp5 kr2
Старый 27.05.2015, 08:38   #3  
at5454 is offline
at5454
Участник
 
61 / 10 (1) +
Регистрация: 29.05.2014
нет не подходит. пишет что не то формат
Старый 27.05.2015, 08:44   #4  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2476 (88) +++++++++
Регистрация: 20.08.2005
Вы бы код привели, который ошибку генерирует
__________________
Axapta v.3.0 sp5 kr2
Старый 27.05.2015, 08:57   #5  
at5454 is offline
at5454
Участник
 
61 / 10 (1) +
Регистрация: 29.05.2014
просто меняю строчку
comWorkSheets = m_comDocument.worksheets();
на
comWorkSheets = COMVariant::createFromCOM(m_comDocument.worksheets());
перепробовал все COMVariant::createFrom...
Тут явно надо как то иначе)
Все время пишет "Типы операнда не совместимы с оператором."
Старый 27.05.2015, 09:03   #6  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2476 (88) +++++++++
Регистрация: 20.08.2005
Вы тип comWorkSheets не меняли?
Иначе, получается, что вы в переменную типа COM пытаетесь записать переменную типа COMVariant
__________________
Axapta v.3.0 sp5 kr2
Старый 27.05.2015, 09:26   #7  
at5454 is offline
at5454
Участник
 
61 / 10 (1) +
Регистрация: 29.05.2014
Сделал так.Но не аукнется ли это в другом месте?
private COMVariant getWorkSheets()
{
Comvariant f;
if (!comWorkSheets && m_comDocument)
{
try
{
f=COMVariant::createFromCOM(m_comDocument.worksheets());
}
catch (Exception::Error)
{
throw error("@GEE6043");
}
}
return f;
}
Старый 27.05.2015, 09:34   #8  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2476 (88) +++++++++
Регистрация: 20.08.2005
Конечно, аукнется)

Вы бы написали, чего именно этим хотите добиться
А вообще, правильнее было бы добавить свой метод, а не ломать существующий
__________________
Axapta v.3.0 sp5 kr2
Старый 27.05.2015, 09:51   #9  
at5454 is offline
at5454
Участник
 
61 / 10 (1) +
Регистрация: 29.05.2014
Все это я делаю чтоб избавиться от знаменитой ошибки работы класса ComExcelDocument_RU на терминалах. как то раз поправил метод getworkrsheet :

COM getWorkSheet(anytype _workSheetID)
{
COM comRet;

Comvariant f;
;
if (m_comDocument)
{
try
{
this.getWorkSheets();

if (typeof(_workSheetID) == Types::Class && classidget(_workSheetID) == classnum(COMVariant))
{
f = _workSheetID;
comRet = comWorkSheets.item(f);
}
else
{
comRet = comWorkSheets.item(_workSheetID);
}

}

catch (Exception::Error)
{
throw error("@GEE6043");
}
}

return comRet;
}


Прошло время и сейчас уже ругается на getWorkSheets
[IMG][/IMG]
Старый 27.05.2015, 10:36   #10  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2476 (88) +++++++++
Регистрация: 20.08.2005
Замена на COMVariant ничем эту ошибку не исправит

Смотрите в сторону COMDispFunction
__________________
Axapta v.3.0 sp5 kr2
Старый 27.05.2015, 15:28   #11  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,651 / 1158 (42) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Вы бы сделали хотя бы поиск по данному форуму по ключевому слову "ComDispFunction". Есть масса примеров его использования.

В данном конкретном случае решение будет выглядеть так:

Сначала коллекция листов (рабочая книга. Файл Excel)

X++:
// Метод getWorkSheets()
private COM getWorkSheets()
{
    ComVariant  varRet;
    ComDispFunction funcGet;
    ;

    if (!comWorkSheets && m_comDocument)
    {
        try
        {
            /*
            comWorkSheets = m_comDocument.worksheets();
            */
            funcGet = new ComDispFunction(m_comDocument, "worksheets", COMDispContext::PropertyGet);
            varRet  = new COMVariant(COMVariantInOut::OUT_RETVAL, COMVariantType::VT_DISPATCH);
            funcGet.call(varRet);
            comWorkSheets = COM::createFromInterface(varRet.iDispatch());
        }

        catch (Exception::Error)
        {
            throw error("@GEE6043");
        }
    }

    return comWorkSheets;
}
Теперь собственно один лист

X++:
private COM getWorkSheet(anytype _workSheetID)
{
    COM comRet;
    ComVariant  varRet;
    ComDispFunction funcGet;
    COMVariant varArgStr;
    COMVariant varArgInt;
    ;

    if (m_comDocument)
    {
        try
        {
            this.getWorkSheets();
            /*
            comRet = comWorkSheets.item(_workSheetID);
            */
            funcGet = new ComDispFunction(comWorkSheets, "item", COMDispContext::PropertyGet);
            varRet  = new COMVariant(COMVariantInOut::OUT_RETVAL, COMVariantType::VT_DISPATCH);

            switch (typeOf(_workSheetID))
            {
            case types::String :
                        varArgStr = new COMVariant(COMVariantInOut::In, COMVariantType::VT_BSTR);
                        varArgStr.bStr(_workSheetID);
                        funcGet.call(varArgStr, varRet);
                        break;
        
            case types::Integer :
                        varArgInt = new COMVariant(COMVariantInOut::In, COMVariantType::VT_INT);
                        varArgInt.int(_workSheetID);
                        funcGet.call(varArgInt, varRet);
                        break;

            default :
                        throw error('Не корректный тип параметра');
                        break;
            }   // switch (typeOf(_workSheetID))
    
            comRet = COM::createFromInterface(varRet.iDispatch());

        }

        catch (Exception::Error)
        {
            throw error("@GEE6043");
        }
    }

    return comRet;
}
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
За это сообщение автора поблагодарили: AlGol (2), NeveB (1), Logger (7), Ace of Database (5), ena_ax (1), Sergey Petrov (1), at5454 (1).
Старый 26.08.2015, 19:33   #12  
AlGol is offline
AlGol
Участник
 
277 / 93 (4) ++++
Регистрация: 24.12.2001
Адрес: Тверь.
По такому принципу пытаюсь переделать форматирование шрифта в ячейке, который был написан так:
X++:
void bold(MSOfficeBookMark_RU _bookMark, int _workSheet = 1)
{
    Com     MultiRange;
    Com     ComApplication;
    Com     Font;
    ;

    if (m_comDocument)
    {
        comApplication = m_comDocument.application();
        if (comApplication)
        {
            MultiRange = this.findRange(_bookMark, _workSheet);
            Font = MultiRange.Font();
            Font.Bold(1);
        }
    }
}
И не получается никак подобрать замену Font.Bold(1);

При написании такой конструкции
X++:
            funcGet = new ComDispFunction(Font, "Bold", COMDispContext::PropertyGet);
            varRet  = new COMVariant(COMVariantInOut::OUT_RETVAL, COMVariantType::VT_DISPATCH);
            varArgInt = new COMVariant(COMVariantInOut::In, COMVariantType::VT_INT);
            varArgInt.int(1);
            funcGet.call(varArgInt);
            //--------------
            //Font.Bold(1);
Получаю ошибку
--------------------
Метод "Bold" в COM-объекте класса "Font" возвратил код ошибки 0x8002000E (DISP_E_BADPARAMCOUNT), который означает: Число аргументов, указанных в вызове функции, отличается от числа аргументов в объявлении метода.
--------------------
При вызове без аргументов funcGet.call(); работает отлично.
Каким образом сделать шрифт болдом?
__________________
Ален ноби, ностра алис.
Что означает - если один человек построил, другой завсегда разобрать может.
За это сообщение автора поблагодарили: NeveB (1).
Старый 26.08.2015, 20:33   #13  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2476 (88) +++++++++
Регистрация: 20.08.2005
ProprtyPut надо использовать
__________________
Axapta v.3.0 sp5 kr2
За это сообщение автора поблагодарили: AlGol (2).
Старый 26.08.2015, 20:51   #14  
AlGol is offline
AlGol
Участник
 
277 / 93 (4) ++++
Регистрация: 24.12.2001
Адрес: Тверь.
Спасибо!
Работает.
X++:
    ComDispFunction funcGet, funcPut;
    COMVariant      varArgInt, varArgBool;
    ;
...
            funcPut = new ComDispFunction(Font, "Bold", COMDispContext::PropertyPut);
            varArgBool = new COMVariant(COMVariantInOut::In, COMVariantType::VT_BOOL);
            varArgBool.boolean(true);
            funcPut.call(varArgBool);
__________________
Ален ноби, ностра алис.
Что означает - если один человек построил, другой завсегда разобрать может.
Старый 26.07.2018, 09:16   #15  
ena_ax is offline
ena_ax
Участник
 
254 / 46 (2) +++
Регистрация: 06.12.2006
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Вы бы сделали хотя бы поиск по данному форуму по ключевому слову "ComDispFunction". Есть масса примеров его использования.

В данном конкретном случае решение будет выглядеть так:

Сначала коллекция листов (рабочая книга. Файл Excel)

X++:
// Метод getWorkSheets()
private COM getWorkSheets()
{
    ComVariant  varRet;
    ComDispFunction funcGet;
    ;

    if (!comWorkSheets && m_comDocument)
    {
        try
        {
            /*
            comWorkSheets = m_comDocument.worksheets();
            */
            funcGet = new ComDispFunction(m_comDocument, "worksheets", COMDispContext::PropertyGet);
            varRet  = new COMVariant(COMVariantInOut::OUT_RETVAL, COMVariantType::VT_DISPATCH);
            funcGet.call(varRet);
            comWorkSheets = COM::createFromInterface(varRet.iDispatch());
        }

        catch (Exception::Error)
        {
            throw error("@GEE6043");
        }
    }

    return comWorkSheets;
}
Теперь собственно один лист

X++:
private COM getWorkSheet(anytype _workSheetID)
{
    COM comRet;
    ComVariant  varRet;
    ComDispFunction funcGet;
    COMVariant varArgStr;
    COMVariant varArgInt;
    ;

    if (m_comDocument)
    {
        try
        {
            this.getWorkSheets();
            /*
            comRet = comWorkSheets.item(_workSheetID);
            */
            funcGet = new ComDispFunction(comWorkSheets, "item", COMDispContext::PropertyGet);
            varRet  = new COMVariant(COMVariantInOut::OUT_RETVAL, COMVariantType::VT_DISPATCH);

            switch (typeOf(_workSheetID))
            {
            case types::String :
                        varArgStr = new COMVariant(COMVariantInOut::In, COMVariantType::VT_BSTR);
                        varArgStr.bStr(_workSheetID);
                        funcGet.call(varArgStr, varRet);
                        break;
        
            case types::Integer :
                        varArgInt = new COMVariant(COMVariantInOut::In, COMVariantType::VT_INT);
                        varArgInt.int(_workSheetID);
                        funcGet.call(varArgInt, varRet);
                        break;

            default :
                        throw error('Не корректный тип параметра');
                        break;
            }   // switch (typeOf(_workSheetID))
    
            comRet = COM::createFromInterface(varRet.iDispatch());

        }

        catch (Exception::Error)
        {
            throw error("@GEE6043");
        }
    }

    return comRet;
}

Коллеги, данный изменение методов решило проблему timeout при работе отчетов модуля "Генератор Российских отчетов". см мою ссылку по теме

Axapta 2009. str2IntOk

Есть два вопроса:
1. На сколько это решение является универсальным? Какие могут быть исключения?
2. Почему данный подход не реализован в стандартном функционале?
Старый 27.07.2018, 05:53   #16  
Maximin is offline
Maximin
NavAx
NavAx Club
 
408 / 341 (12) ++++++
Регистрация: 09.10.2002
Адрес: Москва
Оно не решило, на самом деле.
Оно уменьшило его вероятность. Все равно - на тысячах строк будет иногда вылезать. Еще выжать вероятности поможет - написать в catch пару раз retry при COM ошибке после небольшой задержки миллисекунд в 100-300..
Тема уже исхожена эта вдоль и поперек. Радикально решает - доступ через .NET - искать здесь же на форуме.
__________________
Жизнь прекрасна! Если, конечно, правильно подобрать антидепрессанты...

Последний раз редактировалось Maximin; 27.07.2018 в 05:58.
Старый 27.07.2018, 09:31   #17  
ena_ax is offline
ena_ax
Участник
 
254 / 46 (2) +++
Регистрация: 06.12.2006
Цитата:
Сообщение от Maximin Посмотреть сообщение
Оно не решило, на самом деле.
Оно уменьшило его вероятность. Все равно - на тысячах строк будет иногда вылезать. Еще выжать вероятности поможет - написать в catch пару раз retry при COM ошибке после небольшой задержки миллисекунд в 100-300..
Тема уже исхожена эта вдоль и поперек. Радикально решает - доступ через .NET - искать здесь же на форуме.
понятно, спасибо.

В новой версии я так понимаю уже через NET реализовано?
Теги
com-объект, comdispfunction, excel, excel com формат, законченный пример, полезное

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Ax2009 RU5: класс CustVendAutoSettlement_Cust_RU, метод description() Damn DAX: Программирование 4 18.12.2010 15:42
Метод "version" не поддерживается интерфейсом Automation COM-объекта класса "<неизвестно>". Poleax DAX: Администрирование 2 02.11.2010 15:25
Метод 'SendMail' в COM-объекте класса 'Dundas.mailer' возвратил код ошибки 0x80004005 (E_FAIL), который означает: The HELLO command failed. Andrew Akhmetov DAX: Программирование 4 09.04.2008 13:24
ComExcelDocument_RU Antonuch DAX: Программирование 4 15.01.2008 13:10
Метод класса, возвращающий сумму налога. 2.5SP5 studentLPC DAX: Программирование 2 25.07.2003 12:21
Опции темы Поиск в этой теме
Поиск в этой теме:

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

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

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

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 01:44.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.