Как отсортировать DBGrid
Пожалуйста подскажите, как отсортировать DBGrid!
1. в общем как ты запрос построишь так и отсортируется
2. можешь поправить немного исходник самого класса DBGrid (а он по-моему наследуется от TCustomGrid), дык вот там есть такая функция как MoveRow(индекс откуда, индекс куда); вот ты её сунь в паблик... я лично так сделал для сортировки TStringGrid
Посмотри вот эту ветку
и вот чаво получилось! В принципе нормально!
// Универсальная сортировка в гридах
void __fastcall DBGridEhTitleBtnClick(TObject *Sender, int ACol, TColumnEh *Column, char *FirstFields, char *LastFields, char *FieldsDesc) {
// Нельзя сортировать по полям, которые не fkData
if(!Sender || Column && Column->Field->FieldKind-fkData)return;
TDBGridEh *DBGridEh = (TDBGridEh*)Sender;
TClientDataSet *DataSet = (TClientDataSet*)(DBGridEh)->DataSource->DataSet;
if(!DataSet->Active) return;
// Прибиваем старый индекс
DataSet->IndexName = "";
DataSet->IndexDefs->Update();
for(int i=0; i<DataSet->IndexDefs->Count; i++)
if(DataSet->IndexDefs->Items->Name=="Index") { // Если он есть, конечно
DataSet->DeleteIndex("Index");
DataSet->IndexDefs->Update();
break;
}
// Нажатые контрольные клавиши - режим мультисортировки
if(GetKeyState(VK_SHIFT)<0 || GetKeyState(VK_CONTROL)<0 || GetKeyState(VK_MENU)<0) DBGridEh->OptionsEh << dghMultiSortMarking;
else if(DBGridEh->OptionsEh.Contains(dghMultiSortMarking)) {
ClearTitleSortMarker(DBGridEh);
DBGridEh->OptionsEh >> dghMultiSortMarking;
}
// Ставим значок сортировки
if(Column)
switch(Column->Title->SortMarker){
case smNoneEh:
Column->Title->SortMarker = smUpEh;
break;
case smUpEh:
Column->Title->SortMarker = smDownEh;
break;
case smDownEh:
Column->Title->SortMarker = smNoneEh;
break;
}
// Побежали по столбцам, ищем маркированые, пихаем в справочники
std::map<String, int> mFields, mFieldsDesc;
for(int i=0; i<DBGridEh->Columns->Count; i++){
if(DBGridEh->Columns->Items->Title->SortIndex){
mFields[DBGridEh->Columns->Items->FieldName.UpperCase()] = DBGridEh->Columns->Items->Title->SortIndex;
if(DBGridEh->Columns->Items->Title->SortMarker==smDownEh)
mFieldsDesc[DBGridEh->Columns->Items->FieldName.UpperCase()]=0;
}
}
// Дописываем в справочники поля, пришедшие извне
std::auto_ptr<TStringList> apList(new TStringList);
apList->Delimiter = ';';
apList->DelimitedText = UpperCase(FieldsDesc);
for(int i=0; i<apList->Count; ++i) if(mFields.find(apList->Strings)==mFields.end()) mFieldsDesc[apList->Strings]=0;
apList->DelimitedText = UpperCase(FirstFields);
for(int i=0; i<apList->Count; ++i) mFields[apList->Strings] = i-2000;
apList->DelimitedText = UpperCase(LastFields);
for(int i=0; i<apList->Count; ++i) if(mFields.find(apList->Strings)==mFields.end()) mFields[apList->Strings] = i+2000;
// Расставляем поля в соответствии с приоритетами
std::map<int, String> mF;
for(std::map<String, int>::iterator i=mFields.begin(); i!=mFields.end(); ++i) mF[i->second] = i->first;
// Разбираем полученные справочники, генерим строки с полями индексов
String IndexFields="", IndexFieldsDesc="";
if(!mF.empty()) {
std::map<int, String>::iterator I=mF.begin();
IndexFields = I->second;
for(++I; I!=mF.end(); ++I) IndexFields += ";"+I->second;
}
if(!mFieldsDesc.empty()) {
std::map<String, int>::iterator I=mFieldsDesc.begin();
IndexFieldsDesc = I->first;
for(++I; I!=mFieldsDesc.end(); ++I) IndexFieldsDesc += ";"+I->first;
}
// Собственно делаем индекс
if(IndexFields.IsEmpty()) return;
DataSet->AddIndex("Index", IndexFields, TIndexOptions()<<ixCaseInsensitive, IndexFieldsDesc, "",0);
DataSet->IndexDefs->Update();
DataSet->IndexName = "Index";
}
//---------------------------------------------------------------------------
void ClearTitleSortMarker(TDBGridEh *Table, TColumnEh *Column){
for(int i=0; i<Table->Columns->Count; i++)
if(Table->Columns->Items!=Column)
Table->Columns->Items->Title->SortMarker = smNoneEh;
}