Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel 如何在VBA中设置全局变量_Excel_Vba - Fatal编程技术网

Excel 如何在VBA中设置全局变量

Excel 如何在VBA中设置全局变量,excel,vba,Excel,Vba,我想在一个模块的VBA中定义一个全局变量,并在其他VBA模块中使用它 我试着遵循: 我创建了一个名为“GlobalVariables”的新模块,首先声明公共变量,然后在函数中设置它们的值(试图在开放代码中这样做会导致错误)。我的代码如下 但是全局变量StartYear似乎不适用于其他VBA模块。我做错了什么 Option Explicit Public StartYear As Integer Public BaseYear As Integer Function DeclareGlobal

我想在一个模块的VBA中定义一个全局变量,并在其他VBA模块中使用它

我试着遵循:

我创建了一个名为“GlobalVariables”的新模块,首先声明公共变量,然后在函数中设置它们的值(试图在开放代码中这样做会导致错误)。我的代码如下

但是
全局
变量StartYear似乎不适用于其他VBA模块。我做错了什么

Option Explicit

Public StartYear As Integer
Public BaseYear As Integer

Function DeclareGlobalVariables()
    StartYear = ActiveWorkbook.Worksheets("RunModel").Range("StartYear").Value
    BaseYear = ActiveWorkbook.Worksheets("RunModel").Range("BaseYear").Value
End Function
  • 确保将golobal变量放在模块中,而不是工作表范围中,以便在其他模块中访问它

  • 您的
    函数
    应该是
    子函数
    ,因为它不返回任何内容

  • 如果单元格中包含文本(字符串),则代码将出错。永远不要相信用户的输入始终验证

  • 因此,我建议如下

    模块1

    Option Explicit
    
    Public StartYear As Long
    Public BaseYear As Long
    
    Public Function InitializeGlobalVariables() As Boolean
        InitializeGlobalVariables = True
        With ActiveWorkbook.Worksheets("RunModel").Range("StartYear")
            If IsYear(.Value) Then
                StartYear = CLng(.Value)
            Else
                InitializeGlobalVariables = False
                MsgBox "StartYear needs to be a number"
            End If
        End With
    
        With ActiveWorkbook.Worksheets("RunModel").Range("BaseYear")
            If IsYear(.Value) Then
                BaseYear = CLng(.Value)
            Else
                InitializeGlobalVariables = False
                MsgBox "BaseYear needs to be a number"
            End If
        End With
    End Function
    
    'validate if the input value is a valid year
    Private Function IsYear(ByVal InputValue As Variant) As Boolean
        If IsNumeric(InputValue) Then
            If CLng(InputValue) = InputValue And _
               InputValue > 0 And InputValue < 9999 Then 'integer not decimal AND 4 digit year
                IsYear = True
            End If
        End If
    End Function
    

    代码对我来说似乎是正确的。您的意思是不能在其他模块中使用该变量,还是它没有您期望的值?您的代码看起来是正确的。我试过了,可以访问其他模块中的变量。检查它们是否正确分配了值。DeclareGlobalVariables应该是一个子函数,而不是函数,您还需要执行它,以便初始化全局变量。与您的问题无关,但不要使用
    Integer
    变量。此数据类型可能无法保存您正在使用的数值,从而导致溢出错误。谢谢您,佩赫,非常感谢。通过测试,您似乎必须运行或调用sub来初始化它。考虑到我习惯的其他语言,这似乎有点笨拙。如果我有一堆函数将使用StartYear和BaseYear,并且我不想继续将这些值作为参数输入,那么初始化变量的最佳方法是什么?在每个函数中调用DeclareGlobalVariables()似乎效率低下。打开EXCEL工作簿时,是否最好尝试调用此子项?好的,每个使用全局变量的函数/过程都需要检查它们是否已设置。如果在打开工作簿时初始化它们,它们将被初始化,直到工作簿关闭,但是如果出现任何错误,代码意外停止,则全局变量可能最终未初始化(being
    0
    )。因此,如果变量已初始化,则应检入每个过程/函数(例如,检查它是否不是
    0
    ,因为如果依赖它初始化或使用有效的用户输入,则可能导致过程失败。@brb我将上面的过程更改为一个函数,以显示我的意思。这是一种安全的方法,可以不依赖任何关于全局变量的值或状态的假设。
    Option Explicit
    
    Public Sub TestOutput()
        'before using the variables test if they are initialized (not 0)
        If StartYear = 0 Or BaseYear = 0 Then 
            'they are not initalized so initalize them (and at the same time check if it was successful)
            If InitializeGlobalVariables = False Then 
                'the function returns FALSE if the initialization process failed so we need to cancel this procedure or we use not initilized variables!
                 MsgBox "Variables were not intitialized. Trying to initialize them failed too. I cannot proceed."
                 Exit Sub
            End If
        End If
    
        Debug.Print StartYear
        Debug.Print BaseYear
    End Sub