Показать сообщение отдельно
Старый 14.06.2006, 10:45   #31  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2476 (88) +++++++++
Регистрация: 20.08.2005
Еще один вариант - при помощи DDE.
Время выгрузки - 20-21 с

PS Так как пользователь может в настройках отключить возможность обработки запросов DDE, то, перед созданием класса clientDDE, можно вставить сброс этого флага
X++:
    app.IgnoreRemoteRequests(false);
    ddeClient = new DDEClient("Excel", sheet.Name());
PPS По просьбе Gustav перемещаю код в окно.
Заодно добавил выгрузку ч/з буфер обмена. Для выгрузки использую TextBuffer.toClipboart().
Для переключения используется макрос DDE. Значение TRUE - выгрузка ч/з DDE, значение FALSE - clipboard
Время выгрузки примерно одинаковое для обоих вариантов

X++:
static void ExportExcelDDE(Args _args)
{
    LedgerTrans ledgerTrans;
    LedgerTable ledgerTable;
    int timeFullStart, timeFullFinish, timeFullTotal;
    int cnt = 0;
    str Buf, s;
    ComExcelDocument_Ru excel;
    COM                 doc;
    COM                 app;
    COM                 sheet;
    COM                 range;
    DDEClient           ddeClient;
    TextBuffer          tb;

    #define.RowsCount(5000)
    #define.DDE(false)
    #define.xlR1C1(0xFFFFEFCA)

    #if.DDE(false)
        void LoadKeyboardLayout()
        {
            dll dll = new dll("user32");
            dllFunction dllFunction = new dllFunction(dll, "LoadKeyboardLayoutA");
            #define.KLF_ACTIVATE(1)
            ;
            dllFunction.arg(ExtTypes::String, ExtTypes::DWord);
            dllFunction.returns(ExtTypes::DWord);
            dllFunction.call("00000419", #KLF_ACTIVATE);
        }
    #endif
    ;
    // засекаем время
    timeFullStart = timenow();

    excel = new ComExcelDocument_Ru();
    excel.newFile("", false);
    doc = excel.getComDocument();
    app = doc.application();
    sheet = app.ActiveSheet();

    buf = "RecId\tAccountNum\tAccountName\tAccountPlType\tBondBatchTrans_RU\tBondBatch_RU\tTransDate\tTxt\tAmountMST\tCrediting\n";

    range = sheet.range("A:A;E:E");
    range.NumberFormat("0");
    range = sheet.range("B:D;F:F;H:H;J:J");
    range.NumberFormat("@");
    range = sheet.range("G:G");
    range.NumberFormat("ДД.ММ.ГГГГ");
    range = sheet.range("I:I");
    range.NumberFormat("# ##0,00");

    #IF.DDE(true)
        app.IgnoreRemoteRequests(false);
        ddeClient = new DDEClient("Excel", sheet.Name());
    #ENDIF
    #IF.DDE(false)
        tb = new textBuffer();
        LoadKeyboardLayout();
    #ENDIF

    cnt++;
    while select  ledgerTrans
            join  ledgerTable
            where ledgerTrans.AccountNum == ledgerTable.AccountNum
               && ledgerTrans.TransDate >= str2date('dd.mm.yy',123) && ledgerTrans.TransDate <= str2date('DD.MM.YY',123)
    {
            // 10 полей
        buf +=
            strfmt(
                "%1\t%2\t%3\t%4\t%5\t%6\t%7\t%8\t%9\t%10\n",
                ledgerTrans.RecId, ledgerTrans.AccountNum, ledgerTable.AccountName, ledgerTable.AccountPlType,
                ledgerTrans.BondBatchTrans_RU, ledgerTrans.BondBatch_RU,
                date2str(ledgerTrans.TransDate, 321, 2, 3, 2, 3, 4), ledgerTrans.Txt,
                strltrim(strrem(num2str(ledgerTrans.AmountMST, 10, 2, 2, 0), "+")), ledgerTrans.Crediting);

        cnt++;
        if (cnt > 0 && (cnt mod #RowsCount == 0))
        {
            s = strfmt("A%1:J%2",  cnt-#RowsCount+1, cnt);
            range = sheet.range(s);
            #IF.DDE(true)
                ddeClient.poke(range.Address(true, true, #xlR1C1), buf);
            #ENDIF
            #IF.DDE(false)
                tb.setText(buf);
                tb.toClipboard();
                sheet.paste(range);
            #ENDIF

            buf = "";
        }
        if (cnt >= 65000) break;
    }
    if (cnt < #RowsCount)
        range = sheet.range("A1:J" + int2str(cnt));
    else
        range = sheet.range(strfmt("A%1:J%2",  cnt-(cnt mod #RowsCount)+1, cnt));
    #IF.DDE(true)
        ddeClient.poke(range.Address(true, true, #xlR1C1), buf);
    #ENDIF
    #IF.DDE(false)
        tb.setText(buf);
        tb.toClipboard();
        sheet.paste(range);
    #ENDIF

    excel.visible(true);

    timeFullFinish = timenow();
    timeFullTotal = timeFullFinish - timeFullStart;
    info('Время выполнения, сек');
    info(int2str(timeFullTotal));
}
__________________
Axapta v.3.0 sp5 kr2

Последний раз редактировалось AndyD; 14.06.2006 в 14:39.
За это сообщение автора поблагодарили: konopello (1), Gustav (2), JuniorAx (1).