Autor
|
Thema: Programmabbruch VB (777 mal gelesen)
|
Timberwolve Mitglied
Beiträge: 233 Registriert: 21.07.2006
|
erstellt am: 01. Aug. 2006 11:59 <-- editieren / zitieren --> Unities abgeben:
Hallo ich habe ein Problem beim Beenden meines Programms: Es gibt eine Schaltfläche, mit dieser führe ich mein Programm aus. sprich das ganze sieht in CODE so aus : Private Sub cmdStart_Click() Call Subroutine 1 (Dokumentlokalisieren) Call Subroutine 2 (Dokument prüfen) Call Subroutine 3 (Export als igs) End Sub
So ist das ganze vereinfacht. Jetzt habe ich in meiner Subroutine 2 das Problem, wenn ein Abbruchkriterium in Routine 2 erkannt wird soll das komplette Programm abgebrochen werden. Ich komm jedoch nur mit Exit Sub aus der 2ten Routine raus. Routine 3 wird jedoch trotzdem durchgeführt. Gibt es keinen Globalen Befehl oder Methode mit der ich das ganze Programme einfach an ner beliebigen Stelle beenden kann?? Vielen Dank für eure HIlfe ------------------ Wenn alle Stricke reissen, nehm ich ein Drahtseil Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Jules_Vernes Mitglied Systemadmin
Beiträge: 145 Registriert: 04.10.2005 Catia V5R24SP4
|
erstellt am: 01. Aug. 2006 12:12 <-- editieren / zitieren --> Unities abgeben: Nur für Timberwolve
|
Timberwolve Mitglied
Beiträge: 233 Registriert: 21.07.2006
|
erstellt am: 01. Aug. 2006 12:19 <-- editieren / zitieren --> Unities abgeben:
Danke, so einfach kann das Leben manchmal sein ;-) Man sollte nur wissen wie. Musste mir eben an den kopf klatschen. Naja trotzdem danke ------------------ Wenn alle Stricke reissen, nehm ich ein Drahtseil Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
dr Mitglied CAD-/PLM-Entwickler und -Berater
Beiträge: 87 Registriert: 30.10.2001
|
erstellt am: 01. Aug. 2006 12:21 <-- editieren / zitieren --> Unities abgeben: Nur für Timberwolve
Ein Programm an einer beliebigen Stelle zu beenden ist natürlich möglich (wie bereits beschrieben), aber sehr, sehr unschön. Insbesondere wenn das Programm komplexer wird und dann nachträglich doch noch irgendwie anders auf die bisherige Abbruchsituation reagiert werden soll, wird's sehr unübersichtlich. Schlecht ist es beispielsweise auch, wenn Dein Programm irgendwelche Ressourcen verwendet, die nicht automatisch freigegeben werden (beispielsweise kannst Du Dateien öffnen, die VB nicht automatisch beim Programmende schliesst), musst Du die Aufräumarbeiten an jeder Abbruchstelle ausführen. Besser: Mach aus Deinen Subroutinen Funktionen, die einen Fehlercode zurückgeben und frage den Fehlercode immer in den übergeordneten Funktionen bzw. der Main-Routine ab und reagiere dann entsprechend darauf. Andere Entwickler bevorzugen Exceptions anstelle von Fehlercodes - aber das halte ich für unübersichtlicher... ------------------ -- Danny Reinhold Reinhold Software Services Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Timberwolve Mitglied
Beiträge: 233 Registriert: 21.07.2006
|
erstellt am: 01. Aug. 2006 13:40 <-- editieren / zitieren --> Unities abgeben:
mmh naja mit Funktionen und Fehlercodes bin ich leider noch nicht so weit im Programmieren drin. Hab da schon noch meine Defizite ------------------ Wenn alle Stricke reissen, nehm ich ein Drahtseil Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
dr Mitglied CAD-/PLM-Entwickler und -Berater
Beiträge: 87 Registriert: 30.10.2001
|
erstellt am: 01. Aug. 2006 14:21 <-- editieren / zitieren --> Unities abgeben: Nur für Timberwolve
Das kann in Code gegossen grob so aussehen: Code:
Sub CATMain()Dim success As Boolean success = func1(-1, "Hallo Welt!") If Not success Then MsgBox "Oha - func1 hat einen Fehler gemeldet - Abbruch" Else MsgBox "func1 lief durch - also weitermachen..." success = func2 If Not success Then MsgBox "Oha - Fehler in func2!" Else MsgBox "Super - func2 lief auch durch..." End If End If End Sub Function func1(param1 As Integer, param2 As String) As Boolean MsgBox param2 ' Eine Möglichkeit If param1 < 0 Then ' FEHLER func1 = False Else func1 = True End If End Function Function func2() As Boolean
Dim success As Boolean success = func3(1, 2) If success Then ' Aha - func3 hat keinen Fehler geliefert ' Also koennen wir hier noch etwas huebschen machen... End If func2 = success End Function Function func3(v1 As Integer, v2 As Integer) As Boolean Dim success As Boolean success = True ' Hier nehmen wir mal an, dass es ein Fehler sein soll, wenn v1 + v2 > 2 ist If v1 + v2 > 2 Then success = False End If func3 = success End Function
Ist natürlich stark gekünselt und sieht daher ein bissel besch*ert aus. Wenn Du etwas Ähnliches aber probehalber in einem echten Programm machst, wirst Du dich an die immer wiederkehrenden Muster schnell gewöhnen und das ganze als flexibel empfinden...
------------------ -- Danny Reinhold Reinhold Software Services Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Timberwolve Mitglied
Beiträge: 233 Registriert: 21.07.2006
|
erstellt am: 02. Aug. 2006 08:45 <-- editieren / zitieren --> Unities abgeben:
muss ich die Functions immer als Boolean deklarieren??? bzw. wie sieht es mit den Werten aus die ich übergebe? Also ehrlich gesagt bin ich bei deinem Beispiel noch nicht ganz durchgestiegen ;-) ------------------ Wenn alle Stricke reissen, nehm ich ein Drahtseil Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
dr Mitglied CAD-/PLM-Entwickler und -Berater
Beiträge: 87 Registriert: 30.10.2001
|
erstellt am: 02. Aug. 2006 09:18 <-- editieren / zitieren --> Unities abgeben: Nur für Timberwolve
Boolean war nur ein Beispiel. Der Rückgabewert besagt dann einfach 'alles ok' oder 'fehler'. Du kannst auch jeden beliebigen anderen Rückgabetyp nehmen, solange es dabei einen Wert gibt, der einen Fehlerzustand anzeigt. Das Prinzip ist immer: - Du definierst eine Function statt einer Sub. Falls Du normalerweise eine Subroutine geschrieben hättest, gestaltest Du die Function so, dass Sie einen Boolean zurückgibt. Der Rückgabewert True signalisiert dem Aufrufer, dass alles ok ist und ganz normal weitergemacht werden kann. Der Rückgabewert False signalisiert dem Aufrufer, dass in der Function ein Fehler aufgetreten ist. Falls Du ohnehin eine Function geschrieben hättest, gibt es verschiedene Möglichkeiten: Entweder bietet der Rückgabetyp einen Wert, mit dem Du einen Fehler signalisieren kannst oder Du definierst einen zusätzlich Fehlerparameter, den Du als Referenz übergibst. Wenn eine Function beispielsweise GetName() heisst und einen leeren String zurückliefert, ist das sicherlich verdächtig und kann vom Aufrufer als Fehlersituation interpretiert werden. Oder wenn eine Function getQuadratwurzel einen negativen Wert liefert etc... - Beim Aufrufer sieht's dann immer so in der Art aus:
Code:
sub main() dim success as boolean success = machWas() if success then ' Ok, weitermachen dim i as integer i = getQuadratwurzel(sonstwas) if getQuadratwurzel(-1) < 0 then msgbox "getQuadratwurzel() hat einen Fehler gemeldet" else msgbox "Die Quadratwurzel von " & sonstwas & " ist: " & i end if else msgbox "machWas() hat einen Fehler gemeldet" end if end sub
So in der Art eben. Immer wenn ein Fehler auftritt, wird die Funktion dadurch beendet, dass eben nicht der 'if success then' Block durchlaufen wird. Wenn eine Function von einer anderen Function aufgerufen wird, kann der Fehlercode auch einfach 'nach oben' weitergereicht werden. Ist alles viel komplizierter zu erklären und hört sich dadurch etwas wirrer an als es eigentlich ist... Ich hoffe, dass ich Dich jetzt nicht noch zusätzlich verwirrt habe. Probier's einfach mal aus. Schreibe ein paar Functions, die im Fehlerfall einen entsprechenden Code zurückliefern. Versuche auf Konstrukte wie "Exit Sub" etc. innerhalb einer Funktion oder Subroutine zu verzichten. Dann stellt sich mit der Zeit automatisch ein anderer Stil ein. Irgendwann macht's dann einfach 'Klick' und Du siehst ein, warum das sinnvoll ist... (Spätestens wenn Du das erste Mal davon profitierst, dass Du einen Fehler aus einer aufgerufenen Funktion weiter 'oben' behandeln kannst...) ------------------ -- Danny Reinhold Reinhold Software Services Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
93Aero Mitglied Ing
Beiträge: 106 Registriert: 02.12.2004
|
erstellt am: 19. Sep. 2006 11:23 <-- editieren / zitieren --> Unities abgeben: Nur für Timberwolve
Oder einfach mit Exit Sub, z.B. Sub CatMain Dim nValue as Long ' Read this value somwhere If MuxTwo( nValue ) > 2 Exit Sub End If End Sub Function MuxTwo (nArg As Long) As Long MuxTwo = nArg * nArg End Function Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
dr Mitglied CAD-/PLM-Entwickler und -Berater
Beiträge: 87 Registriert: 30.10.2001
|
erstellt am: 19. Sep. 2006 13:51 <-- editieren / zitieren --> Unities abgeben: Nur für Timberwolve
Ein paar Zeilen über Deiner Antwort habe ich geschrieben, dass man "Exit Sub" möglichst vermeiden sollte, um sich einen Programmierstil anzugewöhnen, bei dem es immer nur einen "Exit Point" in einer Funktion oder Routine gibt... Probiert's einfach mal aus. Am Anfang wirken die Programme dann komisch und sind häufig auch etwas länger, aber nach einer Weile hat man sich dran gewöhnt. Und spätestens, wenn dann mal ein Fall kommt, bei dem man am Ende einer Routine irgendwelche Ressourcen aufräumen möchte, freut man sich plötzlich, dass man es nur an einer Stelle zu tun braucht...
------------------ -- Danny Reinhold Reinhold Software Services Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Carasianer Mitglied Elektroniker
Beiträge: 12 Registriert: 21.09.2006
|
erstellt am: 04. Dez. 2006 12:40 <-- editieren / zitieren --> Unities abgeben: Nur für Timberwolve
Ich möchte ein Makro mit 1 Befehl an beliebiger Stelle sofortig beenden. Wenn das Makro gerade in der CatMain läuft, ist das klar: exit sub. Wenn das Makro allerdings in Unter-Prozeduren steht, nützt dieser Befehl nicht viel, da ich ja dann nur 1 Ebene höher lande. Der hier im Forum z.T. vorgeschlagene END-Befehl funktioniert zwar im VB, aber irgendwie nicht bei CATIA-Makros (warum eigentlich?): da bekomme ich immer nur die Fehlermeldung "IF erwartet". Die STOP-Anweisung funktioniert unter CATIA ebensowenig. Codebeispiel: Code:
Sub CATMain() 'In CATMain möchte ich keine Codeänderungen machen!! while 2>1 'das läuft ewig... UnterProgramm wend End Sub Sub UnterProgramm() 'Irgendwann möchte ich das Makro hier abbrechen. Nur wie? End Sub
PS: Dass so eine Art der Programmbeendung programm-stilistisch nicht gut ist, weiß ich. Ich brauche das vor allem zum Verlassen von Endlosschleifen während des Debuggens. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |