VBA:查看文件是否打开的两种方法

时间:2015-06-19 19:55:56

标签: excel vba excel-vba file-io

我有两种方法可以判断文件是否打开。

方法1 (错误:下标超出范围):

If Not Workbooks(filename) Is Nothing Then
    Workbooks.Open (filename)
End If

方法2

If Not IsWorkbookOpen(filename) Then
    Workbooks.Open (filename)
End If

IsWorkbookOpen()的位置:

Private Function IsWorkbookOpen(wbname) As Boolean

Dim wBook As Workbook
Set wBook = Nothing

On Error Resume Next
Set wBook = Workbooks(wbname)

If wBook Is Nothing Then
    IsWorkbookOpen = False
    Else: IsWorkbookOpen = True
End If

End Function

除了On Error Resume Next方法1 似乎与方法2 几乎相同。

有人可以解释为什么方法1 会给出错误吗?

谢谢。

3 个答案:

答案 0 :(得分:5)

他们都给出了一个超出范围错误的下标。但是在方法2中,您使用On Error Resume Next来抑制该错误。

Sub SeeError()

    On Error Resume Next
    Debug.Print Workbooks("DoesNotExist").Name

    Debug.Print Err.Description

End Sub

这打印"下标超出范围"在立即窗口中。 On Error语句不会停止发生错误,它只是处理它。方法1不处理错误,因此默认错误处理(停止执行并报告错误)生效。

答案 1 :(得分:1)

VBA在评估条件语句之前尝试评估所有部分。因此,如果我有变量myvar = "xyz"并尝试运行以下行...

If IsNumeric(myvar) And Round(myvar, 1) = 3 Then
    'you will get an error before the IF is evaluated
End If

它不起作用。 VBA将评估IsNumeric(myvar)罚款,然后尝试评估Round(myvar, 1) = 3并在检查整个条件之前得到错误。因此,VBA会在执行AND运算符之前通知您错误。如果VBA有short circuit evaluation,它将正常工作,因为第一部分将评估为false。

但以下内容可行

If IsNumeric(myvar) Then
    If Round(myvar, 1) = 3 Then
        'second IF statement is not touched since first IF statement evaluates to false
    End If
End If

这是有效的,因为IsNumeric(myvar)的计算结果为false,因此会跳过嵌套语句。

所以它在Workbooks(filename)上抛出的错误只会给出错误,除非你告诉它继续下一步。所以我使用的方法是

    On Error Resume Next
    Set wb = Workbooks(file)
    If wb Is Nothing Then
        Set wb = Application.Workbooks.Open(dir & "\" & file, ReadOnly:=True)
    End If
    On Error GoTo 0

编辑提供更多详细信息并正确捕获第二个示例不会被评估,并为手头的问题提供有用的解决方案。

答案 2 :(得分:0)

Workbooks(filename)尝试从集合filename中获取带有标识符(或“index”)Workbooks的元素。如果集合不包含这样的元素,您将得到“下标超出范围”错误。 (简而言之:只要文件没有打开,这段代码就会失败。你可能不希望这样。)

然而,如果文件未打开,即提出错误,则在第二种方法中使用了这种访问将失败的知识。代码尝试从filename集合中获取标识为Workbooks的元素,并将其分配给变量wBook。如果失败,变量wBook的值将保持Nothing。如果成功,变量wBook将包含对相应Workbook对象的引用。