AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Aufruf neuer Typen in anderen Units

Offene Frage von "DeddyH"
Ein Thema von Caesar2012 · begonnen am 31. Jan 2012 · letzter Beitrag vom 1. Feb 2012
 
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
 

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:51 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-2025 by Thomas Breitkreuz