VBA如何跟踪哪些工作簿处于打开状态?
我正在编写一个数据挖掘宏,它从可变数量的工作簿中获取信息。用户可以选择通过用户表单解析哪些工作簿。但是,可以在用户窗体运行时打开和关闭工作簿 那么,我的userform如何跟踪哪些工作簿是打开的,以便它可以准确地显示它们。
现在,我正在使用一个用“Application.OnTime”调用自身的递归函数。我真的不喜欢这个解决方案,因为它涉及额外的检查以查看用户窗体是否仍处于打开状态,以及由于调用函数的任何时间段而导致延迟。
最终: 来自答案和评论的综合解决方案
userform代码,需要一个名为WorkbookList的ListBox和一个名为FileTextBox的文本框
Private WithEvents App As Application
Public Sub WorkbookList_UpdateList()
WorkbookList.Clear
For Each Wb In Application.Workbooks
WorkbookList.AddItem Wb.name
Next Wb
End Sub
Private Sub WorkbookList_Change()
If WorkbookList.ListIndex = -1 Then Exit Sub
key = WorkbookList.List(WorkbookList.ListIndex)
For Each Wb In Application.Workbooks
IsWorkBookOpen Wb.path
If Wb.name = key Then FileTextbox.text = Wb.path
Next Wb
End Sub
Private Sub App_WorkbookOpen(ByVal Wb As Workbook)
WorkbookList_UpdateList
End Sub
Private Sub App_NewWorkbook(ByVal Wb As Workbook)
WorkbookList_UpdateList
End Sub
Private Sub App_WorkbookBeforeClose(ByVal Wb As Workbook, Cancel As Boolean)
Application.OnTime Now + TimeValue("00:00:01"), "WorkbookClosed"
End Sub
Private Sub UserForm_Initialize()
Set App = Application
WorkbookList_UpdateList
UpdatePeriodicly
End Sub
模块代码(将其放在vba模块中):
'Code From: http://www.ozgrid.com/forum/showthread.php?t=152892
Function IsUserFormLoaded(ByVal UFName As String) As Boolean
Dim UForm As Object
IsUserFormLoaded = False
For Each UForm In VBA.UserForms
If UForm.name = UFName Then
IsUserFormLoaded = True
Exit For
End If
Next
End Function
Public Sub WorkbookClosed()
If IsUserFormLoaded("InputForm") = False Then Exit Sub
InputForm.WorkbookList_UpdateList
End Sub
答案 0 :(得分:2)
您可以使用应用程序事件。
E.g。见cpearson.com/excel/appevent.aspx
Private WithEvents app As Excel.Application
Sub Init()
Set app = Application 'start capturing events
End Sub
Private Sub app_NewWorkbook(ByVal Wb As Workbook)
Debug.Print "New"
End Sub
Private Sub app_WorkbookBeforeClose(ByVal Wb As Workbook, Cancel As Boolean)
Debug.Print "Before close: " & Wb.Name
End Sub
Private Sub app_WorkbookOpen(ByVal Wb As Workbook)
Debug.Print "Open: " & Wb.Name
End Sub
答案 1 :(得分:1)
所以我认为这是一个有趣的脚本,可能对你试图解决的问题有用。
Public Function IsWorkBookOpen(FileName As String)
Dim ff As Long, ErrNo As Long
On Error Resume Next
ff = FreeFile()
Open FileName For Input Lock Read As #ff
Close ff
ErrNo = Err
On Error GoTo 0
Select Case ErrNo
Case 0: IsWorkBookOpen = False 'Workbook IS NOT
Case 70: IsWorkBookOpen = True 'Workbook IS open
Case Else: Error ErrNo
End Select
End Function
您可以通过执行此类操作来调用此方法
Ret = IsWorkBookOpen("C:\test.xlsm")
If Ret = True Then 'YOUR CODE HERE