当一个函数从 Access 表中获取一列字段值并将其放入 VBA 集合并返回该集合时,我看到了一种奇怪的情况。该函数将表名和字段名作为参数,并返回包含字段列中所有(或唯一)值的集合。当 sub 运行此函数时,sub 可以读取结果集合中的元素计数。但是,当子尝试访问元素错误结果时。
我说“错误”是因为当我尝试以不同方式访问元素时会得到不同的错误。例如,如果我尝试通过键访问集合元素:
For i=0 to col.count
Debug.Print col(Cstr(i)) ' results in error: "Automation error"
i=i+1
Next
我收到“自动化错误”。但是当我尝试通过 For Each 访问集合元素时
For Each var in col
Debug.Print var ' results in error: "Object invalid or no longer set."
Next
同样奇怪的是,集合的元素可以在将返回它的函数内访问,但不能在集合返回给调用子时访问。但是调用 sub 可以访问集合计数。
使用 Access 表的相同方法可以很好地将一列字段值放入数组中。函数返回一列字段值的数组后,可以将该数组转换为集合。生成的集合可以传递给另一个 sub 并在其中使用。但是该方法不能让函数从 Access 获取信息,将其打包到一个集合中并将包含来自 Access 的信息的集合返回给调用子。
我的代码如下。我已经尝试过,但找不到任何与远程相关的问题。
Option Compare Database
Option Explicit
Sub colUniqueTableValues_tester()
Dim col As New Collection
Dim var As Variant
Dim i As Integer
Dim strTable As String: strTable = "tbl_Projects"
Dim strField As String: strField = "Project_Code"
Set col = colUniqueTableValues(strTable, strField)
Debug.Print "colListOfUniqueValues_tester: col.count = " + CStr(col.Count)
' Set col = colAnyLengthAndStep(4, 1) ' sub will complete if the collection from Access is overwritten
i = 0
For Each var In col
i = i + 1
Debug.Print CStr(i) + ": " + col(CStr(i)) ' results in error: "Automation error"
Debug.Print var ' returns error: "Object invalid or no longer set."
Next
Set col = Nothing
End Sub
Function colUniqueTableValues(ByVal strTable As String, ByVal strField As String) As Collection
Dim strSQL As String
Dim rs As Recordset
Dim dbs As Database
Dim i As Integer
Dim col As New Collection
strSQL = "Select distinct " + strField + " from " + strTable
Set dbs = CurrentDb
Set rs = dbs.OpenRecordset(strSQL)
i = 0
rs.MoveFirst
Do While Not rs.EOF
col.Add rs.Fields(strField), CStr(i)
Debug.Print "Function: " + col(CStr(i)) 'check value
rs.MoveNext
i = i + 1
Loop
Set colUniqueTableValues = col
Debug.Print "colUniqueTableValues: colUniqueTableValues.count = " + CStr(colUniqueTableValues.Count)
Set dbs = Nothing
Set rs = Nothing
Set col = Nothing
End Function
Function colAnyLengthAndStep(ByVal intLength As Integer, ByVal intStep As Integer) As Collection
Dim col As New Collection
Dim i As Integer
Dim var As Variant
For i = 1 To intLength * intStep Step intStep
col.Add "Value" + CStr(i), CStr(i)
Next
Set colAnyLengthAndStep = col
Set col = Nothing
End Function