3

I am trying to loop through all files in a folder, open them and remove document info. I am having trouble dealing with files that cannot be opened or when opened have a pop us regarding disabling macros. I tried to solve this using on error resume next and on error goto 0. But then I get a runtime failure because my workbook object (wb) has not been set when I was trying to close files that did open.

I have read the documentation on "On Error Resume Next" & "On error goto 0" but I do not believe I am using them correctly here. Any help is greatly appreciated, Thanks.

Option Explicit
Sub test_Scrubber_New()

Dim directory As String, fileName As String, i As Variant, wb As Workbook
Application.DisplayAlerts = False
Application.ScreenUpdating = False

'directory = "C:\Users\bayli\Desktop\Files for Testing\"
directory = "C:\Users\bayli\Desktop\excel files\"
fileName = Dir(directory & "*.xl??")

i = 0
Do While fileName <> ""
    On Error Resume Next
    Set wb = Workbooks.Open(directory & fileName)
    On Error GoTo 0
        'remove info
        ActiveWorkbook.RemoveDocumentInformation (xlRDIAll)
    wb.Close True
    i = i + 1
    fileName = Dir()
    Application.StatusBar = "Files Completed:  " & i
Loop

Application.StatusBar = False
Application.ScreenUpdating = True
Application.DisplayAlerts = True
MsgBox "Complete"

End Sub

I updated my code to include: If Not wb Is Nothing Then remove the info as @PatricK suggested and it is working however it keeps stopping with a pop up about updating links. If I click "Do not update" my code continues working as needed but is there a way to handle this problem. I am looping through over 5k files so as you can imagine it is taking a while. The time it is taking is not a problem but currently I am sitting here having to click "dont update" quite a few times. I thought Application.DisplayAlerts = False would prevent these pop ups however it is not.

braX
  • 11,506
  • 5
  • 20
  • 33
Seth
  • 99
  • 1
  • 1
  • 4
  • 2
    You try to open a workbook, ignore errors if that fails, and then proceed wordking on that workbook. That will of course fail, since it couldn't be opened! You need to catch the error, and then do something else. `If Err.Number <> 0 Then 'do something else` – Rno Nov 28 '18 at 21:47
  • 2
    Note that if you have an error when opening the file, the line `ActiveWorkbook.RemoveDocumentInformation (xlRDIAll)` will run **regardless**, and will be on that Activeworkbook. You might want to switch that to `wb.RemoveDocumentInformation(...)`. – BruceWayne Nov 28 '18 at 21:52
  • 3
    @MichalRosa "your code is correct" - I beg to differ. `RemoveDocumentInformation` should run against `wb`, not `ActiveWorkbook`. And `On Error Resume Next` isn't proper error handling. "Correct" code doesn't merrily run in an unknown error state and happily report "complete" when everything caught fire. The hard-coded path is also a problem, `i` being `Variant` is highly questionable, `xlRDIAll` is forced-passed `ByVal` for no reason whatsoever, `Dir()` doesn't need the redundant parentheses, and the procedure name could be more meaningful, `PascalCase`, and explicitly `Public`. – Mathieu Guindon Nov 28 '18 at 21:57
  • 3
    @MichalRosa - The existence of a file does not mean that Excel can open it. Also, *anything* that hits the file system should be expected to be able to fail, because the code that's running is not the only IO consumer. It's completely feasible that some other process deletes the file between the `Dir` call and the `Workbooks.Open` call. – Comintern Nov 28 '18 at 22:08
  • 1
    An easy way to tell if Excel fails to open the file is to check if the `wb Is Nothing` after trying to open it. – PatricK Nov 28 '18 at 23:11
  • Very thorough answer to your "update links" problem - https://stackoverflow.com/questions/14908372/how-to-suppress-update-links-warning – Tim Williams Nov 29 '18 at 00:00

1 Answers1

8

OK, so there are a couple questions here. First, regarding the error handling. When you're using inline error handling (On Error Resume Next), the basic pattern is to turn off the automatic error handling, run the line of code that you want to "catch" the error for, then test to see if the Err.Number is zero:

On Error Resume Next
ProcedureThatCanError
If Err.Number <> 0 Then
    'handle it.
End If
On Error GoTo 0

The rest of the questions deal with dialogs you can encounter when you're opening workbooks. Most of this is documented on the MSDN page for Workbook.Open, but you'll want to change the Application.AutomationSecurity property to deal with the macro prompts as appropriate. For the updates, you should pass the appropriate UpdateLinks parameter. I'd also recommend specifying IgnoreReadOnlyRecommended, Notify, and CorruptLoad. Something like this should work (untested), or at least get you a lot closer:


Sub TestScrubberNew() 'Underscores should be avoided in method names.

    Dim directory As String, fileName As String, i As Variant, wb As Workbook
    Application.DisplayAlerts = False
    Application.ScreenUpdating = False

    Dim security As MsoAutomationSecurity
    security = Application.AutomationSecurity
    Application.AutomationSecurity = msoAutomationSecurityForceDisable

    directory = "C:\Users\bayli\Desktop\excel files\"
    fileName = Dir(directory & "*.xl??")

    i = 0
    Do While fileName <> vbNullString
        On Error Resume Next
        Set wb = Workbooks.Open(fileName:=directory & fileName, _
                                UpdateLinks:=0, _
                                IgnoreReadOnlyRecommended:=True, _
                                Notify:=False, _
                                CorruptLoad:=xlNormalLoad)
        If Err.Number = 0 And Not wb Is Nothing Then
            On Error GoTo 0
            wb.RemoveDocumentInformation xlRDIAll
            wb.Close True
            i = i + 1
            Application.StatusBar = "Files Completed:  " & i
            fileName = Dir()
        Else
            Err.Clear
            On Error GoTo 0
            'Handle (maybe log?) file that didn't open.
        End If
    Loop

    Application.AutomationSecurity = security
    Application.StatusBar = False
    Application.ScreenUpdating = True
    Application.DisplayAlerts = True
    MsgBox "Complete"

End Sub
Comintern
  • 21,855
  • 5
  • 33
  • 80
  • Thank you very much. This was very helpful! Testing code you provided now and it looks to be working great – Seth Nov 29 '18 at 00:34