Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2006.02.19;
Скачать: [xml.tar.bz2];

Вниз

Как прервать цикл 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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.55 MB
Время: 0.043 c
15-1138625615
ArtemESC
2006-01-30 15:53
2006.02.19
Получают ли что-то модераторы?


3-1135066879
skulll
2005-12-20 11:21
2006.02.19
Помогите подключиться к MSSQL через DBE


2-1138617068
box
2006-01-30 13:31
2006.02.19
Связь адотабле и адоКвери


9-1125324298
Goorus
2005-08-29 18:04
2006.02.19
Геометрия: перенос точек


3-1135111481
kreyl
2005-12-20 23:44
2006.02.19
Обновление TADODataSet из TClientDataSet





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский