My macro generates yahoo ticker download URL's for specific companies. I generate 3 URL's per ticker, each having a different date segment for the data download.
The problem that I have, is that data does not exist for some of the dates, hence an error is returned from Yahoo which causes my Macro to crash.
I've attempted the following with a GOTO label:-
On Error GoTo error_handler
Workbooks.Open Filename:=("http://chart.finance.yahoo.com/table.csv?s=FAN.L&a=2&b=04&c=2014&d=2&e=21&f=2014&g=d&ignore=.csv")
however this does not work, it does not GOTO the label.
Any ideas would be greatly appreciated.
Try this:
On Error Resume Next
Workbooks.Open Filename:=("http://chart.finance.yahoo.com/table.csv?s=FAN.L&a=2&b=04&c=2014&d=2&e=21&f=2014&g=d&ignore=.csv")
On Error GoTo error_handler
The On Error Resume Next will allow it to the skip ahead.
Download the file with seperate error handling and then if-check
If Dir(MyFileName) <> "" Then
Workbooks.Open Filename:="C:\123.xls"
Else
MsgBox "Spreadsheet could not be found in C:\", vbCritical + vbOKOnly, "File not found"
End If
Here is some example of error handling. Replace your code with the Debug.print 5/0 and it should work.
Public Sub ErrorHandlingExample()
On Error GoTo ErrorHandlingExample_Error
Debug.Print 5 / 0
On Error GoTo 0
Debug.Print "No error"
Exit Sub
ErrorHandlingExample_Error:
Debug.Print "Error was found - " & Err.Description
End Sub
Related
I have an issue with the error handling in VBA.
The code has previously worked, but now suddenly errors are not handled by On Error GoTo statements and instead the code is crashing and giving a pop up with the error message as if On Error GoTo 0 would be active.
Here is an example of how the code structure is:
On Error GoTo logError
For d = 0 To Doclist.Count -1
On Error GoTo DownloadFailed
session.findById("wnd[0]/tbar[1]/btn[30]").press
session.findById("wnd[1]/usr/sub:SAPLSPO4:0300/ctxtSVALD-VALUE[0,21]").Text = filepath
On Error GoTo logError
...
DownloadFailed:
Err.Clear
On Error GoTo logError
Next d
logError:
ws1.Cells(1, 7).Value = Err.Description
Workbooks("Main.xlsm").Save
In the first iteration the On Error GoTo DownloadFailed is working as expected, but after this the code is crashing.
The error that I am getting is Run-time error '619'.
I saw on some similar post to clear the error with Err.Clear but this did nothing to my code.
In another part of the code I am using On Error Resume Next which at the same time stopped working.
As mentioned the code has worked previously so I have no idea what could be wrong.
Does anybody have experience with similar issues and any possible solutions for this?
Error Handling
The GoTo keyword is kind of reserved for the error-handling routine so this solution is strict about that.
Some contributors argue though that it is OK to use the GoTo keyword to skip a code block in a loop but I don't think it refers to doing it with On Error.
Sub ErrorTest()
Dim LogErrorFound As Boolean
Dim ErrNum As Long
On Error GoTo LogError ' start error-handling routine
For d = 0 To Doclist.Count - 1
On Error Resume Next ' defer error trapping
session.findById("wnd[0]/tbar[1]/btn[30]").press
ErrNum = Err.Number
If ErrNum = 0 Then
session.findById("wnd[1]/usr/sub:SAPLSPO4:0300/ctxtSVALD-VALUE[0,21]").Text = filepath
ErrNum = Err.Number
End If
On Error GoTo LogError ' resume error-handling routine; clears error
If ErrNum = 0 Then
'...
'Else ' download failed i.e. 'ErrNum <> 0'; do nothing!?
End If
Next d
ProcExit:
If LogErrorFound Then
On Error Resume Next ' defer error trapping; avoid endless loop
ws1.Cells(1, 7).Value = Err.Description
Workbooks("Main.xlsm").Save
On Error GoTo 0 ' stop error trapping
MsgBox "A log error occurred.", vbCritical
Else
MsgBox "Finished successfully.", vbInformation
End If
Exit Sub
LogError: ' continuation of the error-handling routine
LogErrorFound = True
Resume ProcExit
End Sub
While Err.Clear does clear the error object, it does not re-enable error handling like Resume or On Error GoTo 0. In order to manually do this, replace Err.Clear with On Error GoTo -1 like this:
On Error GoTo logError
For d = 0 To Doclist.Count -1
On Error GoTo DownloadFailed
session.findById("wnd[0]/tbar[1]/btn[30]").press
session.findById("wnd[1]/usr/sub:SAPLSPO4:0300/ctxtSVALD-VALUE[0,21]").Text = filepath
On Error GoTo logError
...
DownloadFailed:
On Error GoTo -1
On Error GoTo logError
Next d
logError:
ws1.Cells(1, 7).Value = Err.Description
Workbooks("Main.xlsm").Save
I'm trying to implement an error handler into my code, I've managed to create a message box if a run time error occurs but after clearing the message box the run time error box pops up. This is a snippet of my code:
combinedFilename = Application.GetOpenFilename(filter, , caption)
If combinedFilename <> "False" Then
Set combinedWorkbook = Application.Workbooks.Open(combinedFilename)
Else
MsgBox "No file was uploaded", vbExclamation
End If
Any help will be appreciated.
Many thanks
Write Err.Clear after the MsgBox.
If clears the Error. See this small sample:
Public Sub TestMe()
On Error Resume Next
Debug.Print 5 / 0 '11, because this is the number of the error.
Debug.Print Err.Number
Err.Clear
Debug.Print Err.Number '0, because the error is cleared.
End Sub
I am trying to get multiple on error statements to work and can't figure it out.
If pdf can be found in local then open, if not then open network location. If there is no PDF in then return msgbox.
Sub Cutsheets()
Application.ScreenUpdating = False
Dim finalrow As Integer
finalrow = Cells(Rows.Count, 1).End(xlUp).Row
On Error GoTo net1
If Not Application.Intersect(ActiveCell, Range("A9:A" & finalrow)) Is Nothing Then
'Local Location
ActiveWorkbook.FollowHyperlink "C:\Local" & ActiveCell & ".pdf"
Application.SendKeys "{ENTER}", True
End If
Exit Sub
net1:
If Not Application.Intersect(ActiveCell, Range("A9:A" & finalrow)) Is Nothing Then
'Network Location
On Error GoTo whoa
ActiveWorkbook.FollowHyperlink "P:\Network" & ActiveCell & ".pdf"
Application.SendKeys "{ENTER}", True
End If
Exit Sub
whoa:
MsgBox ("No cutsheet can be found for this item.")
Application.ScreenUpdating = True
End Sub
Also I don't remember why I put sendkeys in there but it doesn't work without it.
Using multiple On Error Goto XYZ handlers for control flow is over-complicating some easy validation checks you can do and then simply use the error handling for actual errors.
As #Rory pointed out in a comment you can use the Dir function. You can combine the use of Dir with an If...ElseIf...Else...End If construct to control what you code does:
Option Explicit
Sub Cutsheets()
On Error GoTo ErrHandler
Dim strLocalCheck As String
Dim strNetworkCheck As String
'check for files - Dir will return "" if file not found
strLocalCheck = Dir("C:\Local" & ActiveCell.Value & ".pdf")
strNetworkCheck = Dir("P:\Network" & ActiveCell.Value & ".pdf")
'control flow
If strLocalCheck <> "" Then
ActiveWorkbook.FollowHyperlink strLocalCheck
Application.SendKeys "{ENTER}", True
ElseIf strNetworkCheck <> "" Then
ActiveWorkbook.FollowHyperlink strNetworkCheck
Application.SendKeys "{ENTER}", True
Else
MsgBox "No cutsheet can be found for this item."
End If
Exit Sub
ErrHandler:
Debug.Print "A real error occurred: " & Err.Description
End Sub
I am trying to get multiple on error statements to work
Don't.
Imagine you're the VBA runtime. You're executing a procedure called Cutsheets, and you come across this instruction:
On Error GoTo net1
From that point on, before you blow up in the user's face, you're going to jump to the net1 label if you ever encounter a run-time error. So you keep running instructions. Eventually you run this line:
ActiveWorkbook.FollowHyperlink "C:\Local" & ActiveCell & ".pdf"
And when the FollowHyperlink method responds with "uh nope, can't do that" and raises a run-time error, your execution context changes.
You're in "error handling" mode.
So you jump to the net1 label. You're in "error handling" mode. There are certain things you can do in "normal execution mode" that you can't (or shouldn't) do in "error handling mode". Raising and handling more errors is one of these things.
On Error GoTo whoa
You're already handling a run-time error: what should you do when you encounter that statement in an error handler subroutine? Jump to the whoa right away?
When the VBA runtime is in "error handling mode", your job as a programmer is to handle runtime errors and do everything you can to get back to "normal execution mode" as soon as possible - and that's normally done with a Resume instruction, or by leaving the current scope.
Copying a chunk of code from the "normal execution path" and trying to run it (slightly altered) in "error handling mode" isn't handling errors and getting back to normal execution mode as soon as possible.
Error handling or not, copy-pasting chunks of code is poorly written code anyway.
Extract a procedure instead:
Private Sub OpenPortableDocumentFile(ByVal path As String)
On Error GoTo ErrHandler
ActiveWorkbook.FollowHyperlink path
Application.SendKeys "{ENTER}", True
Exit Sub
ErrHandler:
MsgBox "Could not open file '" & path & "'."
End Sub
Now that that's out of the way, clean up your control flow by verifying if the file exists before you pass an invalid path to the OpenPortableDocumentFile procedure.
The best error handling strategy is to avoid raising run-time errors in the first place.
The following macro I am trying to use to move files in one location to another from an excel spreadsheet. The copy and pastes are used to copy the formula driven "source location" and "destination location" to new columns, to be used in the macro.
I keep getting the error? What is not right right with my approach?
Sub Combine()
Paste_Values
Paste_Values_Two
Copy_Files
End Sub
Sub Paste_Values()
Range("C2:C1000").Copy
Range("E2").PasteSpecial (xlPasteValues)
End Sub
Sub Paste_Values_Two()
Range("D2:D1000").Copy
Range("F2").PasteSpecial (xlPasteValues)
End Sub
Sub Copy_Files()
On Error GoTo ErrorHandler
Dim cell As Range
For Each cell In Range("E2", Range("E" & Rows.Count).End(xlUp))
FileCopy Source:=cell.Value, Destination:=cell.Offset(, 1).Value
Next cell
Exit Sub
ErrorHandler:
MsgBox "NOT WORKING"
End Sub
Many thanks
Since you do not provide any information at the error handling you do not know what exactly happens. However the only function which seems to be able to give an error is FileCopy:
If you try to use the FileCopy statement on a currently open file, an error occurs.
To show the error you can:
Disable the error handling (On Error GoTo ErrorHandler). This gave me the error: "Run-time error '53': File not found", but is not really user friendly since it stops the script.
You probably want something more informative, and handle this situation (by giving a message, and continuing to the following item). A more informative error message can be:
Msg = "Error # " & Str(Err.Number) & ": " & Err.Description
MsgBox Msg, , "Error", Err.HelpFile, Err.HelpContext
You might want to change the error handling to:
ErrorHandler:
If Err.Number <> 0 Then
Msg = "Error # " & Str(Err.Number) & ": " & Err.Description
MsgBox Msg, , "Error", Err.HelpFile, Err.HelpContext
End If
Resume Next
With Resume Next the For Each loop is continued.
Edit 1: If you get the error, are you sure that your files exist? You mentioned in your comments you have files like: Z:\1. Pro\XYZ\08_Decision_Tracker\5. M\1006\Mel.docx, are you completely sure the path is correct, do all the (sub)directories exist? And do you have write permission to Z:?
This question already has answers here:
Why VBA goes to error handling code when there is no error?
(5 answers)
Closed last year.
I have my code below, the strange thing is that the Errorhandler procedure is still executing even though there are no errors in the code... What can be the issue?
Running the code without any errorhandlers generates no errors, but still the msgbox under Errorhandler shows up when I include an error handling statement!
Code
Public Sub ExportGraphs(Optional PivotExport As Boolean)
' Exports only graphs on the "Mainwindow" sheet to a new worksheet
Dim wsh As Worksheet: Set wsh = Sheets.Add
Dim source_sht As Worksheet: Set source_sht = Sheets("Mainwindow")
ActiveWindow.Zoom = 70
On Error GoTo Errorhandler
With wsh
If source_sht.OLEObjects("Btn_CurrentTime").Object.Value = True Then
.Name = source_sht.OLEObjects("CombBox_Instruments").Object.Value & " " & source_sht.OLEObjects("DTPicker_FROM").Object.Value _
& "-" & source_sht.OLEObjects("DTPicker_TO").Object.Value
Else
.Name = source_sht.OLEObjects("CombBox_Instruments").Object.Value & " " & "Max_Possible_To" _
& "-" & source_sht.OLEObjects("DTPicker_TO").Object.Value
End If
End With
Dim source_chart As ChartObject
Dim target_rng As Range: Set target_rng = wsh.Range("A1")
For Each source_chart In source_sht.ChartObjects
source_chart.CopyPicture xlScreen, xlBitmap
target_rng.PasteSpecial
Set target_rng = target_rng.Offset(20, 0)
Next
If PivotExport = True Then
Debug.Print "se"
End If
Errorhandler:
MsgBox "An export sheet for this ticker and timeline already exists"
End Sub
#dee provided the correct answer.
The Errorhandler: is just a place holder. It does NOT operate like you think. You are using it like an If... Then... statement:
If Error Then
Show MsgBox
Else
Skip MsgBox
End If
As the Errorhandler is just a placeholder and NOT an If... Then..., the code after the placeholder will run regardless of error or no error. To rectify this issue, add an Exit Sub above the Errorhandler: line:
Exit Sub
Errorhandler:
MsgBox "An export sheet for this ticker and timeline already exists"
End Sub
In this piece of code, ErrorHandler: is what is known as a line label.
Errorhandler:
MsgBox "An export sheet for this ticker and timeline already exists"
End Sub
Line labels are not executable code, but rather just a marker that can tell other code where to jump to via any GoTo Statement. Armed with this knowledge, they are obviously not exclusive to error handlers.
The solution here is to use the Exit Statement to return from the Sub "early".
Exit Sub
Errorhandler:
MsgBox "An export sheet for this ticker and timeline already exists"
End Sub
Others may disagree with me, but I like to build my error handling so that the code always stops execution on Exit Sub. If the code ends its execution on End Sub, something has gone wrong.