|
#1
|
|||
|
|||
Поиск
Вот делаю квалифу на тему АДО. Столкнулся с такой проблемой - широкий поиск. Идея была такова : открываю базу мдб своей программой, выбираю поиск и на форме появляется дбгрид(отображение результатов) и лэйблы с эдитами. В лэйблы идут все названия полей из текущей открытой таблицы, а в эдиты мы вводим наши критерии поиска,и по событию onchange эдитов, создавать запрос на выбор нужной информации. Столкнулся с проблемой - как создать на форме определённое количество лэйблов,а рядом с ними и эдитов, учитывая, что открываем любую базу данных. Помню, был какой-то метод динамеческого построения объектов, но не помню его Если кто разбирается в этих делах - попомгите пожалуйста,хотя бы с алгоритмом.
Заранее спасибо. |
#2
|
|||
|
|||
Заводишь массив типа
Код:
type TMyContols = record ALabel : TLabel; AEdit : TEdit; end; var AMyControls = array of TMyControls; Это динамический массив. Далее после открытия таблицы делаешь такую штуку: Код:
var I : Integer; begin For I := 0 To ADOQuesr1.Fields.Count-1 Do Begin setLength(AMyControls,Length(AMyControls)+1); // Добавляем 1 элемент AMyControls[High(AMyControls)].ALabel := TLabel.Create(Self); AMyControls[High(AMyControls)].ALabel.Parent := Self; AMyControls[High(AMyControls)].ALabel.Top := 10 * I; AMyControls[High(AMyControls)].ALabel.Left := 100; AMyControls[High(AMyControls)].ALabel.Caption := ADOQuesr1.Fields[i].FieldName; AMyControls[High(AMyControls)].AEdit := TEdit.Create(Self); AMyControls[High(AMyControls)].AEdit.Parent := Self; AMyControls[High(AMyControls)].AEdit.Top := I * 10; AMyControls[High(AMyControls)].AEdit.Left := 300; AMyControls[High(AMyControls)].AEdit.OnChange := EditChangeEvent; End; end; EventChangeEvent - обработчик изменения контрола. Как собирать данные - циклом по массиву - из метки берешь имя поля, из эдита - данные. Очистка массива - сначала удалить сами контролы, потом поставить массиву длинну 0. ЗЫ. Я бы делал запуск запроса не по изменению значения в эдите, а по кнопке, т.к. выборки могут быть большие и ты учухаешься ждать, пока после нажатия любой клавиши у тебя выполнится новый зпрос. |
#3
|
|||
|
|||
Огромное спасибо.
Созрел второй,он же,кажется, последний Вот даже пусть по кнопке,но как мне собрать все данные в 1 SQL запрос? Располагаю тэйблнэймом,массивом, где есть и названия полей таблицы, и критерии отбора, вот кажется уже всё есть,но никак не могу додумать последней мысли. Помогите, пожалуйста |
#4
|
|||
|
|||
Ну так и собирай!!!
Код:
var I : Integer; S : String; begin S := 'SELECT * FROM ' + YourTableName + #13#10; For I := Low(AMyControls) To High(AMyControls) Do Begin If I <> Low(AMyControls) Then S := S + ' AND '; S := S + AMyControls.ALabel.Caption + ' = ''' + AMyControls.AEdit.Text + ''''; End; Собирает условие по 'равно'. Нет проверки на пустое значение. Рассматривает все поля как текстовые. Все это доделаешь сам. |
#5
|
|||
|
|||
На примере небольшой таблички формирую таким образом запрос :
SELECT * FROM Таблица1 WHERE ((Номер) LIKE "%") AND ((Ім'я) LIKE "%") AND ((Прізвище) LIKE "%") AND ((Посада) LIKE "%") но в нём синтаксическая ошибка |
#6
|
|||
|
|||
Появился следующий вопрос - как проверить тип данного поля? каким методом? И как при этом поменять тип текстового поля в тип этого поля? нужно для сравнения в запросе...
|
#7
|
|||
|
|||
Код:
dbgrid1.DataSource:=datasource1; adoquery1.Active:=false; adoquery1.SQL.Clear; p:='SELECT * FROM '+Adotable1.TableName+#13#10+' WHERE '; for i:=Low(ACons) to High(ACons) do begin if ACons[i].AEdit.Text<>'' then begin if (i<>Low(ACons)) and (p<>'SELECT * FROM '+Adotable1.TableName+#13#10+' WHERE ') Then p:=p+' AND '; if adotable1.FieldByName(ACons[i].ALabel.Caption).DataType=ftstring then p:=p+ACons[i].ALabel.Caption+' = '''+ACons[i].AEdit.Text+''''; if adotable1.FieldByName(ACons[i].ALabel.Caption).DataType=ftSmallint then p:=p+ACons[i].ALabel.Caption+' = "'+ACons[i].AEdit.Text+'"'+''; if adotable1.FieldByName(ACons[i].ALabel.Caption).DataType=ftInteger then p:=p+ACons[i].ALabel.Caption+' = ''"'+ACons[i].AEdit.Text+'"'+''; if adotable1.FieldByName(ACons[i].ALabel.Caption).DataType=ftWord then p:=p+ACons[i].ALabel.Caption+' = '''+ACons[i].AEdit.Text+''''; if i=High(Acons) then p:=p+';'; showmessage(tfieldtype adotable1.FieldByName(ACons[i].ALabel.Caption).DataType); end; end; if p='SELECT * FROM '+Adotable1.TableName+#13#10+' WHERE ' then dbgrid1.DataSource:=datasource1 else begin adoquery1.SQL.Add(p); adoquery1.Active:=true; dbgrid1.datasource:=datasource2; end; lmikle: Где теги, мать вашу!!! Вот такая вот штука получается. Но оно вообще не проверяет тип поля,даже если оно текстовое, оно этого не замечает,и запрос оканчивается словом WHERE. Без проверки на тип поля поиск работает,но только для текстовіх полей. Помогите пожалуйста,в последний раз Что тут не так? |