Just nu i M3-nätverket
Gå till innehåll

Error handler


Dami

Rekommendera Poster

Hej!

 

Jag kör en del makron i Excel som körs "ontime" var 10 minut.

 

Det dom gör är egentligen att går igenom vissa rader i en excelbok och summerar datan i ett excelblad i en annan bok.

Det som händer (väldigt sällan skall tilläggas men ändock) är att om man matar in siffor i källboken, samtidigt som målboken kör ontime makrot så genererar det ett fel..

Det man skulle vilja göra är ju eftersom makrot rullar var 10:e minut, så om ett fel uppstår så bör makrot stängas direkt (end sub). utan felmeddelande. makrot kommer ju ändå att rullla igång igen 10 minuter senare..

 

Sen ett annat scenario. samma böcker hämtar även information från en delad arbetsbok genom "dataanslutning" detta är satt att uppdateras var 10 minut. Även här finns en risk att om man är igång att spara i den delade arbetsboken samtidigt som dataanslutningen försöker hämta data så blir det ett fel.

Kan man istället då lägga in en ontime funktion till att "thisworkbook.refreshall" och på något sätt även här köra en felhanterare som "vid fel, end sub". Här är mer frågon om det skulle fungera så?

Länk till kommentar
Dela på andra webbplatser

Visst går det! Gäller bara att tänka till lite. Excel har några Error-argument.

 

On Error Resume Next

Kör vidare som om inget hänt om något går fel på en rad.

On Error Goto #

Går till given rad och kör koden där.

On Error Goto 0

Nollställer felhanteringen.

 

Du skulle exempelvis kunna skriva

Sub MySub()
  On Error Goto errHandle
' massa kod som kan ge fel/anrop till din funktion som kan ge fel
Exit Sub
errHandle:
  'gör något vettigt
  'eventuellt Resume Next för att hoppa tillbaka efter du rättat felet
End Sub

 

Det går även att i felhanteraren kolla vad som gått fel via funktionen err

Sådär, nu har du lite att göra.

Länk till kommentar
Dela på andra webbplatser

Okej, så eftersom jag vill hålla det enkelt i mitt format så vore det bästa att göra något likt

 

Sub[/color] [color=#660066]MySub[/color][color=#666600]()[/color] 

[color=#660066]On[/color] [color=#660066]Error[/color] [color=#660066]Goto[/color] errHandle

 

thisworkbook.refreshall

[color=#008800]

Exit Sub

errHandle:

 

Exit sub [/color]

[color=#008800]

[color=#008800][/color]End Sub[/color] [[color=#660066]/code]

 

[/color][color=#000000]Så egentligen fungerar det med "Exit sub" under errHandle?[/color]

Länk till kommentar
Dela på andra webbplatser

Exit sub hoppar ut ur subrutinen direkt.

 

Om du skriver

 

Sub Test
...
..

Exit Sub
errHandle:

Exit Sub
End Sub

så fyller den andra Exit Sub ingen funktion eller subrutinen tar slut på nästa rad ändå.

 

Man måste inte lägga en Exit Sub innan errHandle, ibland vill man att koden i errHandle ska köras oavsett vad som hänt i koden ovan.

Exempelvis om man stängt av automatiska beräkningarna eller liknande, det vill återställa.

Länk till kommentar
Dela på andra webbplatser

DVS att om jag vill ha en kod som direkt vid ett fel "stänger/avslutar" rutinen så jag slipper ett felmedelande.

Bör se ut såhär

 

[color="#660066"]Sub[/color] MySub() 
On Error Goto errHandle 

thisworkbook.refreshall

Exit Sub 
errHandle: 

End Sub 

Länk till kommentar
Dela på andra webbplatser

ja, det fungerar.

 

Fast ska sägas, är det QueryTables som körs som hämtar externa data kan dessa köras i bakgrunden i en helt egen tråd. Om dessa går fel fångas de inte upp i denna rutin.

Länk till kommentar
Dela på andra webbplatser

Nja, det går inte att blockera detta felmeddelande

post-8996-0-89383400-1298445613_thumb.png

 

men man kan skapa en klass som använder en QueryTable som bas, kan hantera dess händelser och via denna hantera det fel som uppstår.

Precis som att koden på ett arbetsblad är med bladets händelser kan man skapa en klass som är med QueryTables händelser. Man kan skapa liknande klasser för alla objekt som finns i VBA i princip, går att göra en del ganska trevliga saker.

 

 

Alltså

1: Skapa en ny klass i VBA-editorn.

2: I klassen, skriv in raden

Public WithEvents qtQueryTable As QueryTable

på en av de första raderna.

3: Om du undersöker dropdownen ovan nu ser du att det kommit till ett nytt objekt i denna, qtQueryTable, som har två händelser

Private Sub qtQueryTable_AfterRefresh(ByVal Success As Boolean)

och

Private Sub qtQueryTable_BeforeRefresh(Cancel As Boolean)

 

4: Med AfterRefresh kan man fånga när det går fel i viss mån. Dock, som sagt, fel kan inte, vad jag vet, helt undertryckas men du kan hantera dem om det behövs.

 

Kanske det går bättre om man väljer att inte köra frågorna i bakgrunden men det har andra nackdelar som du säkert är medveten om.

Länk till kommentar
Dela på andra webbplatser

  • 2 veckor senare...

Hmm, har testat så smått, haft lite annat att göra så inte kunnat lägga tid på just detta.

 

Tror jag blev bortsnurrad någonstans kring.

 

1: Skapa en ny klass i VBA-editorn.

2: I klassen, skriv in raden

Public WithEvents qtQueryTable As QueryTable

på en av de första raderna.

3: Om du undersöker dropdownen ovan nu ser du att det kommit till ett nytt objekt i denna, qtQueryTable, som har två händelser

Private Sub qtQueryTable_AfterRefresh(ByVal Success As Boolean)

och

Private Sub qtQueryTable_BeforeRefresh(Cancel As Boolean)

 

4: Med AfterRefresh kan man fånga när det går fel i viss mån. Dock, som sagt, fel kan inte, vad jag vet, helt undertryckas men du kan hantera dem om det behövs.

 

:rolleyes:

Var inte riktigt med på vad som menas med "klassen" och dropdownen. Testade skapa en "klassmodul" och en vanlig modul, fick änd inte fram dropdownen som nämns :o

 

Tack iaf.

Länk till kommentar
Dela på andra webbplatser

Hmm, med "felet går ej att undertrycka helt" menar du att om man skulle lägga till i din kod ett

 

Sub update()
on error goto ErrH
   myQt.qtQueryTable.Refresh True
ErrH:
End Sub

 

skulle det ändå inte hjälpa ifall problemet uppstår. Alltså att "felmedelandet visas".

 

Alltså att man kan inte påverka själva "uppdateringsfunktionen"

Länk till kommentar
Dela på andra webbplatser

Om du skriver

Sub update()
On Error GoTo errHandle
myQt.qtQueryTable.Refresh False
Exit Sub
errHandle:
Debug.Print "failure"
End Sub

då kommer du till felhanteraren.

Dvs om du kör webbfrågan i bakgrunden kan du inte fånga felet, men om du kör den i samma tråd kan du fånga det.

 

Med andra ord, jag har varit lite fel ut ovan. Det går utmärkt att fånga fel vid webbfrågor så länge de inte körs i bakgrunden.

Länk till kommentar
Dela på andra webbplatser

Tror icke det. VBA har visserligen utvecklats lite mellan versionerna men det är mest att nya objekt har kommit till, inte att det som finns har ändrats.

Länk till kommentar
Dela på andra webbplatser

Lustigt, skrev om makrot och det fungerade i "webfråga". Men när jag testar det i min fil så får jag ett felmedelande (körfel nr 9. Indexet är utanför intervall)

 

 

Sub Update2()
   Set myQt = New clQt
   Set myQt.qtQueryTable = Me.QueryTables("Tabell_Fråga_från_Excel_Files_1")

      On Error GoTo errHandle
       myQt.qtQueryTable.Refresh False
Exit Sub
errHandle:
       Debug.Print "failure"
End Sub

 

 

Länk till kommentar
Dela på andra webbplatser

korrekt namn på din QueryTable?

 

Samt kanske att du egentligen inte behöves klassen jag skapade då det ju faktiskt går att fånga felet när frågan inte körs i bakgrunden.

Länk till kommentar
Dela på andra webbplatser

Vilket skulle leda till följande..

 

Sub Update2()

Se

Set myQt = Me.QueryTables("Tabell_Fråga_från_Excel_Files_1")

 

On Error GoTo errHandle

myQt.qtQueryTable.Refresh False

Exit Sub

errHandle:

Debug.Print "failure"

End Sub

 

Querytable namn borde va rätt då jag kopierade.

Länk till kommentar
Dela på andra webbplatser

Om du stegar genom koden, var fastnar den? Jag kantar att det är på raden med Set

Sub Update2() 
   Dim myQt As QueryTable
   Set myQt = Me.QueryTables("Tabell_Fråga_från_Excel_Files_1") 
On Error GoTo errHandle 
       myQt.Refresh False 
Exit Sub 
errHandle: 
       Debug.Print "failure" 
End Sub

Så borde det stå...

Länk till kommentar
Dela på andra webbplatser

Stegade igenom det och det är referensraden

"Set myQt = Me.QueryTables("Tabell_Fråga_från_Excel_Files_1")"

Som resulterar i fel...

 

Det tråkiga är att jag har både dubbel och trippelkollat att namnet är korrekt..

Länk till kommentar
Dela på andra webbplatser

Kanske värt att nämna att jag använt under fliken "data"

Från andra källor/från microsoft query. Därefter under "välj datakälla" valt från excel fil.

Länk till kommentar
Dela på andra webbplatser

Hmm, tydligen problematiskt detta. Det verkar som att just excel-excel skapar en konflikt, för fungerar gör det inte :(

 

 

Länk till kommentar
Dela på andra webbplatser

Laddar upp 2 filer. En målfil (webbfråga) och en källfil (test). Där query frågan ställs från webbfråga till test.

 

I anslutningssträngen är "test" i U:\test.xls detta får modifieras efter behov.

Test.xls

WebbFråga(2).xls

Länk till kommentar
Dela på andra webbplatser

Excel 2007 arbetar visst lite annorlunda...

 

Du hittar din fråga under ListObject, dvs

Me.ListObjects("Tabell_Fråga_från_Excel_Files").QueryTable

 

där är den...

Länk till kommentar
Dela på andra webbplatser

Arkiverat

Det här ämnet är nu arkiverat och är stängt för ytterligare svar.

×
×
  • Skapa nytt...