VBA打开工作簿时的错误处理

3
我试图遍历文件夹中的所有文件,打开它们并删除文档信息。但是当处理无法打开的文件或打开时出现有关禁用宏的弹出窗口时,我遇到了麻烦。我尝试使用on error resume next和on error goto 0来解决这个问题。但随后由于我的工作簿对象(wb)在我尝试关闭打开的文件时未设置而导致运行时错误。 我已经阅读了“On Error Resume Next”和“On error goto 0”的文档,但我不认为我在这里正确使用它们。 非常感谢您的帮助,谢谢。
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

我已更新我的代码,并按照@PatricK的建议添加了If Not wb Is Nothing Then remove the info,目前它已经可以正常工作,但是却一直弹出关于更新链接的提示框。如果我点击“不更新”,则代码将继续正常工作,但是有没有一种方法来解决这个问题呢?我正在遍历5000多个文件,所以您可以想象这需要一些时间。目前所需的时间不是问题,但是我目前在这里不得不多次点击“不更新”。我原以为设置Application.DisplayAlerts = False 可以防止这些弹出框,但实际上并不能。

2
你尝试打开一个工作簿,如果失败则忽略错误,然后继续在该工作簿上操作。这当然会失败,因为它无法打开! 你需要捕捉错误,然后做其他事情。 如果Err.Number <> 0 Then '做其他事情 - Rno
2
请注意,如果打开文件时出现错误,则行ActiveWorkbook.RemoveDocumentInformation(xlRDIAll)无论如何运行,并且将在该Activeworkbook上。您可能希望将其切换到wb.RemoveDocumentInformation(...) - BruceWayne
3
@MichalRosa说 "你的代码是正确的" - 我不这么认为。RemoveDocumentInformation 应该对 wb 运行,而不是对 ActiveWorkbook 运行。而且 On Error Resume Next 并不能算是合适的错误处理方式。如果代码在未知的错误状态下愉快地运行,并在一切都失控时轻松报告 "完成" ,那就不是"正确"的代码了。硬编码路径也是一个问题,iVariant 类型非常值得质疑,xlRDIAll 被强制传递 ByVal 却没有任何理由,Dir() 不需要多余的括号,而且过程名应该更有意义、使用 PascalCase 并明确声明为 Public - Mathieu Guindon
3
文件的存在并不意味着Excel可以打开它。此外,任何接触文件系统的东西都应该预料到可能会失败,因为运行的代码不是唯一的IO消费者。完全有可能在Dir调用和Workbooks.Open调用之间,某个其他进程删除了该文件。 - Comintern
1
检测Excel打开文件失败的简单方法是在尝试打开后查看wb Is Nothing是否为空。 - PatricK
非常详细的回答,解决了您的“更新链接”问题-https://dev59.com/umUp5IYBdhLWcg3w-LQJ - Tim Williams
1个回答

8

好的,这里有几个问题。首先,关于错误处理。当您使用内联错误处理(On Error Resume Next)时,基本模式是关闭自动错误处理,运行要“捕获”错误的代码行,然后测试是否 Err.Number 为零:

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

剩下的问题涉及到打开工作簿时可能遇到的对话框。大部分内容都在Workbook.OpenMSDN页面上有记录,但您需要根据需要更改Application.AutomationSecurity属性以处理宏提示。 对于更新,您应该传递相应的UpdateLinks参数。 我还建议指定IgnoreReadOnlyRecommendedNotifyCorruptLoad。像这样的代码应该可以运行(未经测试),或者至少可以让您更接近目标:
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

非常感谢。这非常有帮助!我现在正在测试您提供的代码,看起来运行得很好。 - Seth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接