15. september 2000 - 23:08Der 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.
I dette særtema ser vi på, hvordan cloud og AI bliver fundamentet for virksomhedernes digitale forretning, og hvordan de nye muligheder for automatisering og forretningsværdi kan udnyttes uden at miste overblik, sikkerhed og menneskelig kontrol.
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;
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.
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)
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;
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.
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\');
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
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.
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.
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.
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.
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
Synes godt om
Ny brugerNybegynder
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.