Avatar billede skurggman Nybegynder
04. oktober 2000 - 14:15 Der er 20 kommentarer og
5 løsninger

Søgning i database?

Jeg skal bruge en kode der kan søge i en database, min db er en tabel fra bde, paradox 7. Jeg skal gerne kunne søge både på navn og nr. dvs 2 forskellige felter!
Avatar billede delphi Nybegynder
04. oktober 2000 - 14:17 #1
Bruger du en TQuery eller en TTable (eller er du ligeglad) ??

Delphi
Avatar billede powell Nybegynder
04. oktober 2000 - 14:20 #2
Jeg ved ikke om du kender denne site, men den er ret informationsrig:
http://www.kaposnet.hu/books/tysdelphi4/ch16/ch16.htm
Avatar billede skurggman Nybegynder
04. oktober 2000 - 14:29 #3
Ttable, skulle jeg mene. Jeg er ikke helt sikker
Avatar billede pellelil Nybegynder
04. oktober 2000 - 14:34 #4
TTable har en Find og/eller Locate, men personlig ville jeg foreslå/foretrække en TQuery hvor du helt selv kan bestemme:

\"SELECT * FROM MyTable ORDER BY Navn, Nr\"
Avatar billede delphi Nybegynder
04. oktober 2000 - 14:40 #5
Jeg foretrækker nu godt nok at benytte en Query når jeg skal lave søgninger i en tabel.  TTables har nogle rutiner (Find, Locate - søg dem i online hjælpen eller skriv igen hvis du vil ha\' et eksempel). 

Nedenfor er der et eksempel på hvorledes du kan benytte en query.

Start på en ny, tom form.  Klasy en TQuery component på formen samt en datasource.  sæt datasourcens Dataset property til Query1.  Sæt en DBGrid på formen og sæt dens datasource property til Datasource1.  Placer derefter en button på formen og i dens OnClick event skriver du følgende kode:

Query1.Close;
  Query1.DatabaseName := \'DBDEMOS\';
  Query1.SQL.Clear;
  Query1.SQL.Add(\'Select *\');
  Query1.SQL.Add(\'From Customer\');
  Query1.SQL.Add(\'Where CustNo = :CustNo\');
  Query1.SQL.Add(\'  Or Company = :CompName\');
  Query1.SQL.Add(\'  Or City = :CityName\');

  Query1.ParamByName(\'CustNo\').AsInteger := 1221;
  Query1.ParamByName(\'CompName\').AsString := \'Unisco\';
  Query1.ParamByName(\'CityName\').AsString := \'Freeport\';
  Query1.Open;


Avatar billede pellelil Nybegynder
04. oktober 2000 - 14:59 #6
Glem mit \"svar\", da jeg tænkte på sorteringen - kig i stedet på delphi\'s
Avatar billede skurggman Nybegynder
04. oktober 2000 - 19:31 #7
Til delphi

Det virker ikke, fejl: missing operater or semicolon, undeclared identyfier \'asinteger\'

ect...

desuden, hvad ér det for noget med custno og alle de compname osv...hvad skal jeg rette dem til?
Avatar billede skurggman Nybegynder
04. oktober 2000 - 19:31 #8
prøv med ttable måske???
Avatar billede delphi Nybegynder
05. oktober 2000 - 09:20 #9
Hvilken version af Delphi arbejder du med?
Ovenstående er taget fra et program jeg bankede sammen i Delphi 5 - og der virker det.

Delphi
Avatar billede delphi Nybegynder
05. oktober 2000 - 10:07 #10
Jeg har lavet en TTable version.  Programmet er lidt omfattende, idet det indeholder SetRange, Locate, Find og FindNearest metoderne - det skulle give dig mulighed for at komme vidre - så derfor har jeg inkluderet kode for både form og unit.

Kig på det og råb op hvis du har spørgsmål.

Delphi.

PS: Jeg har fri i morgen (fredag), så der er jeg er måske lidt fraværende....

//******  Formens kode (som text)
object Form1: TForm1
  Left = 676
  Top = 505
  Width = 870
  Height = 640
  Caption = \'Form1\'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = \'MS Sans Serif\'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object DBGrid1: TDBGrid
    Left = 16
    Top = 8
    Width = 761
    Height = 345
    DataSource = DataSource1
    TabOrder = 0
    TitleFont.Charset = DEFAULT_CHARSET
    TitleFont.Color = clWindowText
    TitleFont.Height = -11
    TitleFont.Name = \'MS Sans Serif\'
    TitleFont.Style = []
  end
  object buRange: TButton
    Left = 24
    Top = 376
    Width = 75
    Height = 25
    Caption = \'&Apply Range\'
    TabOrder = 1
    OnClick = buRangeClick
  end
  object buLocate: TButton
    Left = 120
    Top = 376
    Width = 75
    Height = 25
    Caption = \'&Locate\'
    TabOrder = 2
    OnClick = buLocateClick
  end
  object buFind: TButton
    Left = 208
    Top = 376
    Width = 75
    Height = 25
    Caption = \'&Find 1560\'
    TabOrder = 3
    OnClick = buFindClick
  end
  object buFindNearest: TButton
    Left = 296
    Top = 376
    Width = 113
    Height = 25
    Caption = \'Find&Nearest Uni\'
    TabOrder = 4
    OnClick = buFindNearestClick
  end
  object Table1: TTable
    Active = True
    DatabaseName = \'DBDEMOS\'
    TableName = \'customer.db\'
    Left = 56
    Top = 40
  end
  object DataSource1: TDataSource
    DataSet = Table1
    Left = 56
    Top = 72
  end
end




//******  Unitens kode

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Grids, DBGrids, Db, DBTables;

type
  TForm1 = class(TForm)
    Table1: TTable;
    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    buRange: TButton;
    buLocate: TButton;
    buFind: TButton;
    buFindNearest: TButton;
    procedure buRangeClick(Sender: TObject);
    procedure buLocateClick(Sender: TObject);
    procedure buFindClick(Sender: TObject);
    procedure buFindNearestClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

// SetRange eksempel.  Bemærk at denne metode ikke
// decideret finder noget du søger efter.  Den begrænser
// blot hvor stor en mængde af data der vises fra tabellen.
// Eksemplet bygger på on-line hjælpen.
procedure TForm1.buRangeClick(Sender: TObject);
begin
  Table1.Active := False;
  Table1.DatabaseName := \'DBDemos\';
  Table1.TableName    := \'Customer.db\';
  Table1.IndexName    := \'ByCompany\';
  Table1.Active      := True;

  if buRange.Caption = \'&Apply Range\' then
    begin
      Table1.SetRange([\'a\'],[\'c\']);

      buRange.Caption := \'&Drop Range\';
    end
  else
    begin
      Table1.CancelRange;
      Table1.Refresh;
      buRange.Caption := \'&Apply Range\';
    end;
end;

// Eksempel hvor der tabellens cursor flyttes til
// de specifikt søgte data. 
// Fordelen ved Locate er at du kan søge på alle
// kolonner, ikke kun dem der er index.  Ulempen er,
// sommed FindKey, at du skal kende de helt rigtige
// søgekriterier.  Fx. Kan du ikke søge på \'UNI\'
// for at finde firmate \'UNISCO\'.

procedure TForm1.buLocateClick(Sender: TObject);
begin
  Table1.Locate(\'CustNo;Company;\',VarArrayOf([\'1380\',\'Blue Jack Aqua Center\']),
                [loPartialKey]);
end;

// FindKey eksempel, lidt lige som Locate, men man
// kan kun søge på index kolonner - det kan
// udemærket være et kombineret index, men et sådant
// findex bare ikke i DBDEMOS, Customer tabellen.
// Her beder jeg tabellen om at flytte cursoren
// til det firma der har nr. 1560
procedure TForm1.buFindClick(Sender: TObject);
begin
  Table1.IndexFieldNames := \'CustNo\';
  Table1.FindKey([\'1560\']);
end;

// Som FindKey, men finder første record, der matcher
// eller er \"højere\" end søgekriterierne.
// Her søges på første firma hvis navn starter
// med \'Uni\' - eller noget højere.
procedure TForm1.buFindNearestClick(Sender: TObject);
begin
  Table1.IndexFieldNames := \'Company\';
  Table1.FindNearest([\'Uni\']);
end;

end.
Avatar billede pellelil Nybegynder
05. oktober 2000 - 11:12 #11
Du kan også gøre den uden brug af parametre:
<SNIP>
  Query1.Close;
  Query1.DatabaseName := \'DBDEMOS\';
  Query1.SQL.Clear;
  Query1.SQL.Add(\'Select *\');
  Query1.SQL.Add(\'From Customer\');
  Query1.SQL.Add(\'Where (CustNo = 1221)\');
  Query1.SQL.Add(\'  Or (Company = \'+chr(39)+\'Unisco\'+Chr(39)+\')\');
  Query1.SQL.Add(\'  Or (City = \'+chr(39)+\'Freeport\'+Chr(39)+\')\');
  Query1.Open;
</SNIP>

Den eneste forskel er at parametrene gør det lidt nemmere (smag og behag) men resultatet er det samme (dog har jeg brug paranteser \"omkring where-delen\").
Avatar billede delphi Nybegynder
05. oktober 2000 - 11:27 #12
Jo da, man kan se\'følig gøre det med indlagte streng konstanter, som ved pellelil, eller med varaiable (med parametre er nu det der er mest \"rigtigt\").  Jeg mener kun at paranteser forstyrer - de er ikke nødvendige i dette eksempel og ikke påkrævet af SQL.

Eksempel med variable søgeværdier (og en Query).

Var
  CustNo  : Integer;
  CompName : String;
  CityName : String;

Begin
  CustNo  := 1221;
  CompName := \'Unisco\';
  CityName := Edit1.Text;  // Fx. en TEdit på formen.

  Query1.Close;
  Query1.DatabaseName := \'DBDEMOS\';
  Query1.SQL.Clear;
  Query1.SQL.Add(\'Select *\');
  Query1.SQL.Add(\'From Customer\');
  Query1.SQL.Add(\'Where CustNo = \'+IntToStr(CustNo));
  Query1.SQL.Add(\'  Or Company = \'+CompName);
  Query1.SQL.Add(\'  Or City = \'+CityName);

  Query1.Open;
End;

(Ud af hånden og ned på tastaturet => ikke afprøvet!)

Delphi
Avatar billede pellelil Nybegynder
05. oktober 2000 - 11:30 #13
delphi> du skal lige have et sæt anførsels-tegn omkring dine strenge, og jeg må indrømme at jeg ikke er klar over om parenteser omkring dine or-dele er påkrævet, men god/gammel vane gør at jeg altid sætter dem !?
Avatar billede delphi Nybegynder
05. oktober 2000 - 11:35 #14
Du har ret der mangeler gåseøjne eller anførselstegn (afhængigt af bagvedliggende DB-system).

Paranteser er ikke nødvendige.  De skal dog bruges hvor man vil gøre forskel på den normale vægtning af et udtryk.  Fx. er der stor forskel på følgende udtryk:

1:  Where A=1 OR B=2 AND C=3 

2:  Where (A=1 OR B=2) AND C=3

Eksempel 1: er underforstået det samme som:

    Where A=1 OR (B=2 AND C=3)

Fidusen er, at du i dit eksemple skrev:

    Where (A=1) OR (B=2) AND (C=3)

Hvilket ikker er noget du har lært fra SQL, men er et krav under Delphi\'s object pascal (i en If sætning, se\'følig).

Delphi


Avatar billede delphi Nybegynder
05. oktober 2000 - 11:36 #15
Skal vi så iøvrigt ikke ha\' lukket det spørgsmål....
Avatar billede pellelil Nybegynder
05. oktober 2000 - 12:25 #16
delphi> Du behøver ikke at lære mig om boolskalgebra eller Delphi\'s implementering af samme, men jeg er ikke klar over hvad SQL \"kræver\". Som jeg sagde i dag er det bare en god vane, men alligevel tak for din indsats :-)
Avatar billede delphi Nybegynder
05. oktober 2000 - 12:40 #17
Undskyld, men du skrev nu:
\"...jeg må indrømme at jeg ikke er klar over om parenteser omkring dine or-dele er påkrævet...\"

Jeg regnede iøvrigt også med at du kendte parantes reglerne, men det behøvede ikke være sådan og der er andre læsere....

Avatar billede skurggman Nybegynder
06. oktober 2000 - 09:41 #18
Hør lige her, jeg skal bruge det lille rene stump jeg skal bruge til at søge i en database, jeg skal bruge en edit felt, og en knap, når jeg skirver noget i edit og trykker på knappen viser den hvad den har fundet i dbgridet. Når i har det får i de 120 point. I har endnu ikke svaret optimalt, da ingenting virker. Jeg bruger delphi 5!
Avatar billede skurggman Nybegynder
06. oktober 2000 - 09:42 #19
Det er en Ttable!!!!
Avatar billede pellelil Nybegynder
06. oktober 2000 - 11:17 #20
SQL foresprøgsler virker ikke på en TTable, og de eksempler Delphi og jeg har vist er bygget ud fra en af Delphi\'s demodatabaser, så naturligvis virker det ikke på din tabel.

Hvis du vil have et eksempel der viser nøjagtigt hvordan det skal skrives så er du nødt til at oplyse felt-beskrivelsen (felt: navne, typer, index und so weiter).

Hvis du vil/kan læse mellem linierne så er nedenstående fra Delphi\'s hjælp og beskriver/viser brugen af Locate (på en TTable):
<SNIP>
with CustTable do
  Locate(\'Company;Contact;Phone\', VarArrayOf([\'Sight Diver\', \'P\', \'408-431-1000\']), [loPartialKey]);
</SNIP>

Hvis du vil have din grid til kun at vise de poser (altså en filtrering frem for en søgning) så skal du i stedet (når vi taler TTable) bruge Event\'en OnFilterRecord.

IGEN:  Jeg vil foreslå/foretrække en TQuery  :-)
Avatar billede skurggman Nybegynder
09. oktober 2000 - 08:37 #21
Mine felter man skal søge i hedder, \"Editdelnr\" og \"Editdelnavn\". Jeg skal bruge en søgestring til en Ttable, jeg ved det skal kunne lade sig gøre. Alt det der med TQuery kan du glemme, oliver. Kan I ikke give mig en kode der lige passer ind, jeg skal bruge den meget hurtigt, på forhånd tak.

Avatar billede pellelil Nybegynder
09. oktober 2000 - 08:55 #22
Lad mig lige spørge (bare en gang) HVORFOR vil du ikke gøre brug af en TQuery?. Jeg mener hvis du skal slå et søm i vægen så bruger du vel heller ikke en sav !?

Ovenstående eksempel kan nemt tilrettes til det du har brug for. Jeg gætter på at de felter du indtaster i er dem du nævner some \"Editdelnr\" og \"Editdelnavn\", men du skriver således ikke hvad de hedder i tabellen, så jeg har gættet på at de hedder \"delnr\" og \"delnavn\" (alternativet var \"John\" og \"Aage\" <G>).

<SNIP>
with Table1 do
  Locate(\'delnr;delnavn\', VarArrayOf([EditDelNr.Text, EditDelNavn.Text]), [loPartialKey]);
</SNIP>


Jeg kan varmt anbefale at du prøver at læse lidt i Delphi\'s hjælp - den er ikke helt ubrugelig.
Avatar billede kode Nybegynder
07. november 2000 - 17:40 #23
Et eksempel på hvordan du kan bruge finde funktionen>>Locate

Tablelokaler.Locate(\'værelsesnummer\', \'2\',[]);

Denne function leder i tabellen >>Tablelokaler<< i attributten >>værelsesnummer<< efter >>2<<.
hvis fundet sættes databasens cursor på recorden, ellers returneres false. Håber forklaringen er fyldestgørende :=)
Avatar billede surreal Nybegynder
29. november 2000 - 15:51 #24
And the correct answer is:

procedure GetFirst(var Navn:string; var FoundData:boolean);
begin
  FoundData := False;
  With DataModule1.Table1 do
  begin
    First;
    if not EOF then
    begin
      Navn := FieldByName(\'SName\').AsString;
      FoundData := True;
    end;
  end;
end;

procedure GetNext(var Navn:string; var FoundData:boolean);
begin
  FoundData := False;
  with DataModule1.Table1 do
  begin
    Next;
    if not EOF then
    begin
      Navn := FieldByName(\'SName\').AsString;
      FoundData := True;
    end;
  end;
end;

Avatar billede puddelundercover Nybegynder
17. august 2001 - 15:59 #25
At gøre det helt nemt ville være at bruge følgende:

Table1.Setkey;
Table1.IndexName := \'Feltnavn\'; //Andet end primary Index
Table1.FieldByName(\'Feltnavn\').AsString := Edit1.text;
Table1.GotoNearest

eller

Table1.FindNearest([edit1.text]);
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester