Avatar billede kjeld_klit Nybegynder
26. maj 2006 - 11:44 Der er 21 kommentarer

Stoppe kodeafvikling

Problemet:
Der er opstået en kørselsfejl og fejlen fanges i en On Erro GoTo xx
---
Exit sub
xx:
Call Fejlbehandling
end sub
---
I Fejlbehandling vises en msg med fejlen, og hvor osv. og mulighed for at sende en e-mail.

Problemet er at koden så kører videre når msg lukkes, jeg tror selv det er fordi fejlen opstår inde i flere på hinanden procedure kald, så det kun er det procedure kald der fejler der afbrydes, men er ikke sikker.

Kan jeg stoppe al videre kodeafvikling når fejl-msg lukkes?
Det eneste jeg kan komme på er End men det lukker jo også formen ned.

Mvh/Kjeld
Avatar billede Slettet bruger
27. maj 2006 - 22:25 #1
Har du prøvet med Stop istedet for End ?

End stopper brutalt al kodeudførsel uden at lukke pænt ned efter sig.
Stop suspenderer kodeudførselen på samme måde som et breakpoint.
Avatar billede kabbak Professor
30. maj 2006 - 09:26 #2
---
Exit sub
xx:
Call Fejlbehandling
Exit sub
end sub
Avatar billede kjeld_klit Nybegynder
30. maj 2006 - 15:09 #3
blackadder: Ja, men det er ikke velegnet til det, det stopper koden hvor Stop er og åbner kodevinduet - ikke rigtig noget bruger kan forholde sig til. Så hellere et End.

kabbak: Det er ikke i Fejlbehandling() kørslen evt. går galt, men fx i 3. niveau af procedure der kaldes af hinanden. Problemet med at håndtere fejl på denne måde (hvis det er et problem ;-) er jo at fejlen så bliver behandlet og derefter kører koden færdig i niveau 2 og til sidst nivaue 1 som bruger har sat i gang måske med klik på en knap.

Jeg talte med en programør der sagde noget om at man i Fejlbehandling skal generere en ny fejl som betyder at koden sendes til Fejlbehandling igen i niveau 2 og igen i niveau 1. På den måde kan man kontrollere at koden kører til ende uden at udføre noget - det bliver nok for langhåret for mig.

Så det jeg har gjort er i Fejlbehandling til sidst at lave forskellige indstillinger og afslutte så godt det er muligt og så et End til sidst så det ikke bare siger "pluf" og det hele ligger på gulvet.
Avatar billede kabbak Professor
30. maj 2006 - 22:14 #4
Her er et forslag, nu har jeg ikke lavet det i en Userform, men prinsippet er det samme.

Der er den devideringsfejl i makro2, så kan du teste i en modul i excel.

Option Explicit
Dim Fejl As Boolean, Sted As String

Public Sub Kør_makroer()
    Fejl = False
    Sted = "Makro1"
    Call Makro1
    If Fejl Then Exit Sub
    Sted = "Makro2"
    Call Makro2
    If Fejl Then Exit Sub
    ' sådan kan du gøre imellem de forskellige makrokald
    'Sted = "Makro3"
    'call Makro3
    'If Fejl Then Exit Sub
    ' o.s.v
   
    Sted = ""
End Sub

Public Sub Makro1()
Dim A As Integer
    On Error GoTo xx
    A = 10 / 0
    ' noget kode
    Exit Sub
xx:
    Call Fejlbehandling
End Sub

Public Sub Makro2()
    On Error GoTo xx
    ' noget kode
    Exit Sub
xx:
    Call Fejlbehandling
End Sub

Public Sub Fejlbehandling()
    MsgBox " der skete en fejl i makroen " & Sted & " , programmet stopper"
    Fejl = True
End Sub
Avatar billede kjeld_klit Nybegynder
04. juni 2006 - 12:59 #5
Ja, men det er det samme som det jeg siger (så vidt jeg kan se) - der sker en kørselsfejl et eller andet sted, fejlen fejbehandles, og kørslen sendes tilbage til at fortsætte i proceduren efter det kald til procedure der skabte fejlen.

Det er der "problemet" opstår - at kunne stoppe al videre kodeafvikling i fejlbehandling.

(Jeg ved både hvilken procedure der fejler og i hvilken linie det går galt. Det er disse informationer jeg bruger i fejlbehandling.)
Avatar billede bak Forsker
04. juni 2006 - 18:56 #6
I VBA fungerer fejlbehandling således at hvis en undersub ikke har en fejlfanger, ryger fejlen videre op til næste niveau.
Hvis man tænker sig at du får en fejl på niveau 3, og du har en fejlfanger her, vil den stoppe kodeafvikling på dette niveau.
Det betyder at du skal have fejlfangeren på det niveau du vil stoppe på.
Avatar billede bak Forsker
04. juni 2006 - 19:05 #7
Eksempel:

Her er userform koden

Private Sub CommandButton1_Click()
    On Error GoTo fiel
    Call test1
    msgbox "Ingen fejl overhovedet"
    Exit Sub
fiel:
    MsgBox "stop fejl :" & Err.Number
End Sub


Her er så to "undersubs"

Sub test1()
    Call test2
    MsgBox "ingen fejl i test1"
End Sub


Sub test2()
    s = 7 / 0
    MsgBox "Ingen fejl i test2"
End Sub
Avatar billede bak Forsker
04. juni 2006 - 19:21 #8
Hvis du ændrer koden i userformen og fanger alle fejl der, kan du gøre således.
Bemærk at fejlkoderne skal du have fundet først :-)
Userformen lukker ikke ned

Private Sub CommandButton1_Click()
    On Error GoTo fiel
    Call test1
    MsgBox "Ingen fejl overhovedet"
    Exit Sub
fiel:
    Select Case Err.Number
        Case 7: MsgBox "Ikke mere hukommelse"
        Case 11:  MsgBox "STOP. Division med nul"
        Case 13:  MsgBox "VBA Typefejl"
        Case Else:
    End Select
End Sub
Avatar billede kjeld_klit Nybegynder
04. juni 2006 - 19:36 #9
Bak:
Jeg har en 'fejlfanger' i alle procedurer, men fælles for dem alle er at de sender (efter at have indsamlet info vedr. fejlen) videre til min:
Private Sub Fejlbehandling()

Det som sker i niveau 3 er at fejlen bliver fanget, sendt ned til labels Niveau3_Error: Her sendes den videre med fejloplysningerne til Fejlbehandling

Når Fejlbehandling er færdig vil koden køre Niveau2 færdig og også køre Niveau1 færdig.

Er det fordi fejlbehandlingen foregår udenfor sub'en at den vender tilbage til de foregående niveauer?
Eller på en anden måde. Vil koden stoppe hvis fejlbehandlingen foregår indenfor samme sub? - Det ville jeg dog være ked af da det er uoverskuligt at rette til. Jeg har 500 procedurer
Avatar billede kjeld_klit Nybegynder
04. juni 2006 - 19:37 #10
Bak:
Så ikke dit sidste svar
Hvad er det du viser til sidst?
Avatar billede bak Forsker
04. juni 2006 - 19:45 #11
Det sidste er at fejlfangeren for alle subs er samlet i den sub hvor de startes, altså øverste niveau.

Hvis der er fejlfangere på de nedre niveauer ex niv. 3 vil niveau 2 fortsætte sin kode når fejlfangeren på niv 3 er færdig.
I min model med kun en central fejlfanger på øverste niv. stopper koden øjeblikkelig og går dertil.
Avatar billede kjeld_klit Nybegynder
04. juni 2006 - 20:05 #12
Nu siger du noget der ligner det den flinke mand jeg har omtalt tidligere sagde, men jeg ved ikke på hvilket niveau koden sendes afsted. De forskellige procedurer kan nås fra flere andre procedurer, eller bruger handlinger, og der kan på denne måde opstå flere niveauer afhængig af hvor meget data skal behandles.

Jeg tror ikke jeg tør "fritage" forskellige "underprocedurer" for fejlbehandling - men det er vist heller ikke det du mener ;-)
Avatar billede bak Forsker
04. juni 2006 - 20:15 #13
Vis mig lige en af fejlfangerne i de enkelte sub, samt den centrale.
Avatar billede kjeld_klit Nybegynder
04. juni 2006 - 20:34 #14
On Error GoTo 0
  Exit Sub
UserForm_Initialize_Error:
Dim Fejl As String
    Fejl = "UserForm_Initialize of Form"
    Call Fejlbehandling(Fejl)
End Sub

*******************
Private Sub Fejlbehandling(Fejlbesked As String)
    Dim errSv As String
    errSv = MsgBox("Ups - der skete en fejl.  Procedure er stoppet.  " & vbLf _
                & vbLf _
                & "Tekniske oplysninger:" & vbLf _
                & "  " & Fejlbesked & vbLf _
                & "  Line " & Erl & vbLf _
                & "  Err " & Err.Number & vbLf _
                & "  Error " & Err.Description & "    " & vbLf _
                & vbLf _
                & vbLf & "Du kan hjælpe med fejlrettelser ved at sende en e-mail til kks@ishoejby.dk med fejlen.      " _
                & vbLf & vbLf & "Vil du sende fejlbeskeden?", vbCritical + vbYesNo + vbDefaultButton1, "Fejl")
      If errSv = vbYes Then

KLIP

      MsgBox "Fejlen har medført at programmet af sikkerhedsgrunde afbrydes, og vender tilbage til Excel.                " & vbLf _
            & vbLf _
            & "Du skal starte programmet igen for at det kan afsluttes korrekt.", vbExclamation, "Procedurefejl"

KLIP

Her afslutter jeg programmet så godt jeg kan og klargører Excel med det rigtige faneblad

    End
End Sub
Avatar billede kjeld_klit Nybegynder
04. juni 2006 - 20:42 #15
On Error GoTo 0
...er lidt kortfattet:

Private Sub UserForm_Initialize()
  On Error GoTo UserForm_Initialize_Error
KLIP

alle linier er nummereret

Her er så

  On Error GoTo 0
  Exit Sub
UserForm_Initialize_Error:
Dim Fejl As String
    Fejl = "UserForm_Initialize of Form"
    Call Fejlbehandling(Fejl)
End Sub
Avatar billede bak Forsker
04. juni 2006 - 21:00 #16
ok, giv mig lige lidt tid til at tænke (og se film) :-)

Det burde relativ nemt kunne løses.
Avatar billede bak Forsker
06. juni 2006 - 09:13 #17
Når du nu har så mange subs, er det nok smartest hvis fejlfangeren tager sig af det hele.
Prøv at teste denne metode, hvor fejlen behandles i første gennemløb og der derefter sætter en brugerdefineret fejlkode, som gør at der intet sker i de næste gennemløb.

'Denne konstant skal med, Behøver ikke være 1200
Const FAKEERROR# = 1200

Private Sub Fejlbehandling(Fejlbesked As String)
  Dim errSv As String
  'Check om det er første gangs fejl
  If Err.Number <> FAKEERROR# Then

      errSv = MsgBox("Ups - der skete en fejl.  Procedure er stoppet.  " & vbLf _
            & vbLf _
            & "Tekniske oplysninger:" & vbLf _
            & "  " & Fejlbesked & vbLf _
            & "  Line " & Erl & vbLf _
            & "  Err " & Err.Number & vbLf _
            & "  Error " & Err.Description & "    " & vbLf _
            & vbLf _
            & vbLf & "Du kan hjælpe med fejlrettelser ved at sende en e-mail til kks@ishoejby.dk med fejlen.      " _
            & vbLf & vbLf & "Vil du sende fejlbeskeden?", vbCritical + vbYesNo + vbDefaultButton1, "Fejl")
      If errSv = vbYes Then

        'KLIP

        MsgBox "Fejlen har medført at programmet af sikkerhedsgrunde afbrydes, og vender tilbage til Excel.                " & vbLf _
              & vbLf _
              & "Du skal starte programmet igen for at det kan afsluttes korrekt.", vbExclamation, "Procedurefejl"

        'KLIP

        'Her afslutter jeg programmet så godt jeg kan og klargører Excel med det rigtige faneblad


      End If
      'sæt ny falsk fejl, der får den til at hoppe direkte gennem sub'en næste gang
      Err.Raise FAKEERROR#
  End Sub
Avatar billede kjeld_klit Nybegynder
06. juni 2006 - 16:42 #18
Det ser interessandt ud, men der sker en fejl i 2. gennemløb. Debug kommer op med følgende:

----------------------
Run-time error '1200':

Could not set the Width property. Invalid property value.  Enter a value greater than or equal to zero.
----------------------
(Den sidste bemærkning er fejlen som jeg har genereret for at prøve koden.)

1. gennemløb ser rigtig ud.
If Err.Number <> FAKEERROR# Then (=True) Koden gør det den skal og hopper tilbage i sub og går igen ned i "fejlfanger" hvor den sendes til Fejlbehandling for 2. gang.

2. gennemløb er If Err.Number <> FAKEERROR# Then (=False) og koden hopper ned til Err.Raise FAKEERROR# hvilket jo er rigtig nok, men den kommer altså med denne Run-time error og går i stå på linien: Err.Raise FAKEERROR#
Avatar billede bak Forsker
06. juni 2006 - 22:18 #19
Øverste Sub (den i commandbutton_click) skal have en anden fejlfanger

prøv at se dette eksempel

http://www.tbdl.dk/excel/Fejlfanger1.xls
Avatar billede kjeld_klit Nybegynder
07. juni 2006 - 16:15 #20
Jeg tror nok jeg kan se ideen i det ;-) og dit eksempel forløber jo fuldstændig som det jeg spørger om - husk lige et svar!

Jeg har dog et problem i at skulle afgøre hvad der er "Niveau1".

Hvis jeg ændre 'fejlfangeren' alle de steder hvor der kan være et direkte bruger input / hændelse, hvad sker der så hvis den procedure bliver kaldt automatisk?

Jeg bør måske ændre måden bruger kalder en procedure til:
Private Sub CommandButton1_Click()
    On Error GoTo fejl
    Call DeleProcedure_Bruger_og_VBAkode
    Exit Sub
fejl:
  If Err.Number <> lFAKE_ERROR Then Call Fejlfanger
End Sub

Dermed bliver DeleProcedure_Bruger_og_VBAkode aldrig niveau1 - ville det være fornuftigt?
Avatar billede kjeld_klit Nybegynder
14. juni 2006 - 17:28 #21
Hej bak - Du skal ha' dine points! :-)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi har et stort udvalg af Excel kurser. Find lige det kursus der passer dig lige her.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester