Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как правильно парсить xlTable, парсинг xlTable 
V
    Опции темы
wallstreet
Дата 1.8.2012, 18:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 153
Регистрация: 11.8.2011

Репутация: нет
Всего: нет



Для тех кому понадобится, выкладываю рабочий код.
Заранее благодарю всех учувствующих в теме, большое спасибо smile

Код

case XTYP_POKE:
        {
            if(hsz1 == hszTopic)
            {
                if(hConvApp == hConv)
                {
                    int r=0, c=0; 
                    int iCount = DdeQueryString(idInst, hsz2, NULL, 0, CP_WINANSI) + 1;
                    char* bf = new char[iCount]; 
                    DdeQueryString(idInst, hsz2, (LPWSTR)bf, iCount, CP_WINANSI);
                    std::string s = bf;

                    iCount = DdeGetData(hData, NULL, 0, 0);
                    bf = new char[iCount];
                    DdeGetData(hData, (unsigned char*)bf, iCount, 0);           
                    short Rows, Cols;
                    
                    std::vector<std::vector<Cell>> Tbl = ParseXTbl((unsigned char*)bf, Rows, Cols); 
                    
                    for(r; r<Rows; ++r)
                    {
                        std::string Name = Tbl[r][0].s;
                        double Cs = Tbl[r][0].d;
                    }
                    return ((HDDEDATA)DDE_FACK);
                }
            }


Код

std::vector<std::vector<Cell>> ParseXTbl(unsigned char bf[], short &Colls, short &Rows)
{
    int a = 0;

    unsigned char cb = (unsigned char)(bf[a] + bf[a + 1] * 256);
    a += 2;
    if(cb==16)
    {
        a = 2;
        cb = (unsigned char)(bf[a] + bf[a + 1] * 256);
        a += 2;
        Rows = (short)(bf[a] + bf[a + 1] * 256);
        a += 2;
        Colls = (short)(bf[a] + bf[a + 1] * 256);
        a += 2;
        
        std::vector<std::vector<Cell>> Tbl(Rows, std::vector<Cell>(Colls));
        
        unsigned char* ptr = bf;
        for(int R=0; R<Rows; R++)
            for(int C=0; C<Colls;)
            {
                unsigned char Tp = (bf[a] + bf[a + 1] * 256);
                a += 2;
                cb = (unsigned char)(bf[a] + bf[a + 1] * 256);
                a += 2;
                if(Tp==1)
                {
                    for (; cb > 0; cb -= 8, a += 8, C++)
                    {
                        Tbl[R][C].d = *((double*)(ptr + a));
                        Tbl[R][C].t = Tp;
                    }
                }
                else if(Tp==2)
                {
                    for (; cb > 0; cb --, C++)
                    {
                        unsigned char cb1 = bf[a];
                        a++;
                        cb -= cb1;
                        Tbl[R][C].s = "";
                        for(; 0<cb1; cb1--, a++)
                            Tbl[R][C].s = Tbl[R][C].s + (char)bf[a];
                        Tbl[R][C].t = Tp;

                    }

                }
            }
        return Tbl;
    }
}



Не хватает обработки ошибок и еще по мелочи, а так, вроде бы все в порядке.

Это сообщение отредактировал(а) wallstreet - 1.8.2012, 18:23
PM MAIL   Вверх
wallstreet
Дата 13.8.2012, 17:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 153
Регистрация: 11.8.2011

Репутация: нет
Всего: нет



Если вы парсите данные, которые вам шлет торговый терминал Quik, то знайте, что тип данных tdtBlank в их протоколах передачи не предусмотрен. Индекс обновляемой строки (к примеру при импорте таблицы текущих параметров) ищите в HSZ2 обрабатывая сообщение XTYP_POKE:
Код

  int iCount = DdeQueryString(idInst, hsz2, NULL, 0, CP_WINANSI) + 1;
  char* bf = new char[iCount]; 
  DdeQueryStringA(idInst, hsz2, bf, iCount, CP_WINANSI);
  r = RowFind(bf);
  c = ColFind(bf);

в буфер bf мы получаем строку подобно этой: "R5C3:R15C3" (во второй части этой строки после ':') будет передаваться индекс обновляемой строки данных в передаваемой таблице.
Парсю я ее так:
Row
Код

short RowFind(char* str)

{

    int Count=0;

    char* cRow = new char;

    for(int i=0; i<strlen(str); ++i)
    {
        if(str[i]==':')
        {
            i += 2;
            for(; i<strlen(str); ++i)
            {
                if(str[i]=='C')
                    i = strlen(str);
                else
                    cRow[Count++] = str[i];
            }
        }
    }
    return atoi(cRow);
}

Cols
Код

short ColFind(char* str)
{
    int Count = 0;
    char* cCol = new char;

    for(int i=0; i<strlen(str); ++i)
    {
        if(str[i]==':')
        {
            i += 2;
            for(; i<strlen(str); ++i)
            {
                if(str[i]=='C')
                    for(; i<strlen(str); ++i)
                        cCol[Count++] = str[i+1];
            }
        }
    }
    return atoi(cCol);
}

Кстати если кто знает способ быстрее обрабатывать строку и вытягивать кол-во строк и колонок, плз отметьте в этой ветке.
PM MAIL   Вверх
xvr
Дата 21.8.2012, 18:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Сложно найти способ менее эффективный  smile Посмотрите на функцию strtol - она вам и числа выделит прямо из строки, и позицию после этих чисел укажет
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0437 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.