VBA 2关于变量范围和生存期的问题

VBA 2关于变量范围和生存期的问题,vba,module,scope,Vba,Module,Scope,关于如何使用VBA处理变量的作用域和生命周期,我已经讨论了两个问题 我有不同的潜艇,它们一遍又一遍地使用相同的变量。例如,将列定义为日期列、cDate或app作为应用程序的整数。因为我有一个相当大的声明部分,所以我想使用Global将其放在一个单独的模块中,但这不起作用。我在这里如何设置程序范围重要吗?我该怎么做 与Q1类似,初始化变量如何?具体地说,我没有复制和粘贴查找列标题的同一块(例如cDate),而是将其放入自己的过程中。我遇到了很多问题,试图让它工作。我希望这是可能的,也许不是 如果您

关于如何使用VBA处理变量的作用域和生命周期,我已经讨论了两个问题

  • 我有不同的潜艇,它们一遍又一遍地使用相同的变量。例如,将列定义为日期列、cDate或app作为应用程序的整数。因为我有一个相当大的声明部分,所以我想使用Global将其放在一个单独的模块中,但这不起作用。我在这里如何设置程序范围重要吗?我该怎么做

  • 与Q1类似,初始化变量如何?具体地说,我没有复制和粘贴查找列标题的同一块(例如cDate),而是将其放入自己的过程中。我遇到了很多问题,试图让它工作。我希望这是可能的,也许不是

  • 如果您需要查看代码,请告诉我。告诉我你想看什么,我就扔在这里。(PS-我已经通过VBA帮助、MSDN、Goole等,但这里有一些我不理解的东西)

    编辑:添加经过编辑的代码,因为真实的代码相当长。所有部分都在单独的标准模块中。我阅读了仅在工作簿级别及以下级别工作的全局声明,因此我还尝试在每个模块中将
    app
    wb
    wrk
    声明和设置为
    Public
    (此处未显示): 以下是我的声明:

    Option Explicit
    
    Global app As Application
    Global wb As Workbook
    Global wrk As Worksheet
    
    Global cInvoice As Byte
    
    Global iEndCol As Integer
    Global lEndRow As Long
    Global x As Integer
    
    Global sString1 As String
    
    Global rng As Range
    
    Private Sub Not_Really_a_sub()
        'No code. I read that any declaration needed to be in a module 
        ' with a procedure. I tried it with out the dummy sub also
    End Sub
     'green text, read me and notes
    
    以及执行调用的sub:

       Dim modulevariables As Integer
    
    Sub Calling_Sub()
    
     'doing things
    
     lEndRow = 1 'blah blah blah
     iEndCol = 1 ' blah blah blah
     app.Run "'" & ThisWorkbook.Name & "'!Header_Finder"
    
      'Code using cInvoice etc.
    
    End Sub
    
    和标题查找器:

    Private Sub Header_Finder()
      With wb.ActiveSheet
        For x = 1 To iEndCol
            If InStr(UCase(.Cells(x, 1)), UCase("Invoice")) > 0 Then
                cInvoice = x
            ElseIf .Cells(1, x) = "next thing" Then
                cNextThing = x
            End If
        Next
     End With
    End Sub
    
    已经谢谢了。

    Q1

    您可以在三个不同的级别声明变量。过程级(听起来像是你一直在做的事情,你想离开它)、模块级或项目级

    要在模块级别声明变量,只需在第一个过程之外声明它,例如

    Dim app As Application
    
    Sub mySub()
    ...
    
    该变量适用于模块内的所有程序。要使变量对其他模块中的过程可用,可以使用公共声明,例如

    Public app As Application
    
    Sub mySub()
    ....
    
    问题2

    如果有一个初始化变量的过程,可以根据需要从其他过程调用变量,那么最简单的方法就是这样做。例如,下面的代码创建一个名为PubStr的公共变量,并在从第二个过程调用的第一个过程中对其进行初始化

    Option Explicit
    Public PubStr As String
    
    Sub InitVar()
    PubStr = "Hello World!"
    End Sub
    
    Sub RunMe()
    Call InitVar
    MsgBox PubStr
    End Sub
    
    运行“RunMe”将调用初始化公共变量PubStr的InitVar过程

    希望这能有所帮助。

    Q1

    您可以在三个不同的级别声明变量。过程级(听起来像是你一直在做的事情,你想离开它)、模块级或项目级

    要在模块级别声明变量,只需在第一个过程之外声明它,例如

    Dim app As Application
    
    Sub mySub()
    ...
    
    该变量适用于模块内的所有程序。要使变量对其他模块中的过程可用,可以使用公共声明,例如

    Public app As Application
    
    Sub mySub()
    ....
    
    问题2

    如果有一个初始化变量的过程,可以根据需要从其他过程调用变量,那么最简单的方法就是这样做。例如,下面的代码创建一个名为PubStr的公共变量,并在从第二个过程调用的第一个过程中对其进行初始化

    Option Explicit
    Public PubStr As String
    
    Sub InitVar()
    PubStr = "Hello World!"
    End Sub
    
    Sub RunMe()
    Call InitVar
    MsgBox PubStr
    End Sub
    
    运行“RunMe”将调用初始化公共变量PubStr的InitVar过程


    希望这会有所帮助。

    这不是一个真正的答案,但我需要包含一些代码。作为测试,我将以下代码放在一个模块(模块1)中:

    另一个模块(模块2)中的代码:

    这对我很管用。你能试着在新的工作簿中做同样的事情,并让我知道它是如何进行的吗?此外,您可以尝试更明确地指定引用的变量,如(仍在模块2中):


    不是一个真正的答案,但我需要包括一些代码。作为测试,我将以下代码放在一个模块(模块1)中:

    另一个模块(模块2)中的代码:

    这对我很管用。你能试着在新的工作簿中做同样的事情,并让我知道它是如何进行的吗?此外,您可以尝试更明确地指定引用的变量,如(仍在模块2中):


    由于这不适用于我的其他(非)答案,但我需要再次包括一些代码,我将把它放在这里

    在“变量”模块中,您要声明变量:

    dim wb as Workbook
    
    在使用此变量之前,必须对其进行初始化,即给它一个值(这些示例中的任何一个都可以使用,每个都适用于不同的场景):

    如果在访问该变量之前未初始化该变量,如本例所示:

    dim wb as Workbook
    debug.print wb.name
    
    您将收到错误:“运行时错误'91':未设置对象变量或带块变量”

    只有对象变量需要初始化。其他数据类型则不然。简单地说,非对象数据类型如下所示。默认值(声明时初始化)在括号中:

    • 整数[0]
    • 长[0]
    • 字符串[“”]
    • 双精度[0]
    • 单一[0]
    • 日期[0,或1899年12月30日]
    • 字节[0]
    • 布尔值[假]
    • 货币[$0]
    其他一切都是一个对象,需要某种初始化。例如:

    Option Explicit
    
    Dim wb as Workbook
    Dim app as Excel.Application
    Dim wrk as Worksheet
    
    Set app = Application
    Set wb = app.workbooks(1)
    Set wrk = wb.sheets(1)
    
    'If any of the lines preceding this line are skipped, an error will occur.
    debug.print wrk.name
    

    很抱歉,如果你已经知道这一点(真的,我很抱歉,这是很多东西要写!),我只是想确保我们在上面的评论讨论之后在同一页上。

    因为这与我的其他(非)答案无关,但我需要再次包含一些代码,我将把它放在这里

    在“变量”模块中,您要声明变量:

    dim wb as Workbook
    
    在使用此变量之前,必须对其进行初始化,即给它一个值(这些示例中的任何一个都可以使用,每个都适用于不同的场景):

    如果在访问该变量之前未初始化该变量,如本例所示:

    dim wb as Workbook
    debug.print wb.name
    
    您将收到错误:“运行时错误'91':未设置对象变量或带块变量”

    只有对象变量需要初始化。其他数据类型则不然。简单地说,非对象数据类型如下所示。默认值(声明时初始化)在括号中: