Avatar billede madshenrik Nybegynder
15. september 2000 - 23:08 Der er 16 kommentarer og
2 løsninger

Avanceret sql

Jeg har netop fået et svar på en søgning ud i et dbgrid. Nu skal det være sådan at man kan klikke med musen på en celle hvorefter man springer til en viewform. Denne viewform er kun beregnet til at man skal se en post af gangen.
Queryupdate.SQL.Clear;
Queryupdate.sql.add(\'Select Ident, Overskrift\');
Queryupdate.sql.add(\'From Notatbase\');
Queryupdate.sql.add(\'where Ident = Valgt celle i dbgriden\');
Queryupdate.Open;
Derefter skal det hele pakkes ind i en if sætning, da programmet skal kunne finde ud af det uanset om man trykker på Ident eller Overskrift f.eks.
if dbgridcelle.title = Ident then
begin
gør ovenstående
end;
Problemet er altså at flytte indholdet af den celle man klikker på til where sætningen.

Mads
Avatar billede sjensen Nybegynder
17. september 2000 - 08:14 #1
Mads,

Du skal bruge dbgrid properties: SelectedField, SelectedIndex og/eller SelectedRow til at arbejde med den valgte linie i en dbgrid.

SelectedField giver dig direkte adgang til dataene i den valgte celle, og selectedIndex giver dig nummer på den kolonne cellen er i (d.v.s. der hvor din titel også er)

Endeligt vil SelectedRow pege direkte på den tilsvarende record i dit dataset.

Endeligt har du propertien FIELDS der er et array af kolonner for den valgte record og denne kan du bruge direkte hvis du f.eks. ved hvilken kolonne \"Ident\" er. Eks.

Din kolonne IDENT er kolonne 3 (d.v.s. sige kolonne 4 på skærmen fordi kolonne 0 er den første).

if dbgrid1.selectedindex = 3 then  // 3 = ident kolonnen
begin
  Queryupdate.SQL.Clear;
  Queryupdate.sql.add(\'Select Ident,Overskrift\');
  Queryupdate.sql.add(\'From Notatbase\');
  Queryupdate.sql.add(\'where Ident = dbgrid1.fields[3]\');
  Queryupdate.Open;
end;
Avatar billede sjensen Nybegynder
17. september 2000 - 08:17 #2
Ups. en lille syntaxfejl:

Queryupdate.sql.add(\'where Ident = dbgrid1.fields[3]\');

skal være

Queryupdate.sql.add(\'where Ident = \'+dbgrid1.fields[3]);

Og hvis ident er et tekstfelt, og der f.eks. kan være mellemrum (eller komma) i teksten skal du omkranse den med anførselstegn:

Queryupdate.sql.add(\'where Ident = \'+#39+dbgrid1.fields[3]+#39);

NB! #39 er tegner \'  (d.v.s. det enkelte anførselstegn.
Avatar billede madshenrik Nybegynder
17. september 2000 - 16:39 #3
Der er en invalid type conversion i denne linie.
Queryupdate.sql.add(\'where Ident = \' +#39+resdbgrid.fields[0].value+#39);
og jeg kan ikke få dette til at virke
Queryupdate.sql.add(\'where Ident = \'inttostr(+#39+resdbgrid.fields[0].value+#39)); og er heller ikke sikker på at det er rigtigt. Ved du hvad problemet er sjensen.

Avatar billede tknudsen Nybegynder
18. september 2000 - 09:04 #4
prøv evt at parametrere istedet:

Queryupdate.SQL.Add(\'WHERE Ident = :param1\');
Queryupdate.ParamByName(\'param1\').AsDataType := dbgrid1.fields[3];

- hvor AsDataType skal erstattes af den korrekte datatype feks AsInteger hvis dbgrid1.fields[3] er af typen integer (!)
Avatar billede sjensen Nybegynder
18. september 2000 - 09:12 #5
madshenrik, hvis IDENT er en integer, ligger problemet i at du også prøver at konvertere de 2 anførselstegn til tekst. Brug istedet:

Queryupdate.sql.add(\'where Ident = \'+#39+inttostr(resdbgrid.fields[0].value)+#39);
Avatar billede sjensen Nybegynder
18. september 2000 - 09:14 #6
Ups, lige en forglemmelse: I sql er det ikke nødvendigt at omkranse et heltal med anførselstegn. Det skader nu ikke, men er ikke nødvendigt. Kun for tekst og Realtyper (d.v.s. tal med punktum i f.eks. 123.45)

SÅ du kan også bruge:

Queryupdate.sql.add(\'where Ident = \'+inttostr(resdbgrid.fields[0].value));
Avatar billede madshenrik Nybegynder
18. september 2000 - 15:18 #7
Sjensen nu virker det tildels. Men jeg tror delphi laver den mærkeligste fejl jeg har set til dato. Jeg har mit dbgrid med index 0 og 1 Ident = 0. Jeg benytter mig så af denne kode.
if resDBGrid.selectedindex = 0 then  // 0 = ident kolonnen
begin
    with NotatDataModul do
      begin
          Queryupdate.Close; 
          Queryupdate.SQL.Clear;
          Queryupdate.sql.add(\'Select Ident, Overskrift, Nogleord, Detail\');
          Queryupdate.sql.add(\'From Notatbase\');
          Queryupdate.sql.add(\'where Ident = \'+#39+inttostr(resdbgrid.fields[0].value)+#39);
          Queryupdate.Open;

  Updateform.EditUpdateOverskrift.Text := Queryupdate.fields[1].value;
  Updateform.EditUpdatenogleord.Text := Queryupdate.fields[2].value;
  Updateform.MemoUpdateDetail.Text := Queryupdate.fields[3].value;
  Updateform.Visible := true;

        end;
end;
I min ident har jeg i øjeblikket følgende værdier som forresten er autoincrement 1-3-4-11. Disse har så tilsvarende Overskrift, nøgleord og detaildel. Det mærkelige opstår i det øjeblik jeg klikker på dbgridet i runtime for koden virker på 4 og 11 men ikke på 1 og 3. Hvordan i H... kan dette være. Jeg forstår det ikke da jeg ikke på noget tidspunkt berører SelectedRows. Fejlen er en simpel invalid type conversion, men jeg forstår ikke hvorfor den kommer.
Avatar billede sjensen Nybegynder
18. september 2000 - 15:32 #8
Jeg kan ikke umiddelbart se hvad der er galt, men du skal selvfølgeligt være opmærksom på at en select altid kan returnere flere records. Med et autoincrementfield som nøgle burde den selvfølgeligt ikke, men du bør nok håndtere situationen. F.eks. således:

Queryupdate.Open;
if queryupdate.recordcount > 0 then // hvis der er 1 eller flere recs
begin
  queryupdate.first;  // positioner pointeren på den 1. record
  while not queryupdate.eof do
  begin
    Updateform.EditUpdateOverskrift.Text := Queryupdate.fields[1].value;
    Updateform.EditUpdatenogleord.Text := Queryupdate.fields[2].value;
    Updateform.MemoUpdateDetail.Text := Queryupdate.fields[3].value;
    Updateform.Visible := true;
  end;
end else
begin
  // ingen recs fundet. vis evt. en fejl
  // showmessage(\'Ingen records\');
end;
       
På denne måde håndterer du situationen hvis der er flere end 1. record eller slet ikke er nogen. Det bør der jo være kunne du sige når du nu kan se den i din grid, men i et flerbruger system kan en anden bruger have slettet recorden selvom den stadig fremgår af din grid.

Ellers kan jeg som nævne ikke se hvor der skulle være en fejl. En metode jeg i øvrigt bruger ofte når jeg skal finde fejl er at bruge Showmessage(\'x\'); mellem hver linie, der hvor jeg tror fejlen kommer. På den måde kan jeg se hvilken showmessage der blev vist sidst inden feljen kom og dermed også hvilken linie fejlen opstår i. Det kan måske hjælpe til at finde fejlen. I hvert fald isolerer man den. Prøv evt.:

showmessage(\'1\');
if resDBGrid.selectedindex = 0 then  // 0 = ident kolonnen
begin
showmessage(\'2\');
    with NotatDataModul do
      begin
showmessage(\'3\');
          Queryupdate.Close; 
          Queryupdate.SQL.Clear;
          Queryupdate.sql.add(\'Select Ident, Overskrift, Nogleord, Detail\');
          Queryupdate.sql.add(\'From Notatbase\');
          Queryupdate.sql.add(\'where Ident = \'+#39+inttostr(resdbgrid.fields[0].value)+#39);
showmessage(\'4\');
          Queryupdate.Open;
showmessage(\'5\');

  Updateform.EditUpdateOverskrift.Text := Queryupdate.fields[1].value;
showmessage(\'6\');
  Updateform.EditUpdatenogleord.Text := Queryupdate.fields[2].value;
showmessage(\'7\');
  Updateform.MemoUpdateDetail.Text := Queryupdate.fields[3].value;
showmessage(\'8\');
  Updateform.Visible := true;

        end;
end;

På denne måde kan du følge med i hvor langt programmet når inden fejlen opstår.
Avatar billede martinlind Nybegynder
18. september 2000 - 15:33 #9
Der er også den mulighed at du bruger samme Query som til Griden, den har sat DB-pos til den record der er valgt, så hvorfor slå op igen, du kan jo bare skrive

edit1.text := Query.fieldbyname(\'FelftNavn\').AsString

det opdaterer din editbox med den record du står på i griden.

Bare et foreslag, ellers vil jeg foreslå Param på din Query, det er lidt nemere da du så ikke skal bygge dit sql statment op hvergang, skulle også være hurtigere.

Query.ParamByName(\'Ident\').AsInteger := 11;
Query.Open;

Held og Lykke

/Martin
Avatar billede madshenrik Nybegynder
18. september 2000 - 16:22 #10
Smart sjensen jeg har nu fundet fejlen. Det er memoet der ikke kan lave dette.
Updateform.MemoUpdateDetail.Text := Queryupdate.fields[3].value;
Men hvad skal jeg ellers bruge end et memo. Det skal være flere linier.
Avatar billede martinlind Nybegynder
18. september 2000 - 16:35 #11
Også skal man lige tænke på om det er Paradox eller rigtig SQL man kører op imod, for hvis det er SQL så er RecordCount ikke lige sagen når vi snakker hastighed, og et memo field i en DB skal hentes og gemmes via en MemoStream ellers får du ikke hele indholdet med.
Avatar billede madshenrik Nybegynder
18. september 2000 - 16:42 #12
Har fundet ud af at det er fordi at de records det ikke virker i er værdien af detail \'\' ingenting. 
Avatar billede sjensen Nybegynder
18. september 2000 - 16:46 #13
Prøv at bruge
Updateform.MemoUpdateDetail.Text := Queryupdate.fields[3].asstring;

i stedet
Avatar billede martinlind Nybegynder
18. september 2000 - 16:51 #14
Eller gør som Delphi hjælpen foreskriver, det virker hvergang ( ret smart )
Avatar billede madshenrik Nybegynder
18. september 2000 - 20:53 #15
Tak for hjælpen det virker med .asstring.
Avatar billede martinlind Nybegynder
19. september 2000 - 09:02 #16
Debug er væsentligt hurtigere med et breakpoint et par liner før man tror fejlen opstår, og så steppe en line ad gangen indtil man får fejl, faktik er det endnu en af delphi\'s stærke sider, en rigtig god indbygget debugger.
Avatar billede madshenrik Nybegynder
19. september 2000 - 10:14 #17
Hvis du ser dette martinlind vil du så lige give et eks. på ovenstående.
Avatar billede martinlind Nybegynder
19. september 2000 - 10:27 #18
Ctrl+F8 sætter et breakpoint i koden ( mærkeres med en rød prik i venstre side ) og så trukker du på run som du plejer, når programmer når til den \"røde prik\" stopper det og viser source koden, du tryker så på F8 for at steppe ned gennem din kode en line ad gangen og får alle de fejl du ville få normalt du kan så se hvilken line i koden der var skyld i fejlen ( bemærk at den blå line du får i sourcen er den line der bliver kør næste gang du trykker på F8, var\'s værdier kan ses som \"musse hint\" ved at holde mousen over var\'en i debug mode ) men jeg vil foreslå at du læser i online IDE-hjælpen om debug
der står det hele.

/ held og lykke
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