VBA和MS-Access中的Bang表示法和点表示法

在仔细阅读我正在记录的应用程序时,我在访问对象属性/方法等过程中遇到了一些爆炸符号示例,在其他地方,它们使用点符号来实现相同的目的。


使用一种或另一种有区别或偏好吗?一些简单的谷歌搜索只能显示有关该主题的有限信息,而有些人实际上是在相反的情况下使用它的。也许在某个地方有来自MS的编码标准部分指出了疯狂的方法?


海绵宝宝撒
浏览 566回答 3
3回答

慕田峪4524236

尽管已(以前)接受了该问题的答案,但该爆炸实际上并不是成员或集合访问运算符。它做了一件简单而又具体的事情:bang运算符通过将bang运算符后的文字名称作为字符串参数传递给该默认成员,从而提供对对象默认成员的后期绑定访问。而已。该对象不必是集合。它不必具有称为的方法或属性Item。它所需要的只是一个Property Get或Function可以接受字符串作为第一个参数的参数。有关更多详细信息和证明,请参阅我的博客文章讨论:爆炸!VBA中的(感叹号运算符)

慕的地6264312

一对陷阱可作为已发布的两个出色答案的补充:访问表单与报表中的记录集字段 Access中Form对象的默认项是表单的Controls集合和表单记录集的Fields集合的并集。如果控件的名称与字段的名称冲突,则不确定实际返回哪个对象。由于字段和控件的默认属性都是它们的.Value,因此通常是“无区别的区分”。换句话说,通常不关心它是因为字段和控件的值通常是相同的。当心命名冲突!Access的“表单和报表”设计器默认将绑定控件的命名与绑定到的记录集字段的命名相同,从而加剧了这种情况。我个人采用了使用控件类型前缀重命名控件的约定(例如,tbLastName绑定到LastName字段的文本框)。报表记录集字段不存在!我之前说过Form对象的默认项是Controls和Fields的集合。但是,报表对象的默认项目只是其控件集合。因此,如果要使用bang运算符引用记录集字段,则需要将该字段包括为绑定控件(如果需要的话)的源。当心与显式表单/报表属性发生冲突当将控件添加到表单或报表中时,Access会自动创建引用这些控件的属性。例如,tbLastName通过引用可以从表单的代码模块中获得名为的控件Me.tbLastName。但是,如果Access与现有表单或报表属性冲突,它将不会创建此类属性。例如,假设添加了一个名为Pages的控件。Me.Pages在窗体的代码模块中引用将返回窗体的Pages属性,而不是名为“ Pages”的控件。在此示例中,可以Me.Controls("Pages")使用bang运算符显式或隐式访问“ Pages”控件Me!Pages。但是请注意,使用bang运算符意味着,如果表单的记录集中存在一个Access字段,则它可能会返回一个名为“ Pages”的字段。那.Value呢?尽管未在问题中明确提及,但以上评论中提到了该主题。字段对象和大多数“可数据绑定”¹控件对象的默认属性是.Value。由于这是默认属性,因此通常总是明确地将其包括在内不必要地冗长。因此,这是标准做法:Dim EmployeeLastName As StringEmployeeLastName = Me.tbLastName代替:EmployeeLastName = Me.tbLastName.Value键入字典时,请注意细微的.Value错误。在某些情况下,此约定可能会导致细微的错误。我实际上在实践中碰到的最引人注目的(如果只有内存可用的话)是在将“字段/控件”的值用作“字典”键时使用的。Set EmployeePhoneNums = CreateObject("Scripting.Dictionary")Me.tbLastName.Value = "Jones"EmployeePhoneNums.Add Key:=Me.tbLastName, Item:="555-1234"Me.tbLastName.Value = "Smith"EmployeePhoneNums.Add Key:=Me.tbLastName, Item:="555-6789"人们可能希望上面的代码在EmployeePhoneNums字典中创建两个条目。而是在最后一行抛出错误,因为我们正在尝试添加重复键。即,tbLastName控件对象本身是键,而不是控件的值。在这种情况下,控件的值甚至无关紧要。实际上,我希望对象的内存地址(ObjPtr(Me.tbLastName))可能是幕后用来索引字典的内容。我做了一个快速测试,似乎证实了这一点。'Standard module:Public testDict As New Scripting.DictionarySub QuickTest()    Dim key As Variant    For Each key In testDict.Keys        Debug.Print ObjPtr(key), testDict.Item(key)    Next keyEnd Sub'Form module:Private Sub Form_Current()    testDict(Me.tbLastName) = Me.tbLastName.Value    Debug.Print ObjPtr(Me.tbLastName); "..."; Me.tbLastNameEnd Sub运行上面的代码时,每次关闭并重新打开表单时,都会添加一个词典项。从一个记录移到另一个记录(并因此导致对Form_Current例程的多次调用)不会添加新的词典项,因为它是Control对象本身索引该词典,而不是Control的值。我的个人建议/编码约定多年来,我采用了以下做法,即YMMV:与控制型指标前缀窗体/报表控件名称(如tbTextBox,lblLabel等)使用Me.符号(例如Me.tbLastName)引用代码中的表单/报表控件避免创建与表/查询字段有问题的名字摆在首位Me!发生冲突时(例如,与旧版应用程序(例如Me!Pages))使用符号包括隐藏的报表控件以访问报表Recordset字段值.Value仅在情况需要增加详细程度时才明确包括(例如,词典键)¹ 什么是“数据可绑定”控件?基本上是具有ControlSource属性的控件,例如TextBox或ComboBox。不可绑定的控件将类似于Label或CommandButton。TextBox和ComboBox的默认属性为.Value; 标签和命令按钮没有默认属性。
打开App,查看更多内容
随时随地看视频慕课网APP