views:

83

answers:

2

Hello,

I am trying to retrieve an ADODB recordset from a function in MS-Access 2007 but get a very annoying error message thrown in my face saying: "Argument not optional (Error 449)".

I really can't figure out what I am doing wrong, please help!

Regards,

Stefan

FUNCTION:

Function Rs(sourceSQL As String) As ADODB.Recordset

' Create New Disconnected Recordset

Dim rsConnection As ADODB.Connection
Dim rsRecordset As ADODB.Recordset

Set rsConnection = New ADODB.Connection
rsConnection.Open CurrentProject.Connection

Set rsRecordset = New ADODB.Recordset

rsRecordset.CursorLocation = adUseClient
rsRecordset.Open sourceSQL, rsConnection

Set Rs = rsRecordset

Set rsRecordset.ActiveConnection = Nothing

End Function

FUNCTION CALL:

Private Sub Form_Load()

Call Rs("tblDocumentCode")

Debug.Print Rs.txtDocumentCode(0).Value

End Sub
+3  A: 

You are using rs twice, once as a function, once as the name of a recordset:

Private Sub Form_Load()

Set Myrs= Rs("tblDocumentCode")

Debug.Print MyRs(0).Value

End Sub
Remou
Beautiful, it works!
Stefan Åstrand
@Stefan Åstrand Good. BTW it is nearly always better to use DAO with Access.
Remou
@Remou: Thanks, but I am using SQL Server as DB backend and SQL server does not support DAO.
Stefan Åstrand
@Stefan Astrand - DAO supports SQL Server.
Jeff O
DAO supports SQL Server via ODBC with linked tables, not directly unless you specify connect strings in each query. ODBC is clearly the recommended way to use Access with SQL Server, but it's not direct interaction. On the other hand, ADO is pretty indirect, too (which is one of the main reasons why MS now deprecates ADPs in favor of MDB/ACCDB with ODBC).
David-W-Fenton
I don't think this answer actually identifies the problem at all. The problem is not the lack of a recordset variable, but the fact that it uses the wrong syntax.
David-W-Fenton
@David-W-Fenton Debug.Print Rs.txtDocumentCode(0).Value <- This will not compile or even run, because rs is a function being used a second time as a recordset. The error is argument not optional on the line, the syntax error is a different problem, you will get a similar error with Rs.Fields(0). I reckon I have correctly identified the problem.
Remou
I've corrected my answer to reflect this issue. I think the problems here suggest why the whole thing is a bad idea, actually.
David-W-Fenton
A: 

Assuming that "txtDocumentCode" is a field in the recordset, this:

  Private Sub Form_Load()
    Call Rs("tblDocumentCode")
    Debug.Print Rs.txtDocumentCode(0).Value
  End Sub

...should be changed to this:

  Private Sub Form_Load()
    Debug.Print Rs("tblDocumentCode").Fields("txtDocumentCode").Value
  End Sub

So far as I can tell, that should work without needing to assign the recordset returned by the function to a variable.

But let me step back a bit and suggest that fixing this syntactical error begs the question: what's being done her is pretty inadvisable. Every time this function is called, you're opening a new connection, but Access works better with a single connection that is used over and over again. That's true of both Jet/ACE back ends and server back ends. The overhead required to initialize the connection is going to make your forms load really slowly.

But even worse, this is not Access programming -- this is "refugee from a programming environment that lacks bound forms/controls" programming. You should be using ODBC with linked tables and then you can assign recordsources to your forms without having to muck about with ADO recordsets. If you insist on doing what you're doing, you might as well not be using Access at all, because you're discarding 75% or more of the advantages of Access, and you're getting no performance or concurrency benefits from doing so (and buying yourself a world of problems).

Of course, now that I look at it again, you're using the CurrentProject.Connection, and I'm not sure how this interacts with ODBC linked tables. Indeed, I guess it's possible this is an ADP and not an MDB/ACCDB, but that makes even less sense, since you don't need to do anything extra at all in an ADP to populate your forms with ADO recordsets -- it's the default.

So, in general, something is wrong beyond the syntax error -- what you are doing simply doesn't make a lot of sense.

David-W-Fenton
I have just tried your example, but as I expected, because rs is a function that attemps to open a recordset, Rs("txtDocumentCode").Value will not work, because the a table called txtDocumentCode does not exist.
Remou
You're right -- I was missing the key point in your answer. My answer edited to reflect that.
David-W-Fenton