【问题标题】:When are VBA Variables Instantiated何时实例化 VBA 变量
【发布时间】:2016-08-13 14:19:46
【问题描述】:

我有点犹豫,但我找不到VBA的文档。

相关(但我不认为是骗子):

我认为我使用“实例化”这个词是对的,但如果我错了,请纠正我。 实例化是什么时候创建一个变量并分配它所需的资源?所以在 VBA 中我看到了两种方法。

一切都在顶部!

Public Sub ToTheTop()
    Dim var1 As Long
    Dim var2 As Long
    Dim var3 As Long

    var1 = 10
    var2 = 20
    var3 = var1 + var1
    Debug.Print var3
End Sub

或接近使用

Public Sub HoldMeCloser()
    Dim var1 As Long
    var1 = 10
    Dim var2 As Long
    var2 = 20
    Dim var3 As Long

    var3 = var1 + var1
    Debug.Print var3
End Sub

我喜欢让它们更容易使用,以便更容易记住它们是什么,而其他人可能希望将它们全部排除在外。这是个人喜好。

但是,我想我记得在某处读到 VBE 通过子/函数并实例化所有变量,然后再进行任何其他操作。这将表明在 VBA 中没有正确的方法可以做到这一点,因为变量范围及时不会改变。不是PrivatePublic 中的范围。

而在其他语言中,范围似乎可以根据位置而改变,因此有一个最佳实践

我一直在搜索此文档一段时间,但无论我使用什么词都没有为我指明正确的方向,或者文档不存在。

【问题讨论】:

  • 我同意彼得的回答和托马斯的说法,即普遍接受的做法是在过程的顶部声明变量。 “全局”变量必须位于模块的顶部,在任何过程之前。 VBA 识别的唯一“范围”是“全局”(公共,模块级),模块级(私有,模块级)与过程级。没有“块范围”,例如在 If 中。
  • "Instantiated" 是关于正在创建的对象,我会避免在其他上下文中使用它;我相信正确的词应该是“初始化”。

标签: vba variables scope


【解决方案1】:

变量、常量和对象都是以这种方式实例化的:

  • 模块级别,它们在应用程序启动时被实例化,无论它们被声明为publicprivate 还是static

  • 过程 级别(子/函数),它们在过程执行时被实例化。

你必须明白,虽然它有一个“编译器”,vba 不是真正的编译语言。编译器是一个语法检查器,用于检查代码中的错误,以免在运行时遇到它们。在 MS 访问中,编译器生成称为 p-code 的东西,它是 编译解释 代码的组合。

根据经验:

  • 始终使用option explicit 语句(为此配置您的编译器)

  • 总是在一个地方声明你的变量,在你的模块或子/函数的顶部,并避免在你的代码中间这样做,只是为了清楚起见。这不会以任何方式影响性能。

  • 避免使用variant 数据类型

值得一读的文档: Understanding the Lifetime of Variables(官方mSDN)、Visual/Access Basic Is Both a Compiler and an Interpreter(官方MS)和Declaring variables。您可能还会发现我最近给出的关于 vba garbage collector 的答案很有趣

【讨论】:

  • 关于何时创建过程变量是不正确的。它们是在过程开始执行(生命周期)时创建的,但在声明点(范围)之前是不可访问的。
  • 总是在一个地方声明你的变量,在你的模块或子/函数的顶部,并避免在你的代码中间这样做,只是为了清楚起见 - 这就是我们如何在作用域顶部的声明墙上获得 30 个变量,其中 10 个从未使用过,4 个有一个无用的名称后跟一个数字,......我永远不明白为什么声明更接近使用最适合VBA 以外的任何语言 的可读性。这不是个人偏好,它是 90 年代已经过时的“最佳实践”的一部分,需要用匈牙利表示法留在过去。
【解决方案2】:

根据reference documentation

当程序开始运行时,所有变量都被初始化。数值变量初始化为零,可变长度字符串初始化为零长度字符串(“”),固定长度字符串填充ASCII字符代码0表示的字符,或Chr(0) . Variant 变量被初始化为 Empty。用户定义类型变量的每个元素都被初始化为一个单独的变量。

当您声明一个对象变量时,内存中会保留空间,但它的值会设置为 Nothing,直到您使用 Set 语句为其分配对象引用。

这意味着无论变量声明在哪里声明,它的空间/内存都是在进入过程时分配的。

【讨论】:

  • 谢谢,这正是我要找的文档。
猜你喜欢
  • 2014-10-05
  • 1970-01-01
  • 2015-04-26
  • 2012-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-23
  • 2014-09-14
相关资源
最近更新 更多