C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Лена (сортировка StringGrid по алфавиту), StringGrid
Лена
Отправлено: 10.06.2005, 14:16


Мастер участка

Группа: Участник
Сообщений: 501



Подскажите алгоритм сортировки строк по алфавиту в компоненте StringGrid.
Для баз данных и компонента DBGrid все просто — средствами базы данных.
Со StringGrid подскажите.
Boyko
Отправлено: 10.06.2005, 14:29


Станционный диспетчер

Группа: Участник
Сообщений: 88



QuickSort
smile.gif
GIZMO
Отправлено: 14.06.2005, 09:27


Машинист паровоза

Группа: Участник
Сообщений: 174



QUOTE (Лена @ 10/06/2005, 14:16)
Подскажите алгоритм сортировки строк по алфавиту в компоненте StringGrid.
Для баз данных и компонента DBGrid все просто — средствами базы данных.
Со StringGrid подскажите.

CODE

struct TSortData {
   AnsiString CompareString;
   AnsiString RowString;
};

int __fastcall Compare31(void *Item1, void *Item2)
{
   AnsiString i1 = ((TSortData*)Item1)->CompareString;
AnsiString i2 = ((TSortData*)Item2)->CompareString;
return i1.AnsiCompare(i2);
}
int __fastcall Compare32(void *Item1, void *Item2)
{
   AnsiString i1 = ((TSortData*)Item1)->CompareString;
AnsiString i2 = ((TSortData*)Item2)->CompareString;
return i2.AnsiCompare(i1);
}

void __fastcall TForm1::QuikSort3(int Col, bool Desc)
{
   start_time = Time();
   TList* myList = new TList();
   TSortData* sd;
for(int i = 0;i<SG->RowCount; i++)
{
    sd = new TSortData();
       sd->CompareString = SG->Cells[Col][i];
       sd->RowString = SG->Rows[i]->Text;
       myList->Add((void*)sd);
   }
   if(Desc)
    myList->Sort(Compare31);
   else
       myList->Sort(Compare32);

   for(int i=0;i<myList->Count;i++)
{
    SG->Rows[i]->Text = ((TSortData*)myList->Items[i])->RowString;
   }

   for(int i=0;i<myList->Count;i++)
{
    delete myList->Items[i];
}

   delete myList;

   end_time = Time();
ShowMessage("Done: " + TimeToStr(end_time — start_time));
}


olegenty
Отправлено: 14.06.2005, 09:47


Ветеран

Группа: Модератор
Сообщений: 2412



не знаю, хорошая ли это практика, но привычка уже въевшаяся: я вообще пользуюсь только DBGrid, конкретно — TDBGridEh. когда не нужно привязываться к БД — вяжусь к in memory TMemTableEh. Очень удобно. сортировки, фильтры и пр. — за его же счёт.
Лена
Отправлено: 14.06.2005, 10:13


Мастер участка

Группа: Участник
Сообщений: 501



Спасибо за код.


TMemTableEh это компонет такой?

Тут не нашла http://www.ehlib.com/RUS/default.htm
olegenty
Отправлено: 14.06.2005, 12:12


Ветеран

Группа: Модератор
Сообщений: 2412



если уж ты скачала себе ehlib, то он там уже есть, прсто он входит в отдельный пакет, который, в свою очередь, лежит в подкаталоге AdvTech\MemTableEh
Лена
Отправлено: 14.06.2005, 12:55


Мастер участка

Группа: Участник
Сообщений: 501



При попытке установить MemTableEh пишет внизу ошибку Unable to open file BDEDATADRIVEREN.OBJ Делаю как обычно — пытаюсь откомпилировать bpk файл — MemTableEhB6.bpk — получаю эту ошибку.
Как победить?
Компоненты EhLib у меня установлены несколько месяцев назад, не помню, но вроде устанавливались они без проблем.
Там еще есть папочка Common, может надо как-то по-другому устанавливать MemTableEh?
Мой путь:
C:\AdvTech\MemTableEh\BCB6\ MemTableEhB6.bpk

olegenty
Отправлено: 14.06.2005, 15:30


Ветеран

Группа: Модератор
Сообщений: 2412



перемести все файлы из этой папки в ту, где у тебя исходники TDBGridEh, либо укажи на неё пути. потом вот время компиляции будет ошибка с adoreg.pas. закомментируй строчки с этой ошибкой и следующей (которая появится после того, как закомментируешь эту). и пользуйся.
Лена
Отправлено: 14.06.2005, 18:37


Мастер участка

Группа: Участник
Сообщений: 501



Переместила все четыре файла из папки MemTableEh в C:\BEhlib отсюда устанавливала TDBGridEh.
Открываю и компилирую MemTableEhB6.bpk и снова таже ошибка Unable to open file BDEDATADRIVEREN.OBJ sad.gif
Лена
Отправлено: 14.06.2005, 18:44


Мастер участка

Группа: Участник
Сообщений: 501



Получилось! Надо было еще и файлы из папки Common перенести в директорию.
Подскажите, пожалуйста, как организовывается сортировка с помощью MemTableEh?
olegenty
Отправлено: 15.06.2005, 15:56


Ветеран

Группа: Модератор
Сообщений: 2412



она организовывается с помощью TDBGridEh.

1. #include "EhLibMTE.hpp"
2. #pragma link "EhLibMTE"
3. у DBGridEh SortLocal = true
4. в OptionsEh AutoSortMarking = true
5. у колонки, по которой сортировать — TitleButton = true

после всего этого при щелчке по колонке будет происходить сортировка.

кроме того, можно делать DBGridEh->DefaultApplySorting() — будет сортировать по колонке/колонкам с маркером
Лена
Отправлено: 15.06.2005, 16:47


Мастер участка

Группа: Участник
Сообщений: 501



Вроде все повторила.
Для проверки подсоединилась к базе данных.
У колонки по которой должна быть сортировка при щелчке появляется маркер, но сортировка не происходит. Может еще где параметр выставить надо?
olegenty
Отправлено: 16.06.2005, 07:46


Ветеран

Группа: Модератор
Сообщений: 2412



если подсоединилась, то надо было подсоединяться посредством TXXXDataDriver->TMemTableEh->TDataSource->TDBGridEh.
в противном случае поступать с сортировкой нужно иначе, и это уже зависит от компонентов доступа к БД.

т.е. приведённый пример будет работать ТОЛЬКО если набором данных источника TDBGridEh является TMemTableEh.
GIZMO
Отправлено: 16.06.2005, 09:08


Машинист паровоза

Группа: Участник
Сообщений: 174



QUOTE (Лена @ 14/06/2005, 10:13)
Спасибо за код.


TMemTableEh это компонет такой?

Тут не нашла http://www.ehlib.com/RUS/default.htm

Use
CODE

void __fastcall TForm1::StrindGrid1MouseDown(TObject *Sender, TMouseButton Button,
     TShiftState Shift, int X, int Y)
{
   int Col, Row;
   StrindGrid1->MouseToCell(X, Y, Col, Row);
   if(Row != 0)
       return;

   if(Shift.Contains(ssLeft))
       QuikSort3(Col, true);
   else if(Shift.Contains(ssRight))
       QuikSort3(Col, false);
}

Лена
Отправлено: 16.06.2005, 09:17


Мастер участка

Группа: Участник
Сообщений: 501



Ставлю на форму BDEDataDriverEh1 устанавливаю DataBaseName в BCDEMOS, потом добавляю MemTableEh1 устанавливаю свойство DataDriver в BDEDataDriverEh1. Затем ставлю на форму DataSource1 и устанавливаю свойство DataSet в MemTableEh1. Далее ставлю на форму Table1 и устанавливаю свойства DataBaseName в BCDEMOS, TableName в customer.db. Далее на форму DBGridEh1 и свойство DataSource в DataSource1. У Table1 свойство Active в true.
В DBGridEh1ничего не появляется, что я не так делаю? sad.gif
olegenty
Отправлено: 16.06.2005, 09:48


Ветеран

Группа: Модератор
Сообщений: 2412



ну пока — всё (почти)
посмотри внимательно на связку
TBDEDataDriver -> TMemTableEh

у TBDEDataDriver есть
1. SelectCommand
2. UpdateCommand
3. DeleteCommand
4. GetRecCommand

они необходимы для работы с "живыми" наборами данных.

для выборки необходимо заполнить св-во SelectCommand->CommandText (либо SelectSQL, который ссылается туда же). например select * from customer (при этом на Alias БД будет ссылаться св-во DatabaseName).
затем устанавливаешь св-во TMemTableEh::Active в true и наслаждаешься результатом. ощущение счастья придёт само собой. smile.gif

а зачем тебе понадобился TTable я вообще с трудом понимаю.
Лена
Отправлено: 16.06.2005, 11:12


Мастер участка

Группа: Участник
Сообщений: 501



Супер! Все работает. Большое спасибо за помощь.
Кстати когда устанавливала компонент никаких ошибок с adoreg.pas у меня не было.
Еще вопрос, почему файлы #include "EhLibMTE.hpp"
#pragma link "EhLibMTE" надо подключать вручную? Почему они не подключаются автоматом?

olegenty
Отправлено: 16.06.2005, 11:22


Ветеран

Группа: Модератор
Сообщений: 2412



так реализована технология подключения интерфейсов сортировки/фильтрации. более подробно об этом читай справку. в Delphi надо писать uses, тут — #include/#pragma link. если ты их сотрёшь, ошибок не будет, но и сортировка работать перестанет.
Лена
Отправлено: 16.06.2005, 11:35


Мастер участка

Группа: Участник
Сообщений: 501



Спасибо olegenty за помощь и разъяснения!
Спасибо GIZMO за выложенный код!
Самый лучший форум!
olegenty
Отправлено: 16.06.2005, 11:58


Ветеран

Группа: Модератор
Сообщений: 2412



так основная суть того, что я говорил, в следующем:
TMemTableEh можно использовать и АВТОНОМНО. вообще без источника данных. просто создаёшь Persistent поля в редакторе полей, а потом делаешь CreateDataset — в контекстном меню TMemTableEh. и вот тебе "StringGrid" smile.gif

только такому TMemTableEh нельзя делать Close, вообще никогда. ну и не совсем пока корректно работает связка редактора полей и автономного TMemTableEh. при пересоздании — куча ошибок. так что если вдруг автономный TMemTableEh придётся менять — дешевле удалить старый и создать новый. Нервов меньше потратишь.
Лена
Отправлено: 16.06.2005, 17:21


Мастер участка

Группа: Участник
Сообщений: 501



Еще раз спасибо!
olegenty
Отправлено: 17.06.2005, 08:39


Ветеран

Группа: Модератор
Сообщений: 2412



Дмитрия Большакова благодари smile.gif (разработчика библиотеки EhLib)
Лена
Отправлено: 14.07.2005, 12:57


Мастер участка

Группа: Участник
Сообщений: 501



QUOTE (olegenty @ 16/06/2005, 11:58)
так основная суть того, что я говорил, в следующем:
TMemTableEh можно использовать и АВТОНОМНО. вообще без источника данных. просто создаёшь Persistent поля в редакторе полей, а потом делаешь CreateDataset — в контекстном меню TMemTableEh. и вот тебе "StringGrid" smile.gif

только такому TMemTableEh нельзя делать Close, вообще никогда. ну и не совсем пока корректно работает связка редактора полей и автономного TMemTableEh. при пересоздании — куча ошибок. так что если вдруг автономный TMemTableEh придётся менять — дешевле удалить старый и создать новый. Нервов меньше потратишь.

Возникла необходимость использовать TMemTableEh без источника данных просто как StringGrid. Я не нашла в контекстном меню CreateDataset. Если есть возможность olegenty, напиши подробно по пунктам как использовать DBGridEh для сортировки без связи его с базой данных.
olegenty
Отправлено: 14.07.2005, 13:18


Ветеран

Группа: Модератор
Сообщений: 2412



всё просто:
1. Бросить TMemTableEh на форму или модуль данных
2. В контекстном меню компонента выбрать Fields Editor, этот пункт будет верхним
3. Создать перечень интересующих тебя полей (после Create Dataset менять этот перечень не представится возможным без пересоздания)
4. После создания полей таки появится пункт контекстного меню Create Dataset, который станет последним (нижним) пунктом. Выбрать его и вуаля — TMemTableEh готов к работе. (при этом его св-во Active[B] устанавливается в [B]true, и если присвоить этому св-ву значение false, то все значения TMemTableEh, равно как и список полей, будут уничтожены)

Вот, собственно, и всё.
Лена
Отправлено: 14.07.2005, 13:39


Мастер участка

Группа: Участник
Сообщений: 501



А какие компонеты связать с TMemTableEh чтобы увидеть после компиляции свои созданные поля в компонете DBGridEh?
olegenty
Отправлено: 15.07.2005, 07:13


Ветеран

Группа: Модератор
Сообщений: 2412



Лен, ну ты как маленькая wink.gif. TMemTableEh — это полноценный наследник TDataSet, следовательно, используй TDataSource как для любого набора данных.
Лена
Отправлено: 15.07.2005, 09:12


Мастер участка

Группа: Участник
Сообщений: 501



Спасибо olegenty smile.gif
Что-то я и вправду вчера затормозила sad.gif
** Admin
Отправлено: 15.07.2005, 10:22


Не зарегистрирован







Также могу посоветовать неплохой компонент типа TMemTableEh:
(таблица в памяти)
http://www.components4developers.com/
называется: kbmMemTable — он значительно быстрее работает, чем
RxLib-овский TRxMemoryData, с TMemTableEh его не сравнивал.

А простая сортировка по полям есть и в RxLib-овском TRxMemoryData:
метод SortOnFields();
http://www.cbuilder.ru/rx/rxDBAware/RxMemo.../index.htm#rxm2
olegenty
Отправлено: 15.07.2005, 13:35


Ветеран

Группа: Модератор
Сообщений: 2412



TMemTableEh тоже работает значительно быстрее TRxMemoryData. Когда я его выбирал, выбирал из
1. TClientDataSet
2. TRxMemoryData
3. TkbmMemTable
4. TMemTableEh

2 — отвалился сразу — тормоз
1 — необходима работа с провайдером — ломит

из 3 и 4 выбрал 4, поскольку его набор TXXXDataDriver — это реализация моего представления об идеальной прослойке для клиентских НД.

Вернуться в Вопросы программирования в C++Builder