Makros und Programme einsetzen

Makro-Fehler behandeln

Top  Previous  Next

Wenn bei der Ausführung einer Systemfunktion oder eines Systembefehls ein Fehler auftritt, wird dieser auf eine von zwei Arten gemeldet:

Durch einen speziellen Rückgabewert. Dies ist immer dann der Fall, wenn der Fehler nicht besonders schwerwiegend ist und wenn er in einer Prozedur aufgetreten ist. Bei solchen Fehlern ist der Skript-Programmierer verantwortlich dafür, dass er den Fehlercode untersucht und entsprechend reagiert. Beispielsweise liefert die Funktion FindFirstFile den Wert -2, wenn das zu durchsuchende Verzeichnis gar nicht existiert.
Durch einen Systemfehler. Das passiert dann, wenn der Fehler entweder so bedeutend ist, dass evtl. kein ordnungsgemäßes Weiterarbeiten möglich ist, oder wenn der Fehler an einer Stelle auftritt, wo kein Rückgabewerte verfügbar ist, z.B. bei einer Variablenzuweisung. Bei einem Systemfehler wird die Ausführung des Makros oder des Programms abgebrochen und der Fehler wird an der Benutzeroberfläche gemeldet. Ein Beispiel dafür ist, wenn ReadRec mit einer nicht existierenden Tabellenummer aufgerufen wird.

Auf Systemfehler reagieren

Wenn Sie nicht möchten, dass bei einem Systemfehler abgebrochen wird, können Sie den Abbruch unterdrücken und den Fehler durch eigenen Programm-Code behandeln. Dies geschieht dadurch, dass Sie einen Block mit try und except um die potentielle Fehlerstelle herum aufbauen.

try
       ..Hier könnte ein Fehler auftreten
except
       ..Hier wird weitergemacht, wenn der Fehler tatsächlich auftritt.
end;

Falls kein Systemfehler zwischen try und except auftritt, wird der Teil zwischen except und end übersprungen und hinter dem end mit der Ausführung fortgefahren. Sollte jedoch zwischen dem try und dem except ein Systemfehler eintreten, werden alle folgenden Befehle bis zum except übersprungen und dann die Befehle zwischen except und end durchgeführt. Anschließend geht es in beiden Fällen hinter dem end weiter. Innerhalb des except-Blocks können Sie mit über das Error-Objekt die Nummer und die Beschreibung des Fehlers abfragen.

Ein Beispiel:

vardef N: Integer;
try
       N := Val(IrgendeinString);
       Message('Der Wert von ' + IrgendeinString + ' ist ' + Str(N));
except
       Message('Systemfehler ' + Str(Error.Nummer) + ' ist aufgetreten: ' + Error.Message);
end;
N := 0;

Wenn jetzt der String IrgendeinString einen ungültigen Ausdruck enthält, dann wird die Ausführung in der Zeile mit Val abgebrochen und mit der Message im except-Block fortgesetzt. Wenn der String gültig ist, wird sein Wert in der oberen Message ausgegeben. In jedem Fall wird also genau eine Message ausgegeben und anschließend der Wert von N wieder auf 0 gesetzt.

Einer der Vorteile dieser Methode ist die Tatsache, dass man try/except-Blöcke verschachteln kann. Damit ist es möglich innerhalb eines inneren Abschnitts eine andere Fehlerbehandlung durchzuführen als im äußeren Abschnitt. Betrachten Sie diesen Code:

procedure InnereProzedur
..Anweisungsblock 1
try
       ..Anweisungsblock 2
except
       Message('Ein Fehler ist im Anweisungsblock 2 aufgetreten.');
end;
..Anweisungsblock 3
endproc;
 
procedure ÄußereProzedur
try
       InnereProzedur
except
       Message('Ein Fehler ist in Anweisungsblock 1 oder 3 aufgetreten.');
end;
endproc;

Hier gilt für den Anweisungsblock 3 automatisch die Fehlerbehandlung wie für den Anweisungsblock 1. Das bedeutet, dass Sie beim Schreiben der Prozedur InnereProzedur nicht darauf achten müssen, wie die Prozedur ÄußereProzedur die Fehler außerhalb von Anwendungsblock 2 behandelt.

Die alte Methode

In den Versionen vor TurboDB Studio wurde die Systemfehler-Behandlung mit try/except noch nicht unterstützt. Hier wurde mit dem Steuerbefehl EC gearbeitet. Je nach Einstellung des Steuerbefehls EC (error check) bricht die Programmausführung bei einem Systemfehler ab (EC 0, das ist die Vorgabe) oder es bricht nur die aktuelle Zeile ab und der Fehlercode steht anschließend in der System-Variablen Error/Fehler (EC 1). Die Bedeutung dieser Fehlercodes finden sie unter "Fehlermeldungen".

Achtung: Das Programm wird trotz EC 1 abgebrochen, wenn der Rückgabewert der fehlerhaften Prozedur nicht abgefragt wird.

Fazit: Die Verwendung dieser alten Methode der Fehlerbehandlung wird nicht mehr empfohlen.

Beispiele

Die Funktion FindFirstFile liefert unterschiedliche Fehlercodes, wenn sie nichts finden konnte. Löst aber keinen Systemfehler aus:

vardef Res: Integer;
Res := FindFirstFile("C:\MyDir\*.*", "DHS", FName, FSize, FDate, FTime, FAttr, FFolder);
if Res >= 0
       ..Alles ok, weitermachen
else if Res = -1
       ..
else if Res = -2
       ..
else if Res = -3
       ..
else
       ..
end;

WriteRec dagegen, löst einen Systemfehler aus, wenn das Schreiben nicht möglich ist. Diesen Systemfehler kann man mit try und except abfangen.

try
       WriteRec(MYTABLE, 380);
except
       Message("Fehler " + Str(Error.Number) + " beim Schreiben des Datensatzes: " + Error.Message)
end;

Nach der alten Methode würde man folgendes schreiben:

vardef Res: Integer;
.EC 1
Res := WriteRec(MYTABLE, 380);
if Res <= 0
       Message("Fehler " + Str($Fehler) + " beim Schreiben des Datensatzes: ");
else
       .. Alles ok, weitermachen                
end;
.EC 0