Показать сообщение отдельно
Старый 31.08.2011, 20:16   #4  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Thumbs up Импорт из Excel (тоже с изюминкой)
Не откладывая в долгий ящик, сразу решение обратной задачи - импорт из Excel в том же духе.

Перед запуском нижеследующего джоба следует прогнать вышеупомянутый джоб, который выводит матрицу 50000х10 и сохранить получившийся файл (у меня это mssc_output.xls - у себя пропишите свой). Далее скорее запускайте джоб из этого поста и обнаружьте, что это реально "нечеловеческая музыка" (с):
X++:
static void Job_ReadFromExcel(Args _args)
{
    COM sc;
    str vbCode;
    int i,j;
    int timeStart = timenow();
    str file  = @'C:\Documents and Settings\kulvinov\My Documents\mssc_output.xls';
    str range =  'A2:J50001'; // 50000 x 10
    COMVariant dummy, rowsCount, colsCount;
    ;

    vbCode =
    'Option Explicit                                                        \r\n' +
    'Dim varArray                                                           \r\n' +
    'Sub readRangeToVarArray(fileName, rngAddr)                             \r\n' +
    '    Dim xlApp                                                          \r\n' +
    '    Dim rng                                                            \r\n' +
    '    Dim wbk                                                            \r\n' +
    '    Set xlApp = CreateObject("Excel.Application")                      \r\n' +
    '    With xlApp                                                         \r\n' +
    '        Set rng = .Workbooks.Open(fileName).Application.Range(rngAddr) \r\n' +
    '        varArray = rng.Value                                           \r\n' +
    '        Set rng = Nothing                                              \r\n' +
    '        For Each wbk In .Workbooks                                     \r\n' +
    '            wbk.Close False                                            \r\n' +
    '        Next                                                           \r\n' +
    '        Set wbk = Nothing                                              \r\n' +
    '        .Quit                                                          \r\n' +
    '    End With                                                           \r\n' +
    '    Set xlApp = Nothing                                                \r\n' +
    'End Sub                                                                \r\n'
    ;

    sc = new COM('MSScriptControl.ScriptControl');
    sc.Language('vbscript');

    sc.AddCode( vbCode );
    sc.ExecuteStatement(strFmt('readRangeToVarArray "%1", "%2"',file,range));

    info(strFmt('Время окончания считывания, %1 сек',timenow()-timeStart));

    rowsCount = sc.Eval('UBound(varArray,1)');
    info(strFmt('Количество строк в массиве: %1',rowsCount.long()));
    colsCount = sc.Eval('UBound(varArray,2)');
    info(strFmt('Количество столбцов в массиве: %1',colsCount.long()));

    for (i=1; i<=rowsCount.long(); i++) // цикл по строкам varArray
    {
        for (j=1; j<=colsCount.long(); j++) // цикл по столбцам varArray
        {
            dummy = sc.Eval(strFmt('varArray(%1,%2)',i,j));
            //print strFmt('%1 -- %2 -- %3 -- %4 -- %5',
            //             i,j,dummy.bStr(),dummy.double(),dummy.date());
        }
    }

    info(strFmt('Время окончания перебора всех значений, %1 сек',timenow()-timeStart));
}
Как можно понять, джоб (в его VB-части) считывает из листа Excel диапазон A2:J50001 в одну переменную varArray (одной операцией присваивания! с невероятной скоростью этой операции! и это обещанная изюминка), после чего Excel отпускается, и уже Аксапта в двойном цикле "трогает" по очереди все значения массива в операторе присваивания "dummy = ...". Можно раскомментировать оператор print, чтобы убедиться, что данные реально считываются. Несколько нелепый (и bStr, и double, и date в одном флаконе) print сделан на скорую руку по принципу "уж в одной из позиций strFmt правильное значение ячейки да отобразится".

С закомментированным print мои результаты в инфологе таковы:

Info Сообщение (20:02:24) Время окончания считывания, 0 сек
Info Сообщение (20:02:24) Количество строк в массиве: 50000
Info Сообщение (20:02:24) Количество столбцов в массиве: 10
Info Сообщение (20:02:24) Время окончания перебора всех значений, 21 сек

И данные-то можно читать в совершенно произвольном порядке, никакие "только вперёдные" курсоры нас не лимитируют! Красота!

Ну, вот. На сегодня я, пожалуй, всё сказал. Пошёл в отпуск на недельку. До встречи!
За это сообщение автора поблагодарили: gl00mie (5), mallard (1).