24. januar 2000 - 15:09Der er
13 kommentarer og 2 løsninger
Slette linier fra en combobox?
1. Jeg har en combobox, hvor jeg henter de forskellige linier fra en database med koden:
procedure TFormRediger.FormCreate(Sender: TObject); var I:Integer; begin I := 0; Table1.First; Repeat ComboBoxRedigerKunde.Items.Add(Table1.fieldbyname('Kunde').Value); Inc(I); Table1.FindNext; Until (I = Table1.RecordCount); end;
Det virker osse fint nok. Problemet er bare; lukker jeg denne form og tilføjer en kunde mere i databasen på en andne form, så opdateres comboboxens indhold først, når jeg helt har haft lukket programmet og startet det igen. Der må være en løsning? Jeg har rodet lidt med OnCreate og OnDestroy, men jeg kan ikke få det til at virke.
2. Når jeg vælger en af "emnerne" i comboboxen... så skal den hente infomationer om det emne i databasen og udfylde nogle Edit's med de info. How?
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.
det nemmeste vil være at benytte TDBComboboxLookup, er dens parameter sat korrekt op fylder den selv comboboksen op med værdier fra tablen.
Desuden hvis du vil forsætte din løsning bør du lave det om til nedstående, fordi recountcount ikke altid er en gyldig værdi afhængig hvilket type dataset du benytter. Dit vil dog virke med Table. Det andet er bare mere korrekt
BEGIN Table1.First; WHILE TABLE.EOF = False DO BEGIN ComboBoxRedigerKunde.Items.Add(Table1.fieldbyname('Kunde').Value); Table1.FindNext; END END
Problem 1 skyldes fordi at delphi formentlig autocreate din form, derfor kaldes formcreate og formdestroy kun 1 gang. Benyt derfor formshow og formhide.
Problem 2 benyt delphi TDB???? kontroller de fylder automatisk dine databundne controller med data fra databasen. Det du gør er en klassisk fejl for begynder.
Flyt det du har i formcreate ud i en procedure du f.eks. kalder UpdateCombo; og kald den fra formcreate til at starte med:
Procedure UpdateCombo; var I:Integer; begin ComboBoxRedigerKunde.Items.clear; // NB Ny linie I := 0; Table1.First; Repeat ComboBoxRedigerKunde.Items.Add(Table1.fieldbyname('Kunde').Value); Inc(I); Table1.FindNext; Until (I = Table1.RecordCount); end;
procedure TFormRediger.FormCreate(Sender: TObject); begin updatecombo; end;
og hvergang du kommer tilbage fra den form hvor du opdaterer db'en kalder du bare updatecombo.
Men bemærk den nye linie jeg satte ind i UpodateCombo: Hvis ikke den er der vil de samme kunder blive tilføjer igen og igen.
og for nr. 2:
I comboboxens OnClick event kan du gøre følgende:
knr : string; begin if ComboBoxRedigerKunde.itemindex <> -1 then begin knr := ComboBoxRedigerKunde.item[ComboBoxRedigerKunde.itemindex]; if table1.findkey([knr]) then begin edit1.text := table1.fieldbyname('kunde').asstring; edit2.text := table1.fieldbyname('næstefelt').asstring; end else begin showmessage('Kunder er blevet slettet !'); end; end; end;
:o) Nu er vi da vist ved at have været omkring alt omhandlende MS Access programmering? hehe! Anyway... Det virker fint nu, men når jeg via ComBoBox'en henter info om en kunde, skál jeg jo kunne rette disse info og gemme i DB igen. Men eftersom disse felter allerede eksisterer i DB, overskriver den ikke bare; i hvert fald ikke med Table1.Insert;
Skal jeg slette hele kunde og oprette igen? Eller er der en nemmere måde, hvorpå den bare overskriver de "gamle" info?
Og nu vi er ved det... Hvordan sletter jeg en kunde fra databasen? Table1.Delete;?? Oder was
(Rolig gutter... skal nok få delt de point ud så snart det her virker, hehe)
Cope21> Hvis du i en database tabel skal ændre indholdet i en record (og, som i dit eksempel, benytter TTables), så skal du først sørge for at din "current record pointer" peger på den rigtige record. Dvs. du enten bruger en af TTable's søge funktioner eller benytter en simpel søge algoritme, alá:
( Bemærk: Jeg bruger her DBDemos databasen og min TTable, kaldet taCustomer er tilknyttet Customer tabellen. Når jeg arbejder med TTables, så opretter jeg altid fields med tabellens Field editor. Det gør det meget nemmere at arbejde med de enkelte felter (=kolonner) i tabellen, idet man ikke skal rode med FieldByName('xx') rutiner mv.)
MyTable.First; While (Not taCustomer.EOF) and (taCustomerCustNo.AsString=aCustNo) Then taCustomer.Next;
If (taCustomerCustNo.AsString=CustNo)Then Begin // Her ændre du så indholdet af recorden. End;
Når du nu er sikker på at stå på den rigtige linie er proceduren for at lave ændringer, at du: 1: Sætter tabellen i Edit mode. 2: Laver dine ændringer 3: Gemmer dine ændringer.
Ovenstående Begin-End sektion skal dermed udvides med:
If ... Then Begin // 1. Sæt tabellen i Edit mode. taCustomer.Edit;
// 2. Lav ændringer taCustomerCompany.AsString := 'xx'; taCustomerAddr.AsString := 'xx'; taCustomerAddr2.AsString := 'xx'; // Etc. indtil alle ændringer er foretaget. Bemærk felter der ikke ændres beholder deres originale indhold.
Jeg har iøvrigt bemærket at du flere gange, dvs. i andre spørgsmål, har brugt:
i := 0 Table.First Repeat ... table.Next Inc(i) Until i=table.recordcount
Som blackthorne skriver, så kan du ikke altid regne med RecordCount værdien. Desuden er det en forholdmæssigt meget langsom funktion - prøv fx. med en SQL query på en Access 2.0 med en ODBC forbindelse under Win 3.1 på en 33 MHz maskine (det har jeg) - det er døden at anvende RecordCount. Istedet er den rigtige metode at anvende
table.first While Not table.Eof Do Begin ... table.next end;
Cope21>for lige at simplificere dit spørgsmål vedr. opdatering, uden at jeg på den måde vil tage noget fra Delphi's forklaring der er ganske udmærket, så er principperne vedr. oprettelse og opdatering ganske enkle:
opretter en nye record registret i alfabetisk/nummer orden i forhold til den værdi din nøgle har. Insert kan du altid bruge, uden først at skulle have fundet en record.
Opdatering/rettelse: if table1.findkey([nøgleværdi]) then begin table1.edit; table1.fieldbyname('feltnavnx').value := værdix; table1.fieldbyname('feltnavny').value := værdiy; table1.post;
Find din record (f.eks. med table1.findkey([nøgleværdi]) og brug table1.edit (rette/opdatere) flyt de værdier ind i de felter du vil ændre med table1.fieldbyname('feltnevn').value := værdi; og afslut det hele med table1.post;
Seltning: if table1.findkey([nøgleværdi]) then begin table1.delete; end;
Find din record på samme måde som med opdatering/rettelse og kald derefter table1.delete;
så enkelt er det, og jeg ved godt det er det samme som Delphi har skrevet, men her i samme stil som det øvrige vi har talt om.
Nu er jeg (heller) ikke ekspert i delphi, med kunne cope21 ikke bare bruge ene DB komponenter, dvs. DBCombo DBEdit DBText De bliver (så vidt jeg ved) automatisk opdateret.
Der skal selvfølgelig også være en opdater knap (table.edit), en opret (table.insert) knap og en gem ændringer (table.post)
De nævnte komponenter kan ikke (uden unødigt besvær) bruges, hvis du ønsker at rette tabellens værdier fra kode. De benyttes udelukkende interaktivt.
Tænkt eksempel: Alle 1000 medarbejdere i et firma skal have en Skatteforhøjelse på 0.2%. Det ville være døden at skulle indtaste alle disse ændringer manuelt. I kode fylder det ~10 linier.
Table.Open Table.First While Not Table.EOF Do Begin Table.Edit; TableTaxRate.Value := TableTaxRate.Value * 1.002; Table.Next; // Poster automatisk ændring. End; Table.Close;
Du sletter med "Delete" metoden (logisk nok), Kommandoen sletter den aktuelle record/post. Nedenstående vil slette hele den første post i en tabel:
Table1.Open Table1.Delete; Table1.Close;
Hvis du vil ha' slettet en hel tabel bruger du "DeleteTable" metoden. (Det er rimeligt forklaret i on-line hjælpen).
NiP
PS: Er det ikke på tide at få lukket det her spørgsmål og evt. oprettet et eller flere nye til dine tillægsspørgsmål?
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.