【问题标题】:Referencing global variable - MS Access引用全局变量 - MS Access
【发布时间】:2010-08-16 03:41:19
【问题描述】:

我试图将全局变量的名称传递给子例程,并想知道如何引用它。例如,我可以使用控件执行以下操作:

Private Sub passCtrlName(ctlName as String)
Me.Controls(ctlName) = "Whatever"
End Sub

编辑:

举例

Public imGlobVar As String
Public Sub passGlobVar(frm as Form, ctlName as String, globVar as String)
frm.Controls(ctlName) = globVar
End sub

并将其称为 私有子 imaButton_Click() imGlobVar = "某事" 调用 passGlobVar(Me , txtBox1, imGlobVar) 结束子

第二次编辑:

看来我肯定是在这里找错了树,所以我将解释我想要实现的目标。

我有一个表单,其中包含用户(风险)地址的文本框,顶部有一个复选框,允许用户选择此地址与系统上已有的“联系人”详细信息相同,并且文本框是锁定。

填充文本框很好并且有效。我使用全局变量的目的是为了提高可用性(尽管有一点点)。 用户可以添加新的详细信息,如果他们点击“与联系人相同”复选框,他们输入的详细信息将存储在全局变量中,每个控件都有一个。

如果用户打错了复选框,他们并没有丢失这些值,并且通过取消选中该框,输入的值将被返回。 我希望创建一个子例程,我可以在其中传递全局变量和控件的名称并调用此例程,而不是为每个控件编写它。

我有一种感觉,我可能使用了错误的技术来实现我的目标。但在回答我最初的问题时,您似乎无法以我希望的方式将全局变量传递给子例程。

【问题讨论】:

  • 在我看来,您可能会考虑在表单级别使用内存结构,例如保存相关字段原始值的 snapshop 记录集。在这种情况下,全局变量显然是错误的范围。您最终使用的任何数据结构是否需要公开尚待确定。如果您在子表单中需要它并且它将在父表单中定义,那么如果您从子表单中使用它,则它需要是公共的。但这与 GLOBAL 非常不同。

标签: ms-access vba ms-access-2007


【解决方案1】:

您不需要传递全局变量,您可以简单地通过名称引用它们。请注意,如果发生未处理的错误,则会重置全局变量。

http://msdn.microsoft.com/en-us/library/dd897495(office.12).aspx 中,您将找到关于变量和常量的作用域和生命周期的部分。

在一个模块中:

Option Explicit 
Public glbVarName As String
Const MyConstant=123

Sub InitVar
   glbVarName="Something"
End Sub

任何其他模块,包括表单的类模块:

Sub SomeSub
    MsgBox glbVarName
    SomeVar=2+MyConstant
End Sub

【讨论】:

  • 嗨 Remou,你的意思是我可以将其称为“Private Sub passCtrlName(glbVarName as Global)”吗?或者类似的东西?我需要能够将全局变量名称传递给子。
  • 不,我添加了一些注释以确保我们指的是同一件事。也许,如果你确切地说出你想做什么以及为什么,别人给你一个方法可能会更容易。
  • 嗨 Remou,我知道我可以通过名称引用全局变量。我想要实现的是将全局变量传递给子例程(因此无法保证名称,因为它可能是众多变量之一),然后在例程中引用它。希望我上面的编辑有助于使其更清晰。
  • 我可以看到你想要做什么,但为什么呢?这将解决的根本问题是什么?为什么需要传递变量的名称而不是值?
  • 你为什么认为你需要一个全球性的?首先要避免使用全局变量,但是全局存储某些内容的原因是它在所有代码上下文中都是全局可用的。因此,它不必作为参数传入。
【解决方案2】:

如果您问是否可以使用包含变量名称的字符串动态引用全局变量,答案是否定的。您可以使用单个全局数组并传递索引,这将允许您动态引用数组的元素。

[编辑]
针对问题中的说明:当用户选中复选框时,您可以将每个控件的值保存到其 Tag 属性中。然后,如果用户取消选中该复选框,您只需遍历控件并将值从 Tag 分配回控件的 Value

【讨论】:

  • 是的,Ben 这就是我希望做的,不幸的是我不能,为有关数组的建议欢呼。
  • Eval 不接受 VBA 中用户定义变量的名称,只接受用户定义函数 AFAIK。
  • @BenV:代表我道歉,糟糕的stackoverflow礼仪!
  • @glinch:没问题。针对问题中的说明,我已经用可能的解决方案更新了我的答案。
  • 很好的建议 BenV,将与 Remou 一起使用 defaultValue 作为我使用标签的其他东西。干杯都一样,从来没有想过以这种方式使用这些属性。
【解决方案3】:

您可以将控件的值存储在 Dictionary 对象中,使用控件名称作为字典键。然后您可以根据控件的名称检索每个控件的值。

Option Compare Database
Option Explicit

Const cstrMyControls As String = "Text0,Text2,Text4,Text6"
Dim objDict As Object

Private Sub chkToggle_Click()
    If Me.chkToggle = True Then
        Call SaveValues
    Else
        Call RestoreValues
    End If
End Sub

Private Sub SaveValues()
    Dim varControls As Variant
    Dim i As Long

    Set objDict = Nothing 'discard previous saved values '
    Set objDict = CreateObject("Scripting.Dictionary")
    varControls = Split(cstrMyControls, ",")
    For i = 0 To UBound(varControls)
        objDict.Add varControls(i), Me.Controls(varControls(i)).Value
    Next i
End Sub

Private Sub RestoreValues()
    Dim varControls As Variant
    Dim i As Long
    If objDict Is Nothing Then
        'MsgBox "No values to restore." '
    Else
        varControls = objDict.keys()
        For i = 0 To UBound(varControls)
            Me.Controls(varControls(i)).Value = objDict(varControls(i))
        Next i
    End If
End Sub

【讨论】:

  • 是否有理由使用脚本对象字典而不是 VBA 自定义集合或数组?
  • 我选择字典而不是集合,因为字典有一个 .keys() 方法,这里实际上没有必要。我没有考虑使用数组。此外,由于 Python,我仍然倾向于首先考虑字典。
  • @HansUp 为另一种我根本不知道的技术欢呼,非常感谢。
  • 我将集合用于单列列表。它们非常易于使用且速度极快。我只在需要多个属性时才使用数组。我从未使用过字典对象,因为它不是由 Access/VBA 提供的。 .Keys() 方法有什么作用?
  • .keys() 返回字典键的数组。当您将密钥分配给集合项时,我不知道如何检索密钥。我的方法是使用控件名称作为项的键,控件的值作为项的值。但是,既然你提到了单列列表,我想我们对这件事的看法不同。我很想从您的 POV 中听到更多信息。
【解决方案4】:

我在表中使用附加字段 - 名称取消 - 当然是布尔值 - 当我不确定字段内容是否有效时,我将其设置为 true。如果这个字段到最后是真的 - 然后我清理(当然可能是所有记录或一些文件)。很简单。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多