Einzelnen Beitrag anzeigen

Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#6

AW: Aufruf neuer Typen in anderen Units

  Alt 31. Jan 2012, 17:05
Sodele, ich habe dann mal die Unit entsprechend kommentiert und ausgebessert
Delphi-Quellcode:
unit kennzeichen;

// {$mode objfpc}{$H+}

interface

uses
  SysUtils,
  Classes;
// , Graphics, Controls, Forms, Dialogs, ExtCtrls;

type
  TDatensatz = class
    kennzeichen : STRING;
    // Öffentliche Variable, die das "kennzeichnen" ausgibt
    Ort : STRING;
    // Öffentliche Variable, die den "ort" ausgibt
    Bundesland : STRING;
    // Öffentliche Variable, die das "bundesland" ausgibt
    Sonder : STRING;
    // Öffentliche Variable, die das "bundesland" ausgibt
    constructor Create;
    // Konstruktor von TDatensatz
    destructor Destroy;
    // Destruktor von TDatensatz
    procedure Einlesen( DatenString : STRING );
    // Aufteilen von "datenstring" in "kennzeichen", "ort", "bundesland"
    function IstKennzeichen( KennzeichenString : STRING ) : BOOLEAN;
    // Boolean'sche Funktion, ob "kennzeichenstring" == "kennzeichen"
  end;

  TListe = class
  public
    Liste : ARRAY [1 .. 600] OF TDatensatz;
    // riesiges Array der kompletten *.csv des Types "TDatensatz"
    Anzahl : CARDINAL;
    // Nr. der aktuellen Zeile in der *.csv
    CompleteFile : TStringList;
    // Ganzes File als TStringList
    NotA : BOOLEAN;
    // Sagt aus, ob Input verfügbar
    constructor Create;
    // Konstruktor von TListe
    destructor Destroy; override;
    // Destruktor von TListe
    procedure DateiEinlesen( datname, suchKFZ : STRING );
    // Einlesen und Verarbeiten der *.csv (LoadFileFrom, Erstellen von "liste")
    function Lesen( i : CARDINAL; datnamen : TStringList ) : TDatensatz;
    // Gibt einen result des Typen TDatensatz aus

    function GibAnzahl : CARDINAL;
    // Gibt Variable "anzahl" aus

    // aber wozu? die Variable kann man doch direkt auslesen, wozu nochmals eine function dafür?

    function NAcheck( j : INTEGER; Stringlist : TStringList ) : BOOLEAN;
  end;

var
  unsereListe : TListe;

implementation

constructor TDatensatz.Create;
begin
  inherited; // <-- fehlte
  kennzeichen := '';
  Ort := '';
  Bundesland := '';
  Sonder := '';
end;

destructor TDatensatz.Destroy;
begin
  // überflüssig

  // kennzeichen := '';
  // Ort := '';
  // Bundesland := '';
  // Sonder := '';
  inherited; // <-- fehlte
end;

procedure TDatensatz.Einlesen( DatenString : STRING );
begin
  kennzeichen := Copy( DatenString, 1, pos( ';', DatenString ) - 1 );
  Delete( DatenString, 1, pos( ';', DatenString ) );
  Ort := Copy( DatenString, 1, pos( ';', DatenString ) - 1 );
  Delete( DatenString, 1, pos( ';', DatenString ) );
  Bundesland := DatenString;
end;

function TDatensatz.IstKennzeichen( KennzeichenString : STRING ) : BOOLEAN;
begin
  Result := false; // <-- verschoben, da sonst immer False als Result
  if KennzeichenString = kennzeichen
  then
    Result := true;
  // result := false;
end;

constructor TListe.Create;
begin
  inherited;
  Anzahl := 0;
  NotA := false;
  CompleteFile := TStringList.Create; // das muss hier hin
end;

destructor TListe.Destroy;
var
  i : CARDINAL;
begin
  if Anzahl > 0
  then
    begin
      for i := 1 to Anzahl do
        Liste[i].Free; // nicht Destroy direkt aufrufen
      Anzahl := 0;
    end;
  NotA := false;
  CompleteFile.Free; // nicht Destroy direkt aufrufen
  inherited; // <-- fehlte
end;

procedure TListe.DateiEinlesen( datname, suchKFZ : STRING );
begin
  // try

  datname := extractfilepath( ParamStr( 0 ) ) + 'lib\kfz.csv';

  // Nein, da gibt es schon eine Instanz

  // CompleteFile := TStringList.Create;

  CompleteFile.LoadFromFile( datname );
  if NAcheck( Anzahl, CompleteFile )
  then
    begin
      Lesen( Anzahl, CompleteFile );
      if not Liste[Anzahl].IstKennzeichen( suchKFZ )
      then
        begin
          Anzahl := GibAnzahl + 1;
          DateiEinlesen( datname, suchKFZ );
        end
      else
        begin
          if Lesen( Anzahl, CompleteFile ).Bundesland = ''
          then
            begin
              Liste[Anzahl].Sonder := Liste[Anzahl].Bundesland;
              Liste[Anzahl].Bundesland := '';
              Liste[Anzahl].Ort := '';
            end;
        end;
    end;

  // und diese Instanz bleibt

  // finally
  // CompleteFile.Free;
  // end;
end;

function TListe.Lesen( i : CARDINAL; datnamen : TStringList ) : TDatensatz;
begin
  Liste[i].Einlesen( datnamen.Strings[i] );
  Result := Liste[i];
end;

function TListe.GibAnzahl : CARDINAL;
begin
  Result := Anzahl;
end;

function TListe.NAcheck( j : INTEGER; Stringlist : TStringList ) : BOOLEAN;
begin
  Result := false; // <-- verschoben, da sonst immer False als Result
  if j <= Stringlist.Count
  then
    Result := true;
  NotA := true;
  // Result := false;
end;

end.
Allerdings ist der wirkliche Fehler gar nicht in der Unit zu finden
sondern hier:
Delphi-Quellcode:
procedure TForm1.Search( SearchString : String );
begin
  if ( Length( SearchString ) <> 0 ) and ( SearchString <> Last01.Caption )
  then
    begin
      Form1.Enabled := False;
      StartProgressBar( 25 );
      Wait( 3 );
      ChangeLast( SearchString );

      // hier war der Haupt-Fehler

      unsereListe := TListe.Create; // statt unsereListe.create

      try

        unsereListe.dateieinlesen( 'kfz.csv', SearchString );
        if not unsereListe.NotA // statt unsereListe.NotA = False
        then
          begin
            Output2.Caption := unsereListe.liste[unsereListe.anzahl].kennzeichen;
            Output4.Caption := unsereListe.liste[unsereListe.anzahl].ort;
            Output6.Caption := unsereListe.liste[unsereListe.anzahl].bundesland;
            Output8.Caption := unsereListe.liste[unsereListe.anzahl].sonder;
          end;

      finally
        unsereListe.Free; // freigeben, sonst gibt das ein riesen Speicherleck
      end;

      // Geduldsprobe für den User, es passiert nichts, ausser dass der Balken sich bewegt

      while ProgressBar.Position <> 0 do
        Wait( 2 );

      Form1.Enabled := True;
    end;
end;
  • Warum ist unsereListe global definiert? so wie du diese benutzt könntest du die auch lokal in der Methode deklarieren. Oder in der Form-Klasse ... aber so passt das nicht so richtig zusammen
  • Wofür du aber extra die Ausführung abbremst um da in einer ProgressBar etwas anzuzeigen, ist mir etwas schleierhaft.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat