![]() |
CD-Datenbank - Array, aus dem man löschen kann..
Hallo!
Dies ist mein erster Beitrag hier, ich hoffe, man kann mir helfen. :) Also folgendes: Ich will ein Programm zum Verwalten von CDs (Interpret, Album, Genre, Jahr, Preis) erstellen. Ich habe also ein Record "tEintrag" und ein Unterrecord "tCDname" (t nehme ich für "typisiert" wegen dem Überblick...) habe also dafür diese Vereinbarung:
Delphi-Quellcode:
Ich hatte das Programm soweit, daß man eintragen, speichern, drucken und öffnen konnte. Aber ich will auch einzelne Einträge aus dem Feld löschen können. Da ich mein Array so vereinbart hatte
type tCDname=Record
interpret, album:string[20]; end; //unterrecord type tEintrag=Record CDname:tCDname; genre:string[15]; jahr:integer; preis:real; end; //record
Delphi-Quellcode:
konnte ich nichts einzeln löschen, hab es jedenfalls nicht hinbekommen. Da habe ich einfach mit
tAlleCDs=Array[1..max] of tEintrag; //max ist eine Konstante
Delphi-Quellcode:
aus der Listbox die einzelnen Einträge gelöscht und dann gespeichert. Doch so will er auf einmal nicht mehr sortieren (nach Interpret beispielsweise...). Also brauche ich wohl ein "dynamisches Array" und dazu eine Löschroutine. Beides habe ich versucht aber nicht hinbekommen, da die Sources aus dem Netz immer zu viel voraussetzen bei mir... :( Vielleicht habt Ihr eine gute Idee? Bin auch übers ICQ zu erreichen, dort meist invisible.
cd_Listbox.Items.Delete(cd_Listbox.ItemIndex);
Viele Grüße, AS [edit=Luckie]Delphi-Tags ergänzt. Beim nächsten mal bitte selber machen. Mfg, Luckie[/edit] |
Re: CD-Datenbank - Array, aus dem man löschen kann..
Hallo und herzlich willkommen in der DP!
Zu deinem Problem: Bei einem dynamisches Array muss vor Verwendung die Länge (Anzahl der Eintrgäge) festgelegt werden. Das geht mit
Delphi-Quellcode:
Wenn du nun einen Eintrag löschen willst, musst du die Anderen Einträge im Array ja um eins nach oben verschieben. Ich würde deshalb das ganze Array, außer des zu löschenden Eintrags, in ein anderes Array kopieren:
SetLength(Array,50); //50 Einträge möglich
Delphi-Quellcode:
Ich hoffe mal, das das stimmt, was ich geschrieben hab. Bin schon etwas müde, also bitte korrigiert mich, wenn ich Schmarrn geschrieben hab. :wink:
var
Arr1, Arr2: Array of TEintrag; . . . procedure EintragLoeschen(Eintrag, LaengeArr: Integer); var i : Integer; begin SetLength(Arr2, LaengeArr -1); For i := 0 to LaengeArr - 1 do begin IF i < Eintrag THEN Arr2[i] := Arr1[i] ELSE IF i > Eintrag THEN Arr2[i] := Arr1[i+1] end; For i := 0 to Length(Arr2) -1 do begin SetLength(Arr1,Length(Arr2)); Arr1[i] := Arr2[i] end; end; Man liest sich, Stanlay :hi: |
Re: CD-Datenbank - Array, aus dem man löschen kann..
Ich denke, das 2. Array ist entbehrlich:
Delphi-Quellcode:
hoffe, das hülfet Dir, dynamische Arrays zu verstehen...
type
DeinTyp = Array of tEintrag; var DeinArray : DeinTyp; procedure InsertEintrag(DerEintrag : tEintrag; Index : Integer = -1); var i : Integer; begin if (Index >= 0) and (Index < Length(DeinArray)) // Index ist irgendwo VOR dem neuen // Ende des Arrays... then begin SetLength(DeinArray,Length(DeinArray)+1); // Array vergrößern for i := Index+1 to High(DeinArray) do DeinArray[i] := DeinArray[i-1]; // Alle Items von Index bis Ende verschieben... DeinArray[Index] := DerEintrag; // und den Eintrag an gewünschte Stelle schreiben. end else begin // kein Index angegeben - also Add am Ende AddEintrag(DerEintrag) // siehe Procedure AddEintrag... end; end; procedure AddEintrag(DerEintrag : tEintrag); begin SetLength(DeinArray,Length(DeinArray)+1); // Array vergrößern DeinArray[High(DeinArray)] := DerEintrag; // Eintrag ans Ende schreiben - fertig! end; procedure DeleteEintrag(Index : Integer); var i : Integer; begin if (Index >= 0) and (Index < Length(DeinArray)) then begin for i := Index+1 to High(DeinArray) do DeinArray[i-1] := DeinArray[i]; // umkopieren SetLength(DeinArray,Length(DeinArray)-1); // anschließend Array // verkleinern - fertig. end else raise Exception.Create('Ungültiger Index!'#13#10+ 'Minimum = 0'#13#10+ 'Maximum = '+InToStr(High(DeinArray))+#13#10+ 'Fehlerhafter Wert = '+IntToStr(Index)+' !'); end; procedure ClearDeinArray; var i : Integer; begin SetLength(DeinArray,0); // Länge auf Null setzen - fertig! end; Gruß |
Re: CD-Datenbank - Array, aus dem man löschen kann..
Erstmal vielen Dank für die schnellen Antworten! Aber da gibt's schon wieder ein unvorhergesehenes Problem:
Delphi-Quellcode:
Außerdem weiß ich noch nicht so richtig, wo ich die Länge vereinbaren muß. Ich hab global (also gleich nach der Record-Vereinbarung)
procedure DeleteEintrag(Index : Integer);
var i : Integer; begin if Index >= 0 and Index < Length(DeinArray) then begin <<---an dieser Stelle bringt er den Fehler '(' erwartet, aber ')' gefunden
Delphi-Quellcode:
vereinbart. Schonmal vielen Dank für Eure Geduld und gute Nacht! :)
type tAlleCDs=Array of tEintrag;
[edit=Luckie]Delphi-Tags ergänzt. Das nächste mal bitte selber machen. Danke. Mfg, Luckie[/edit] |
Re: CD-Datenbank - Array, aus dem man löschen kann..
Zu 1. Sowas kommt von sowas - kaum bin ich nicht in der IDE, fange ich an zu schlampen.
es fehlten die Klammern. Habe das Beispiel oben korrigiert Denke ich. Sollte jetzt funktionieren. Zu 2. Soweit ganz richtig. Die Länge wird nun dynamisch gesetzt - nicht mehr von Dir zur Entwurfszeit. Immer wenn Du Deinem Array einen Eintrag mit der Add- oder Insertprozedur hinzufügst, wird es um 1 vergrößert, bei der Deleteprozedur wird es um 1 verkleinert. Wie groß es konkret ist, weist Du zur Entwurfszeit nun nicht mehr - aber das ist nicht weiter schlimm - Du kannst für for-Schleifen ja die Funktion High() benutzen, so daß Du nicht über das Array-Ende "hinausschlitterst". Erwähnenswert ist vielleicht noch, das dynamische Arrays immer einen nullbasierten Index haben. Daraus ergibt sich für DeinArray mit 10 Elementen z.B.: DeinArray[0] = 1. Element, High(DeinArray) = 9 und Length(DeinArray) = 10 Das wär alles, was mir zum Thema im Moment einfällt... Gruß |
Re: CD-Datenbank - Array, aus dem man löschen kann..
Hallo,
mit den neuen Klammern bringt Delphi den selben Fehler:
Delphi-Quellcode:
[Fehler] Unit1.pas(136): '(' erwartet, aber ')' gefunden
if (Index >= 0) and (Index < Length(tAlleCDs))
Woran liegt das? Ich verzweifle hier noch... :( Immer, wenn man denkt, man hat was verstanden, kommt was neues Unerklärliches. |
Re: CD-Datenbank - Array, aus dem man löschen kann..
Der Fehler ist wiedermal meiner. Wir definieren den Typ DeinArray, schaffen aber keine Arrayvariable dieses Types. Wenn wir nun DeinArray benutzen, erwartet der Compiler einen Type-Cast und der Verlangst nach Klammern.
Ändere die Zeile
Delphi-Quellcode:
in
type
DeinArray = Array of tEintrag;
Delphi-Quellcode:
Dann hast Du in DeinArray eine Arrayvariable vom DeinTyp, und es sollte funktionieren.
type
DeinTyp = Array of tEintrag; var DeinArray : DeinTyp; Sorry & Gruß |
Re: CD-Datenbank - Array, aus dem man löschen kann..
Delphi-Quellcode:
So geht es auch nicht, ist das, was du meintest?
implementation {$R *.dfm}
type tCDname=Record interpret, album:string[20]; end; //unterrecord type tEintrag=Record CDname:tCDname; genre:string[15]; jahr:integer; preis:real; end; //record type tAlleCDs = Array of tEintrag; var CDArray:tAlleCDs; i:integer; procedure TForm1.FormCreate(Sender: TObject); begin i:=0; end; procedure eintrag_loeschen(Index : Integer); var i:Integer; begin if (Index >= 0) and Index < (Length(ArrayCDs)) then begin for i:=Index+1 to High(tAlleCDs) do ArrayCDs[i-1]:=ArrayCDs[i]; // umkopieren SetLength(ArrayCDs,Length(ArrayCDs)-1); // anschließend Array verkleinern - fertig. end else raise Exception.Create('Ungültiger Index!'#13#10+ 'Minimum = 0'#13#10+ 'Maximum = '+InToStr(High(ArrayCDs))+#13#10+ 'Fehlerhafter Wert = '+IntToStr(Index)+' !'); end; |
Re: CD-Datenbank - Array, aus dem man löschen kann..
Nein:
Delphi-Quellcode:
so!
implementation {$R *.dfm}
type tCDname=Record interpret, album:string[20]; end; //unterrecord type tEintrag=Record CDname:tCDname; genre:string[15]; jahr:integer; preis:real; end; //record type tAlleCDs = Array of tEintrag; var CDArray:tAlleCDs; i:integer; procedure TForm1.FormCreate(Sender: TObject); begin i:=0; end; procedure eintrag_loeschen(Index : Integer); var i:Integer; begin if (Index >= 0) and Index < (Length(CDArray)) then begin for i:=Index+1 to High(CDArray) do CDArray[i-1]:=CDArray[i]; // umkopieren SetLength(CDArray,Length(CDArray)-1); // anschließend Array verkleinern - fertig. end else raise Exception.Create('Ungültiger Index!'#13#10+ 'Minimum = 0'#13#10+ 'Maximum = '+InToStr(High(CDArray))+#13#10+ 'Fehlerhafter Wert = '+IntToStr(Index)+' !'); end; :-) |
Re: CD-Datenbank - Array, aus dem man löschen kann..
Ich glaub, mein Delphi will mich fertig machen:
Delphi-Quellcode:
Meldung: Operator auf diesen Operandentyp nicht anwendbar!
if (Index >= 0) and Index < (Length(CDArray))
Sowas... :wall: |
Re: CD-Datenbank - Array, aus dem man löschen kann..
Klammer falsch gesetzt:
Delphi-Quellcode:
nu is aber gut!
if (Index >= 0) and (Index < Length(CDArray))
|
Re: CD-Datenbank - Array, aus dem man löschen kann..
So, das Programm compilert erstmal - schonmal nicht schlecht. :) Wenn ich einen Eintrag hinzufüge, und zwar so:
Delphi-Quellcode:
...dann steht der Eintrag in der Listbox. Wenn ich diesen aber löschen will:
procedure TForm1.BitBtn1Click(Sender: TObject);
var jahr, monat, tag, std, min, sec, msec:word; jahrstr, monatstr, tagstr, stdstr, minstr, secstr:string; begin setlength(daten,500); i:=i+1; daten[i].CDname.interpret:=interpret_edit.Text; daten[i].CDname.album:=album_edit.Text; daten[i].genre:=genre_combobox.Text; daten[i].jahr:=jahr_spinedit.Value; daten[i].preis:=strtofloat(preis_edit.text); cd_listbox.Items.Add(daten[i].CDname.interpret+#9+daten[i].CDname.album+ #9+daten[i].genre+#9+inttostr(daten[i].jahr)+#9+floattostrf(daten[i].preis,fffixed,8,2)); eintrag_hinzufuegen(daten[i]); anzahl_edit.text:=IntTostr(cd_listbox.Items.Count); DecodeTime(Time,std,min,sec,msec); stdstr := IntToStr(std); if length(stdstr)<2 then stdstr := '0'+stdstr; minstr := IntToStr(min); if length(minstr)<2 then minstr := '0'+minstr; secstr := IntToStr(sec); if length(secstr)<2 then secstr := '0'+secstr; uhr_edit.Text:=(stdstr+':'+minstr+':'+secstr); DecodeDate(Date,jahr,monat,tag); jahrstr := IntToStr(Jahr); Case length(jahrstr) of 1:jahrstr := '000'+jahrstr; 2:jahrstr := '00'+jahrstr; 3:jahrstr := '0'+jahrstr; end; monatstr := IntToStr(monat); if length(monatstr) < 2 then monatstr := '0' + monatstr; tagstr := IntToStr(tag); if length(tagstr) < 2 then tagstr := '0' + tagstr; datum_edit.text:=(tagstr+'.'+monatstr+'.'+jahrstr); end;
Delphi-Quellcode:
procedure TForm1.lschen1Click(Sender: TObject);
begin cd_Listbox.Items.Delete(cd_Listbox.ItemIndex); eintrag_loeschen(cd_Listbox.ItemIndex); end;
Delphi-Quellcode:
dann kommt dieser Fehler:
procedure eintrag_loeschen(Index : Integer);
var i:Integer; begin if (Index >= 0) and (Index < Length(daten)) then begin for i:=Index+1 to High(daten) do daten[i-1]:=daten[i]; // umkopieren SetLength(daten,Length(daten)-1); // anschließend Array verkleinern - fertig. end else raise Exception.Create('Ungültiger Index!'#13#10+ 'Minimum = 0'#13#10+ 'Maximum = '+InTtoStr(High(daten))+#13#10+ 'Fehlerhafter Wert = '+IntToStr(Index)+' !'); end; "Im Projekt...ist eine Exception der Klasse Exception aufgetreten. Meldung: Ungültiger Index. Minimum=0 Maximum=5 Fehlerhafter Wert=-1 Prozess wurde angehalten" Was kann man da machen? Danke für deine Geduld mit mir... ich hoffe, ich hab's bis heute Abend kapiert... :pale: |
Re: CD-Datenbank - Array, aus dem man löschen kann..
Delphi-Quellcode:
PS.: findest Du meinen Code nicht auch wesentlich einfacher lesbar?
procedure TForm1.BitBtn1ClickSoWieErMichWuetendMacht(Sender: TObject);
begin setlength(daten,500); // was soll das ?!!! // Du schaffst Dir mit viel Mühe ein Dynamisches Array // samt dazugehörigen Methoden, um damit arbeiten zu können, // um es anschließend doch wieder statisch zu machen? i:=i+1; daten[i].CDname.interpret:=interpret_edit.Text; // hier weist du einem Index-Element daten[i].CDname.album:=album_edit.Text; // Deines vergewaltigten Arrays einen Wert zu daten[i].genre:=genre_combobox.Text; daten[i].jahr:=jahr_spinedit.Value; daten[i].preis:=strtofloat(preis_edit.text); cd_listbox.Items.Add(daten[i].CDname.interpret+#9+ daten[i].CDname.album+#9+ daten[i].genre+#9+ inttostr(daten[i].jahr)+#9+ floattostrf(daten[i].preis,fffixed,8,2)); eintrag_hinzufuegen(daten[i]); // und hier weist Du einem neu erzeugten Element von // Deinem Array dieselben Daten nochmal zu, indem Du // Du ein neues Array-Element erzeugst (das macht doch // eintrag_hinzufügen oder?) und diesem diesem den Wert // des Elementes Nr.: i zuweist anzahl_edit.text:=IntTostr(cd_listbox.Items.Count); // Rest weggelassen... end; procedure TForm1.BitBtn1Click(Sender: TObject); var TempEintrag : tEintrag; begin TempEintrag.CDname.interpret:= interpret_edit.Text; TempEintrag.CDname.album := album_edit .Text; TempEintrag.genre := genre_combobox.Text; TempEintrag.jahr := jahr_spinedit .Value; TempEintrag.preis := strtofloat(preis_edit.text); eintrag_hinzufuegen(TempEintrag); cd_listbox.Items.Add( TempEintrag.CDname.interpret+#9+ TempEintrag.CDname.album +#9+ TempEintrag.genre +#9+ inttostr(TempEintrag.jahr) +#9+ floattostrf(TempEintrag.preis,fffixed,8,2)); anzahl_edit.text:=IntTostr(cd_listbox.Items.Count); // Rest weggelassen... end; procedure TForm1.lschen1ClickSoWieEsNichtGeht(Sender: TObject); begin // klar, geht das schief, da nach dem Delete aus der // TListbox der ItemIndex unter Umständen = -1 ist // und der Anschließende Versuch, das -1. Element aus dem // Array zu löschen schief gehen muß (Erinnerung: // dynamische Arrays sind Null-basiert) cd_Listbox.Items.Delete(cd_Listbox.ItemIndex); eintrag_loeschen(cd_Listbox.ItemIndex); end; procedure TForm1.lschen1Click(Sender: TObject); begin if cd_Listbox.ItemIndex >= 0 then begin eintrag_loeschen(cd_Listbox.ItemIndex); // erst das ArrayElement cd_Listbox.Items.Delete(cd_Listbox.ItemIndex); // dann den Listboxeintrag end; end; |
Re: CD-Datenbank - Array, aus dem man löschen kann..
Jetzt klappt es (wer hätte das gedacht). Danke vielmals für deine Hilfe, jetzt fällt mir das auch auf, was du da bemängelt hast in meinem Quelltext... Wenn ich dir auch mal helfen kann, werd' ich's tun. :spin2:
|
Re: CD-Datenbank - Array, aus dem man löschen kann..
Gelobt sei das Orakel von Delphi - seine Programmierseele konnte errettet werden :mrgreen:!
Ich helfe gern, immer wieder, wenn ich ernsthaftes eigenes Bemühen erkennen kann. Gruß |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:37 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz