在子中访问打开的工作簿有时会生成错误 1004“对象 '_Global' 的 'Sheets' 方法未失败”
Posted
技术标签:
【中文标题】在子中访问打开的工作簿有时会生成错误 1004“对象 \'_Global\' 的 \'Sheets\' 方法未失败”【英文标题】:Accessing open workbook in a sub generates Error 1004 "Method of 'Sheets' of Object '_Global' not failed" sometimes在子中访问打开的工作簿有时会生成错误 1004“对象 '_Global' 的 'Sheets' 方法未失败” 【发布时间】:2018-09-01 22:18:01 【问题描述】:当我尝试引用活动工作簿时,我得到不一致的结果。大约一半的时间我得到“对象'_Global'的'Sheets'方法没有失败”错误,其他时候代码工作正常。我没有看到模式。
VBA 代码是 Word 文档的一部分,它允许用户打开模板 Excel 文件并将 Word 文档中的文本选择/复制到 Excel 文件的行中。
在之前的 sub 中,我成功打开了一个 Excel 模板文件(我称之为 RTM 模板)。在下面的代码中,我想激活“RTM”工作表,选择第一个单元格,模板中可能已经包含先前执行的数据,如果有,则计算存在多少行数据。这样,新数据将发布在没有任何数据的第一行。我在工作簿中使用命名范围来引用起始单元格(“First_Cell_For_Data”)。
当我运行我的代码时,有时它运行时没有错误,而其他时候它在“Sheets(”RTM").Activate”处停止并给我“方法....”错误。当我将 wb_open 的变量定义更改为 Object 时,也会出现相同的结果。我也尝试过使用“wb_open.Sheets("RTM").Activate" 获得相同的结果。
按照下面的 cmets 中的建议,我添加了“如果 wb_open 什么都不是……”来调试问题。我还添加了子 List_Open_Workbooks 枚举打开的工作簿(其中只有 1 个)并激活与具有正确文件名的工作簿名称匹配的工作簿。这是成功的。但是在返回 Check_Excel_RTM_Template 后,我仍然在“Sheets("RTM").Activate" 行中遇到方法错误。
第二次更新:经过更多时间诊断问题(仍然间歇性发生)后,我添加了一些可能有助于找到问题根源的代码。在“List_Open_Workbooks”子中,我测试了xlApp.Workbooks.Count = 0
。因此,对打开的 Excel 工作簿的所有引用都将失败。此时我的模板工作簿已在 Windows 中打开。我得出正确的结论吗?
第三次更新:我尝试了Set wb_open = GetObject(str_filename)
,其中str_filename
包含我刚刚打开的Excel 模板文件的名称。
我收到以下错误消息。
另外,我注意到,如果我从新发布的 Word 和 Excel 开始,它似乎运行得很好。
Sub Check_Excel_RTM_Template(b_Excel_File_Has_Data As Boolean, i_rows_of_data As Integer)
Dim i_starting_row_for_data As Integer
Dim wb_open As Object
Set wb_open = ActiveWorkbook
i_rows_of_data = 0
If wb_open Is Nothing Then
MsgBox "RTM Workbook not open in Check_Excel_RTM_Template"
Call List_Open_Workbooks(b_Excel_File_Has_Data, i_rows_of_data)
Else
' On Error GoTo Err1:
' Sheets("RTM").Activate
' range("First_Cell_For_Data").Select
Workbooks(wb_open.Name).Worksheets("RTM").range("First_Cell_For_Data").Select
If Trim(ActiveCell.Value) <> "" Then
b_Excel_File_Has_Data = True
Do Until Trim(ActiveCell.Value) = ""
ActiveCell.Offset(1, 0).Select
i_rows_of_data = i_rows_of_data + 1
Loop
Else
b_Excel_File_Has_Data = False
End If
End If
Exit Sub
Err1:
MsgBox getName(str_Excel_Filename) & " is not a RTM template file."
b_abort = True
End Sub
Sub 枚举所有打开的工作簿
Sub List_Open_Workbooks(b_Excel_File_Has_Data As Boolean, i_rows_of_data As Integer)
Dim xlApp As Excel.Application
Set xlApp = GetObject(, "Excel.Application")
Dim str_filename As String
Dim xlWB As Excel.Workbook
If xlApp.Workbooks.Count = 0 Then
MsgBox "Error: Windows thinks there are no workbooks open in List_Open_Workbooks"
b_abort = True
Exit Sub
End If
For Each xlWB In xlApp.Workbooks
Debug.Print xlWB.Name
str_filename = getName(str_Excel_Filename)
If Trim(xlWB.Name) = Trim(str_filename) Then
xlWB.Activate
If xlWB Is Nothing Then
MsgBox "Workbook still not active in List_Open_Workbooks"
b_abort = True
Exit Sub
Else
' Sheets("RTM").Activate
Workbooks(xlWB.Name).Worksheets("RTM").range("First_Cell_For_Data").Select
range("First_Cell_For_Data").Select
If Trim(ActiveCell.Value) <> "" Then
b_Excel_File_Has_Data = True
Do Until Trim(ActiveCell.Value) = ""
ActiveCell.Offset(1, 0).Select
i_rows_of_data = i_rows_of_data + 1
Loop
Else
b_Excel_File_Has_Data = False
End If
End If
End If
Next xlWB
Set xlApp = Nothing
Set xlWB = Nothing
End Sub
从路径/文件名中提取文件名的功能
Function getName(pf)
getName = Split(Mid(pf, InStrRev(pf, "\") + 1), ".")(0) & ".xlsx"
End Function
【问题讨论】:
在Sheets("RTM")
行上设置条件断点,条件为Sheets Is Nothing
,这将帮助您诊断问题。我怀疑没有单个活动工作簿时正在调用您的宏。
@Dai - 您如何获得多个活动工作簿?
@Jeeped 可能是没有打开工作簿,或者工作簿已打开但它在 Excel 中未处于活动状态 - 或者打开了另一个没有名为“RTM”的工作表的工作簿。
@Dai 最后一种情况是 index out of bounds (9),而不是 object 或未设置块变量 (91)。 Kaiser,Sheets(...)
是隐式引用ActiveWorkbook
,您应该使用显式Workbook
对象来限定它,例如wb_open.Sheets(...)
- 否则 wb_open
毫无用处。在对它进行成员调用之前,还要验证它是否是Nothing
。如果没有活动的工作簿,If wb_open Is Nothing Then Exit Sub
将退出。
如果您打开了多个 Excel 实例,GetObject
将返回第一个匹配进程。这可能是也可能不是您调用List_Open_Workbooks
来自 的实例。如果从 Excel 内部调用此代码,则没有理由使用 GetObject
- 只需在需要的地方使用 Application
对象即可。
【参考方案1】:
我希望我找到了问题的根源并解决了它。
我相信在 Dim wb_open As Object
和 Set wb_open = ActiveWorkbook
中使用 Check_Excel_RTM_Template
子中的打开的工作簿会导致我出现不一致的问题......也许这是 Word 中的 VBA 实现中的异常(错误) .
在我在下面发布的修改后的代码中,我从调用例程传递了o_Excel
对象,并使用oExcel.Activesheet.xxx
来引用范围和值。
现在我的下一个问题是我在表单控制按钮代码上出现错误,该代码也使用Dim wb_open As Object
和Set wb_open = ActiveWorkbook
方法来引用打开的工作簿。但我会把它作为一个新问题发布。
感谢所有评论和提供建议的人。
Sub Check_Excel_RTM_Template(oExcel As Object)
Dim i_starting_row_for_data As Integer
Dim str_filename As String
i_rows_of_data = 0
On Error GoTo Err1:
oExcel.ActiveSheet.range("First_Cell_For_Data").Select
If Trim(oExcel.ActiveCell.Value) <> "" Then
b_Excel_File_Has_Data = True
Do Until Trim(oExcel.ActiveCell.Value) = ""
oExcel.ActiveCell.Offset(1, 0).Select
i_rows_of_data = i_rows_of_data + 1
Loop
Else
b_Excel_File_Has_Data = False
End If
Exit Sub
Err1:
Documents(str_doc_index).Activate
MsgBox getName(str_Excel_Filename) & " is not a RTM template file."
b_abort = True
End Sub
【讨论】:
以上是关于在子中访问打开的工作簿有时会生成错误 1004“对象 '_Global' 的 'Sheets' 方法未失败”的主要内容,如果未能解决你的问题,请参考以下文章