Показать сообщение отдельно
Старый 14.06.2006, 22:23   #38  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2476 (88) +++++++++
Регистрация: 20.08.2005
Несколько предложений по исследованию Gustav различных вариантов использования ComExcelDocument_RU

1. При создании нового файла Excel использован код
X++:
excel.newFile("", true, -1);
Замечание по поводу второго параметра _bVisible=true - при массовой вставке данных в лист Excel будет довольно ощутимое замедление выгрузки. Еще одна особенность при таком параметре - если пользователь в листе Excel во время вызгрузи выделит ячейку мышкой, то выполнение прервется с ошибкой.
Первый (самый простой) вариант - открывать в невидимом режиме и показывать после выгрузки всех данных.
Второй вариант - запретить перед экспортом пользовательский ввод и обновления в открытой книге.
X++:
    COM app;
    ;
...
    app = doc.Application();
    app.Interactive(False); // запрет пользовательского ввода
    app.ScreenUpdating(False); // запрет обновления окна при изменении данных
...
    app.Interactive(True);
    app.ScreenUpdating(True);
2. Хотелось бы вступиться за Range . Значительное увеличение времени в первом варианте присходит из-за реализации метода findRange(), используемого в insertValue(). Если заменить этот код на более простой (часть кода взята из второго варианта)
X++:
    COM doc;
    COM actSheet;
    COM range;
...
    doc = excel.getComDocument();
    actSheet = doc.ActiveSheet();
...
    while ()
    {
...
        range = actSheet.range(ComExcelDocument_RU::numToNameCell( 1, row));
        range.Value2(ledgerTrans.RecId);
        range = actSheet.range(ComExcelDocument_RU::numToNameCell( 2, row));
        range.Value2(ledgerTrans.AccountNum);
...
то загрузка хотя и будет происходить медленнее второго способа, но разница будет составлять уже проценты, а не разы.

3. Окончательная реабилитация Range.
Третий вариант с использованием только интерфейсов - вставка при помощи массивов
X++:
    COM actSheet;
    COM range;
    Array arr;
...
    while ()
    {
...
        arr = new Array(Types::String);
        arr.value( 1, strfmt("%1", ledgerTrans.RecId));
        arr.value( 2, strfmt("%1", ledgerTrans.AccountNum));
        arr.value( 3, strfmt("%1", ledgerTable.AccountName));
        arr.value( 4, strfmt("%1", ledgerTable.AccountPlType));
        arr.value( 5, strfmt("%1", ledgerTrans.BondBatchTrans_RU));
        arr.value( 6, strfmt("%1", ledgerTrans.BondBatch_RU));
        arr.value( 7, strfmt("%1", ledgerTrans.TransDate));
        arr.value( 8, strfmt("%1", ledgerTrans.Txt));
        arr.value( 9, strfmt("%1", ledgerTrans.AmountMST));
        arr.value(10, strfmt("%1", ledgerTrans.Crediting));
        range = actSheet.range(strfmt("A%1:J%1", row));
        range.value2(COMVariant::createFromArray(arr));
Этот вариант по сравнению со вторым в моем случае дает увеличение скорости до 7 раз

PS. Упс. Ошибка. Так делать нельзя.
X++:
excel.insertValue(range, ledgerTrans.AccountNum);
На самом деле хотел вставить
X++:
excel.insertValueInRange(range, ledgerTrans.AccountNum);
но этот метод объявлен как protected в стандарте. Если необходимо - можно изменить объявление класса, либо просто вставлять значения так
X++:
range.Value2(ledgerTrans.AccountNum);
__________________
Axapta v.3.0 sp5 kr2

Последний раз редактировалось AndyD; 15.06.2006 в 09:24.
За это сообщение автора поблагодарили: belugin (11).