【问题标题】:How to activate a wookbook named in a different module如何激活在不同模块中命名的工作簿
【发布时间】:2019-05-31 15:47:17
【问题描述】:

我从 module1 调用 module2,我在 module2 中将工作簿命名为“x”。但后来当我在 module1 中尝试“x.Activate”时,我收到一个错误“运行时错误'424':需要对象”

我有一个相当长的模块,我想把它分成多个模块来组织。到目前为止,我已经在这个模块中创建了一个名为“INPUTS”的模块我有一个“Sub RT_CMM_DATA_COMPILER_INPUTS()”大概在未来我将在这个模块中拥有其他 Subs“Sub RT_Some_Other_Project_INPUTS()”我在“Sub RT_CMM_DATA_COMPILER_INPUTS( )”并尝试在名为沙箱的单独模块中按名称激活该工作簿。但它显示一个错误。

'RT_Sandbox Module
Sub sandbox()

    Call RT_CMM_DATA_COMPILER_INPUTS

    wkbwatchFolders_table.Activate
    lastShtRow = LASTSHEETROW(ActiveSheet)

    MsgBox lastShtRow

End Sub


'Inputs module
Sub RT_CMM_DATA_COMPILER_INPUTS()

    watchFolders_filePath = "D:\RT_CMM_Data_File_Paths.xlsx"
    Set wkbwatchFolders_table = Workbooks.Open(Filename:=watchFolders_filePath)

End Sub

我是否会尝试组织我的代码完全错误?我应该为此使用类模块吗?还是只是我缺少一些语法?

【问题讨论】:

标签: excel vba


【解决方案1】:

您缺少的关键部分是每个模块顶部的Option Explicit

使用该选项,代码将拒绝编译,直到所有变量都被显式声明。

没有它,watchFolders_filePath 在两个过程中都是一个未声明的变量,在读取但未赋值的范围内,它的数据类型是Variant/Empty

Rubberduck(我管理的免费、开源 VBIDE 插件项目)可以帮助您在代码中定位和修复这些问题(以及其他问题):


至于您的代码,您不需要任何全局变量。 尽可能避免使用全局变量。改用函数(和参数):

Function RT_CMM_DATA_COMPILER_INPUTS() As Workbook
    Dim watchFolders_filePath As String
    watchFolders_filePath = "D:\RT_CMM_Data_File_Paths.xlsx"
    Set RT_CMM_DATA_COMPILER_INPUTS = Workbooks.Open(Filename:=watchFolders_filePath)
End Function
Sub sandbox()

    Dim wb As Workbook
    Set wb = RT_CMM_DATA_COMPILER_INPUTS    
    wb.Activate
    lastShtRow = LASTSHEETROW(wb.ActiveSheet)

    MsgBox lastShtRow

End Sub

【讨论】:

  • 我最终使用了这个的变体。实际上,我打开了几个文件。有些是只读的,有些是有密码的。此特定实例是只读的。所以我做了一个函数(3行):第1行=“函数OPEN_PATH_READ_ONLY(文件路径作为字符串)作为工作簿”第2行=“设置OPEN_PATH_READ_ONLY = Workbooks.Open(文件名:=文件路径,只读:=真,IgnoreReadOnlyRecommended:=真) " Line 3 = "End Function" 这样我就可以简单地将任何路径输入到这个通用函数中
  • 你可以有一个ByVal openReadOnly As Boolean 参数而不需要第二个函数。
  • 另外,考虑使用PascalCase 而不是SCREAMING_SNAKE_CASE,以获得更好的可读性。标准库(和 Excel)中的所有内容都是 PascalCase...
【解决方案2】:

使用Public 语句将在这里工作:

Public x As Workbook 
Public your_var As Object

你需要在你的过程之外,在模块的顶部声明这些。声明这些后,您可以在任何模块中的任何位置访问它们。

在此处阅读更多信息:Declaring Variables

【讨论】:

  • 好的...看起来我已经开始工作了。我不确定“模块外”是什么意思。但我发现“excel-easy.com/vba/examples/variable-scope.html”是帮助我理解的好来源。但是,我只使用了“Public x As Workbook”而不是“Public your_var As Object”。你能提供一些关于第二部分的见解吗?几周前,我遇到了一个与在 excel vba 中制作图表有关的 sn-p,并且 sn-p 声明了一些“作为对象”我认为像 Dim chrt As Object 之类的东西......我用谷歌搜索了一段时间,但不能真正找到意义/何时使用“作为对象”
  • 那篇文章太让我头疼了... :-(
  • @XCELLGUY 这意味着您针对Object 进行的任何成员调用都只能在运行时解决,即它是“后期绑定的”。尽可能使用已知接口(例如WorkbookWorksheetRange 等)而不是使用Object。这样您就可以获得编译时验证,并且编辑器会在您编写代码时为您提供帮助(智能感知、自动完成、参数快速信息)。你周围的一切都是一个对象:As Object(或As Variant)可能是任何东西,而你通常不希望这样。
  • 谢谢...这很有帮助。很高兴知道我通常应该避免使用“作为对象”。我已经知道要避免使用“作为变体”。虽然我只是将“As Variant”用于动态数组。据我了解,这是必要的。你能举一个我可能遇到的需要“作为对象”的情况的例子吗?
猜你喜欢
  • 2019-11-19
  • 2015-03-15
  • 1970-01-01
  • 2014-07-02
  • 2020-08-06
  • 2017-01-16
  • 2019-03-03
  • 2023-04-05
  • 2016-07-28
相关资源
最近更新 更多