gerain
gerain

Reputation: 35

VBA Recordset doesn't return all fields

I just startied working with this database and I have a small problem. So the main idea behind this is to use VBA to get needed information from database that I can use later on. I am using ADO recordset and connect sting to connect to server. All is fine apart from one problem: when I am creating RecordSet by using SQL request it only returns one field when i know there should me more. At the moment I think that RecordSet is just grabbing first result and storing it in but looses anything else that should be there. Can you please help me.

Here is my code:

'Declare variables'
    Dim objMyConn As ADODB.Connection
    Dim objMyCmd As ADODB.Command
    Dim objMyRecordset As ADODB.Recordset
    Dim fldEach As ADODB.Field
    Dim OrderNumber As Long

    OrderNumber = 172783

    Set objMyConn = New ADODB.Connection
    Set objMyCmd = New ADODB.Command
    Set objMyRecordset = New ADODB.Recordset

'Open Connection'
    objMyConn.ConnectionString = "Provider=SQLOLEDB;Data Source=Local;" & _
                                    "Initial Catalog=SQL_LIVE;"
    objMyConn.Open

'Set and Excecute SQL Command'
    Set objMyCmd.ActiveConnection = objMyConn
    objMyCmd.CommandText = "SELECT fldImage FROM tblCustomisations WHERE fldOrderID=" & OrderNumber
    objMyCmd.CommandType = adCmdText


'Open Recordset'
    Set objMyRecordset.Source = objMyCmd
    objMyRecordset.Open

    objMyRecordset.MoveFirst
    For Each fldEach In objMyRecordset.Fields
        Debug.Print fldEach.Value
    Next

At the moment Debug returns only one result when it should return two because there are two rows with the same OrderID.

Upvotes: 1

Views: 4459

Answers (3)

Eduardo Molteni
Eduardo Molteni

Reputation: 39453

In addition to the @enderland's answer, you can also have a disconnected RecordSet, that have all the values and fields ready for consumption. It's handy when you need to pass the data around or need to close the connection fast.

Here's a function that returns a disconnected RecordSet:

Function RunSQLReturnRS(sqlstmt, params())
    On Error Resume next

    ' Create the ADO objects
    Dim rs , cmd
    Set rs = server.createobject("ADODB.Recordset")
    Set cmd = server.createobject("ADODB.Command")

    ' Init the ADO objects  & the stored proc parameters
    cmd.ActiveConnection = GetConnectionString()
    cmd.CommandText = sqlstmt
    cmd.CommandType = adCmdText
    cmd.CommandTimeout = 900 ' 15 minutos

    collectParams cmd, params

    ' Execute the query for readonly
    rs.CursorLocation = adUseClient
    rs.Open cmd, , adOpenForwardOnly, adLockReadOnly
    If err.number > 0 then
        BuildErrorMessage()
        exit function
    end if

    ' Disconnect the recordset
    Set cmd.ActiveConnection = Nothing
    Set cmd = Nothing
    Set rs.ActiveConnection = Nothing

    ' Return the resultant recordset
    Set RunSQLReturnRS = rs

End Function

Upvotes: 0

enderland
enderland

Reputation: 14185

The recordset only opens a single record at a time. You are iterating through all the fields in a single record. Not each record in the recordset.

If your query returns two records, you need to tell the Recordset to advance to the next one.

A query returns one recordset which has some number of records which have some number of fields.

You are iterating through the fields only for one record in the returned recordset.

You can do this with a few ways, but I generally do something like:

   objMyRecordset.MoveFirst

   Do
        If Not objMyRecordset.EOF Then
           debug.print "Record Opened - only returning 1 field due to SQL query"
            For Each fldEach In objMyRecordset.Fields
                Debug.Print fldEach.Value
            Next
            'this moves to the NEXT record in the recordset
            objMyRecordset.MoveNext

        Else
            Exit Do
        End If

    Loop

Note that if you want to include more fields you will need to modify this line:

objMyCmd.CommandText = "SELECT fldImage FROM tblCustomisations WHERE fldOrderID=" & OrderNumber

To include whatever additional fields you want returned.

Upvotes: 3

Thomas G
Thomas G

Reputation: 10226

You are mixing up terms in your question which makes it unclear

In your first paragraph you describe a problem with "Fields", in the last paragraph you turn it into "Rows". Not exactly the same.

But whatever you are trying to achieve, the code you wrote will only return one field and one row.

If you want all FIELDS, your query should be:

objMyCmd.CommandText = "SELECT * FROM tblCustomisations WHERE fldOrderID=" & OrderNumber

If you want all ROWS, your loop should be:

objMyRecordset.MoveFirst
If Not objMyRecordset.BOF Then
    While Not objMyRecordset.EOF
        debug.print objMyRecordset!fldImage  
        RS.MoveNext
    Wend
End If

Upvotes: 0

Related Questions