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

Нижеследующий джоб выводит в инфолог отсортированные ПО УБЫВАНИЮ суммарные дебетовые обороты главной книги, сгруппированные по счетам бухучета за один день хозяйственной деятельности (1 сентября 2007):
X++:
static void KKu_TestAdoDescSortingInMemory(Args _args)
{
    LedgerTrans ledgerTrans;

    COM rstAxa;    // ADO: Recordset
    COM flds, fld; // ADO: Fields, Field

    str currAccountNum;
    real currAmountMST;

    int adoTypeToExcel(str _type)
    {
        switch (_type)
        {
            case 'num' : return   5; // adDouble
            case 'str' : return   8; // adBSTR
            case 'date': return 133; // adDBDate
        }
        return 8;
    }

    anytype adoValueFromExcel(COMVariant _val, int _type)
    {
        switch (_type)
        {
            case   5:      return _val.double();    // adDouble
            case   6:      return _val.currency();  // adCurrency
            case   7:      return _val.date();      // adDate
            case  11:      return _val.boolean();   // adBoolean
            case 202, 203: return _val.bStr();      // adVarWChar, adLongVarWChar("memo")
        }
        return '';
    }
;
    rstAxa = new COM('ADODB.Recordset');

    flds = rstAxa.Fields(); // сооружаем "таблицу" из двух полей в памяти
    flds.Append('AccountNum' , adoTypeToExcel('str' ));
    flds.Append('AmountMST'  , adoTypeToExcel('num' ));

    rstAxa.Open();

    while select AccountNum, sum(AmountMST) 
        from ledgerTrans
        group by AccountNum
        where ledgerTrans.TransDate == 01\09\2007 
           && ledgerTrans.Crediting == NoYes::No
    {
        rstAxa.AddNew();
            fld = flds.Item('AccountNum' ); fld.Value(ledgerTrans.AccountNum );
            fld = flds.Item('AmountMST'  ); fld.Value(ledgerTrans.AmountMST  );
        rstAxa.Update();
    }

    rstAxa.Sort('AmountMST DESC'); // задаем убывающую сортировку по полю AmountMST

    rstAxa.MoveFirst();
    while (!rstAxa.EOF())
    {
        fld = flds.Item('AccountNum' ); 
        currAccountNum = adoValueFromExcel(fld.Value(), fld.Type());

        fld = flds.Item('AmountMST'  );
        currAmountMST  = adoValueFromExcel(fld.Value(), fld.Type());

        info(strfmt('%1 --- %2', currAccountNum, currAmountMST));
        rstAxa.MoveNext();
    }

    rstAxa.Close();
}
Вложенные функции и обозначения переменных я на скорую руку заимстовал из примеров Поговорим об ADO (поэтому пусть не пугает подстрока "Excel" в их названии). Там же можно почитать подробные комментарии.

Кстати, на базе подхода можно попробовать взрастить конкурента некоторым системным классам-коллекциям (Set, RecordSortedList)
За это сообщение автора поблагодарили: PavelX (1).