如何在 VBA 中声明全局变量?

我写了以下代码:

Function find_results_idle()


Public iRaw As Integer
Public iColumn As Integer
iRaw = 1
iColumn = 1

我得到了错误消息:

“子或函数中的无效属性”

你知道我做错了什么吗?

我尝试使用 Global而不是 Public,但是遇到了同样的问题。

我尝试将函数本身声明为‘ Public,但这也没有用。

我需要做什么来创建全局变量?

1100371 次浏览

你需要在函数之外声明变量:

Public iRaw As Integer
Public iColumn As Integer


Function find_results_idle()
iRaw = 1
iColumn = 1

若要使用全局变量,请从 VBAProjectUI 中插入新模块,并使用 Global声明变量

Global iRaw As Integer
Global iColumn As Integer

这是一个关于 范围的问题。

如果只想让变量持续函数的生命周期,那么在函数或子函数中使用 Dim(尺寸的缩写)来声明变量:

Function AddSomeNumbers() As Integer
Dim intA As Integer
Dim intB As Integer
intA = 2
intB = 3
AddSomeNumbers = intA + intB
End Function
'intA and intB are no longer available since the function ended

使用 Public关键字在函数外声明 全球性的变量(正如 SLaks 所指出的)。此变量将在运行应用程序期间可用。对于 Excel,这意味着只要打开特定的 Excel 工作簿,变量就是可用的。

Public intA As Integer
Private intB As Integer


Function AddSomeNumbers() As Integer
intA = 2
intB = 3
AddSomeNumbers = intA + intB
End Function
'intA and intB are still both available.  However, because intA is public,  '
'it can also be referenced from code in other modules. Because intB is private,'
'it will be hidden from other modules.

还可以通过使用 Private关键字声明只能在特定模块(或类)中访问的变量。

如果您正在构建一个大型应用程序,并且感到需要使用全局变量,我建议为您的全局变量创建一个单独的模块。这应该可以帮助您在一个地方跟踪他们。

如果这个函数在一个模块/类中,那么可以在函数外部编写它们,因此它有 Global Scope。Global Scope 意味着变量可以被另一个函数 在同一个模块/类中访问(如果使用 dim作为声明语句,如果希望变量可以被所有模块中的所有函数访问,则使用 public) :

Dim iRaw As Integer
Dim iColumn As Integer


Function find_results_idle()
iRaw = 1
iColumn = 1
End Function


Function this_can_access_global()
iRaw = 2
iColumn = 2
End Function

在“常规声明”中创建公共整数。

然后在你的函数中你可以每次增加它的值。 参见示例(将电子邮件附件保存为 CSV 的函数)。

Public Numerator As Integer


Public Sub saveAttachtoDisk(itm As Outlook.MailItem)
Dim objAtt As Outlook.Attachment
Dim saveFolder As String
Dim FileName As String


saveFolder = "c:\temp\"


For Each objAtt In itm.Attachments
FileName = objAtt.DisplayName & "_" & Numerator & "_" & Format(Now, "yyyy-mm-dd H-mm-ss") & ".CSV"
objAtt.SaveAsFile saveFolder & "\" & FileName
Numerator = Numerator + 1


Set objAtt = Nothing
Next
End Sub

正如另一个人所说,问题的关键在于范围。

简而言之,考虑一下这个“模块”:

Public Var1 As variant     'Var1 can be used in all
'modules, class modules and userforms of
'thisworkbook and will preserve any values
'assigned to it until either the workbook
'is closed or the project is reset.


Dim Var2 As Variant        'Var2 and Var3 can be used anywhere on the
Private Var3 As Variant    ''current module and will preserve any values
''they're assigned until either the workbook
''is closed or the project is reset.


Sub MySub()                'Var4 can only be used within the procedure MySub
Dim Var4 as Variant    ''and will only store values until the procedure
End Sub                    ''ends.


Sub MyOtherSub()           'You can even declare another Var4 within a
Dim Var4 as Variant    ''different procedure without generating an
End Sub                    ''error (only possible confusion).

您可以查看这个 MSDN 参考了解更多关于变量声明的信息,查看另一个 堆栈溢出问题了解更多关于变量如何超出作用域的信息。

还有两件事:

  1. 使用工作簿级别变量时要有组织,这样代码就不会混乱。首选 职能(具有适当的数据类型)或传递参数 拜,裁判
  2. 如果希望变量在调用之间保持其值,可以使用 静电干扰语句。

创建 Public/Global 变量的一个好方法是将 Form 视为类对象并声明属性,然后使用 Public Property Get [ variable ]访问 Property/method。还可能需要引用或传递对实例化的 Form 模块的引用。如果对关闭的窗体/报表调用方法,则会得到错误。
示例: 将 Me. Form. Module. Parent 传递到子/函数中,而不是在表单中。

Option Compare Database
Option Explicit
''***********************************''
' Name: Date: Created Date Author: Name
' Current Version: 1.0
' Called by:
''***********************************''
' Notes: Explain Who what when why...
' This code Example requires properties to be filled in
''***********************************''
' Global Variables
Public GlobalData As Variant
''***********************************''
' Private Variables
Private ObjectReference As Object
Private ExampleVariable As Variant
Private ExampleData As Variant
''***********************************''
' Public properties
Public Property Get ObjectVariable() As Object
Set ObjectVariable = ObjectReference
End Property
Public Property Get Variable1() As Variant
'Recommend using variants to avoid data errors
Variable1 = ExampleVariable
End property
''***********************************''
' Public Functions that return values
Public Function DataReturn (Input As Variant) As Variant
DataReturn = ExampleData + Input
End Function
''***********************************''
' Public Sub Routines
Public Sub GlobalMethod()
'call local Functions/Subs outside of form
Me.Form.Refresh
End Sub
''***********************************''
' Private Functions/Subs used not visible outside
''***********************************''
End Code

所以在另一个模块中,你可以访问:

Public Sub Method1(objForm as Object)
'read/write data value
objForm.GlobalData
'Get object reference (need to add Public Property Set to change reference object)
objForm.ObjectVariable
'read only (needs Public property Let to change value)
objForm.Variable1
'Gets result of function with input
objForm.DataReturn([Input])
'runs sub/function from outside of normal scope
objForm.GlobalMethod
End Sub

如果您像我一样使用后期绑定,那么在尝试执行任何处理之前,总是要检查 Null 值和 Nothing 对象。

你也可以使用-

Private Const SrlNumber As Integer = 910


Private Sub Workbook_Open()
If SrlNumber > 900 Then
MsgBox "This serial number is valid"
Else
MsgBox "This serial number is not valid"
End If
End Sub

它在2010年进行了测试

我发现的最佳方法是将属性分配给工作簿

只要工作簿是打开的,它的作用域就是有效的

Public WhenOpened As Date


Private Sub Workbook_Open()
ThisWorkbook.WhenOpened = Now()
End Sub