【问题标题】:Reference add in global variables from worksheet code参考从工作表代码中添加全局变量
【发布时间】:2015-07-09 01:37:03
【问题描述】:

我正在构建一个 Excel 插件,它在 sub 中声明了一些公共变量。首次使用 Addin 时,它会从 Addin (ThisWorkBook) 复制一些工作表 到用户的工作簿 (ActiveWorkBook)。这些工作表中有一些工作表事件子项。

问题:ActiveWorkBook 工作表事件 subs 需要引用 ThisWorkBook 中定义的公共变量,但似乎找不到它们。我想是因为他们在不同的工作簿中。但是在这种加载项的情况下,肯定有某种方法可以做到这一点吗?

具体例子:模块Module1中的GlobalAddin.xlam声明

Option Explicit
Public TestMe As Integer

然后

Public Sub RunSub()
TestMe = 10
MsgBox "The Addin says that TestMe is " & TestMe
End Sub

从 ThisWorkBook._Open() 事件中调用 RunSub。

GlobalAddin.xlam 成为一个活动插件。现在在 Sheet1 中的另一个工作簿 Book2.xlm 中,我们有

Option Explicit
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
MsgBox "The Worksheet says TestMe is " & TestMe
End Sub

现在打开 Book2.xlm。一个对话框报告 TestMe 的值为 10(这来自 xlam workbook_open,甚至调用了 RunSub。)但是随后单击 Book2 中的 Sheet1 会导致变量未定义错误,说未定义 TestMe。

所以这是有道理的,但是我如何可以在 Book2 的工作表事件中访问 TestMe 的值?

(编辑:我想我可以通过 ActiveWorkBook 中的(隐藏)工作表传递变量,但这似乎有点笨拙。有更好的方法吗?)

【问题讨论】:

  • 您可以使用Application.Run("my_addin.xla!MySub")从另一个工作簿运行潜艇
  • @ja72 我的问题不是正在运行的潜艇,而是如何在活动工作簿中读取/写入插件中的公共变量。这些公共变量似乎只在 addin.xla 中是全局的。我会用一个具体的例子来编辑我的问题

标签: excel vba


【解决方案1】:

你不能做以下吗?

  1. 创建一个在模块中声明字段的插件。

    作为整数的公共 TestMe

  2. 还在同一个插件模块中声明一个公共函数来获取字段值。

    公共函数 GetTestMe() 作为整数 GetTestMe = 测试我 结束函数

  3. 现在在同一个 Excel 应用程序的任何其他工作簿中,后期绑定调用以获取值。

    公共子TestAddinCall() 将 x 调暗为整数 x = Application.run("GetTestMe") 结束子

这显然是后期绑定,但可能是最简单的方法。

【讨论】:

  • 谢谢,这看起来最简单!从这个角度来看,我也看到了 @ja72 在说什么。
【解决方案2】:

我以前解决过与此类似的问题,不仅将工作表复制到新工作簿中(每个工作表都附带支持代码),而且还通过将 VBA 模块导入新工作簿中。显然,VBA 模块可以定义任何公开的全局变量并让它们存在于该工作簿中。当已为工作簿安装外接程序并且您希望这些公共变量“本地”到启用外接程序的工作簿时,这一点很重要。

在某些时候,您必须将 VBA 模块导出到文本文件:

Sub ExportAllModulesAndClasses()
    On Error GoTo Err_ExportAllModulesAndClasses
    'Purpose:   Connects to the current project and exports each of the VBA
    '           components to an external, text-based file. File extensions
    '           are automatically selected based on the type of the component.
    'Return:    n/a
    'Author:    PeterT
    Dim i As Integer
    Dim sourceCode As Object
    Dim filename As String

    i = 0
    For Each sourceCode In Application.VBE.ActiveVBProject.VBComponents
        filename = CHOOSE_YOUR_DIRECTORY_PATH_HERE & sourceCode.name & GetFileExtension(sourceCode)
        Debug.Print "Exported: " & filename
        sourceCode.Export filename
        i = i + 1
    Next
    Debug.Print "Export complete: " & i & " source code files created from this application"

Exit_ExportAllModulesAndClasses:
    Exit Sub

Err_ExportAllModulesAndClasses:
    MsgBox "In ExportAllModulesAndClasses: " & Err.Number & " - " & Err.Description, vbOKOnly
    Resume Exit_ExportAllModulesAndClasses
End Sub

Public Function GetFileExtension(vbComp As Object) As String
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' This returns the appropriate file extension based on the Type of
' the VBComponent.
' based on: http://www.cpearson.com/excel/vbe.aspx
'
' Type property constants:
' vbext_ct_StdModule       =   1  Standard Module
' vbext_ct_ClassModule     =   2  Class Module
' vbext_ct_MSForm          =   3  Microsoft Form
' vbext_ct_ActiveXDesigner =  11  ActiveX Designer
' vbext_ct_Document        = 100  Document Module
'
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    Select Case vbComp.Type
        Case 2                        'class
            GetFileExtension = ".cls"
        Case 100                      'document
            GetFileExtension = ".cls"
        Case 3                        'form
            GetFileExtension = ".frm"
        Case 1                        'standard module
            GetFileExtension = ".bas"
        Case Else
            GetFileExtension = ".bas"
    End Select
End Function

然后当您的插件安装时,您可以将您的模块导入到新工作簿中:

Sub ImportVBAProjectFiles()
On Error GoTo Err_ImportVBAProjectFiles
    'Purpose:   Uses the constants defined above to access a specific
    '           directory. All files within that directory will be added as
    '           a module, class, form, etc to this application project.
    'Return:    n/a
    'Author:    PeterT
    Dim i As Integer
    Dim name As Variant
    Dim filenames As New Collection

    '--- build up an array of all the files (modules, forms, classes, etc)
    '    that will be imported
    Call FillDir(filenames, CHOOSE_YOUR_DIRECTORY_PATH_HERE , "*.*", False)

    '--- add each item to this project
    i = 0
    For Each name In filenames
        Application.VBE.ActiveVBProject.VBComponents.Import CStr(name)
        Debug.Print "Imported: " & name
        i = i + 1
    Next

Exit_ImportVBAProjectFiles:
    Exit Sub

Err_ImportVBAProjectFiles:
    MsgBox "In ImportVBAProjectFiles: " & Err.Number & " - " & Err.Description, vbOKOnly
    Resume Exit_ImportVBAProjectFiles
End Sub

Private Function FillDir(colDirList As Collection, ByVal strFolder As String, _
                         strFileSpec As String, bIncludeSubfolders As Boolean)
    'Build up a list of files, and then add add to this list, any additional folders
    'from:      http://allenbrowne.com/ser-59.html
    Dim strTemp As String
    Dim colFolders As New Collection
    Dim vFolderName As Variant

    'Add the files to the folder.
    strFolder = TrailingSlash(strFolder)
    strTemp = Dir(strFolder & strFileSpec)
    Do While strTemp <> vbNullString
        colDirList.Add strFolder & strTemp
        strTemp = Dir
    Loop

    If bIncludeSubfolders Then
        'Build collection of additional subfolders.
        strTemp = Dir(strFolder, vbDirectory)
        Do While strTemp <> vbNullString
            If (strTemp <> ".") And (strTemp <> "..") Then
                If (GetAttr(strFolder & strTemp) And vbDirectory) <> 0& Then
                    colFolders.Add strTemp
                End If
            End If
            strTemp = Dir
        Loop
        'Call function recursively for each subfolder.
        For Each vFolderName In colFolders
            Call FillDir(colDirList, strFolder & TrailingSlash(vFolderName), strFileSpec, True)
        Next vFolderName
    End If
End Function

Public Function TrailingSlash(varIn As Variant) As String
    'from:      http://allenbrowne.com/ser-59.html
    If Len(varIn) > 0& Then
        If Right(varIn, 1&) = "\" Then
            TrailingSlash = varIn
        Else
            TrailingSlash = varIn & "\"
        End If
    End If
End Function

【讨论】:

    猜你喜欢
    • 2016-01-24
    • 1970-01-01
    • 2014-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多