У меня есть функция, которая возвращает набор записей ADO, который, в свою очередь, используется для подачи последующих функций. Первый раз, когда он передается одной из этих функций, он работает нормально; но в следующей функции набор записей находится в EOF. Я предполагал, что мой набор записей был передан By Ref
, поэтому попытался использовать MoveFirst
: это дает мне ошибку, потому что тип курсора по умолчанию установлен только для пересылки.
Я попробовал следующее:
- Установите для этого параметра значение
By Val
; это не имело никакого эффекта.
- Создала копию набора записей и использовала оригинал в первой функции и копию во второй; все та же проблема (во-вторых, говорит EOF, что означает, что он пуст, а не в EOF; я не могу представить, что два набора записей связаны каким-либо образом, но, возможно,).
- Изменил код моей БД на использование другого типа курсора (
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)
просто возвращает следующее поле в запросе).