Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.02.19;
Скачать: CL | DM;

Вниз

Как прервать цикл While?   Найти похожие ветки 

 
dera   (2006-02-01 14:36) [0]

В цикле while not Table1.Eof do ищется запись в довольно большой таблице. Таблица выведена в гриде. Как можна сделать:
1) по нажатию на ESC прервать поиск и выйти из цикла
2) на время поиска "отключить" таблицу от грида (возможно так будет быстрей искать)


 
Ega23 ©   (2006-02-01 14:39) [1]


> 1) по нажатию на ESC прервать поиск и выйти из цикла


В цикле поставь Application.ProcessMessages


> 2) на время поиска "отключить" таблицу от грида (возможно
> так будет быстрей искать)



Table1.DisableControls

While
.....
end;

Table1.EnableControls;


 
ZeroDivide ©   (2006-02-01 14:46) [2]


> 1) по нажатию на ESC прервать поиск и выйти из цикла


Варианты:
1. Сделать поиск в отдельном потоке
2. Ловить сообщения


 
stone ©   (2006-02-01 14:49) [3]


> В цикле while not Table1.Eof do ищется запись в довольно
> большой таблице.

А не проще использовать метод Locate?


 
Ega23 ©   (2006-02-01 14:50) [4]


> А не проще использовать метод Locate?


Вообще-то проще использовать запрос с фильтрами, а не всякие Table, но это уже Дзен...   :о)


 
dera   (2006-02-01 15:02) [5]

>>2. Ловить сообщения
а можна подробнее?


 
Ega23 ©   (2006-02-01 15:03) [6]


> а можна подробнее?


Можно. Но это будет долго. Лучше почитай про многопоточность в книжке.


 
КиТаЯц ©   (2006-02-01 15:10) [7]

var BRK: boolean = falsle;

...

Table1.DisableControls
while условие do begin
Application.ProcessMessages; // иначе форме все нажатия на клавиши до одного места пока цикл не отработает
...
  if BRK then begin
     BRK:= False; // переменную сразу на место
     break; // прерывание цикла
  end;
...
end;
Table1.EnableControls;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
 Shift: TShiftState);
begin
 if Key = VK_ESCAPE then BRK:= True;
end;


 
msguns ©   (2006-02-01 15:13) [8]

>Ega23 ©   (01.02.06 15:03) [6]
>Можно. Но это будет долго. Лучше почитай про многопоточность в книжке.

Зачем в этом контексте многопоточность ?

>dera  

Твои ошибки:
1. Использование TXXTable (таблицу в 100000 записей ни один юзер не в силах даже просто просмотреть, не говоря уж о каком-то внимании)
2. Поиск собственно в датасете во всех случаях вместо того, чтобы разбить его на мин. 2 части: поиск первого (Locate) и поиск в список (отдельный динамический запрос с получением списка найденных записей в виде указателей (UID) на них).
Причем, судя по всему, на время поиска грид не "освобождается" датасетом от реакции на его события (DisableControls).


 
Shirson ©   (2006-02-01 15:14) [9]

А вариант
while (условие) and (not BRK)  do begin
Не прокатит?


 
evvcom ©   (2006-02-01 15:21) [10]

прокатит


 
dera   (2006-02-01 15:30) [11]

>>КиТаЯц ©   (01.02.06 15:10) [7]
>>Shirson ©   (01.02.06 15:14) [9]
Спасибо, понял

>>msguns ©   (01.02.06 15:13) [8]
Использование TXXTable (таблицу в 100000 записей ни один юзер не в силах даже просто просмотреть, не говоря уж о каком-то внимании)

Можно было бы и не показывать таблицу, но дело в том, что я делаю просмотрщик таблиц и тут никуда не деться :-(
Нащет 2). Я тоже думал, что можна сначала найти первую запись, и от нее плясать. Но поиск может происходить не по одному полю, то что, для каждого кол-ва полей писать Locate?


 
ZeroDivide ©   (2006-02-01 15:34) [12]

Locate можно делать по нескольким полям, разделенным ";"


 
Ega23 ©   (2006-02-01 15:34) [13]

В методе Locate можно список полей указать.


 
msguns ©   (2006-02-01 15:34) [14]

>dera   (01.02.06 15:30) [11]

Какие форматы БД (парадокс, дибэйз, склXXX..) будут обрабатываться ?
Выбор компонент BDE жестко фиксирован ?


 
dera   (2006-02-01 15:41) [15]

>>msguns ©   (01.02.06 15:34) [14]
 СУБД Brtieve
 Получилось только к Table подключить таблицу через ист.данных в ОДБС.
 C Query не получается.


 
Ega23 ©   (2006-02-01 15:47) [16]


>  Получилось только к Table подключить таблицу через ист.
> данных в ОДБС.
>  C Query не получается.


Не верю. Select * from не проходит???


 
Asail   (2006-02-01 15:54) [17]


> Не верю. Select * from не проходит???

И я тоже. Table.Open выполняет тот-же SELECT насколько я понимаю.


 
dera   (2006-02-01 15:56) [18]

>>Не верю. Select * from не проходит???
  при попытке подключить Query пишет
  "Query1: No SQL statement available"


 
Ega23 ©   (2006-02-01 15:57) [19]

А
Query.SQL.Text:="Select * from Table1";
Query.Open;

делать пробовал?

:о)


 
Digitman ©   (2006-02-01 15:59) [20]


> dera   (01.02.06 15:56) [18]
>   при попытке подключить Query пишет


Что значит "подключить" ?

Телепатировать будем по поводу "подключить" ?

Давай потелепатируем.

Чему у тебя равно зн-е св-ва Query.SQL.Text ?


 
Asail   (2006-02-01 16:02) [21]


> Что значит "подключить" ?

Видимо, автор пытался в Object Inspector"е для Query Active=True выставить, а в SQL тело запроса прописать и забыл...


 
dera   (2006-02-01 16:06) [22]

под "подключить" я понимаю  Query.Open;

я все неправильно делал :-(

теперь получилось! Благодарю, мастера!


 
msguns ©   (2006-02-01 16:06) [23]

Переключись с BDE на ADO - там другой SQL с куда большими возможностями. В частности там есть волшебное слово TOP


 
Kolan ©   (2006-02-01 16:08) [24]

Как прервать цикл While

Самое простое:
Заводишь переменную:
var
 FIsBreakLoop: Boolean;


while () do
begin
{ Любые действия}
 {Те проверяешь. Если переменная = True то надо цикл оборвать}
 if FIsBreakLoop then
 begin
   FIsBreakLoop := False;
   Break;
 end;
end;


А в программе пишешь в OnKeyDown:
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
 Shift: TShiftState);
begin
 if Key = VK_ESCAPE then  
   FIsBreakLoop := True;
end;


 
dera   (2006-02-01 16:12) [25]

>>Asail   (01.02.06 16:02) [21]

Совершенно правильно. :-)

Но мне как раз надо редактировать найденную запись. Как можна реализовать? Ведь Query этого не позволяет.


 
Ega23 ©   (2006-02-01 16:13) [26]


> Kolan ©   (01.02.06 16:08) [24]
>
> Как прервать цикл While
>
> Самое простое:
> Заводишь переменную:
> var
>  FIsBreakLoop: Boolean;
>
> while () do
> begin
> { Любые действия}
>  {Те проверяешь. Если переменная = True то надо цикл оборвать}
>  if FIsBreakLoop then
>  begin
>    FIsBreakLoop := False;
>    Break;
>  end;
> end;
>
> А в программе пишешь в OnKeyDown:
> procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
>
>  Shift: TShiftState);
> begin
>  if Key = VK_ESCAPE then  
>    FIsBreakLoop := True;
> end;


Ты забываешь, что цикл выполняется В ОСНОВНОМ ПОТОКЕ ПРОГРАММЫ.
Попробуй сам такой код написать. Без Applicatio.ProcessMessages в теле цикла.
И тогда ты увидишь, что твой вариант нихрена не работает.


 
Kolan ©   (2006-02-01 16:17) [27]

Где и как выполняется цикл неважно.

Как боротся с "зависание" главного потока - другой вопрос. И решений несколько - доп. поток, Applicatio.ProcessMessages ...

Я ответил на вопрос...


 
ZeroDivide ©   (2006-02-01 16:17) [28]


> Но мне как раз надо редактировать найденную запись. Как
> можна реализовать? Ведь Query этого не позволяет.


Возможно все что ты хочешь сделать можно написать одним Update Statement"ом.
Напиши алгоритм, который у тебя в теле цикла.


 
evvcom ©   (2006-02-01 16:19) [29]


> Ведь Query этого не позволяет.

Позволяет. См. TUpdateSQL


 
msguns ©   (2006-02-01 16:22) [30]

>dera   (01.02.06 16:12) [25]
>Но мне как раз надо редактировать найденную запись. Как можна реализовать? Ведь Query этого не позволяет.

Даже на этом ресурсе есть статьи по работе с BDE, которые тебе просто необходимо прочитать.
Query вполне позволяет, если к нему "прикрутить" TUpdateSQL. Кроме того ничто не мешает другим квери апдэйтить таблицу, после чего отображающий просто переоткрывать с позиционированием на обновленную запись (сейчас уже меня запинают ;))
Помимо этого можно уйти от BDE в пользу ADO, где есть "универсальная" компонента, сочетающая в себе достоинства и Table, и Query,- TADODataSet.
Можно остановить выбор на dbExpress вообще практически с неорграниченными возможностями.


 
Ega23 ©   (2006-02-01 16:23) [31]


> (сейчас уже меня запинают ;))


Почему? Я обычно так и делаю...


 
dera   (2006-02-01 16:27) [32]

>>Напиши алгоритм, который у тебя в теле цикла.

while not table1.eof  do begin
  Application.ProcessMessages;
  if pos(Edit1.Text,Table1.FieldByName(ComboBox2.Text).AsVariant)>0 then   begin
   r:=MessageDLG("Запись найдена! Продолжить поиск?", mtConfirmation,[mbYes,mbNo],0);
   if r=mrNo then break;
  end;
  Table1.Next;
 end;


 
msguns ©   (2006-02-01 16:36) [33]

Где DisableControls ?


 
dera   (2006-02-01 16:39) [34]

>>Где DisableControls ?

в приведенном примере его нет, т.к. он стоит до и после цикла


 
ZeroDivide ©   (2006-02-01 16:50) [35]

Но мне как раз надо редактировать найденную запись.
Мм... я думал ты прямо в цикле собираешься редактировать что-то... тогда Update прокатил бы...

И как долго этот поиск выполняется? Вроде как тормозить особо нечему. Единственное, можно поставить сразу AsString, вместо AsVariant. И AnsiUpperCase, но это уже не для ускорения, а для улучшения поиска.


 
msguns ©   (2006-02-01 16:53) [36]

Не нравится мне вот это
FieldByName(ComboBox2.Text).AsVariant

Замени его на AsString
Другого криминала в теле цикла не узрел. Так в чем проблема-то ?


 
Asail   (2006-02-01 16:57) [37]

А какой размер таблицы?
Может и нет смысла мучаться? При DisableControls такой цикл на не слишком больших таблицах выполняется почти мгновенно, пользователь и кнопку Esc на клаве найти не успеет. Если теоретический размер таблицы не превышает нескольких десятков мегабайт, то можно и необрабатывать сообщения в цикле. Только, надо учесть, что вычисляемые поля и lookup-поля в таблице тоже могут сильно тормозить процесс, поэтому их лучше избегать в больших таблицах.


 
dera   (2006-02-01 16:58) [38]

>>И как долго этот поиск выполняется?
   В таблице 1.27 млн. строк. Поиск выполняется оч-ч-чень долго!

>>Единственное, можно поставить сразу AsString, вместо AsVariant.
  а если поле не стринг попадется для поиска.

Это программа просмотра/редактирования записей. Юзер выбирает название поля, вводит искомое значение и ищет. Когда нашел - возможно, редактирует. Но в этом примере поиск только по одному полю, а я хочу сделать поиск макс. по  5 полям. Но сейчас это неважно. Главное - как ускорить энтот поиск по одному полю.


 
dera   (2006-02-01 17:03) [39]

размер таблицы 109Мб


 
Asail   (2006-02-01 17:07) [40]

В таблице, я так понимаю, должен быть PrimaryKey.
1. Так-что можно реализовать поиск через SQL с возвратом списка значений ключей записей, соответствующих запросу. А потом, с помощью GotoKey прыгать по таблице только на соответствуюшие записи.
2. По причине того, что названия полей каждый раз разные, в SQL-запросе можно использовать параметры.



Страницы: 1 2 вся ветка

Текущий архив: 2006.02.19;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.077 c
2-1138351597
СержК
2006-01-27 11:46
2006.02.19
Как грамотно остановить, убить поток


3-1135510557
Varlock
2005-12-25 14:35
2006.02.19
Widestring и Table


2-1138677594
OlegM
2006-01-31 06:19
2006.02.19
Узнать какое изображение используеться в качесте обоев


2-1138968917
~ShamaN~
2006-02-03 15:15
2006.02.19
Перемещение курсора в DateTimePicker


11-1119470765
Trubis
2005-06-23 00:06
2006.02.19
Вопросы по ListView1