我有一个返回ADO记录集的函数,后者又用于提供后续函数。它第一次传递给其中一个函数,运行正常;但在下一个函数中,记录集位于EOF。我假设我的记录集已被传递By Ref
,所以尝试使用MoveFirst
:这给了我一个错误,因为游标类型默认为只转发。
我尝试了以下内容:
By Val
;这没有效果。adOpenStatic
):这实际上对我的应用程序更正确,但它给出了非常奇怪的结果。也就是说,在更改之前工作正常的查询中,第一个字段未被返回!这很重要,所以我不能继续这条路。有什么想法吗?
主数据库查询功能:GetData
。获取SQL和varchar
参数列表(如果有)并返回记录集。它引用dbOpen
,它只是用提供的凭据打开连接。
Private Function GetData(ODBC As DBConnection, ByVal QuerySQL As String, Optional Parameters As Collection) As ADODB.Recordset
Dim DB As ADODB.Connection
Dim Query As ADODB.Command
Dim Parameter As ADODB.Parameter
Set DB = New ADODB.Connection
If dbOpen(DB, ODBC) Then
Set Query = New ADODB.Command
Query.ActiveConnection = DB
Query.CommandText = QuerySQL
If Not Parameters Is Nothing Then
For Each param In Parameters
Set Parameter = Query.CreateParameter(, adVarChar, adParamInput, Len(param), param)
Query.Parameters.Append Parameter
Next
Set Parameter = Nothing
End If
Set GetData = Query.Execute
' Uncommenting this seems to reset the data in GetData...
' A bit of a memory leak, but we assume VBA will take care of it :P
'dbClose DB
Else
MsgBox "Cannot connect to the database.", vbExclamation
Set GetData = Nothing
End If
End Function
然后我做了这样的事情:
Dim myRecords as ADODB.Recordset
' For the sake of argument, we assume this returns a nontrivial recordset
Set myRecords = GetData(someDSN, someSQL, someParameters)
Debug.Print myRecords.EOF ' Returns False
ID = writeHeader(myRecords)
Debug.Print myRecords.EOF ' Returns True
writeData ID, myRecords ' Breaks because at EOF
writeHeader
函数将使用MoveNext
遍历记录集中的每条记录。但是,如果我按值传递myRecords
或作为副本传递,那么我们仍会遇到EOF问题。如果我在MoveFirst
中的记录迭代代码末尾添加writeHeader
,它会抱怨我无法移动到这样的记录集的开头。如果我更改了GetData
功能,以便将Set GetData = Query.Execute
更改为:
Set GetData = New ADODB.Recordset
GetData.CursorType = adOpenStatic
GetData.Open Query
然后,当我的代码中的查询运行时 - 它没有改变 - 第一个字段不是记录集的一部分(!?)比如说,myRecords!ID
是第一个字段:如果引用了这个,我会收到一条警告:该项不是记录的成员(并且它也不是枚举成员;因此myRecords.Fields(1)
只返回查询中的下一个字段。)< / p>
答案 0 :(得分:1)
通过@TimWilliams的有用提示,我通过将GetData
函数更改为以下内容来解决此问题:
Private Function GetData(ODBC As DBConnection, ByVal QuerySQL As String, Optional Parameters As Collection) As ADODB.Recordset
Dim DB As ADODB.Connection
Dim Query As ADODB.Command
Dim Parameter As ADODB.Parameter
Dim Output As ADODB.Recordset
Set DB = New ADODB.Connection
If dbOpen(DB, ODBC) Then
Set Query = New ADODB.Command
Query.ActiveConnection = DB
Query.CommandText = QuerySQL
If Not Parameters Is Nothing Then
For Each param In Parameters
Set Parameter = Query.CreateParameter(, adVarChar, adParamInput, Len(param), param)
Query.Parameters.Append Parameter
Next
Set Parameter = Nothing
End If
Set Output = New ADODB.Recordset
Output.CursorType = adOpenStatic
Output.CursorLocation = adUseClient
Output.Open Query
Else
MsgBox "Cannot connect to the database.", vbExclamation
Set Output = Nothing
End If
Set GetData = Output
End Function
然后,在通过记录集进行游说之前,我使用MoveFirst
。