Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Поиск по таблице в DELPHI

Автор: Andrey aka Master
Дата сообщения: 02.09.2003 20:17
Имееться таблица dbf (визуальных компонентов на форме нет), также имеется несколько эдтбоксов в которые пользователь вводит данные. Необходимо по нажатию кнопки найти все строки в таблице которые удовлетворяют тому что пользователь ввел в эдиты и результаты показать в listview.
Помогите !!!!
Автор: Arion
Дата сообщения: 02.09.2003 22:55
А в чем загвоздка? Используй TQuery с запросом SELECT.
Автор: Andrey aka Master
Дата сообщения: 02.09.2003 23:13
А я не умею ... =) Ниразу не работал с бд. Хотелось бы ссылку на подобный пример.
А без запросов че никак ?
Автор: ShIvADeSt
Дата сообщения: 03.09.2003 00:57
Andrey aka Master во первых, я что то не понимаю то ли ты едитбоксы и кнопку за визуальные компоненты не считаешь, то ли у тебя расходятся со всем миром понятие о визуальных компонентах. Тем более, что у тебя листвью есть. Есть два способа. Первый. Если у тебя только TTable. Тогда Table1.First. Table1.Next. Потом что то типа if Pos(Edit1.Text,Table1[1]) or Pos(Edit1.Text,Table1[2]) и т д то добавляем в листвью. до тех пор пока NOT Table.EOB.
Второй с использованием SQL. Это уже рассматривалось ранее. Найди по фильтру. Чтобы не было предупреждений за повторные топики.
Автор: mastervigo
Дата сообщения: 03.09.2003 05:11
Andrey aka Master
почитай kulib'у
или на mastak'e поищи (http://delphi.mastak.com/).
там, кстати, есть ещё поиск на Королестве Delphi (http://delphi.vitpc.com/),
а там уже точно есть ответы на 95% твоих будующих вопросов
Автор: Andrey aka Master
Дата сообщения: 03.09.2003 06:37
Я имел ввиду нету визуальных компонетнов связанных с таблицей типа Grid ...
Автор: mastervigo
Дата сообщения: 03.09.2003 09:45
DBgrid соответствено :)
Тебе и правда сначала стоит почитать книжки. Там все найдешь.
Автор: ShIvADeSt
Дата сообщения: 04.09.2003 00:01
Andrey aka Master А ты посмотри в первом случае там где нить упоминается о гриде? Там просто реализация посика по таблице. То есть в принципе то что тебе надо.
Автор: Andrey aka Master
Дата сообщения: 06.09.2003 00:16

Цитата:
if Pos(Edit1.Text,Table1[1]) or Pos(Edit1.Text,Table1[2])

Table1[1] - что это такое ? у меня делфи говорит что несовместимые типы стринг и интегер

Цитата:
то добавляем в листвью

А как добавить то ? те что добавлять. как теск выташить из записи в бд ?
Автор: Arion
Дата сообщения: 06.09.2003 06:21
Пусть - есть 2 едита Edit1 и Edit2, компонента TADOQuery с именем qQuery и ListBox.


Код:
var query : string;
begin
query:='select * from MyTable where Row1='+#39+Edit1.Text+#39+
' and Row2='+#39+Edit2.Text+#39;
qQuery.Close; qQuery.SQL.Clear;
qQuery.SQL.Add(query);
qQuery.Open;
while not qQuery.Eof do begin
LisBox.Items.Add(qSys.FieldByName('Row3').AsString);
qQuery.Next;
end;
end;
Автор: Andrey aka Master
Дата сообщения: 06.09.2003 11:23

Цитата:
Код:
var query : string;
begin
query:='select * from MyTable where Row1='+#39+Edit1.Text+#39+
' and Row2='+#39+Edit2.Text+#39;
qQuery.Close; qQuery.SQL.Clear;
qQuery.SQL.Add(query);
qQuery.Open;
while not qQuery.Eof do begin
LisBox.Items.Add(qSys.FieldByName('Row3').AsString);
qQuery.Next;
end;
end;

А этот код будет искать записи если во втором эдите ничего не введено. Он будет искать пустые записи или проигнорирует поиск по второму полю ? Нужно чтоб проигнорировал. И в случае если во втором эдите ничего нет он искал ьоько по первому полю. Причем условие if edit2.text='' then .... мне не подходит тк у меня эдитов штук 10...

Добавлено
Да и еше что означает
Цитата:
#39
?


Добавлено
В свойство connection что писать нада а то Делфи ругается Missing connection !

Добавлено

Цитата:
qSys.FieldByName('Row3').AsString

Еше ругается на это типа необьявленная переменная
Автор: Arion
Дата сообщения: 07.09.2003 16:26
1) qSys это qQuery, я просто опечатался, #39 в паскале означает символ одинарной кавычки.

2) В Дельфи в поле connection нужно указывать компоненту TADOConnection, означающую подключение к базе данных. Ее альтернативой является использование свойства ConnectionString.

3) Если Edit2 пуст, приведенный код будет искать записи, поле Row2 которых трансформируются в пустую строку. При указанных тобой условиях использовать условные директивы все равно придется. Например так:


Код:
query:='select * from MyTable where 1=1 and ';
if Edit1.Text<>'' then query:=query+'Row1='+#39+Edit2.Text+#39+' and ';
//...
if Edit10.Text<>'' then query:=query+'Row10='+#39+Edit0.Text+#39+' and ';

query:=query+' 1=1';
//...
Автор: Tishka
Дата сообщения: 16.09.2003 16:26
К стати, у любого датасета есть метод Locate (в хелпе есть пример).
Автор: Andrey aka Master
Дата сообщения: 16.09.2003 17:33
А методом локате как искать я делал как в хелпе он находит первую запись устанавливает там курсор ... а дальше не ишет мне нада что все записи нашлись а не одна ближайшая

Добавлено
Вот то что мне было нужно:

procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
begin
for i:=0 to table1.RecordCount -1 do
begin
Table1.Next;
if edit1.Text=Table1.Fields.Fields[0].AsString then listbox1.Items.Add(edit1.Text)
end;
end;

Только немного доделать чтобы искать по певым знакам строки монжно было а не обязательно по всей и все.
Всем спасибо
Автор: Arion
Дата сообщения: 16.09.2003 20:10
Только такой код совершенно неэффективен и труден в сопровождении.
Во первых:
Представь в твоей таблице хотя бы 100K записей, тогда цикл

Код:
for i:=0 to table1.RecordCount -1 do
Автор: Andrey aka Master
Дата сообщения: 16.09.2003 22:12
Да ... херовато наверно но в моей таблице максим 2000 колонок это много или мало ?
Автор: wyrd
Дата сообщения: 16.09.2003 22:20

Цитата:
Тебе всегда необходимо помнить какой столбец какому кортежу таблицы соответствует

Конечно лучше ориентироваться на название поля, чем на его индекс.

Цитата:
Представь теперь, что однажды вследствие изменения структуры БД из таблицы был удален восьмой столбец и на его место добавлены два.

Удаление стобцов из таблиц происходит сравнительно редко, и зачастую оно может отменить саму необходимость поиска

Цитата:
edit1.Text=Table1.Fields.Fields[0].AsString

Я думаю, что для сравнения лучше использовать функцию AnsiStrComp, etc.
Автор: vserd
Дата сообщения: 17.09.2003 11:24
Andrey aka Master
Слушай, за 15 дней можно прочитать весь HELP (F1) по TTable со словарем.
Есть методы ApplyRange, CancelRange, EditKey, EditRangeEnd, EditRangeStart, FieldByName, FindFirst, FindKey, FindLast, FindNearest, FindNext, FindPrior, GotoKey, GotoNearest, Locate, Lookup, SetFields, SetKey, SetRange, SetRangeEnd, SetRangeStart.
Выбирай на вкус и потребности.

Также можно прочитать про TQuery, и язык SQL.
Возможное решение для кучи эдитов.

function BuildWhere (AWhere, Astr : String) : String;
begin
if AWhere <> '' then Result := AWhere + ' AND ';
Result := Result + AStr;
end;

Query.Sql.Text := 'Select * from "MyCoolTable.dbf" where '
tmpWhere := '';
if edit1.text <> '' then tmpWhere := BuildWhere(tmpWhere, '(CoolField1='+edit1.text+')');
if edit2.text <> '' then begin tmpWhere := BuildWhere (tmpWhere, '(CoolField2='+edit2.text+')');
........
if edit10.text <> '' then begin tmpWhere := BuildWhere(tmpWhere, '(CoolField10='+edit10.text+')');

Query.Sql.Text := Query.Sql.Text +tmpWhere;

Если для строковых полей будешь делать поиск, тогда нужно писать так '(CoolField1='''+edit1.text+''')'

Можно конечно изголиться и сделать так чтобы условия поиска заполнялись при вводе данных, но это уже другой разговор.

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


Цитата:
но в моей таблице максим 2000 колонок

Куда столько? ограничение в DBF в 256 колонок.

wyrd

Цитата:
Удаление стобцов из таблиц происходит сравнительно редко, и зачастую оно может отменить саму необходимость поиска

А что делать когда структура таблицы не изменилась, а позиции столбцов изменились?
А если новый столбец добавили в переди поискового? Например после 2-го, а старый 3-й был поисковым (теперь он 4-й)?
Так что закладываться на позицию столбца, это выкапывание ямы под самого себя. Обращение только по имени.
И если уж закладываться на позицию, тогда использовать именованые константы, а не числа. Чтобы в одном месте поменял, а изменения распространились везде.
Автор: Andrey aka Master
Дата сообщения: 17.09.2003 12:03

Цитата:
2000 колонок

Имел ввиду строк
А через запросы вылетает окно в спросьбой ввести пароль для доступа к бд
Автор: vserd
Дата сообщения: 17.09.2003 16:35
Знаешь, на такие запросы у меня только один ответ, разориться на книжку и прочитать как нужно работать. Тем более что можно поискать в интернете, может на халяву найдешь. Кроме того, полезно читать справку по копонентам. Она очень полезная, дает ответ на 99% вопросов. Нужно только знать как их сформулировать.

Ты пойми очень простую истину, никому не охота отвечать на чайниковские вопросы слишком часто, все хотят отвечать на сложные проблемы, это стимулирует работу мозга. :)) И добывать информацию ты обязан сам, и искать ответы на проблемы, и пр.

TDatabase.loginpromt := False делал?
Автор: wyrd
Дата сообщения: 17.09.2003 22:16

Цитата:
Так что закладываться на позицию столбца, это выкапывание ямы под самого себя. Обращение только по имени.

Так ведь и я про то же...
Автор: STEEL
Дата сообщения: 15.07.2004 20:11
Прошу помочь разобраться с поиском по бд.
Разрабатываю простенькую бд для агенства недвижимости. Выбрал Paradox. Ниже представлена таблица для примера:
Необходимо осуществить поиск сразу по нескольким критериям. Для этого у нас имеется три EditBox.
Задаём параметры для поиска, размер должен быть 170 и место расположение Moscow, жмём на кнопку и получаем результат.

+--------+------------+--------+
| name | location | size |
+--------+------------+--------+
| Peter | Moscow | 170 |
| Mike | Sochi | 150 |
| Kate | Adler | 190 |
+--------+------------+--------+

Есть небольшой опыт работы с SQL.

Не совсем понимаю, как организовать запрос для TQuery, как пробежаться по всем полям, как узнать количество полей таблице и как наконец вывести её, да хотя бы в ту же DBGrid или что посоветуете. Заранее благодарен.
Автор: ShIvADeSt
Дата сообщения: 16.07.2004 00:47
STEEL
создаешь алиас например City в котором прописываешь, что используешь свою базу данных или в TQuery прописываешь путь к ней в DatabaseName свойстве
потом в SQL поле пишешь сл. запрос
select * from MyTable.dbf where location='Moscow' and size=170
делаешь свойтсво Active true а потом при помощи TDataSource соединяешь TQuery и TDBGrid. Если надо в рантайме менять запрос то используй функцию Format
вот пример рантаймного запроса

Цитата:

with Bases.SQL do begin
Close;
Clear;
Add('USE GB');
end;
Bases.Open;
if Bases.IsEmpty then begin
Bases.Close;
Exit;
end;

Автор: STEEL
Дата сообщения: 16.07.2004 21:46
Как вывести результат в другую DBGrid?

Добавлено
Почему при следующем коде вылетает такая ошибка:

ENoResultSet with message 'Error creating cursor handle'.


Код:
procedure TForm1.Button2Click(Sender: TObject);
var
query : string;
begin
query := Format('INSERT INTO mydb.db values(''%s'',''%s'')', ['STEEL','STEELIK']);
with Query1.SQL do
begin
Close;
Clear;
Add(query);
end;
Query1.Open;
if Query1.IsEmpty then begin
Query1.Close;
Exit;
end;
Автор: vndovr
Дата сообщения: 17.07.2004 00:42

Цитата:
Use ExecSQL to execute queries that do not return a cursor to data (such as INSERT, UPDATE, DELETE, and CREATE TABLE).


Цитата:
Note: For SELECT statements, call Open instead of ExecSQL.



Добавлено

Цитата:
Как вывести результат в другую DBGrid?

Результат чего и какая DBGrid первая?
Автор: STEEL
Дата сообщения: 17.07.2004 20:11
Как оформить теперь запрос?

Код:
var
query : string;
begin
query := Format('INSERT INTO mydb.db values(''%s'',''%s'')',[Edit1.Text,Edit2.Text]);
with Query1.SQL do
begin
Close;
Clear;
Add(query);
end;
Query1.ExecSQL;
end;
Автор: Felix
Дата сообщения: 17.07.2004 20:40

Цитата:
var
query : string;
begin
query := Format('INSERT INTO mydb.db values(''%s'',''%s'')',[Edit1.Text,Edit2.Text]);
with Query1.SQL do
begin
Close; - не к месту
Clear;
Add(query);
end;
Query1.ExecSQL;
end;

Автор: vndovr
Дата сообщения: 18.07.2004 00:12
STEEL

Цитата:
Допустим в DBGrid1 у нас постоянно видна таблица.. а в DBGrid2 у нас ваводиться результат поиска, который описывался ShIvADeSt


Просто два отдельных запроса, каждый подсоединен к своему гриду. Первый просто select * from Table, второй обновляется если пользователь меняет критерии поиска.

Автор: STEEL
Дата сообщения: 18.07.2004 17:47
vndovr
Не понимаю, к чему мне привязывать BDGrid2 ?
Создавать ещё один Query2 ? Какой смысл? Или создать ещё один DataSource2 и ещё один Query2 ? Наверняка есть что-нибудь погениальней?
Я скармливаю Query1 новый запрос и хочу, чтобы результат он вывел на DBGrid2!
Автор: vndovr
Дата сообщения: 18.07.2004 18:48
STEEL

Цитата:
Не понимаю, к чему мне привязывать BDGrid2 ?

К чему его вообще можно привязать - к DataSource - ложишь DataSource на форму и привязываешь его к нему. Теперь DataSource нужно к чему-то привязать - ты хочешь привязать его к результату поиска в Query - ложишь на форму TQuery.
Формируешь его и открываешь - все работает.

Теперь думаешь:

Цитата:
Создавать ещё один Query2 ? Какой смысл? Или создать ещё один DataSource2 и ещё один Query2? Я скармливаю Query1 новый запрос и хочу, чтобы результат он вывел на DBGrid2!

Смотришь - что может показывать DBGrid? - судя по всему он может показавать только данные из TDataSet (через TDataSource). При этом он не выгребает все данные из запроса а достает их по необходимости - нужно данные - полезли в TDataSet и зачитали их. А если что-то в самом DataSet поменялось то он соответственно нотифицирует DBGrid что данные изменились и последний пробует их отобразить. Значит если TQuery1 поменяется то и данные в первом гриде поменяются.
И понимаешь что с DBGrid нихрена так сделать не получится... Смотришь что может в таком случае помочь и находишь StringGrid который не привязывается ни к каким query... и т.д. и может сделать то что надо. Правда если думать дальше то понимаешь что использовать StringGrid для таких дел можно только в определенных случаях - но это уже другой вопрос...

Цитата:
Наверняка есть что-нибудь погениальней?

И что же в этом методе такого плохого? Вроде как все гениальное просто - а проще 2 запросов на 2 задачи...

Страницы: 12

Предыдущая тема: Как вытащить текст из Word'a?


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.