简体   繁体   中英

#Value Error in a vba function to return a recordset

I wrote the below vba function aiming to return a SQL record set into a cell. I get #Value error when I use this function. It should get two arguments, namely two cells, and simply return Yes or No. I checked the SQL query and it works fine when written as a subroutine. So pardon for replacing some sql commands with *

Public Function TrRe(No1 As String, No2 As String) As ADODB.Recordset
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim SourceText As String

Set cn = New ADODB.Connection
cn.ConnectionString = _
    "Provider=MSOLEDBSQL;Server=****;Database=*****;Integrated Security=SSPI"
cn.Open
Set rs = New ADODB.Recordset
SourceText = " SELECT  " & _
            "   CASE  " & _
            "   WHEN ***** LIKE 'TEST%' OR *****=1 THEN 'Yes' " & _
            "   ELSE 'No " & _
            "   END " & _
            "  FROM *** "
            " WHERE ****=" & No1 & _
            "   AND ****=" & No2  
rs.ActiveConnection = cn
rs.Source = SourceText
rs.CursorType = adOpenForwardOnly
rs.LockType = adLockReadOnly
rs.Open
Set TrRe= rs
rs.Close
cn.Close
Set cn = Nothing
End Function

I would appreciate your comments/helps.

Update: a) The query always returns a 1x1 recordset and this is Yes or No. b) The code should be written as a Function since I want to let the user to choose the inputs.

AS @Rory stated, you can't write a recordset into a cell. A RecordSet is an object, containing all kind of information, eg the field names and -types, the state, the connection, somehow the information about the current row that was read and so on. You can't (and you don't want to) write all that into a cell.

Your sql statement will return one row with exactly one field (containing either the string yes or no ). In that case, you can simply write (note that this statement is without Set )

TrRe = rs(0)

That is a shortcut, fetching the first field of the current row. Current row is the first row, assuming that the sql statement was executed successfully and returns at least one row. To move to the next row, you would use rs.MoveNext . To check if there are any more rows, use If rs.EOF Then .

If you issue an sql that returns more than that, there are two handy commands:

(1) To write the complete data that was returned into Excel, use Range.CopyFromRecordset

ThisWorkbook.Sheets(1).Range("A2").CopyFromRecordset rs

(2) To read all data into a 2-dimensional array use RecordSet.GetRows

Dim data as Variant
data = rs.GetRows
dim row as long, col as long
For row = 0 To UBound(data, 2)  ' Index for rows = 2
    For col = 0 to UBound(data, 1) ' Index for fields (columns) = 1
        ... (do your stuff here)
    next col
Next row

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM