Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Zugriffsverletzung bei 2. Durchlauf einer Schleife (https://www.delphipraxis.net/109554-zugriffsverletzung-bei-2-durchlauf-einer-schleife.html)

Michael80 3. Mär 2008 14:55


Zugriffsverletzung bei 2. Durchlauf einer Schleife
 
Hallo Leute,

ich habe hier ein kleines Problem und komme nicht weiter. Ich versuche mehrere Dateien nacheinander in eine Tabelle einzulesen.
Mit der ersten Datei klappt alles wunderbar, doch sobald das Programm zum 2. mal durchläuft bekomme ich folgende Fehlermeldung:

Zugriffsverletzung bei Adresse 004217FB in Modul "einlesen.exe". Lesen von Adresse 00000005.

und dann steht die Schleife. Im Debug-Mode habe ich die Stelle lokalisiert, weiß nur nicht wo der Fehler ist.

Vielleicht findet ihr hier was.

Hier die gesamte Prozedur:
Delphi-Quellcode:
procedure TForm2.Button1Click(Sender: TObject);
var
  mastersl                                             : TStringList;
  detailsl                                             : TStringList;
  fieldssl                                             : TStringList;
  logsl                                                : TStringList;
  ndx                                                  : Integer;
  anz,i,po, datensaetze,fidx, flag,didx,wmax,lidx      : Integer;
  pfad, datei,fields, jetzt, fehlfeld,felder,werte     : string;
begin
OpenDialog1.Execute;
Listbox1.Items := OpenDialog1.Files;
  mastersl := TStringList.Create; // Master StringList
  detailsl := TStringList.Create; // Detail StringList
  fieldssl := TStringList.Create; // Felder StringList
  logsl    := TStringList.Create; // Log StringList
  for i :=0 to ListBox1.Items.Count -1 do
    begin
    pfad := Listbox1.Items[i];
    datei := pfad;
    po := pos('\',datei);
    while (po > 0) do
    begin
    delete(datei,1,po);
    po := pos('\',datei);
    end;
    begin
    Adoquery1.SQL.Text := 'select * from information_schema.tables where table_name=''dpd_'+datei+''' ' ;
    adoquery1.Active := true;
    end;
    if adoquery1.RecordCount > 0 then
      begin
        logsl.Add('Die Tabelle '+datei+' wurde gefunden ');
        fieldssl.Delimiter := '|';
        mastersl.LoadFromFile(pfad);
        fields := mastersl.strings[5];
        po := pos(' ',fields);
        delete(fields,1,po);
        fieldssl.DelimitedText := fields;
        wmax := fieldssl.count-1;
        for fidx := 0  to wmax -1 do
        begin
        if felder = '' then
        begin
        felder := '['+fieldssl.strings[fidx]+']';
        end
        else
        begin
        felder := felder + ',['+fieldssl.strings[fidx]+']';
        end;
        end;
        flag := 0;
        fehlfeld := '';
        werte := '';
        for fidx := 0 to Pred(wmax) do
        begin
        if werte = '' then
        begin
        werte := ':wert'+inttostr(fidx);
        end
        else
        begin
        werte := werte +',:wert'+inttostr(fidx);
        end;
        end;
          for fidx := 0 to Pred(wmax)-1 do
          begin
          Adoquery2.SQL.Text := 'select * from information_schema.columns where table_name=''dpd_'+datei+''' and Column_name='''+fieldssl.strings[fidx]+''' ' ;
          AdoQuery2.Active := true;
            if adoquery2.RecordCount > 0 then
            begin
            //logsl.Add('Das Feld '+fieldssl[fidx]+' wurde gefunden ');
            try
            detailsl.Delimiter := '|';  // Trennzeichen der Einträge pro Zeile
            mastersl.LoadFromFile(pfad);
            for ndx := 7 to Pred (mastersl.Count) do
            begin
            detailsl.Clear;
            detailsl.DelimitedText := mastersl.Strings[ndx];
            datensaetze := 0;
            with arbeitsquery do
            begin
            Close;
            SQL.Text := 'INSERT INTO DPD_'+datei+' ('+felder+') VALUES ('+werte+')';
            ParamCheck := True;
            for didx := 0 to wmax -1 do
            begin
            if detailsl.strings[didx] = '' then
            begin
            Parameters.ParamByName('wert'+inttostr(didx)).value := 'NULL';
            logsl.add ('wert'+inttostr(didx)+' NULL');
            end
            else
            begin
            Parameters.ParamByName('wert'+inttostr(didx)).value := detailsl.Strings[didx];
            logsl.add ('wert'+inttostr(didx)+' '+detailsl.Strings[didx]);
            end;
            end;
            Datensaetze := Datensaetze +1;
            ExecSQL;
            end;
            end;
            finally
            FreeAndNil (mastersl);
            FreeAndNil (detailsl);
            end;
          end
            else
            begin
            flag := 1;
            fehlfeld := fehlfeld + ' '+fieldssl[fidx];
            logsl.Add('Das Feld '+fieldssl[fidx]+' wurde nicht gefunden ');
            end;
          end;
        end
      else
        begin
          logsl.Add(pfad +' nicht gefunden');
          logsl.Add('------------------------------------------------');
          logsl.Add('');
        end;
      if flag = 0 then
        begin
          logsl.Add('');
          logsl.Add('Die Datei '+pfad+' wurde korrekt eingelesen');
          logsl.Add('es wurden '+inttostr(datensaetze)+' Datensätze importiert');
          logsl.Add('------------------------------------------------');
          logsl.Add('');
        end
        else
        begin
          logsl.Add('');
          logsl.Add('Das/Die Felder '+fehlfeld+' wurden nicht gefunden.');
          logsl.Add('es wurden keine Datensätze aus der Tabellen '+datei+' importiert');
          logsl.Add('------------------------------------------------');
          logsl.Add('');
        end;
    end;
  jetzt := datetimetostr(now);
  jetzt := StringReplace(jetzt, ':', '.', [rfReplaceAll]);
  logsl.SaveToFile('c:/import_log_'+jetzt+'.txt');
  end;
und hier die Problemstelle:

Delphi-Quellcode:
for i :=0 to ListBox1.Items.Count -1 do
    begin

Schon mal danke für die Hilfe!

Gruß

Michael

sirius 3. Mär 2008 14:59

Re: Zugriffsverletzung bei 2. Durchlauf einer Schleife
 
Fehlerzeile:
Delphi-Quellcode:
Listbox1.Items := OpenDialog1.Files;
Schau die mal die Methoden Assign oder Addstrings an!

Muetze1 3. Mär 2008 15:01

Re: Zugriffsverletzung bei 2. Durchlauf einer Schleife
 
Zitat:

Zitat von sirius
Fehlerzeile:
Delphi-Quellcode:
Listbox1.Items := OpenDialog1.Files;
Schau die mal die Methoden Assign oder Addstrings an!

Was soll daran falsch sein? TListBox.Items hat einen Setter mit einem Assign() drin.

DeddyH 3. Mär 2008 15:02

Re: Zugriffsverletzung bei 2. Durchlauf einer Schleife
 
Ich würde das in etwa so machen:
Delphi-Quellcode:
if OpenDialog1.Execute then
  begin
    Listbox1.Items.Assign(OpenDialog1.Files);
    ...
  end;

Bernhard Geyer 3. Mär 2008 15:02

Re: Zugriffsverletzung bei 2. Durchlauf einer Schleife
 
Die Freigaben der lokalen Stringlisten sollten auf der gleichen Ebene erfolgen wie die erzeugung. Ansosnten hast du je nach Pfadabdeckung schöne Speicherlücken.

mkinzler 3. Mär 2008 15:04

Re: Zugriffsverletzung bei 2. Durchlauf einer Schleife
 
Befinden sich überhaupt Einträge in der ListBox?

Nuclear-Ping 3. Mär 2008 15:04

Re: Zugriffsverletzung bei 2. Durchlauf einer Schleife
 
Zitat:

Zitat von Michael80
Delphi-Quellcode:
procedure TForm2.Button1Click(Sender: TObject);
// ...
begin
OpenDialog1.Execute;
Listbox1.Items := OpenDialog1.Files;
// ...

Und was machst du, wenn der Benutzer "Abbrechen" in dem Dialog wählt?

OT: Jeder hat so seinen Stil was Source-Formatierung angeht. Aber ich würde dir auch mal einen Pascal-Styleguide zu lesen empfehlen und über ordentliche Code-Einrückung nachdenken. ^^

jottkaerr 3. Mär 2008 15:05

Re: Zugriffsverletzung bei 2. Durchlauf einer Schleife
 
Du erzeugst masterl und detailsl am Anfang der Prozedur, zerstörst sie aber innerhalb der inneren for-Schleife im finally-Teil. Beim zweiten Schleifendurchlauf kracht es dann.

Ich habe mir den Code nicht genauer angeschaut, aber vielleicht möchtest Du statt FreeAndNil(masterl) lieber masterl.Clear aufrufen.

jkr

shmia 3. Mär 2008 15:06

Re: Zugriffsverletzung bei 2. Durchlauf einer Schleife
 
Dein Sourcecode ist ja ein richtiger Saustall - bitte besser einrücken und vielleicht auch mal eine Unterfunktion einbauen.
Und mittendrin steht FreeAndNil (mastersl); FreeAndNil (detailsl); das wirft dann beim 2. Schleifendurchlauf die Bomben. Ich will jetzt auch gar nicht nachschauen, ob die Anweisungen innerhalb oder ausserhalb der Schleife liegen...

Michael80 3. Mär 2008 15:07

Re: Zugriffsverletzung bei 2. Durchlauf einer Schleife
 
machbar wäre das ja so auch:

Delphi-Quellcode:
Listbox1.Items.AddStrings(OpenDialog1.Files);
Abbrechen habe ich noch nicht abgefangen, das weiß ich. Mir gehts im Moment rein um das Problem mit dem Durchlauf, der Rest (Feinheiten) kommt danach.

Styleguide, ok sollt ich mal wieder auffrischen :p


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:48 Uhr.
Seite 1 von 2  1 2      

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-2025 by Thomas Breitkreuz