我有两种方法可以判断文件是否打开。
方法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 会给出错误吗?
谢谢。
答案 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对象的引用。