Экспорт пользовательских данных из МТ в Эксель (DDE-Samle - боком, вообще про котировки не идёт речь)

 

Народ, помогите пожалуйста разобраться. Тема конечно избитая, но я ни где не нашёл приемлемого результата. Мне необходимо значимые для меня данные выгружать в определённые ячейки таблицы (котировки тут не при чем). Я нашёл метод уже кем-то написанный, переделал на свой лад и... затык. Дело в том что на старых билдах он работал на ура, а сейчас нет. Версия МТ version 5.0 build 1980, Офис 2013.

#define        APPCLASS_STANDARD                0x00000000
#define        APPCMD_CLIENTONLY                0x00000010
#define        DMLERR_NO_ERROR                  0
#define        XTYP_POKE                        0x4090
#define        CF_TEXT                          1
#define        CP_WINANSI                       1004
#define     XCLASS_BOOL              0x1000
#define     XTYPF_NOBLOCK            0x0002
#define     XTYP_CONNECT            (0x0060 | XCLASS_BOOL | XTYPF_NOBLOCK)

#define     XCLASS_DATA              0x2000
#define     XTYP_WILDCONNECT        (0x00E0 | XCLASS_DATA | XTYPF_NOBLOCK)


#define        VK_CONTROL                             0x00000011
#define        VK_SHIFT                               0x00000010

#import "user32.dll"
int DdeInitializeA(int &pidInst[],int pfnCallback,int afCmd,int ulRes);
int DdeUninitialize(int idInst);
int DdeCreateStringHandleA(int idInst,string psz,int iCodePage=0);
int DdeFreeStringHandle(int idInst,int iStrHandle);
int DdeConnect(int idInst,int iService,int iSheet,int pCC=0);
int DdeDisconnect(int iConv);
int DdeClientTransaction(string szData,int cbData,int iConv,int iItem,int wFmt,int wType,int dwTimeout,int pdwResult=0);
int DdeGetLastError(int idInst);
bool DdeFreeDataHandle(int hData);

int GetKeyState(int nVirtKey);
#import




int idInst=0,iConv=0;

int ReportFile=0;
string SheetName="Лист2";
int _ExcelInit;
//+------------------------------------------------------------------+
//| excel initialization function                                   |
//+------------------------------------------------------------------+
int ExcelInit(string Sheet)
  {
   int ptr[1]={0};
   int iRet = DdeInitializeA(ptr, 0, APPCLASS_STANDARD | APPCMD_CLIENTONLY, 0);
   if(iRet != DMLERR_NO_ERROR)
     {
      return(0);
     }
   idInst=ptr[0];

   int iService=DdeCreateStringHandleA(idInst,"EXCEL",CP_WINANSI);
   if(iService==0)
     {
         Print("Faile to create service ", DdeGetLastError(idInst));
         return(0);
     }
   int iSheet=DdeCreateStringHandleA(idInst,Sheet,CP_WINANSI);
   if(iSheet==0)
     {
         Print("Faile to create sheet ", DdeGetLastError(idInst));
         return(0);
     }
   
   iConv=DdeConnect(idInst,iService,iSheet,NULL);
   DdeFreeStringHandle(idInst,iService);
   DdeFreeStringHandle(idInst,iSheet);
   if(iConv==0)
     {
      Alert(DdeGetLastError(idInst));
      DdeUninitialize(idInst);
      return(0);
     }
   return(1);
  }
//+------------------------------------------------------------------+
//| excel deinitialization function                                 |
//+------------------------------------------------------------------+
void ExcelDeinit()
  {
   if(iConv>0)
      DdeDisconnect(iConv);
   if(idInst>0)
   {
      DdeUninitialize(idInst);
      DdeFreeDataHandle(idInst);
   }
  }
//+------------------------------------------------------------------+
//| excel write data                                 |
//+------------------------------------------------------------------+
int ExcelWrite(string CellAddress,string CellValue)
  {
   StringTrimLeft(CellAddress);
   StringTrimRight(CellAddress);
   int iItem= DdeCreateStringHandleA(idInst,CellAddress,CP_WINANSI);
   if(iItem==0)
     {
         Print("Item create hadle faile ", DdeGetLastError(idInst));
         return(0);
     }
   int iRet = DdeClientTransaction(CellValue,StringLen(CellValue)+1,iConv,iItem,CF_TEXT,XTYP_POKE,1000,0);
   if(iRet==0)
     {
         Print("Transaction failed! ",DdeGetLastError(idInst));
     }
   DdeFreeStringHandle(idInst,iItem);
   return (iRet);
  }
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----

//----
   return(0);
  }

//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
//if(ReportFile>0) FileClose(ReportFile);
   ExcelDeinit();

//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
void OnTick(void)
  {
   Print("GetKeyState(VK_SHIFT) ",GetKeyState(VK_SHIFT)," GetKeyState(VK_CONTROL) ",GetKeyState(VK_CONTROL));
   if(GetKeyState(VK_SHIFT)>0)
     {
      if(ObjectFind(0,"VK_SHIFT")<=0)
        {
         ObjectCreate(0,"VK_SHIFT",OBJ_LABEL,0,0,0);
         ObjectSetString(0,"VK_SHIFT",OBJPROP_TEXT,"Shift key is down!");
         ObjectSetInteger(0,"VK_SHIFT",OBJPROP_CORNER,3);
         ObjectSetInteger(0,"VK_SHIFT",OBJPROP_XDISTANCE,100);
         ObjectSetInteger(0,"VK_SHIFT",OBJPROP_YDISTANCE,20);
        }
      ExcelDeinit();
      _ExcelInit=0;
     }
   else
     {
      if(ObjectFind(0,"VK_SHIFT")==0)
        {
         ObjectDelete(0,"VK_SHIFT");
        }
     }

   if(GetKeyState(VK_CONTROL)>0)
     {
      if(ObjectFind(0,"VK_CONTROL")<=0)
        {
         ObjectCreate(0,"VK_CONTROL",OBJ_LABEL,0,0,0);
         ObjectSetString(0,"VK_CONTROL",OBJPROP_TEXT,"Control key is down!");
         ObjectSetInteger(0,"VK_CONTROL",OBJPROP_CORNER,3);
         ObjectSetInteger(0,"VK_CONTROL",OBJPROP_XDISTANCE,100);
         ObjectSetInteger(0,"VK_CONTROL",OBJPROP_YDISTANCE,10);
        }

      if(_ExcelInit<=0)
        {
         _ExcelInit=ExcelInit(SheetName);
         if(_ExcelInit<=0)
           {
            Alert("ExcelInit failed!");
            return;
           }
        }
      //----
      double op=0,hi=0,lo=0,cl=0;
      if(_ExcelInit!=0)
        {
         int xl=2;

         int i=1;
           {
            string e_range="R"+IntegerToString(13-i)+"C"+IntegerToString(xl);
            string e_value = (string)iOpen(Symbol(),PERIOD_CURRENT,0);
            ExcelWrite(e_range,e_value);
           }
        }
      else
        {
         Print("Советник не иницилизовался!");
        }

     }
   else
     {
      if(ObjectFind(0,"VK_CONTROL")==0)
        {
         ObjectDelete(0,"VK_CONTROL");
        }
     }

//----
   return;
  }
//+------------------------------------------------------------------+

При вызове DDEConnect вылазит ошибка 16394 (0x400A) DMLERR_NO_CONV_ESTABLISHED. Вопрос, как победить? И можно ли вообще победить?


 
Могу сказать точно: UAC не при чём, проблема в кодировке. Т.е. пока я не указал CP_WINANSI, DdeCreateStringHandleA нормально не заработала, а вот как указать кодировку для DdeConnect - проблема, так как она передаётся последним параметром в структуре, которую МТ не поддерживает. Может будут у кого какие мысли...
 
М:
Может будут у кого какие мысли...

Сделать нормальную ДЛЛ реализующую функции ДДЕ на С++ или на C#, а МТ-MQL оставить только непосредственную передачу данных в нашу ДЛЛ. И не заморачиваться.

Причина обращения: