通过(动态)名称声明一个新的 DAO.Recordset
Posted
技术标签:
【中文标题】通过(动态)名称声明一个新的 DAO.Recordset【英文标题】:Declare a new DAO.Recordset by (dynamic) name 【发布时间】:2015-01-31 01:53:17 【问题描述】:这是用于创建 DAO 记录集的typical example:
Private Sub OpenOneRecordset()
Dim dbExercise As DAO.Database
Dim rsEmployees As DAO.Recordset
Set dbExercise = CurrentDb
Set rsEmployees = dbExercise.OpenRecordset("Employees")
dbExercise.Close
Set dbExercise = Nothing
End Sub
我想创建多个记录集,一个用于在数组中找到的每个名称:
Public Sub OpenAllRecordsets()
Dim dbExercise As DAO.Database
Set dbExercise = CurrentDb
For Each varTable In arrTables
strRecordsetName = "rst" & varTable
''Above is a string...
''How can I use the string to declare this object?
'' !!!!!!!!! OBVIOUSLY THIS WON'T WORK...
Dim strRecordsetName As DAO.Recordset
Set strRecordsetName = dbExercise.OpenRecordset(varTable)
Next
dbExercise.Close
Set dbExercise = Nothing
End Sub
我看不到如何动态声明名称,然后用它来制作记录集。我认为这与TableDefs
类似,我在其中调用集合并添加成员。你觉得呢?
在第一个发布的答案之后更新:
我在递归函数中使用这些记录集。它有效,但我想减少运行时间。我一直在为所需的新记录重新创建每个记录集。
If nodeThis.hasChildNodes Then
strTable = nodeThis.parentNode.nodeName
Dim rsNewChild As DAO.Recordset ' ***
Set rsNewChild = cnn.OpenRecordset(strTable, dbOpenDynaset) ' ***
rsNewChild.AddNew
'' ...populate fields
For Each ...
strName = nodeThis.nodeName
rsNewChild(strName) = nodeThis.Text
Next
rsNewChild.Update
rsNewChild.close ' ***
Set rsNewChild = Nothing ' ***
End If
但我知道需要哪些记录集,所以我宁愿在开始时将它们全部打开,然后根据需要调用。这会让我删除标记为***
的行。那么问题是如何使用字符串(在函数中可用)来调用给定的记录集。
为了更正确、更有帮助地重新陈述目标:我需要获取一个字符串并使用它来调用所需的记录集:
[ BASED ON STRING ].AddNew
对于 Barranka 的解决方案,我担心每次调用都会循环遍历该数组的资源。但我会试一试,做一些测试。
【问题讨论】:
【参考方案1】:正如 TableDefs
是 TableDef
对象的内置 Collection
一样,您可以创建自己的 Collection
Recordset
对象并按名称引用它们,如下所示:
Dim cdb As DAO.Database, rst As DAO.Recordset, myRecordsets As Collection
Dim testArray(1) As String, tblName As Variant
' test data
testArray(0) = "People"
testArray(1) = "OtherPeople"
' build the collection
Set myRecordsets = New Collection
Set cdb = CurrentDb
For Each tblName In testArray
Set rst = cdb.OpenRecordset(tblName, dbOpenTable)
myRecordsets.Add rst, tblName
Set rst = Nothing
Next
' use the members of the collection
Debug.Print myRecordsets("People").Fields("LastName").Value
myRecordsets("People").MoveNext
Debug.Print myRecordsets("People").Fields("LastName").Value
Debug.Print myRecordsets("OtherPeople").Fields("LastName").Value
Set myRecordsets = Nothing
Set cdb = Nothing
(注意Collections
对象的.Add
方法的参数是value, key
,这与Dictionary
的方式相反,其他关联数组在添加新条目时倾向于对其参数进行排序。 )
编辑回复:更新问题
这也有效
' add a new record
myRecordsets("OtherPeople").AddNew
myRecordsets("OtherPeople").Fields("LastName").Value = "NewPerson"
myRecordsets("OtherPeople").Update
【讨论】:
不错。您是否能够找到一种方法让 Intellisense 在myRecordsets("People").
之后显示记录集方法和属性?
@HansUp 在 VBA 下我不认为 IntelliSense 是一个选项,因为 VBA Collection
是任意对象的集合。 AFAIK 无法像在 VB.NET 中那样输入值(或键),我们可以在其中使用Dim myRecordsets As New Dictionary(Of String, Recordset)
。
接收read-to-go测试代码是一种特权。复制、粘贴、运行。
@HansUp ,您可以通过编写自定义集合类让 Intellisense 显示底层对象的成员。此类必须是Collection
对象的包装器,在文本编辑器中进行操作以允许默认成员,在这种情况下,集合的Item
属性重新转换为Recordset
对象。不过这很麻烦!【参考方案2】:
我会创建一个记录集数组:
dim rs() as DAO.Recordset
' You must redim the array with something like: ReDim rs(1 to UBound(arrTables))
dim i as Integer
' ...
i = 1
for each varTable in arrTables
Set rs(i) = dbExcercise.openRecordset(varTable)
i = i + 1;
next varTable
【讨论】:
听起来不错。为了向特定记录集添加记录,我是否必须遍历所有成员并根据rs(i).Name
检查我的姓名?我很确定这是 VBA 数组通常需要的……但是您知道快捷方式吗?
这是一个运行时速度问题。我有很多写操作。如果我可以独立定义记录集而不是运行循环来获取所需的记录集,那似乎更有效。
考虑使用集合或字典来保存以表名作为键的记录集,而不是数组。然后,您可以通过其表名键直接引用任何特定的记录集。
查看here 了解有关收藏的信息...我自己从未使用过它们,但这似乎是个好主意以上是关于通过(动态)名称声明一个新的 DAO.Recordset的主要内容,如果未能解决你的问题,请参考以下文章