Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Exeption - Woher? (https://www.delphipraxis.net/118859-exeption-woher.html)

fortuneNext 16. Aug 2008 16:40


Exeption - Woher?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi,
in der Schule programmieren wir aktuell ein kleines Übungsprojekt, das eine Buchliste (Datenstruktur siehe Anhang) auslesen und ein TBuch schreiben soll.
Wir benutzen übrigens Delphi 6.

Ein Buch ist als folgendes deklariert (in eigener Unit mBuch):
Delphi-Quellcode:
unit mBuch;

interface

type
   TBuch = class(TObject)
   private
   {}
   public
   ID: integer;
        Thema: string;
        Autor: string;
        Titel: string;
        Ort: string;
        Erscheinungsjahr: integer;
        Verlag: string;
   end;

implementation

end.
Der Quellcode des restlichen Projekts:

Delphi-Quellcode:
unit mBuchliste;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, mBuch, StdCtrls;

type
  TfMain = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
  {}
  protected
    procedure LineExtract;
  public
    Buchliste: Array[1..1602] of TBuch;
  end;

var
  fMain: TfMain;
  s: string;
  z: integer;

const
  MyDat ='Buecher.txt';


implementation

{$R *.dfm}

function PosEx(const Substr: string; const S: string; Offset: Integer): Integer;
begin
  if Offset <= 0 then Result := 0
  else
    Result := Pos(Substr, Copy(S, Offset, Length(S)));

  if Result <> 0 then
    Result := Result + Offset - 1;
end;

procedure TfMain.LineExtract;
var
  x,y: integer;
begin
  x := 0;
  y := 1;
  For x := 1 to 7 do
  begin
    If x <> 7 then
    begin
      Case x of
      1: Buchliste[z].ID := StrToInt(Copy(s, y, PosEx(';', s, y) - y));
      2: Buchliste[z].Thema := Copy(s, y, PosEx(';', s, y) - y);
      3: Buchliste[z].Autor := Copy(s, y, PosEx(';', s, y) - y);
      4: Buchliste[z].Titel := Copy(s, y, PosEx(';', s, y) - y);
      5: Buchliste[z].Ort := Copy(s, y, PosEx(';', s, y) - y);
      6: begin
           If Copy(s, y, PosEx(';', s, y) - y) <> '' then
             Buchliste[z].Erscheinungsjahr := StrToInt(Copy(s, y, PosEx(';', s, y) - y))
           Else if Copy(s, y, PosEx(';', s, y) - y) = '' then
             Buchliste[z].Erscheinungsjahr := 0;
         end;
      end;
      y := PosEx(';', s, y) + 1;
    end
    Else if x = 7 then
    begin
      Buchliste[z].Verlag := Copy(s, y, Length(s) - y + 1);
    end;
  end;
end;

procedure ReadIn;
var
  datei: Textfile;
begin
  z := 0;
  assignfile(datei,MyDat);
  reset(datei);
  while not EOF(datei) do
  begin
    readln(datei,s);
    z := z + 1;
    fMain.LineExtract;
  end;
  closefile(datei);
end;

procedure TfMain.FormCreate(Sender: TObject);
begin
  ReadIn;
end;

end.
Beim ausführen von LineExtract gibts dann leider immer eine Exception der Klasse EAccessViolation (Zugriffsverletzung).
Keiner - nichtmal der Lehrer :P - weiss woher die kommmt. Hat jemand eine Idee?
mfg
fortuneNext

leddl 16. Aug 2008 16:53

Re: Exeption - Woher?
 
Zitat:

Zitat von fortuneNext
Hat jemand eine Idee?

Habs jetzt nur mal kurz überflogen, aber:
Du hast ein Array von Objekten, die Du nirgends erzeugst, greifst aber trotzdem darauf zu? :gruebel: Das kann ja gar nicht gehen ;)
Setze ein Buchliste[z] := TBuch.Create() und es sollte doch eigentlich gehen.

Btw hast Du also eine Klasse, die nichts anderes ist als ein Datencontainer. Hätte es dafür ein Record nicht auch getan? Damit würde es nämlich auch so funktionieren ;)

taaktaak 16. Aug 2008 16:56

Re: Exeption - Woher?
 
Ja, ein Record hätte es auch getan!

[OT] Was'n dat für'n Lehrer? [/OT]

DeddyH 16. Aug 2008 17:05

Re: Exeption - Woher?
 
Diese Logik erschließt sich mir nicht so recht:
Zitat:

Delphi-Quellcode:
  For x := 1 to 7 do
  begin
    If x <> 7 then
    begin
      ...
    end
    Else if x = 7 then
    begin
      ...
    end;

Wieso lässt Du nicht die Schleife bis 6 laufen und machst anschließend etwas mit Nummer 7?

grenzgaenger 16. Aug 2008 18:01

Re: Exeption - Woher?
 
mhhh... scheint mir 'n mix zwischen konsolapp und fensterapp zu sein... (z.b. readln im constructor). der aufbau scheint mir da auch so 'n mix aus objektorientierung und prozeduraler zu sein... class buch in verbindung mit record...


tja, als übungsprobjekt schon sehr gut, da hast du noch 'n bischen arbeit vor dir, bis es rund läuft ... :-)

PS: mit den tipp von leddl, sollt es klappen...

fortuneNext 17. Aug 2008 12:44

Re: Exeption - Woher?
 
Ah, danke für die ganzen konstruktiven Kommentare :-)
Werde bald mal alles ausprobieren... das mit dem Create ist natürlich klar, hatte ich ganz vergessen :-D

Und naja... zur Unterrichtung junger Informatiker wird in der Regel kein kompetentes Personal genutzt...
Und generell gehts in der Schule ja nicht dadrum, sinnvolle, gut laufende, simpel geschriebene und funktionierende Programme zu schreiben, sondern irgendwelche überhaupt nicht passenden Komponenten dabei zu verwenden (Record - Typ)...

fortuneNext 18. Aug 2008 21:21

Re: Exeption - Woher?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Okay... der Create war die Lösung.
Nun versuchen wir, die eingelesenen Daten in ein StringGrid einzutragen.
Dazu 2 Fragen:
1. Es wird wieder eine Exception ausgelöst... völlig sinnlos, beim lesen von Eintrag 1598 und den folgenden 4. Die kann zwar durch einen Try-Block umgangen werden, was aber eine sehr schlampige Lösung ist und nicht die Frage beantwortet, woher sie kommt. Das seltsame daran ist, dass das Programm trotzdem gut läuft, alle Sachen werden korrekt dargestellt etc.
2. Jetzt möchten wir die Sachen sortieren, nach den div. Datentypen (also z.B. nach ID, nach Autor etc). Das wollten wir auslösen, indem man auf die "Fixed-Cols" drückt (oben wo die Beschriftung ist). Ein OnCellSelect geht leider nicht, da sich die Dinger nicht anklicken lassen. Gibt es da irgendeine Lösung oder werden wir eigene Buttons einbauen müssen? Also die Frage ist, lassen sich die Fixed Einträge zu Buttons umfunktionieren?.

Danke!
mfg

omata 18. Aug 2008 21:24

Re: Exeption - Woher?
 
- Bereichprüfung einschalten.
- Breakpoints setzen.
- Debugger ausgiebig benutzen.

mkinzler 18. Aug 2008 21:24

Re: Exeption - Woher?
 
Jag das Programm doch durch den Debugger, dann siehst du welcher Befehl diesen Fehler auslöst und dann vielleicht auch warum

fortuneNext 18. Aug 2008 22:05

Re: Exeption - Woher?
 
Ich weiss ja woher der Fehler kommt.

Delphi-Quellcode:
StrGrid_Buchliste.Cells[0,x] := IntToStr(Buchliste[x].ID);
Bloß wieso bringt das einen Fehler?
Und vor allem erst bei Eintrag 1598-1602? Und warum klappts dann auch noch trotzdem? oO Für mich ein mysterium... das kompetente Lehrpersonal weiss es auch nicht ^^

mkinzler 18. Aug 2008 22:07

Re: Exeption - Woher?
 
Was steht den in ID?

omata 18. Aug 2008 22:11

Re: Exeption - Woher?
 
Der Fehler kann ja nur in Buchliste[x] sein. Was für einen Wert hat x, wenn der Fehlerauftritt?

grenzgaenger 18. Aug 2008 22:33

Re: Exeption - Woher?
 
Liste der Anhänge anzeigen (Anzahl: 1)
hier mal 'n kleines testprogramm:
Delphi-Quellcode:
UNIT Unit1;

INTERFACE

USES
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Grids, csv;

TYPE
  TForm1 = CLASS(TForm)
    sg: TStringGrid;
    PROCEDURE FormCreate(Sender: TObject);
    PROCEDURE FormDestroy(Sender: TObject);
  private
    { Private-Deklarationen }
    sl: TStringList;
  public
    { Public-Deklarationen }
  END;

VAR
  Form1: TForm1;

IMPLEMENTATION

{$R *.dfm}

PROCEDURE TForm1.FormCreate(Sender: TObject);
VAR
  csv: tCSV;
  i:  integer;
  j:  integer;
BEGIN
  sl := TStringList.Create;
  sl.LoadFromFile('Buecher.txt');
  csv := tCSV.Create;
  TRY
    sg.ColCount := 8;
    sg.RowCount := sl.Count + 1;
    FOR i := 0 TO sl.Count - 1 DO
    BEGIN
      csv.Analyze(sl.Strings[i]);
      sg.Cells[0, i + 1] := IntToStr(i + 1);
      FOR j := 0 TO csv.Count - 1 DO
        sg.Cells[j + 1, i + 1] := csv.Columns[j];
    END;
  FINALLY
    csv.Free;
  END;
END;

PROCEDURE TForm1.FormDestroy(Sender: TObject);
BEGIN
  sl.Free;
END;

END.
Edit://Code umformatiert, da die codedarststellung in der DP recht eigensinnig ist und macht was sie will ... hoffe so ist es besser lesbar

Edit2: Kommentar von vorhin noch mal hinzugefügt, da der Editor diese vorloren hat...:

Wenn Du dir die zeilen ansiehst, sollte dir etwas bei auffallen...

omata 18. Aug 2008 22:39

Re: Exeption - Woher?
 
Warum muss die StringList global sein?

grenzgaenger 18. Aug 2008 22:42

Re: Exeption - Woher?
 
muss nicht, nur schnell reingehackt...

so, besser?

Delphi-Quellcode:
UNIT Unit1;

INTERFACE

USES
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Grids, csv;

TYPE
  TForm1 = CLASS(TForm)
    sg: TStringGrid;
    PROCEDURE FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  END;

VAR
  Form1: TForm1;

IMPLEMENTATION

{$R *.dfm}

PROCEDURE TForm1.FormCreate(Sender: TObject);
VAR
  csv: tCSV;
  i:  integer;
  j:  integer;
  sl: TStringList;
BEGIN
  sl := TStringList.Create;
  TRY
    sl.LoadFromFile('Buecher.txt');
    csv := tCSV.Create;
    TRY
      sg.ColCount := 8;
      sg.RowCount := sl.Count + 1;
      FOR i := 0 TO sl.Count - 1 DO
      BEGIN
        csv.Analyze(sl.Strings[i]);
        sg.Cells[0, i + 1] := IntToStr(i + 1);
        FOR j := 0 TO csv.Count - 1 DO
          sg.Cells[j + 1, i + 1] := csv.Columns[j];
      END;
    FINALLY
      csv.Free;
    END;
  FINALLY
    sl.Free;
  END;
END;

END.

omata 18. Aug 2008 23:01

Re: Exeption - Woher?
 
Wenn du schon fragst: Warum zwei Try-Finally-Blöcke?

Aber was ich viel spannender finde: wo kommt die csv-Unit her?
Bei Delphi7 hab ich die irgendwie nicht. Oder bin ich blind?

grenzgaenger 18. Aug 2008 23:14

Re: Exeption - Woher?
 
die zwei try finally kommen daher, weil bei jeden create etwas schiefgehen kann und da das objekt noch nicht initialisiert wäre... ein abprüfen auf NIL scheidet aus, da die objekte auf den stack angelegt sind und somit vor dem initialisieren irgendeinen wert aufweisen. deswegen der verschachtelte try finally...

die CSV unit ist selbst gebastelt, hatte keine lust die stringzerlegung mit der hand nachzuvollziehen, obgleich fortuneNext im ersten post etwas entsprechendes hatte. alzheimer hatte auch mal eine CSV unit in der opensource sparte gepostet...
aber die stringzerlegung war ja hier auch nicht das problem... deswegen erlaubte ich mir die erleichterung ..., ausserrdem will ich ihm ja auch nicht die ganze arbeit abnehmen ... ;-)

schöne grüsse und noch 'n schönen abend
GG

grenzgaenger 18. Aug 2008 23:19

Re: Exeption - Woher?
 
Zitat:

Zitat von fortuneNext
2. Jetzt möchten wir die Sachen sortieren, nach den div. Datentypen (also z.B. nach ID, nach Autor etc). Das wollten wir auslösen, indem man auf die "Fixed-Cols" drückt (oben wo die Beschriftung ist). Ein OnCellSelect geht leider nicht, da sich die Dinger nicht anklicken lassen. Gibt es da irgendeine Lösung oder werden wir eigene Buttons einbauen müssen? Also die Frage ist, lassen sich die Fixed Einträge zu Buttons umfunktionieren?.

kannst du das OnClick ereignis nicht verwenden? hier könntest doch abbprüfen ob in der ersten spalte/zeile oder auf etwas spezifisches gedrückt wurde und entsprechend darauf reagieren...

omata 18. Aug 2008 23:26

Re: Exeption - Woher?
 
Zitat:

Zitat von grenzgaenger
die CSV unit ist selbst gebastelt ... aber die stringzerlegung war ja hier auch nicht das problem...

Dann ist das aber kein sinnvolles Beispiel, weil es nicht nachvollziehbar ist bzw. der, dem es eigentlich helfen soll mit Fehlern zu gemüllt werden, die gar nichts mit dem eigentlichen Problem zu tun haben.

Ein Hinweis wäre da das Mindeste gewesen.

fortuneNext 19. Aug 2008 17:10

Re: Exeption - Woher?
 
Also ich muss sagen, das Beispiel verstehe ich wirklich nicht. Ich sehe zwar die Logik des Codes so einigermaßen ein (auch wenn ich die Unit nicht kenne), aber das hilft mir bei der Suche nach meinem Fehler überhaupt nicht.
x ist wie gesagt 1598...
und was ich auch schon schrieb (siehe post 1):
Delphi-Quellcode:
type
   TBuch = class(TObject)
   private
   {}
   public
   ID: integer;
        Thema: string;
        Autor: string;
        Titel: string;
        Ort: string;
        Erscheinungsjahr: integer;
        Verlag: string;
   end;
Weiss einer wo das Problem liegt?
Manchmal wünscht ich, in diesem Fach könnte einem der Lehrer zumindest manchmal weiterhelfen...

marabu 19. Aug 2008 17:24

Re: Exeption - Woher?
 
Hi,

eines deiner Probleme dürfte die Tatsache sein, dass die Datei BUECHER.TXT nur 1597 Datensätze aufweist.

Grüße vom marabu

omata 19. Aug 2008 17:30

Re: Exeption - Woher?
 
[wegen Nicht-Beachtung gelöscht]

fortuneNext 19. Aug 2008 18:56

Re: Exeption - Woher?
 
Oh gott... ich glaubs nicht... was stellt uns der Kerl eigentlich für Material zur Verfügung... erst war da in einer Zeile ein Fehler der Datenstruktur, waren 2 Autoren mit ; getrennt und wir suchen uns nen Wolf weil ders nich kapiert, und jetzt sowas...
xD
okay danke...das ist natürlich ein doofer fehler...

grenzgaenger 19. Aug 2008 20:32

Re: Exeption - Woher?
 
Zitat:

Zitat von marabu
Hi,

eines deiner Probleme dürfte die Tatsache sein, dass die Datei BUECHER.TXT nur 1597 Datensätze aufweist.

Grüße vom marabu

dachte, das bringt er selbst raus, nach meinen hinweis ... :-) in #13, aber da hat er sich wohl die falschen zeilen angesehen ... :-)

PS: das war wohl ditaktik, ihr sollt ja progrmmieren lernen, und dazu gehört auch die fehlersuche mit zu ... :-)

jetzt mal klartext, dein .RAR kann ich nicht entziffern, aber meine :glaskugel: erzählt mir, dass du ein array definierter länge hast, das du beim einlesen nicht ordentlich initialisiert... beim auslesen, stollperst du über die fehlerhaften initialisierungen... und das bringt die fehler ...

hier kannst (a) ordentlich initialisieren und (b) beim auslesen vernünftig darauf reagieren...

z.b.
Delphi-Quellcode:
fillchar(myarray, sizeof(myarray), 0);

if assigned(myarray[xyz]) then myObject(myarray[xyz]).dosomething;
dann sollt es auch keine fehlermeldungen mehr geben, und du hast (a) gelernt deine datenstrukturen zu initialsieren und (b) eine ordentliche fehlerbehandlung aufzubauen :-)

<HTH> GG

fortuneNext 19. Aug 2008 20:50

Re: Exeption - Woher?
 
Naja, die Taktik wars gewiss nicht ;) Sonst wär nicht der Satz gekommen "Naja... keine Ahnung... müssen wir wohl mit dieser kleinen Ausnahme leben, ich wüsste auch nich woher sie kommt" xD

Gut, wir initialisieren dann mal richtig ab jetzt :)


Zitat:

Zitat von grenzgaenger
Zitat:

Zitat von fortuneNext
2. Jetzt möchten wir die Sachen sortieren, nach den div. Datentypen (also z.B. nach ID, nach Autor etc). Das wollten wir auslösen, indem man auf die "Fixed-Cols" drückt (oben wo die Beschriftung ist). Ein OnCellSelect geht leider nicht, da sich die Dinger nicht anklicken lassen. Gibt es da irgendeine Lösung oder werden wir eigene Buttons einbauen müssen? Also die Frage ist, lassen sich die Fixed Einträge zu Buttons umfunktionieren?.

kannst du das OnClick ereignis nicht verwenden? hier könntest doch abbprüfen ob in der ersten spalte/zeile oder auf etwas spezifisches gedrückt wurde und entsprechend darauf reagieren...



naja, wie soll man das abprüfen? Die fixed-cols sind leider nicht anklickbar, so gibt es überhaupt keinen Indikator...



Und @ omata: sry... muss es wohl irgendwie überlesen haben :-/ jetzt fällts mir erst beim 2. durchschauen auf... xD

grenzgaenger 19. Aug 2008 20:53

Re: Exeption - Woher?
 
im übrigen, objekte werden im constructor automatisch initialisiert...

aber dein array, auch records, wie auch deine lokalen und globalen variablen musste mit der hand initialisieren :-)


PS: Ordentlich initialiseren und vernünftig einrücken, erspart dir schlaflose nächte mit dem debugger :-)

grenzgaenger 19. Aug 2008 21:17

Re: Exeption - Woher?
 
Zitat:

Zitat von fortuneNext
naja, wie soll man das abprüfen? Die fixed-cols sind leider nicht anklickbar, so gibt es überhaupt keinen Indikator...

dann schreib dir doch dein OnClick selbst :-)

Delphi-Quellcode:
procedure TForm1.StringGrid1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
 c, r: integer;
begin
 TStringGrid(sender).MouseToCell(x, y, c, r);
 if mbLeft = button then
 begin
  StatusBar1.SimpleText := inttostr(c) + '/' + inttostr(r);
 end;
end;
ps: alternativ könntest auch 'n listview statt 'n stringgrid nehmen... :roll:

fortuneNext 20. Aug 2008 13:56

Re: Exeption - Woher?
 
Mit dem Code weiss ich aber immernoch nicht auf welche Zelle jetzt gedrückt wurde... :-(

DeddyH 20. Aug 2008 13:58

Re: Exeption - Woher?
 
Wieso nicht? Schau mal in der Hilfe nach, was MouseToCell macht.

fortuneNext 20. Aug 2008 14:12

Re: Exeption - Woher?
 
Achsooo... okay ich habs zuerst falsch verstanden :D ich dachte, es gibt nur die Mauskoordinaten aus... xD
Okay danke! :)
Weiss zufällig noch einer wie ich einzelne Zellen editiere? Also haben die vielleicht Eigenschaften wie Farbe oder Textausrichtung? :-) Ansonsten wenn nicht auch egal...
Danke an alle Helfer! :-)

mfg

edit ps: dank auflage des lehrers müssen wir leider ein stringgrid benutzen ...


Alle Zeitangaben in WEZ +1. Es ist jetzt 17: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-2025 by Thomas Breitkreuz