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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 01.06.2011, 12:46   #1  
oip is offline
oip
Axapta
Лучший по профессии 2014
 
2,564 / 1416 (53) ++++++++
Регистрация: 28.11.2005
Записей в блоге: 1
DDE в Ax2009
Когда-то очень давно я уже поднимал вопрос о работе с DDE в Аксапте. Если в 3.0 все работало на ура, то в 4.0 заставить нормально работать так и не получилось (подробностей за давностью лет уже не помню). Настала пора версии 2009.

Вроде в данной версии все должно работать. Однако цветочек каменный что-то пока не выходит, да и слово "счастье" из известных четырех букв тоже не складывается.

1. Имеется следующий простой джоб:

X++:
static void DDETest1(Args _args)
{
    DDEClient   DDEClient;
;
    dDEClient = new DDEClient( 'excel', 'system' );
    info(DDEClient.request('SysItems'));
}
В случае 2003 офиса в инфолог выводится нечто в непонятной кодировке. В 2007 и 2010 - все ок. В чем причина? Что надо подправить, чтобы и в 2003 все было нормально?

2. В случае, если первый тест пройден успешно, создайте в С:\Temp шаблон DDETest.xlt и запустите следующий вырванный из контекста джоб (в 3.0 работает без проблем):

X++:
static void DDETest2(Args _args)
{
    ComExcelDocument_RU excellDocument = new ComExcelDocument_RU();
    DDEClient           dDEClientPar;
    str                 sDocName;
    Array               arDDEClient;
    COM                 comDoc;

    void addDDEClient( str _chanelName )
    {
        DDEClient   dDEClient;
        str         sWorkSheetName;
        int sheetIdx;
        COM     workSheets;

        if( StrScan( _chanelName, sDocName, 1, strlen( _chanelName ) ) )
        {
            dDEClient = new DDEClient('excel', _chanelName );
            if ( !dDEClient.isValid())
            {
                return;
            }
             workSheets = comDoc.worksheets();
            for( sheetIdx = 1; sheetIdx <= workSheets.count(); sheetIdx++  )
            {
                sWorkSheetName = excellDocument.getWorkSheetName( sheetIdx );
                sWorkSheetName = substr( sWorkSheetName, 2, strlen( sWorkSheetName ) - 2 );
                if( StrScan( _chanelName, sWorkSheetName, 1, strlen( _chanelName ) ) )
                {
                    arDDEClient.value( sheetIdx, dDEClient );
                    break;
                }
            }
        }
    }

    DDEClient getDDEClient( int _workSheet = 1 )
    {
        DDEClient   dDEClientExcelSystem;

        str         channelList;
        str         channelName;
        str 1       tab     = num2char(9);
        int         foundTab;
        int         sheetIdx;
        int         resStrScan;
        int         resStrLen;
        ;
        if( arDDEClient.lastIndex() == 0 )
        {
            dDEClientExcelSystem = new DDEClient( 'excel', 'system' );
            if  ( !dDEClientExcelSystem.isValid() )
            {
                throw error( "Excel не запущен!" );
            }
            comDoc = excellDocument.getComDocument();
            sDocName = comDoc.name();

            channelList = dDEClientExcelSystem.request('Topics');
            foundTab = strScan(channelList, tab, 1, strLen(channelList));
            while (foundTab)
            {
                addDDEClient( subStr(channelList, 1, foundTab - 1) );
                channelList = strDel(channelList, 1, foundTab);

                foundTab = strScan(channelList, tab, 1, strLen(channelList));
            }
            if (strLen(channelList) > 0)
            {
                addDDEClient( channelList );
            }
        }

        return arDDEClient.value( _workSheet );
    }
;
    arDDEClient = new Array( Types::Class );
    excellDocument.newFile('C:\\Temp\\'+ 'DDETest.xlt', false);
    dDEClientPar = getDDEClient(1);
    dDEClientPar.poke('R1C1', 'Тест' );
    dDEClientPar.poke('R2C1', 'Test');
    excellDocument.visible(true);
}
Проверьте, пожалуйста, что у вас в Эксель выведется? Какая версия Аксапты/ОС/Эксель? Русский текст у меня попадает в непонятной кодировке, а английский обрезается до первого символа. От версий девятки вроде не зависит, проверял на разных. Версии ОС тоже разные. Excel 2007 и 2010. Что я делаю не так? Где и что надо подправить?
Старый 01.06.2011, 14:56   #2  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
Проблема в том, что функции DDEClient.poke(Item, Data) оба значения передются как UNICODE.
Но внутри идет вызов функции DdeClientTransaction(), в которой значение pData передается как UNICODE, а параметр wFmt установлен в CF_TEXT (как ANSI текст). Соответственно, Excel неправильно интерпретирует передаваемые данные.

Как возможный вариант исправления, могу предложить написать dll-ку, которая будет перехватывать вызовы DdeClientTransaction и подменяеть параметр CF_TEXT на значение CF_UNICODETEXT.


Что касается 2003-го офиса, то, возможно, проблема в том же самом UNICODE, но только со стороны Excel. Возможно, он так же не умеет с ним работать.
Но это только гипотеза. Проверить не на чем
__________________
Axapta v.3.0 sp5 kr2
За это сообщение автора поблагодарили: oip (5).
Старый 01.06.2011, 15:04   #3  
oip is offline
oip
Axapta
Лучший по профессии 2014
 
2,564 / 1416 (53) ++++++++
Регистрация: 28.11.2005
Записей в блоге: 1
Цитата:
Сообщение от AndyD Посмотреть сообщение
Проблема в том, что функции DDEClient.poke(Item, Data) оба значения передются как UNICODE.
Но внутри идет вызов функции DdeClientTransaction(), в которой значение pData передается как UNICODE, а параметр wFmt установлен в CF_TEXT (как ANSI текст). Соответственно, Excel неправильно интерпретирует передаваемые данные.
То есть, в AX2009 DDE тоже не работает. Какая прелесть. Спасибо.

Цитата:
Сообщение от AndyD Посмотреть сообщение
Как возможный вариант исправления, могу предложить написать dll-ку, которая будет перехватывать вызовы DdeClientTransaction и подменяеть параметр CF_TEXT на значение CF_UNICODETEXT.
К сожалению, такого писать я не умею.
Старый 01.06.2011, 16:03   #4  
SolNik is offline
SolNik
Участник
 
58 / 36 (2) +++
Регистрация: 22.10.2003
В свое время (еще на 4-ке) писали в саппорт MS на эту тему. Запрос долго пинали между разными инженерами. В итоге в core team ответили, что DDE - умирающая технология и в следующих версиях поддерживаться уже не будет, поэтому мы ничего чинить не будем.
Но в 2009 я смотрю все-таки оставили классы DDE. В общем мы на том проекте все переписали на обмен через буфер обмена (у нас DDE использовался для экспорта в Excel).
За это сообщение автора поблагодарили: George Nordic (2).
Старый 01.06.2011, 16:21   #5  
oip is offline
oip
Axapta
Лучший по профессии 2014
 
2,564 / 1416 (53) ++++++++
Регистрация: 28.11.2005
Записей в блоге: 1
Вот бы где-нибудь получить официальный ответ от MS о том, что "DDE - умирающая технология и в следующих (начиная с 4.0) версиях поддерживаться уже не будет", чтобы клиентам показывать. А еще лучше если это будет в документации к системе прописано.
Старый 01.06.2011, 16:26   #6  
oip is offline
oip
Axapta
Лучший по профессии 2014
 
2,564 / 1416 (53) ++++++++
Регистрация: 28.11.2005
Записей в блоге: 1
Кстати, на счет "умирающей технологии"... Из AX2012 классы DDE* тоже никуда не делись.
Старый 01.06.2011, 17:06   #7  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
Оживим технологию

Бросить dll-ку в папку bin клиента.
Перед началом работы с DDE создавать класс DLL
X++:
DLL                 AxDDEDll = new DLL("axdde.dll");
После окончания - уничтожать его
X++:
AxDDEDll.finalize();
AxDDEDll= null;
Проверял с Win7 32/64 бит с Excel 2010.
Вложения
Тип файла: zip AxDDE.zip (4.7 Кб, 68 просмотров)
__________________
Axapta v.3.0 sp5 kr2
За это сообщение автора поблагодарили: raz (5), lev (1), oip (26), gl00mie (15).
Старый 01.06.2011, 17:27   #8  
oip is offline
oip
Axapta
Лучший по профессии 2014
 
2,564 / 1416 (53) ++++++++
Регистрация: 28.11.2005
Записей в блоге: 1
!
О! На первый взгляд работает (Win 2008 R2 64 bit c Excel 2010) ! Спасибо! Буду теперь это дело тестить в различных условиях. А на быстродействии сильно сказаться не может никак?
Старый 01.06.2011, 17:33   #9  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
Там только вызов функции IsTextUnicode() используется, для надежности.
Сказать, на сколько она будет снижать скорость не берусь, но можно протестировать с запущенной dll-кой и без нее.

Если передавать данные не поячеечно, а одним запросом, думаю, скорость будет отличаться очень мало
__________________
Axapta v.3.0 sp5 kr2
Старый 01.06.2011, 17:36   #10  
oip is offline
oip
Axapta
Лучший по профессии 2014
 
2,564 / 1416 (53) ++++++++
Регистрация: 28.11.2005
Записей в блоге: 1
Данные в большинстве случаев передаются поячеечно. Ок, понял. Буду тестировать. Еще раз спасибо!
Старый 01.06.2011, 18:08   #11  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
А потестировать можно в тройке.
Там функция IsTextUnicode() то же будет вызываться, так что разницу в быстродействии можно будет увидеть (если она есть)

А вот данные в обоих случаях (с dll и без нее) будут загружаться нормально, так что с точки зрения конечного результата будет идентично

PS Погонял тест под трешкой с dll-кой и без нее - время выполнения практически одинаковое (плюс-минус пару десятков миллисекунд в обоих случаях на 20 тыс. вызовов Poke())
__________________
Axapta v.3.0 sp5 kr2

Последний раз редактировалось AndyD; 01.06.2011 в 18:21.
Старый 01.06.2011, 18:52   #12  
oip is offline
oip
Axapta
Лучший по профессии 2014
 
2,564 / 1416 (53) ++++++++
Регистрация: 28.11.2005
Записей в блоге: 1
Ага, спасибо! Я тоже уже проверил и пока проблем не обнаружил.

Для Ax2012 тоже проверил. Без dll-ки не работает, с ней - работает.
Старый 02.06.2011, 14:01   #13  
oip is offline
oip
Axapta
Лучший по профессии 2014
 
2,564 / 1416 (53) ++++++++
Регистрация: 28.11.2005
Записей в блоге: 1
Для работы вышеприведенной dll требуется, чтобы был установлен Microsoft Visual C++ 2010 Redistributable Package. Работоспособность проверялась на WinXP, Win2003, Win2003 R2, Win 2008 R2 (64 bit) в комбинациях с Excel 2007 и 2010.
Старый 02.06.2011, 14:07   #14  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
Ага.

Либо взять вот эту dll-ку. Для нее не требуется райн-тайм лайбрари
Вложения
Тип файла: zip AxDDE.zip (19.2 Кб, 71 просмотров)
__________________
Axapta v.3.0 sp5 kr2
За это сообщение автора поблагодарили: oip (5).
Теги
dde, баг, экспорт в excel, ax2009, ax2012

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Shekhar: AX2009 Misc Charges Blog bot DAX Blogs 0 24.02.2011 15:11
sumitax: SharePoint 2010 and AX2009 Blog bot DAX Blogs 0 11.11.2010 11:11
Khue Trinh: Fill Utility in AX2009 Blog bot DAX Blogs 0 28.09.2010 10:05
Shekhar: Dynamics AX2009 : Standalone Installation on Vista with Role centres and workflow. Blog bot DAX Blogs 0 30.03.2010 15:05
ax2009 & SSRS kitty DAX: Программирование 6 02.04.2009 10:38

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

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

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