Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi CD-Datenbank - Array, aus dem man löschen kann.. (https://www.delphipraxis.net/15637-cd-datenbank-array-aus-dem-man-loeschen-kann.html)

absentsilence 1. Feb 2004 22:26


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:
type tCDname=Record
interpret, album:string[20];
end; //unterrecord

type tEintrag=Record
CDname:tCDname;
genre:string[15];
jahr:integer;
preis:real;
end; //record
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

Delphi-Quellcode:
tAlleCDs=Array[1..max] of tEintrag; //max ist eine Konstante
konnte ich nichts einzeln löschen, hab es jedenfalls nicht hinbekommen. Da habe ich einfach mit

Delphi-Quellcode:
cd_Listbox.Items.Delete(cd_Listbox.ItemIndex);
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.

Viele Grüße,

AS

[edit=Luckie]Delphi-Tags ergänzt. Beim nächsten mal bitte selber machen. Mfg, Luckie[/edit]

Stanlay Hanks 1. Feb 2004 22:45

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:
SetLength(Array,50); //50 Einträge möglich
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:

Delphi-Quellcode:
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;
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:

Man liest sich, Stanlay :hi:

Leuselator 1. Feb 2004 23:48

Re: CD-Datenbank - Array, aus dem man löschen kann..
 
Ich denke, das 2. Array ist entbehrlich:
Delphi-Quellcode:
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;
hoffe, das hülfet Dir, dynamische Arrays zu verstehen...
Gruß

absentsilence 2. Feb 2004 01:45

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:
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
Außerdem weiß ich noch nicht so richtig, wo ich die Länge vereinbaren muß. Ich hab global (also gleich nach der Record-Vereinbarung)

Delphi-Quellcode:
type tAlleCDs=Array of tEintrag;
vereinbart. Schonmal vielen Dank für Eure Geduld und gute Nacht! :)

[edit=Luckie]Delphi-Tags ergänzt. Das nächste mal bitte selber machen. Danke. Mfg, Luckie[/edit]

Leuselator 2. Feb 2004 02:37

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ß

absentsilence 2. Feb 2004 10:39

Re: CD-Datenbank - Array, aus dem man löschen kann..
 
Hallo,
mit den neuen Klammern bringt Delphi den selben Fehler:

Delphi-Quellcode:
if (Index >= 0) and (Index < Length(tAlleCDs))
[Fehler] Unit1.pas(136): '(' erwartet, aber ')' gefunden

Woran liegt das? Ich verzweifle hier noch... :( Immer, wenn man denkt, man hat was verstanden, kommt was neues Unerklärliches.

Leuselator 2. Feb 2004 13:31

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:
type
 DeinArray = Array of tEintrag;
in
Delphi-Quellcode:
type
  DeinTyp = Array of tEintrag;
var
  DeinArray : DeinTyp;
Dann hast Du in DeinArray eine Arrayvariable vom DeinTyp, und es sollte funktionieren.

Sorry & Gruß

absentsilence 2. Feb 2004 13:44

Re: CD-Datenbank - Array, aus dem man löschen kann..
 
Delphi-Quellcode:
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;
So geht es auch nicht, ist das, was du meintest?

Leuselator 2. Feb 2004 13:46

Re: CD-Datenbank - Array, aus dem man löschen kann..
 
Nein:
Delphi-Quellcode:
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;
so!
:-)

absentsilence 2. Feb 2004 13:51

Re: CD-Datenbank - Array, aus dem man löschen kann..
 
Ich glaub, mein Delphi will mich fertig machen:

Delphi-Quellcode:
if (Index >= 0) and Index < (Length(CDArray))
Meldung: Operator auf diesen Operandentyp nicht anwendbar!

Sowas... :wall:

Leuselator 2. Feb 2004 14:05

Re: CD-Datenbank - Array, aus dem man löschen kann..
 
Klammer falsch gesetzt:
Delphi-Quellcode:
if (Index >= 0) and (Index < Length(CDArray))
nu is aber gut!

absentsilence 2. Feb 2004 17:09

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:
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;
...dann steht der Eintrag in der Listbox. Wenn ich diesen aber löschen will:

Delphi-Quellcode:
procedure TForm1.lschen1Click(Sender: TObject);
begin
cd_Listbox.Items.Delete(cd_Listbox.ItemIndex);
eintrag_loeschen(cd_Listbox.ItemIndex);
end;
Delphi-Quellcode:
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;
dann kommt dieser Fehler:
"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:

Leuselator 2. Feb 2004 18:12

Re: CD-Datenbank - Array, aus dem man löschen kann..
 
Delphi-Quellcode:
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;
PS.: findest Du meinen Code nicht auch wesentlich einfacher lesbar?

absentsilence 2. Feb 2004 20:15

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:

Leuselator 2. Feb 2004 20:24

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