提问人:Martin 提问时间:11/8/2023 更新时间:11/8/2023 访问量:52
在 .xlam 和 .xlsm 文件之间传递公共变量
Passing Public variable between .xlam and .xlsm files
问:
我正在从功能区 *.xlam (file1) 运行一个查找函数,该函数打开一个包含所有项目宏 (file2) 的远程 *.xlsm 文件,该文件又在远程数据库 (file3) 上运行查找代码。
File2 创建一个变量“Confirm”字符串,该字符串在显示为 Msgbox 时效果很好 - 但 msgbox 是模态的并停止代码。这意味着当 file2 保持打开状态时,其他用户将没有对 file3 的写入权限。
为了解决这个问题,我在 file1 上创建了一个用户窗体来模仿 file2 中的 msgbox。 一切正常,file2 和 3 按预期打开和关闭,但 file2 的变量“Confirm”未传递到 File1 的用户窗体标签。
下面的压缩代码。 任何帮助都非常感谢!
File1 *.xlam 代码:
Public Confirm As String
Sub ViewSUB(control As IRibbonControl)
Dim Sub_Macros As String, strFileExistsA As String, strFileExistsB As String
Dim currentWorkbook As Workbook
strFileExistsA = Dir(Sub_Macros_L)
strFileExistsB = Dir(Sub_Macros_R)
If strFileExistsA <> "" Then
Sub_Macros = Sub_Macros_L
ElseIf strFileExistsB <> "" Then
Sub_Macros = Sub_Macros_R
Else
MsgBox "Macro File is missing", vbCritical, "Macro File Missing"
Exit Sub
End If
Application.ScreenUpdating = False
Application.Calculation = xlManual
Set currentWorkbook = Application.ActiveWorkbook
Workbooks.Open Sub_Macros, ReadOnly:=True
currentWorkbook.Activate
Application.Run ("'Macros.xlsm'!ViewSUB")
ViewSub_Details.Show vbModeless
Workbooks("Macros.xlsm").Close SaveChanges:=False
Application.Calculation = xlAutomatic
Application.ScreenUpdating = True
End Sub
File2 只是创建字符串,我可以证明它适用于 msgbox。 这只是该代码的一部分:
Public Confirm As String
For i = 3 To LastrowDBase
If DBase.Cells(i, 2) = SUBPN And DBase.Cells(i, 5) = "SomeText" Then
Confirm = Confirm & " - " & DBase.Cells(i, 3) & " - Flag: " & DBase.Cells(i, 7) & " - " & DBase.Cells(i, 6) & vbCrLf
End If
Next i
MsgBox Confirm
然后返回 File1 的用户窗体代码:
Option Explicit
Private Sub UserForm_Initialize()
Label1.Caption = Confirm
End Sub
Private Sub CommandButton01_Click()
Unload ViewSub_Details
End Sub
答:
这些引文来自 Excel 帮助文件
公共 使用 Public 语句声明的变量对所有应用程序的所有模块中的所有过程都是可见的,除非 Option Private Module 有效。在这种情况下,变量仅在它们所在的项目中是公共的。
引用项目 您直接从当前正在处理的项目创建链接的项目。由当前项目的某个直接引用的项目引用的项目称为间接引用的项目。当前项目无法访问其公共变量,除非通过其项目名称进行限定。项目之间的直接引用和间接引用的任何组合都是有效的,只要它们不会导致一个完整的周期。
引用项目 当前项目。如何创建指向项目的链接取决于宿主应用程序。例如,若要在 Microsoft Excel 中直接引用项目,请从“工具”菜单的“引用”对话框中选择该项目。直接引用项目中的公共变量对直接引用的项目可见,但直接引用项目中的公共变量对直接引用的项目不可见。
定义公共模块级作用域 如果将模块级变量声明为公共变量,则该变量可用于项目中的所有过程。在以下示例中,字符串变量
strMsg
可由项目中任何模块中的任何过程使用。
包含在模块的“声明”部分中。
将 strMsg 作为字符串的公共 strMsg
默认情况下,除事件过程外,所有过程都是公开的。当 Visual Basic 创建事件过程时,会自动在过程声明之前插入 Private 关键字。对于所有其他过程,如果不希望该过程是公共的,则必须使用 Private 关键字显式声明该过程。
可以使用引用项目中的标准模块或类模块中定义的公共过程、变量和常量。但是,必须首先设置对定义它们的项目的引用。
在标准模块或类模块(如窗体模块或报表模块)之外定义的公共过程、变量和常量不可用于引用项目,因为这些模块对于它们所在的项目是私有的。
如果不引用相应的工作簿,并且工作簿中没有相同的变量,则无法直接从其他工作簿中读取变量。但是,您可以在不引用工作簿的情况下执行此操作,即使讨论中的变量被声明为 Private
,调用返回相应变量的函数:Public
- 在需要从中读取变量的工作簿的标准模块中,复制以下代码:
Option Explicit
Private myVar As String 'the variable to be returned in another workbook...
Sub GiveMyVarValue()
myVar = "test variable"
End Sub
Public Function GetMyvar() As String 'PUBLIC function!
GetMyvar = myVar
End Function
并运行以为相应的变量提供值(当然,您可以使用现有的过程/变量,但请注意将其作为函数的返回值。GiveMyVarValue
GetMyvar
- 使用活动工作簿中的下一个代码,从另一个工作簿中读取变量:
Sub ReadVariableFromDifferentWB()
Dim wb As Workbook: Set wb = Workbooks("Personal.xlsb") 'use here the real workbook name where from you need to return the variable
Dim x As String
x = Application.Run("'" & wb.name & "'!GetMyVar")
MsgBox x
End Sub
请在测试上述建议的解决方案后发送一些反馈,我需要时多次使用该解决方案......
评论
Option Explicit Private Sub UserForm_Initialize() Dim wb As Workbook: Set wb = Workbooks("Macros.xlsm") Label1.Caption = Application.Run("'" & wb.Name & "'!GetMyVar") End Sub
您无法访问项目外部的变量(项目基本上是您的 Excel 文件)。您的变量是不同的变量,file1 无法访问 file2。该关键字表示该变量在 file2 的整个项目中是全局变量(因此 file2 的所有模块都可以访问它),但对任何其他正在运行的 VBA 代码都不是公共的。confirm
confirm
public
但是,您可以做的是提供字符串作为函数的结果:confirm
Public Function GetConfirmString
For i = 3 To LastrowDBase
If DBase.Cells(i, 2) = SUBPN And DBase.Cells(i, 5) = "SomeText" Then
Confirm = Confirm & " - " & DBase.Cells(i, 3) & " - Flag: " & DBase.Cells(i, 7) & " - " & DBase.Cells(i, 6) & vbCrLf
End If
Next i
GetConfirmString = Confirm
End Function
您可以使用以下命令调用此函数:Application.Run
Private Sub UserForm_Initialize()
Label1.Caption = Application.Run ("'Macros.xlsm'!GetConfirmString")
End Sub
评论