![]() |
Abstrakter Fehler
Hallo miteinander
Habe folgende Procedur programmiert, welche im Endeffekt nichts anderes macht, als zuvor dynamisch erzeugte Elemente wieder zu löschen. Jedoch tritt dabei immer mal wieder ein "abstrakter Fehler" auf.
Delphi-Quellcode:
Woran kann diese liegen???
procedure TForm1.loeschenTeilnehmer(tempzahl:String);
var name: TNamenArray; x,tempx: Integer; temp: String; begin name:=setArrays(); ShowMessage('Loeschen T.'); for x := 0 to 12 do begin TEdit(FindComponent(name[x] + tempzahl)).Free; end; ShowMessage('Loeschen T.'); //Löschen des Mitglied und Kursfeldes TCheckBox(FindComponent('mitglied' + tempzahl)).Free; TComboBox(FindComponent('kurs' + tempzahl)).Free; TComboBox(FindComponent('sportart' + tempzahl)).Free; TButton(FindComponent('loeschen' + tempzahl)).Free; Wäre euch echt dankbar, wenn ihr dafür eine Lösung finden würdet. Gruß Michael |
Re: Abstrakter Fehler
Wieder mal vvergessen : Poezedurkopf. 8)
|
Re: Abstrakter Fehler
So nun ist auch der Prozedurkopf mit drinnen.
|
Re: Abstrakter Fehler
Hehe, da fehlt jetzt noch die Deklaration von der Form. :mrgreen:
|
Re: Abstrakter Fehler
Delphi-Quellcode:
so das ist die Klassendekleration der Form. Ich hoffe, dass ich nun also hab, was du/ihr benötigt.
type
TNamenArray = Array [0..12] of String; TForm1 = class(TForm) MainMenu1: TMainMenu; PageControl1: TPageControl; TabSheet1: TTabSheet; createTeilnehmerleiste: TButton; sendListe: TButton; Label1: TLabel; Label2: TLabel; Label3: TLabel; Label4: TLabel; Label5: TLabel; Label6: TLabel; Label7: TLabel; Label8: TLabel; Label9: TLabel; Label10: TLabel; Label11: TLabel; Label12: TLabel; Label13: TLabel; Label14: TLabel; Label15: TLabel; Label16: TLabel; IdHTTP1: TIdHTTP; IdFTP1: TIdFTP; Datei1: TMenuItem; Beenden1: TMenuItem; TabSheet2: TTabSheet; WebBrowser1: TWebBrowser; Timer1: TTimer; procedure createTeilnehmerleisteClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure sendListeClick(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); //Eigene Funktionen procedure generateTextfeld(left : Integer; name: String; width:Integer); procedure generateTeilnehmerfelder(); procedure generateUeberschriften(); procedure generateAuswahl(left : Integer; name: String); procedure generateCombobox(left : Integer; name: String; top:integer; width:integer); function datensatzRueckgabe(): String; function setArrays():TNamenArray; procedure loadCombobox(datname:String;cbox:String); function changeToID(temp:String): String; procedure dateiUpload(); procedure Beenden1Click(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure generateButton(); procedure LoeschenClick(Sender: TObject); procedure loeschenTeilnehmer(tempzahl:String); procedure verschiebeTeilnehmer(tempzahl:String); |
Re: Abstrakter Fehler
Ne, immer noch nicht. :mrgreen: Wo ist z.B. die Sportart ??
|
Re: Abstrakter Fehler
Hey, ich kann hier nun den kompletten Quelltext dieser Unit hinhauen, aber dann sind es ca. 600 Zeilen und ich weis nicht, ob das dann wirklich übersichtlich ist.
|
Re: Abstrakter Fehler
anhängen. 8)
|
Re: Abstrakter Fehler
Hallo Michael,
wieso verwaltest du 13 Basisnamen für Komponenten in einem TNamenArray und 4 weitere nicht? Was passiert, wenn du bei drei existierenden Teilnehmern den ersten löschst und anschließend einen neuen Teilnehmer erstellst? Wird die zum Löschen verwendete TempZahl wiederverwendet? Grüße vom marabu |
Re: Abstrakter Fehler
Im Array stehen nur die Namen für die Editfelder. Die Namen der anderen Felder hab ich halt statisch festgelegt.
Wenn ich Felder lösche werden die anderen Felder dementsprechend verschoben, so dass im Endeffekt die Zahl tempzahl wieder belegt ist. |
Re: Abstrakter Fehler
Ist der auftretende Fehler reproduzierbar? Kannst du einen bedingten Haltepunkt einsetzen? Du könntest den fehlerträchtigen Code isolieren und in einem Testprojekt einstellen. Zumindest ich könnte dir dann besser helfen.
Freundliche Grüße |
Re: Abstrakter Fehler
Was meinst du mit Testprojekt, bedingtem Haltepunkt, bzw. reproduzierbar?
|
Re: Abstrakter Fehler
Ein Fehler ist reproduzierbar, wenn du exakt angeben kannst, unter welchen Randbedingungen er auftritt. Solche Fehler sind mit relativ wenig Aufwand zu beheben. Kannst du die Bedingungen nicht so genau angeben, dann helfen auch schon Verdachtsmomente. Diese Bedingungen kannst du an einen Haltepunkt knüpfen, damit du die Variablen-Zustände im internen Debugger untersuchen kannst. Wenn du den Fehler nicht alleine findest, dann erstellst du am Besten eine Kopie deines Projektes und befreist diese von allem Unwesentlichen. Mit einem solchen Testprojekt kann man dir besser helfen, da der Fehler ja erst zur Laufzeit auftritt. Ausschnitte aus deinem Quelltext helfen da nur bedingt.
|
Re: Abstrakter Fehler
Ok dann ist dieser Fehler nicht reproduzierbar.
Nachfolgend der von mir bereits entspeckte Quelltext.
Delphi-Quellcode:
unit ssumain;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls, Menus, IdExplicitTLSClientServerBase, IdFTP, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP, OleCtrls, SHDocVw_TLB, ExtCtrls; type TNamenArray = Array [0..12] of String; TForm1 = class(TForm) MainMenu1: TMainMenu; PageControl1: TPageControl; TabSheet1: TTabSheet; createTeilnehmerleiste: TButton; sendListe: TButton; Label1: TLabel; Label2: TLabel; Label3: TLabel; Label4: TLabel; Label5: TLabel; Label6: TLabel; Label7: TLabel; Label8: TLabel; Label9: TLabel; Label10: TLabel; Label11: TLabel; Label12: TLabel; Label13: TLabel; Label14: TLabel; Label15: TLabel; Label16: TLabel; IdHTTP1: TIdHTTP; IdFTP1: TIdFTP; Datei1: TMenuItem; Beenden1: TMenuItem; TabSheet2: TTabSheet; WebBrowser1: TWebBrowser; Timer1: TTimer; procedure createTeilnehmerleisteClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure sendListeClick(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); //Eigene Funktionen procedure generateTextfeld(left : Integer; name: String; width:Integer); procedure generateTeilnehmerfelder(); procedure generateUeberschriften(); procedure generateAuswahl(left : Integer; name: String); procedure generateCombobox(left : Integer; name: String; top:integer; width:integer); function datensatzRueckgabe(): String; function setArrays():TNamenArray; procedure loadCombobox(datname:String;cbox:String); function changeToID(temp:String): String; procedure dateiUpload(); procedure Beenden1Click(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure generateButton(); procedure LoeschenClick(Sender: TObject); procedure loeschenTeilnehmer(tempzahl:String); procedure verschiebeTeilnehmer(tempzahl:String); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; zaehler: Integer; teilnehmer,tempdat : TextFile; implementation uses ssu; {$R *.dfm} procedure TForm1.createTeilnehmerleisteClick(Sender: TObject); begin if zaehler=0 then begin generateUeberschriften(); end; generateTeilnehmerfelder(); end; procedure TForm1.generateTeilnehmerfelder(); var x:Integer; left: Array[0 .. 12] of Integer; name: TNamenArray; tempname: String; width: Array[0 .. 12] of Integer; begin left[0]:=8; left[1]:=72; left[2]:=136; left[3]:=208; left[4]:=248; left[5]:=296; left[6]:=360; left[7]:=432; left[8]:=496; left[9]:=536; left[10]:=600; left[11]:=656; left[12]:=744; width[0]:=64; width[1]:=62; width[2]:=72; width[3]:=40; width[4]:=48; width[5]:=64; width[6]:=72; width[7]:=64; width[8]:=40; width[9]:=64; width[10]:=56; width[11]:=88; width[12]:=70; name:=setArrays(); for x := 0 to 12 do begin generateTextfeld(left[x],name[x],width[x]); end; tempname:='kurs' + IntToStr(zaehler); generateCombobox(830,tempname,-1,135); loadCombobox('kurs.txt',tempname); tempname:='sportart' + IntToStr(zaehler); generateCombobox(965,tempname,-1,50); loadCombobox('sportarten.txt',tempname); generateAuswahl(814,'mitglied'); generateButton(); zaehler:=zaehler+1; end; procedure TForm1.generateButton(); var Button: TButton; tname: String; tleft, ttop,tempzaehler : Integer; begin //Vordekleration der Variablen tname:='loeschen' + IntToStr(zaehler); tleft:=0; tempzaehler:=zaehler-1; ttop:=50+zaehler*20; Button:=TButton.Create(Self); with Button do begin Name:=tname; Parent:=TabSheet1; Left:=tleft; Top:=ttop; Width:=8; Height:=8; OnClick:=LoeschenClick; Caption:='X'; end; end; procedure TForm1.LoeschenClick(Sender: TObject); var tempzahl: String; begin if Sender is TButton then tempzahl:=TButton(Sender).Name; Delete(tempzahl,0,8); tempzahl:=Copy(tempzahl,9,2); loeschenTeilnehmer(tempzahl); zaehler:=zaehler-1; end; procedure TForm1.loeschenTeilnehmer(tempzahl:String); var name: TNamenArray; x,tempx: Integer; temp: String; begin name:=setArrays(); ShowMessage('Loeschen T.'); for x := 0 to 12 do begin TEdit(FindComponent(name[x] + tempzahl)).Free; end; ShowMessage('Loeschen T.'); //Löschen des Mitglied und Kursfeldes TCheckBox(FindComponent('mitglied' + tempzahl)).Free; TComboBox(FindComponent('kurs' + tempzahl)).Free; TComboBox(FindComponent('sportart' + tempzahl)).Free; TButton(FindComponent('loeschen' + tempzahl)).Free; tempx:=strtoint(tempzahl)+1; for x := tempx to zaehler-1 do begin verschiebeTeilnehmer(inttostr(x)); end; end; procedure TForm1.verschiebeTeilnehmer(tempzahl:String); var name: TNamenArray; x: Integer; temp: String; begin ShowMessage('Verschiebe T.'); //erniedrige Tempzahl um 1 (neuer Wert) temp:=InttoStr(Strtoint(tempzahl)-1); //Einlesen des Arrays mit den Editfeldnamen name:=setArrays(); for x := 0 to 12 do begin TEdit(FindComponent(name[x] + tempzahl)).Top:=TEdit(FindComponent(name[x] + tempzahl)).Top-20; TEdit(FindComponent(name[x] + tempzahl)).Name:=name[x] + temp; end; //Positionsänderung der Checkboxen, Comboboxen und des Löschbuttons TCheckBox(FindComponent('mitglied' + tempzahl)).Top:=TCheckBox(FindComponent('mitglied' + tempzahl)).Top-20; TComboBox(FindComponent('kurs' + tempzahl)).Top:=TComboBox(FindComponent('kurs' + tempzahl)).Top-20; TComboBox(FindComponent('sportart' + tempzahl)).Top:=TComboBox(FindComponent('sportart' + tempzahl)).Top-20; TButton(FindComponent('loeschen' + tempzahl)).Top:=TButton(FindComponent('loeschen' + tempzahl)).Top-20; //Umbennen der Checkboxen, Comboboxen und des Löschbuttons TCheckBox(FindComponent('mitglied' + tempzahl)).Name:='mitglied' + temp; TComboBox(FindComponent('kurs' + tempzahl)).Name:='kurs' + temp; TComboBox(FindComponent('sportart' + tempzahl)).Name:='sportart' + temp; TButton(FindComponent('loeschen' + tempzahl)).Name:='loeschen' + temp; end; procedure TForm1.generateAuswahl(left : Integer; name: String); var Auswahlfeld: TCheckBox; tname: String; tbool: Boolean; tleft, tempzaehler : Integer; begin //Vordekleration der Variablen tname:=name + IntToStr(zaehler); tleft:=left; tempzaehler:=zaehler-1; if zaehler>0 then begin tbool:=TCheckBox(FindComponent(name + IntToStr(tempzaehler))).Checked; end; Auswahlfeld:=TCheckBox.Create(Self); with Auswahlfeld do begin if zaehler=0 then begin Checked:=False; end else begin Checked:=tbool; end; Name:=tname; Parent:=TabSheet1; Left:=tleft; Caption:=' '; width:=15; Top:=50+zaehler*20; end; end; procedure TForm1.generateCombobox(left : Integer; name: String; top:Integer; width:integer); var Auswahlfeld: TComboBox; tname: String; twidth, tleft, ttop,tempzaehler : Integer; begin //Vordekleration der Variablen twidth:=width; tname:=name; tleft:=left; tempzaehler:=zaehler-1; ttop:=top; if ttop=-1 then ttop:=50+zaehler*20; Auswahlfeld:=TComboBox.Create(Self); with Auswahlfeld do begin Name:=tname; Parent:=TabSheet1; Left:=tleft; Top:=ttop; Width:=twidth; Text:='Bitte waehlen'; end; end; procedure TForm1.loadCombobox(datname:String;cbox:String); var temp,tcbox:String; combobox: TComboBox; begin tcbox:=cbox; assignfile(tempdat,datname); reset(tempdat); combobox:=TComboBox(FindComponent(tcbox)); while not eof(tempdat) do begin readln(tempdat, temp); with combobox do Items.Add(temp); end; closefile(tempdat); end; procedure TForm1.generateTextfeld(left : Integer; name: String; width:Integer); var Textfeld: TEdit; tname,ttext: String; tleft, twidth,tempzaehler : Integer; begin //Vordekleration der Variablen tname:=name + IntToStr(zaehler); twidth:=width; tleft:=left; tempzaehler:=zaehler-1; if zaehler>0 then begin ttext:=TEdit(FindComponent(name + IntToStr(tempzaehler))).Text; end; //Ab hier wird das Textfeld erzeugt; Textfeld:=TEdit.Create(Self); with Textfeld do begin if zaehler=0 then begin Text:=' '; end else begin Text:=ttext; end; Name:=tname; Parent:=TabSheet1; Left:=tleft; Width:=twidth; Top:=50+zaehler*20; end; end; procedure TForm1.generateUeberschriften(); var x : Integer; begin for x := 1 to 16 do begin (FindComponent('label' + IntToStr(x)) as Tlabel).Visible:=True; end; end; procedure TForm1.FormCreate(Sender: TObject); var x : Integer; begin // Macht die Überschriften Labels unsichtbar for x := 1 to 16 do begin (FindComponent('label' + IntToStr(x)) as Tlabel).Visible:=False; end; // Erzeugt die Ausfahrtliste generateCombobox(250,'ausfahrt',0,300); WebBrowser1.Visible; randomize; end; function TForm1.setArrays():TNamenArray; var name : TNamenArray; begin name[0]:='name'; name[1]:='vorname'; name[2]:='strasse'; name[3]:='plz'; name[4]:='ort'; name[5]:='gebdatum'; name[6]:='email'; name[7]:='telefon'; name[8]:='preis'; name[9]:='bank'; name[10]:='blz'; name[11]:='kontoinhaber'; name[12]:='kontonr'; result := name; end; procedure TForm1.sendListeClick(Sender: TObject); begin end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin Form2.Close; end; procedure TForm1.dateiUpload(); begin end; function TForm1.changeToID(temp:String): String; begin end; function TForm1.datensatzRueckgabe(): String; begin end; procedure TForm1.Beenden1Click(Sender: TObject); begin Form2.Close; Close; end; procedure TForm1.Timer1Timer(Sender: TObject); begin end; end. |
Re: Abstrakter Fehler
Auf Anhieb sehe ich keinen Grund für "abstrakten Fehler". Vielleicht siehts ja irgendwer. Habe aber noch Frage am Rande : wieso erzeugst Du Kleinkram wie Edits zur Laufzeit ? Und dann noch fest von 0..12. :shock: Ich sehe jedenfalls keinerlei Anlass mit eigenem create, free usw. Delphi die Arbeit abzunehmen und sogar Koordinaten von Hand zu setzen. Wenn der Code in dieser Richtung etwas bereinigt würde, ja dann wirds mich nicht wundern, wenn der Fehler praktisch von alleine verschwindet.
|
Re: Abstrakter Fehler
Da ist ja noch was tolles. 8)
Zeilen 325 bis 330 : überflüssig ! Gut, wahrscheinlich hastes eben nicht besser gewußt. Das reicht :
Delphi-Quellcode:
Wetten, daß sich bei systematischem Vorgehen die originalen 600 Zeilen auf maximal 200 reduzieren ließen ? :-D
combobox.Items.LoadFromFile (datname);
|
Re: Abstrakter Fehler
Hallo,
kommt der Fehler vor dem ShowMessage ? Benenne mal deine lokale
Delphi-Quellcode:
Variable (überall) um.
name
TForm hat ebenfalls eine solches property. Vielleicht kommt Delphi damit durch einander. Heiko |
Re: Abstrakter Fehler
Jeah, das war nun schon einmal ein großer Schritt. Nun ist der Fehler nämlich so gut wie reproduzierbar.
Nachdem ich sämtliche Variablen name in fname umbenannt hab, ist der abstrakte Fehler nicht mehr aufgetreten. Nun tritt nur noch (nicht immer aber fast immer) der folgender Fehler auf: Wenn ich eine Zeile von Elementen lösche und dies die letzte Zeile ist, dann tritt manchmal ein Zugriffsfehler auf. Habe diese Procedure inzwischen wie folgt umgeändert.
Delphi-Quellcode:
Dabei tritt der Fehler dem ersten ShowMessage auf. Jedoch wird kein zweites ShowMessage ausgegeben, was soviel heißen müsste, wie dass die Schleife nicht durchlaufen wird, was auch korrekt ist.
procedure TForm1.loeschenTeilnehmer(tempzahl:String);
var fname: TNamenArray; x,tempx: Integer; temp: String; begin fname:=setArrays(); for x := 0 to 12 do begin TEdit(FindComponent(fname[x] + tempzahl)).Free; end; //Löschen des Mitglied und Kursfeldes TCheckBox(FindComponent('mitglied' + tempzahl)).Free; TComboBox(FindComponent('kurs' + tempzahl)).Free; TComboBox(FindComponent('sportart' + tempzahl)).Free; TButton(FindComponent('loeschen' + tempzahl)).Free; showMessage(inttostr(zaehler)); tempx:=strtoint(tempzahl)+1; while tempx < zaehler do begin showMessage(inttostr(tempx) + ' ' + inttostr(zaehler)); verschiebeTeilnehmer(inttostr(tempx)); tempx:=tempx+1; end; end; Woran kann es dann noch liegen? |
Re: Abstrakter Fehler
*loesch*
Sorry, hab verpeilt, dass der Thread nach Seite 1 noch weitergeht... sollte langsam ins Bett :roll: |
Re: Abstrakter Fehler
Hallo Michael,
mach dir doch das Leben nicht so schwer. Wenn du aus Designgründen jeden Datensatz als Summe von 17 einzelnen Controls verwalten möchtest, dann packe diese Controls doch einfach auf ein Panel und hänge diese mit Align = alTop untereinander. Das Löschen und Einfügen geht dann bedeutend einfacher. Grüße vom marabu |
Re: Abstrakter Fehler
Hallo,
vielleicht tritt der Fehler ja NACH dem Aufruf von loeschenTeilnehmer auf. Setz doch mal nen breakpoint auf das letzte end. Heiko |
Re: Abstrakter Fehler
Also meiner Meinung nach tritt der Fehler nach loeschenTeilnehmer auf.
Jedoch frage ich mich wo der Fehler dann auftritt. Denn lschenTeilnehmer wird ja von LoeschenClick aufgerufen und danach wird nur noch der zaehler um 1 erniedrigt.
Delphi-Quellcode:
procedure TForm1.LoeschenClick(Sender: TObject);
var tempzahl: String; begin if Sender is TButton then tempzahl:=TButton(Sender).Name; Delete(tempzahl,0,8); tempzahl:=Copy(tempzahl,9,2); loeschenTeilnehmer(tempzahl); zaehler:=zaehler-1; end; |
Re: Abstrakter Fehler
Hallo,
was heisst hier "Meinung nach" ? setze breakpoints oder ShowMessage, um das herauszufinden. Heiko |
Re: Abstrakter Fehler
Ja genau deshalb. Ich habe ShowMessage am Ende der Prozedur gesetzt welcher noch gezeigt wurde. Somit sollte er die Prozedur verlassen und in die Prozedur von welcher sie aufgerufen wird, zurückgekehrt werden.
|
Re: Abstrakter Fehler
Hallo,
wo rufst du eigentlich das LoeschenClick überhauot auf ? Was mich wundert ist das
Delphi-Quellcode:
Was passiert, wenn Sender nicht TButton ist ?
if Sender is TButton then
tempzahl:=TButton(Sender).Name; Ich würde hier auf jeden Fall erst mal ein begin end einbauen
Delphi-Quellcode:
if Sender is TButton then
begin tempzahl:=TButton(Sender).Name; Delete(tempzahl,0,8); .... end; Heiko |
Re: Abstrakter Fehler
Der Sender ist immer ein Button und diese Abfrage war eigentlich nur zur zusätzlichen Sicherheit. Aber auch wenn ich die Abfrage entferne bzw. mit einem begin und end erweitere tritt der Fehler auf.
Gruß Michael |
Re: Abstrakter Fehler
Hallo,
wenn der Fehler auftritt, drücke F7, dann stehst du zumindestens am Ende der Routine, die den Fehler verursacht hat. Lade dir mal MadExcept runter, der zeigt dir genauere Infos. Heiko |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:53 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