MSAccess 2010 + VBA:值不是记录集字段对象的默认属性

Posted

技术标签:

【中文标题】MSAccess 2010 + VBA:值不是记录集字段对象的默认属性【英文标题】:MSAccess 2010 + VBA: Value is not a default property of recordset Field object 【发布时间】:2014-03-14 22:33:20 【问题描述】:

我需要使用 VBA 代码将 MS Access 表中的一些值复制到 Excel 中。我已经这样做了很多次,并认为自己经验丰富。在我的代码中,我使用以下语句导出数据:

sh.range("A" & row).Value = rs("MyField")

其中 sh 是 Excel 工作表,row 是整数(长整数),rs 是记录集(DAO 或 ADO,对所考虑的问题没有任何影响)。

我的代码在装有 MS Office 2007 的计算机上运行良好。但是当我的客户在装有 MS Office 2010 的计算机上运行代码时,它失败了,并且非常随机地失败。例如。当通过按 F8 逐步调试 MS Access 模块中的 VBA 时,它始终有效。但是当我按下'运行'F5时,它很快就失败了。

经过多次尝试和错误(我尝试使用不同的选项和记录集类型打开记录集并缓存记录等),我终于发现如果我写了

sh.range("A" & row).Value = rs("MyField").Value

一切正常。但是根据文档(例如 http://msdn.microsoft.com/en-us/library/office/ff197799(v=office.15).aspx ), Value 属性是字段对象的默认属性,而字段对象又是记录集对象的默认集合。

但似乎我不能依赖默认值,这是我在大部分代码中一直在做的。实际上我找到了解决问题的方法,但我仍然不知道原因。有谁知道为什么代码会这样做?有什么问题?

PS:我也发现如果我把一行语句展开成两行(三行带声明):

dim v as Variant
v = rs("MyField")
sh.range("A" & row).Value = v

它也有效...

【问题讨论】:

【参考方案1】:

由于rs("MyField") 是一个Field 对象,如果你这样做...

MsgBox TypeName(rs("MyField"))

... Access 会告诉你它的类型是 Field

所以TypeName() 是直接引用对象本身而不是其默认的.Value 属性的一个示例。

但是像Debug.Print 这样的东西总是引用.Value,所以Debug.Print rs("MyField")Debug.Print rs("MyField").Value 是一样的

如果您确切知道何时会隐式引用 .Value,何时不会,您可以仅在绝对需要时添加它,而在其余时间省略它。

但是,一些 Access 开发人员建议始终包含 .Value 以避免这种混淆。如果这对你来说似乎太费力了,至少考虑在你做任何任务时包括.Value ...

something = rs("MyField").Value

...并注意任何其他情况,如果没有.Value,您将无法获得想要的东西

【讨论】:

+1 以获得简洁的解释。长期以来,我一直是“如果你想要 .Value 就要求 .Value”阵营中的一员,而不是那些说“我可以依靠 .Value 作为默认属性来节省六次击键”的人(。 ..这很好,除非上下文指示引用是对对象而不是对象的默认属性...)。 谢谢。从现在开始,我将始终使用 xyz.Value 而不是依赖默认属性。这是一个教训。实际上,我现在很惊讶我之前没有遇到这个错误。

以上是关于MSAccess 2010 + VBA:值不是记录集字段对象的默认属性的主要内容,如果未能解决你的问题,请参考以下文章

MSAccess 2010 VBA打开只读数据库

在 ms access 2010 中将嵌入式宏转换为 vba 后,代码不再起作用

MS Access 2010 vba 查询

在 MSAccess 中使用 VBA (ADODB) 将数据从远程 DB 附加到本地表,而不锁定远程 DB 中的记录

ADO 记录集数据未显示在表单上

大型记录集 (VBA) 的 MS Access 插入慢