我有一系列Excel工作簿,这些工作簿的某些数据依赖于单独的工作簿。因此,我需要在打开主工作簿时自动打开数据工作簿。为了使非技术最终用户的工作变得简单,我将数据工作簿隐藏起来。但是,我需要能够同时处理两个工作簿。因此,我尝试设置一个标志(links_opened
)来指定在打开主工作簿时是否已经打开了数据工作簿。记录下来,这是我第一次接触VBA,我发现它真的很奇怪。
这是我代码的相关部分:
Option Explicit
Dim w As Workbooks
Dim links_opened As Boolean
links_opened = False ' This is where VBA reports an error
Function IsWorkBookOpen(FileName As String)
' Code here tests whether the workbook is already open
' Omitted for brevity
End Function
Private Sub Workbook_Open()
Dim fn As String
fn = ThisWorkbook.Path & "\Work Instructions\Links.xlsx"
If !IsWorkBookOpen(fn) Then
Set w = Workbooks
Application.ScreenUpdating = False
w.Open FileName:=fn, UpdateLinks:=False, ReadOnly:=True
ActiveWindow.Visible = False
ThisWorkbook.Activate
Application.ScreenUpdating = True
links_opened = True
End If
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
If links_opened Then
w.Item(2).Saved = True
End If
End Sub
当我尝试运行此代码时,VBA说,表示我在上面标记的行:
编译错误:
无效的外部程序
我了解由于某些原因,VBA不允许在顶层设置变量。但是我不知道有其他方法可以做到这一点。在我经常使用的其他语言中,效果很好。
如何设置标记以跟踪数据文件是通过代码打开还是手动打开?还是有更好的方法来做到这一点?
答案 0 :(得分:4)
links_opened = False ' This is where VBA reports an error
这是一个赋值操作,它是一个可执行语句。在VBA中,非声明性可执行语句在过程范围之外是非法的。此外,Boolean
变量会自动初始化为False
,因此分配始终是空操作。
If !IsWorkBookOpen(fn)
这将是下一个编译错误; !
在VBA中确实存在,但是它是类型提示或 bang运算符,它们都与否定布尔值无关。您要为此使用Not
关键字:
If Not IsWorkbookOpen(fn)
然后让IsWorkbookOpen
函数返回一个Boolean
:
Private Function IsWorkBookOpen(ByVal FileName As String) As Boolean
On Error Resume Next
Dim wb As Workbook
Set wb = Application.Workbooks(FileName) ' throws error 9 if non-existing
Err.Clear
On Error GoTo 0
IsWorkbookOpen = Not wb Is Nothing
End Function