Лена |
Отправлено: 10.06.2005, 14:16 |
|
Мастер участка
Группа: Участник
Сообщений: 501
|
Подскажите алгоритм сортировки строк по алфавиту в компоненте StringGrid.
Для баз данных и компонента DBGrid все просто — средствами базы данных.
Со StringGrid подскажите. |
|
Boyko |
Отправлено: 10.06.2005, 14:29 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 88
|
QuickSort
|
|
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 |
|
Лена |
Отправлено: 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
|
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ничего не появляется, что я не так делаю? |
|
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 и наслаждаешься результатом. ощущение счастья придёт само собой.
а зачем тебе понадобился 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"
только такому TMemTableEh нельзя делать Close, вообще никогда. ну и не совсем пока корректно работает связка редактора полей и автономного TMemTableEh. при пересоздании — куча ошибок. так что если вдруг автономный TMemTableEh придётся менять — дешевле удалить старый и создать новый. Нервов меньше потратишь.
|
|
Лена |
Отправлено: 16.06.2005, 17:21 |
|
Мастер участка
Группа: Участник
Сообщений: 501
|
Еще раз спасибо! |
|
olegenty |
Отправлено: 17.06.2005, 08:39 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
Дмитрия Большакова благодари (разработчика библиотеки EhLib)
|
|
Лена |
Отправлено: 14.07.2005, 12:57 |
|
Мастер участка
Группа: Участник
Сообщений: 501
|
QUOTE (olegenty @ 16/06/2005, 11:58) | так основная суть того, что я говорил, в следующем:
TMemTableEh можно использовать и АВТОНОМНО. вообще без источника данных. просто создаёшь Persistent поля в редакторе полей, а потом делаешь CreateDataset — в контекстном меню TMemTableEh. и вот тебе "StringGrid"
только такому 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
|
Лен, ну ты как маленькая . TMemTableEh — это полноценный наследник TDataSet, следовательно, используй TDataSource как для любого набора данных.
|
|
Лена |
Отправлено: 15.07.2005, 09:12 |
|
Мастер участка
Группа: Участник
Сообщений: 501
|
Спасибо olegenty
Что-то я и вправду вчера затормозила |
|
** 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 — это реализация моего представления об идеальной прослойке для клиентских НД.
|
|