VBA:查看文件是否打开的两种方法
我有两个方法,我觉得应该告诉一个文件是否打开。
方法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给出了它的错误?
谢谢。
他们都给出了一个下标超出范围的错误。 但是在方法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不处理错误,所以默认的error handling(停止执行和报告错误)是有效的。
Workbooks(filename)
试图从集合Workbooks
获取具有标识符(或“索引”) filename
的元素。 如果集合不包含这样的元素,则会出现“下标超出范围”错误。 (所以简而言之:只要文件没有打开,这段代码就会失败,你可能不想这样做。)
然而,如果文件没有打开,即错误被提出,这种访问将会失败的知识正在第二种方法中使用。 代码尝试从Workbooks
集合中获取具有标识符filename
的元素,并将其分配给variableswBook
。 如果失败,variableswBook
的值将保持为Nothing
。 如果成功,variableswBook
将包含对相应Workbook对象的引用。
VBA在评估条件语句之前尝试评估所有部分。 所以,如果我有一个variablesmyvar = "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有短路评估 ,那么第一部分评估是错误的。
但是,以下将起作用
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
编辑给予更多的细节,并正确地捕捉到第二个例子将不被评估,以及为手头的问题提供有用的解决scheme。