Avatar billede visuel Nybegynder
03. april 2004 - 23:02 Der er 10 kommentarer og
1 løsning

Update ListBox

Når jeg skal opdatere en ListBox med data fra en db, hvad skal jeg så gøre?? Helt konkret skal den hente data fra db når programmet starter. Ligeledes skal den opdatere så snart man indsætter, sletter eller retter i data.

Jeg forestiller mig noget med en funktion (UpdateListBox), der kan kaldes ved programstart samt når man trykker på en knap for at indsætte, slette eller rette data.

Jeg har følgende kode der virker når man indsætter det ved buttonclick, men hvordan får jeg det indkapslet i en function og i hvilken fil (.pas eller .dfm??) skal det indsættes?

procedure TAnsoeg.SamtalerButtonClick(Sender: TObject);
var
  Q1: TADODataset;
begin
  Q1 := TADODataset.Create(self);
  Q1.Connection := ADOConnection1;

  Q1.Close;
  Q1.CommandText := 'SELECT * FROM Firma';
  Q1.Open;

  While not Q1.Eof do begin
    ListBox1.Items.Add(Q1.FieldByName('Firmanavn').AsString);
    Q1.Next;
  end;
  Q1.Free;
end;
Avatar billede vallemanden Nybegynder
04. april 2004 - 05:34 #1
Procedure UpdateListbox;
var
  Q1: TADODataset;
begin
  Q1 := TADODataset.Create(self);
  Q1.Connection := ADOConnection1;

  Q1.Close;
  Q1.CommandText := 'SELECT * FROM Firma';
  Q1.Open;

ListBox1.Clear;
  While not Q1.Eof do begin
    ListBox1.Items.Add(Q1.FieldByName('Firmanavn').AsString);
    Q1.Next;
  end;
  Q1.Free;
end;

Denne sættes som den allerførste procedure i din hoved unit
og når du skal bruge det i en anden procedure skriver du

UpdateListBox;
Avatar billede hrc Mester
04. april 2004 - 10:04 #2
Jeg forstår ikke hvorfor I aldrig sætter en try finally omkring sådan en operation. Det er et eksempel, det ved jeg, men det ødelægges ikke af tre linier mere. Jeg har tit oplevet at løbe ind i en låst tabel eller andre fejl, i en ellers velfungerende funktion - og så har mine utallige try-finally'er ryddet pænt op efter mig.

Min version vill fylde lidt mere (men er den også kørt lidt til de modsatte ekstremer). Jeg ville foretrække at nedarve TADOTable til at indeholde funktionen - hvilket jeg ikke har gjort her. I nedenstående er det en procedure i TAnsogs private sektion.

I øvrigt har jeg gjort den mere generel vha. at sende ListBoksens TStringList som parameter, hvorved du nu sende hvilken som helst liste til den: UpdateStringlist(listBox.Items); // eller andre

Procedure UpdateStringlist(aList : TStrings); // TStrings er baseklasse for strenglisterne
var
  Q1: TADODataset;
begin
  // Sæt timeglas og opret objekt - husk at fjerne dem igen
  Screen.Cursor := crHourglass;
  Q1 := TADODataset.Create(self);
  try // Gik det godt at oprette objekt, så start try-sektion
    Q1.Connection := ADOConnection1;

    // Q1.Close; // Den er lukket - du har lige oprettet den!
    Q1.CommandText := 'SELECT * FROM Firma';
    Q1.Open;

    // Det går hurtigere på denne måde - husk at slå det fra igen
    aList.BeginUpdate;
    try
      aList.Clear;
      while not Q1.Eof do begin
        aList.Items.Add(Q1['Firmanavn']); // Tror nok at det her også virker
        Q1.Next;
      end;
    finally
      aList.Items.EndUpdate; // Slå fra
    end;
  finally
    // To operationer i samme try-finally. Start med de sikreste
    Screen.Cursor := crDefault;
    Q1.Free; // Frigiv opjekt
  end;
end;

Man kunne overveje om der skulle en try-except på også:


try
  operation
except
  on e: exception do
    raise exception.create('Error in UpdateStringlist'+#13#10+e.Message);
end;

Nu har du funktionen der læser data fra tabellen. Der er ingen SQL-funktion der automatisk "fortæller", at der er sket noget i tabellen. Dette løses normalt vha. den Refresh-knap som du også overvejer.

Hvis du bruger Paradox- eller Access-tabeller ville jeg overveje at koble DataSettet sammen med en TDataSource. Den har et OnDataChange-event som du kan bruge, men der er faktisk ingen grund til ovenstående kode nu, idet du derefter bare kan bruge en TDBListBox som forbindes til TDataSourcen.
Avatar billede visuel Nybegynder
04. april 2004 - 12:59 #3
Jeg er ked at sige det venner, men ingen af forslagene virker :(

Jeg får en:

[Error]Ansoeger.pas(122): undeclared identifier: 'self'
Avatar billede visuel Nybegynder
04. april 2004 - 13:06 #4
Det er i linien

Q1 := TADODataset.Create(self);

hvis I ikke skulle have gættet det ;)
Avatar billede hrc Mester
04. april 2004 - 15:08 #5
Sæt du bare den til nil - det sker der ikke noget ved, bare at dy husker at frigive den igen. Fejlen er, at self er pointeren til det pågældende objekt og når nu både UpdateListbox og UpdateStringlist ikke er del af et objekt (eks. "TfrmMain."UpdateStringList), så er self ikke eksisterende.
Avatar billede hrc Mester
04. april 2004 - 15:08 #6
Q1 := TADODataset.Create(nil);
Avatar billede visuel Nybegynder
04. april 2004 - 19:23 #7
Fedt - Mange tak

hrc, sider du lige et svar så kan i dele pointene :)
Avatar billede visuel Nybegynder
04. april 2004 - 20:26 #8
Og hvis nogen ville have lidt ekstra point (igen) ;)

http://www.eksperten.dk/spm/485790
Avatar billede visuel Nybegynder
14. april 2004 - 22:46 #9
hmm, han er tilsyneladende ikke interesseret, så det hele går til dig, vallemanden
Avatar billede vallemanden Nybegynder
14. april 2004 - 22:54 #10
takker :-)
Avatar billede hrc Mester
15. april 2004 - 16:21 #11
Vent, Vent, VEENNNTTT! Aarrrhh! Sørens også.
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