【问题标题】:How do I declare a global variable in VBA?如何在 VBA 中声明一个全局变量?
【发布时间】:2011-02-12 21:49:12
【问题描述】:

我写了以下代码:

Function find_results_idle()

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

我收到错误消息:

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

你知道我做错了什么吗?

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

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

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

【问题讨论】:

    标签: excel vba scope global-variables


    【解决方案1】:

    我发现最好的方法是为工作簿分配一个属性

    只要工作簿打开,它的范围就一直有效

    Public WhenOpened As Date
    
    Private Sub Workbook_Open()
       ThisWorkbook.WhenOpened = Now()
    End Sub
    

    【讨论】:

      【解决方案2】:

      你也可以使用 -

      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
      

      已在 office 2010 上测试

      【讨论】:

        【解决方案3】:

        创建公共/全局变量的一个好方法是将表单视为类对象并声明属性并使用 Public Property Get [variable] 来访问属性/方法。此外,您可能需要引用或将引用传递给实例化的 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 值和空对象。

        【讨论】:

          【解决方案4】:

          正如其他人所说,问题实际上是关于范围的。

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

          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 reference 以了解有关变量声明的更多信息,以及查看其他Stack Overflow Question 了解有关变量如何超出范围的更多信息。

          另外两件事:

          1. 使用工作簿级别变量时要井井有条,这样您的代码就不会混乱。首选函数(具有适当的数据类型)或传递参数ByRef
          2. 如果您希望变量在调用之间保持其值,您可以使用 Static 语句。

          【讨论】:

          • 您确定全局变量可以在不同的工作簿中使用吗?不适合我
          • 好点!我注意到我没有添加关于我从哪里获得该信息的参考......我也没有再次找到它。最好编辑答案...:/哦,谢谢 Seb。
          【解决方案5】:

          在通用声明中创建一个公共整数。

          然后在你的函数中你可以每次都增加它的值。 查看示例(将电子邮件的附件保存为 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
          

          【讨论】:

            【解决方案6】:

            这是一个关于scope的问题。

            如果您只希望变量持续函数的生命周期,请在函数或子函数中使用DimDimension 的缩写)来声明变量:

            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
            

            global 变量(正如 SLaks 指出的那样)在函数外部使用 Public 关键字声明。此变量将在您运行的应用程序的生命周期内可用。对于 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 关键字声明只能在特定模块(或类)中访问的变量。

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

            【讨论】:

            • +1 7 年后仍然有用。但是关于对象变量与数据变量是否有一些额外的细微差别?我遇到了一个与范围对象变量相关的问题,它提示了一个新问题。非常感谢您有时间看一看。 stackoverflow.com/q/46058096/5457466
            • 我尝试了所有其他关于“范围”的建议,但没有一个奏效。唯一有效的是一个专门用于全局变量的新模块,它有效!
            【解决方案7】:

            如果这个函数在一个模块/类中,你可以把它们写在函数之外,所以它有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
            

            【讨论】:

              【解决方案8】:

              要使用全局变量,请从 VBA 项目 UI 中插入新模块并使用 Global 声明变量

              Global iRaw As Integer
              Global iColumn As Integer
              

              【讨论】:

              【解决方案9】:

              需要在函数外声明变量:

              Public iRaw As Integer
              Public iColumn As Integer
              
              Function find_results_idle()
                  iRaw = 1
                  iColumn = 1
              

              【讨论】:

              • 当我尝试将数组声明为公共时,它会说:数组和用户定义的数据类型不能声明为公共。
              • 以上第一个Function/Sub,不只是在外面:"模块级变量可以在顶部用 Dim 或 Private 语句声明第一个过程定义上面的模块。”(来自Scope of variables in Visual Basic for Applications
              猜你喜欢
              • 1970-01-01
              • 2012-03-30
              • 1970-01-01
              • 2011-03-22
              • 2012-11-11
              • 2019-09-11
              • 1970-01-01
              • 1970-01-01
              • 2011-06-22
              相关资源
              最近更新 更多