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。