VBA打开工作簿/检查工作簿是否是打开最佳实践以及原因



我制作了一个宏,可以将工作表从一个工作簿复制到另一个工作簿,并且我有几个关于打开工作簿的最佳实践的问题。

根据以前的编程经验,我知道您应该在尝试打开之前检查某些内容是否已打开。到目前为止,VBA 已经证明这是正确的,因为如果我从中复制的工作表已经打开,我的宏就会崩溃。我想知道测试它是否打开的最佳方法是什么。它可能不是活动的工作簿和测试If Workbooks(file) Is Nothing Then ....给了我错误。(这是我在网上找到的可能的解决方案)

如果我排除上述测试,则会出现以下错误:

Set copyFromWB = Workbooks.Open(file) Set copyFromWS = copyFromWB.Sheets(copyFromSheetName) 'ERROR HERE

当文件已经打开时,但在文件关闭时它可以完美运行。我想知道为什么在文件已经打开时会引发错误,"幕后"答案确实是我在这里寻找的,可以解释计算机在想什么,更何况是理论。

同样关于这一点,我想知道为什么测试If Workbooks(file) Is Nothing Then ....在多个 VBA 帮助论坛上被建议时对我不起作用。这是类型问题还是与我正在使用的 excel 版本有关?

作为参考,存在"file"和"copyFromSheetName",当文件未在运行时从打开启动时不会出现错误。

总结:

  1. 测试工作簿是否打开的最干净方法?
  2. 为什么已打开的工作簿在尝试访问其工作表时会导致崩溃?(我认为这实际上与上面的行有关Set copyFromWB = Workbooks.Open(file)
  3. 为什么将工作簿(文件)与"无"进行比较不起作用?是类型问题、excel 版本问题还是其他问题?

我正在寻找的不仅仅是编码解决方案。如果我不明白为什么你的代码有效而我的代码无效,那对我来说不会有多大用处。

这是我所知道的最干净的方式: 检测 Excel 工作簿是否已打开。

它实际上不会崩溃,但您只能在读写模式下打开文件一次,如果您打开两次,它会要求您以只读方式打开它。

因此,如果您尝试此操作,工作簿每次都会打开,但它在标题中显示只读。

Sub OpenWbk()
Dim xl As Object
Set xl = CreateObject("Excel.Application")
Dim wbk As Workbook
Dim sht As Worksheet
xl.Visible = True
Set wbk = xl.Workbooks.Open("C:UsersUserDesktopBook1.xlsm")
Set sht = wbk.Sheets(1)
End Sub

它可能会抛出错误,因为它想要访问不存在的内容。 如果您set wbk = Workbooks("FileName")(如果未打开则引发错误)并说On Error Resume Next然后检查If wbk Is Nothing它将起作用。
所以我想错误消息是某种保护。

UGP 可能会打败我。 此代码将检查您的工作簿是否已打开。 如果是,那么它会将其设置为变量 myWB,并且不会在我身上崩溃。 如果未打开,它将使用相同的变量打开它。

Sub wsdcvbhui()
Dim wb As Workbook
Dim wbs As Workbooks
Dim myWB As Workbook
Set wbs = Application.Workbooks
For Each wb In wbs
If wb.Path & "" & wb.Name = "C:FilesBounce.xlsx" Then ' change this to your file path and name
Set myWB = wb
GoTo skipOpen
End If
Next wb
Set myWB = Workbooks.Open("C:FilesBounce.xlsx")
skipOpen:
myWB.Activesheet.range("B2").value = "Hello"
myWB.save
myWB.Close Saved = True
Set wbs = Nothing
Set myWB = Nothing
Set wb = Nothing
End Sub

若要确定工作簿是否打开,可以使用该函数来实现此目的,该函数利用"出错时"语句。

Sub testIsOpen()
Dim sFN     As String
Dim bFlag   As Boolean
sFN = "FileName.xlsx"     ' Put the name of your workbook here
bFlag = IsWkbOpen(sFN)
' Print in Immediate window True or False
Debug.Print bFlag
End Sub
Public Function IsWkbOpen(ByVal sFileName As String) As Boolean
Dim wkb         As Workbook
Dim bReturn     As Boolean
On Error GoTo EH   
bReturn = True
Set wkb = Workbooks(sFileName)
IsWkbOpen = bReturn
Exit Function
EH:
bReturn = False
Resume Next
End Function

最新更新