Autor Beitrag
Hänsel
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 150



BeitragVerfasst: Mo 08.09.25 07:15 
Hallo, kann jemand helfen ?
Ich arbeite mit Delphi 10.
Ich möchte eine .csv-Datei in eine Datenbank schreiben.
Bekomme aber ständig die Fehlermeldung: "Listenindex außerhalb gültigen Bereich"
Was habe ich hier vergessen bzw. falsch gemacht?
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
procedure TForm_RWM.Import1FromCSVfile(sFile: string);
var   ON,su,aus,be: string;
   tb,zah: Integer;
   tfDatei: TextFile;
   sZInhalt,D,ob : string;
   slWerte: TStringList;
   iZeile,zähler: Integer;
Begin
       AssignFile(tfDatei, sFile);
       Reset(tfDatei);
         slWerte := TStringList.Create;
         slWerte.StrictDelimiter:=true;
         slWerte.Delimiter := #9;
         slWerte.DelimitedText := sZInhalt;
         slWerte.QuoteChar := ';';
         Readln(tfDatei,sZInhalt);
         inc(iZeile);
       //  slWerte.QuoteChar := '"';
       iZeile:= 0;
     while not EoF(tfDatei) do
       begin
         Inc(iZeile); // erste Zeile ist der Kopf
         if iZeile > 5 then // alles größer als Zeile eins sind Daten
           begin
               DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM.Open;
               DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM.Last;
               DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM.Append;
               DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM.Edit;
               DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM['Feld_01']:='Test';
               DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM['Feld_02'] := slWerte.Strings[2];
               DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM['Feld_02'] := slWerte.Strings[4];
               DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM['Feld_03']  := slWerte.Strings[7];
               DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM['Feld_04']  := slWerte.Strings[8];
               DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM['Feld_05']  := slWerte.Strings[9];
               DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM.Post;
           end;
       end;
           zähler:= DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM.RecordCount;
           Edit1.Text:=inttoStr(zähler);

End;


Moderiert von user profile iconTh69: Delphi-Tags hinzugefügt
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19321
Erhaltene Danke: 1749

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 08.09.25 08:35 
Du weist den Wert sZInhalt (noch leer) der Stringliste slWerte zu und liest den Wert erst danach aus der Datei:
ausblenden Delphi-Quelltext
1:
2:
3:
slWerte.DelimitedText := sZInhalt;
slWerte.QuoteChar := ';';
Readln(tfDatei,sZInhalt);
Dazu kommt, dass du in der Schleife gar nicht mehr aus der Datei liest.

Du solltest dir vielleicht erst einmal überlegen, was du in welcher Reihenfolge machen musst, ohne Quelltext. Und danach dann schauen, wie du das umsetzt. Das ist kein Programmierproblem, sondern ein Logikproblem!

Nebenbei:
Warum lädst du nicht einfach alles in eine Stringlist und gehst dann zeilenweise durch deren Werte durch? Sprich dann hättest du zwei Stringlisten, eine für die Datei und eine für die einzelne Zeile.

Für diesen Beitrag haben gedankt: Th69
Hänsel Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 150



BeitragVerfasst: Mo 08.09.25 11:11 
Danke für die Hinweise.
Da mir hier offensichtlich die Kenntnisse fehlen, wäre es schön ein Grundgerüst an Code zu bekommen. So dass ich die Vorgehensweise nachvollziehen kann.

Danke im Voraus
Hänsel
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19321
Erhaltene Danke: 1749

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 08.09.25 13:01 
Die wichtigste Frage ist erst einmal, ob das eine Aufgabe für einen Schulunterricht oder ähnliches ist? Denn im Code kommen Dinge vor wie die ungarische Notation (sl für Stringliste usw. bei den Variablen), die in Delphi absolut unüblich sind, die aber niemand einfach so macht. Denn wenn du eine bestimmte Aufgabenstellung hast, hilft dir eine andere Lösung vielleicht gar nicht weiter.

Zeilenweise geht z.B. so:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
var
  i: Integer;
  slDatei: TStringList;
begin
  slDatei := TStringList.Create;
  slDatei.LoadFromFile(sFile);
  for i := 0 to slDatei.Count - 1 do
    ShowMessage(slDatei[i]);
...

Für diesen Beitrag haben gedankt: Hänsel
Hänsel Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 150



BeitragVerfasst: Mo 08.09.25 13:19 
Nein das ist nicht für die Schule.
Ich möchte für einige Rauchwarnmelder welche funken, die ecsv-Datei in eine Datenbank schreiben.
Hänsel Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 150



BeitragVerfasst: Gestern um 09:07 
Zu meiner oben gestellten Frage habe ich folgendes herausgefunden: Wenn ich nach den Einstellungen eine .csv Datei einlesen möchte, gibt es eine Fehlermeldung wie beschreiben. Wenn ich eine .rep Datei einlesen möchte, klappt bestens. Welche Voreinstellung habe ich vergessen bzw. falsch gemacht?

Gruß Hänsel
mandras
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 433
Erhaltene Danke: 107

Win 10
Delphi 6 Prof, Delphi 10.4 Prof
BeitragVerfasst: Heute um 00:19 
- Könntest Du einmal die CSV-und die andere Datei (ausschnittsweise) hier einstellen?
- stimmt Dein Listing?
Eigentlich dürfte es gar nicht funktionieren, egal mit was für einer Datei. Grund:

ausblenden Delphi-Quelltext
1:
2:
3:
slWerte.DelimitedText := sZInhalt;
slWerte.QuoteChar := ';';
Readln(tfDatei,sZInhalt);


Bei dem von Dir gezeigten Code bekommt die StringList gar nichts davon mit, was in der Datei steht,
da die Zuweisung an DelimitedText erfolgt, bevor aus der Datei gelesen wird.
Hänsel Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 150



BeitragVerfasst: Heute um 07:47 
Anbei die .csv Datei zur Einsicht.
Hänsel
Hänsel Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 150



BeitragVerfasst: Heute um 08:19 
So geht es vielleicht besser:
ausblenden CSV
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
Programmname;   Ablesungsdatum;  Funkadresse;  Benutzerfeld;  Ausgangskode (Fehler);   Seriennummer;  Identifikationsnummer;  Herstellercode
SonSa2O-ANDROID;03.09.2025 13:30;  30802114;    Ablesung OK;    30802114;  SON;
SonSa2O-ANDROID;03.09.2025 13:30;  30802115;    Ablesung OK;    30802115;  SON;
SonSa2O-ANDROID;03.09.2025 13:30;  30802110;    Ablesung OK;    30802110;  SON;
SonSa2O-ANDROID;03.09.2025 13:30;  30802112;    Ablesung OK;    30802112;  SON;
SonSa2O-ANDROID;03.09.2025 13:30;  30802106;    Ablesung OK;    30802106;  SON;
SonSa2O-ANDROID;03.09.2025 13:30;  30802109;    Ablesung OK;    30802109;  SON;
SonSa2O-ANDROID;03.09.2025 13:30;  30802111;    Ablesung OK;    30802111;  SON;
SonSa2O-ANDROID;03.09.2025 13:30;  30802108;    Ablesung OK;    30802108;  SON;
SonSa2O-ANDROID;03.09.2025 13:30;  30802101;    Ablesung OK;    30802101;  SON;
SonSa2O-ANDROID;03.09.2025 13:30;  30802102;    Ablesung OK;    30802102;  SON;

getrennt sind die Felder mit ';'

Moderiert von user profile iconTh69: Code-Tags hinzugefügt
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6394
Erhaltene Danke: 147

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: Heute um 12:01 
Oh je, wo soll ich anfangen? :gruebel:
Erstmal grundlegendes im Ausgangssource (Ich habe da ein paar Kommentare eingetragen):
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
procedure TForm_RWM.Import1FromCSVfile(sFile: string);
var   ON,su,aus,be: string;
   tb,zah: Integer;
   tfDatei: TextFile;
   sZInhalt,D,ob : string;
   slWerte: TStringList;
   iZeile,zähler: Integer;
Begin
       AssignFile(tfDatei, sFile);
       Reset(tfDatei);
         slWerte := TStringList.Create;
         slWerte.StrictDelimiter:=true;
         slWerte.Delimiter := #9// Der Delimiter ist das Semikolon: ;
         slWerte.DelimitedText := sZInhalt; // Den Text hast du noch gar nicht gelesen. Also ist sZInhalt noch leer
         slWerte.QuoteChar := ';'// In der Datei sind keine quoted Texte
         Readln(tfDatei,sZInhalt); // Das gehört hier nicht hin. Es sei denn du bist sicher, dass immer etwas in der Datei ist
         inc(iZeile); // Auch nur für den Sonderfall, dass die Datei einen Inhalt hat
       //  slWerte.QuoteChar := '"';
       iZeile:= 0// Zuvor inc(iZeile) und jetzt wieder auf 0 setzen?
     while not EoF(tfDatei) do
       begin
         Readln(tfDatei,sZInhalt); // Eine Zeile einlesen
         Inc(iZeile); // erste Zeile ist der Kopf // Der Kommentar ergibt keinen Sinn. Der passt nur zur nächsten Code-Zeile
         slWerte.DelimitedText := sZInhalt; // NACH dem Lesen der Zeile, musst diese Zuweisung gemacht werden
         if iZeile > 5 then // alles größer als Zeile eins sind Daten // Wenn nur die erste Zeile nicht nötig ist, warum überspringst du dann 5 Zeilen?
           begin
               DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM.Open; // Das gehört vor die Schleife
               DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM.Last; // unnötig bei einem Append
               DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM.Append;
               DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM.Edit; // Du hast doch schon eine Append. Das Edit ist daher unnötig
               DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM['Feld_01']:='Test';
               DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM['Feld_02'] := slWerte.Strings[2];
               DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM['Feld_02'] := slWerte.Strings[4];
               DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM['Feld_03']  := slWerte.Strings[7];
               DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM['Feld_04']  := slWerte.Strings[8];
               DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM['Feld_05']  := slWerte.Strings[9];
               DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM.Post;
           end;
       end;
           // Die folgenden 2 Zeilen kannst du hinter die Schleife verschieben. Dein Edit-Feld wird auf diese Weise sowieso nicht katual
           zähler:= DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM.RecordCount;
           Edit1.Text:=inttoStr(zähler);

End;

Dazu kommt, dass die CSV-Datei unvollständig gefüllt ist. Das bedeutet, dass du immer prüfen musst, wieviel Einträge in der StringList sind. Ansonsten greifst du auf Elemente zu, die gar nicht existieren. Das führt dann ebenfalls zu Fehlern beim Listenindex. Die Zählung bei der StringList fängt übrigens bei 0 an. Die CSV-Datei hat 8 Spalten. Das bedeutet, dass du maximal einen Index zwischen 0 und 7 hast. Aktuell sehe ich nur 5 der Spalten besetzt. Das wäre dann Index 0 bis 4. Kommt da dein "if iZeile > 5 then" eventuell her? Dann scheinst du Spalten mit Zeilen zu verwechseln.

Damit es übersichtlicher wird:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
procedure TForm_RWM.Import1FromCSVfile(sFile: string);
var   ON,su,aus,be: string;
   tb,zah: Integer;
   tfDatei: TextFile;
   sZInhalt,D,ob : string;
   slWerte: TStringList;
   iZeile,zähler: Integer;
Begin
     AssignFile(tfDatei, sFile);
     Reset(tfDatei);
     slWerte := TStringList.Create;
     slWerte.StrictDelimiter:=true;
     slWerte.Delimiter := ';';
     iZeile:= 0;

     if not EoF(tfDatei) do
       begin
         DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM.Open;
         while not EoF(tfDatei) do
           begin
             Readln(tfDatei,sZInhalt); // Eine Zeile einlesen
             Inc(iZeile);
             if iZeile > 1 then // alles größer als Zeile eins sind Daten
               begin
                   slWerte.DelimitedText := sZInhalt; // NACH dem Lesen der Zeile, musst diese Zuweisung gemacht werden
                   if slWerte.Count = 6 then // Nur bei vollständigen Daten
                     begin
                       DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM.Append;
                       DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM['Feld_01']:= slWerte.Strings[0];
                       DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM['Feld_02'] := slWerte.Strings[1];
                       DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM['Feld_02'] := slWerte.Strings[2];
                       DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM['Feld_03']  := slWerte.Strings[3];
                       DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM['Feld_04']  := slWerte.Strings[4];
                       DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM['Feld_05']  := slWerte.Strings[5];
                       DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM.Post;
                    else begin
                       // Hier vielleicht eine Fehlermeldung?
                    end;
               end;
           end;
           zähler:= DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM.RecordCount;
           Edit1.Text:=inttoStr(zähler);

           // DataModule_RWM_Auswertung.ADOQuery_Einlesung_RWM.Close; // Falls die Tabelle im Anschluss wieder geschlossen werden soll
        end;
End;

Der Source ist ungeprüft reingetippt. Es können also durchaus Fehler vorliegen.