Question

Type Mismatch on VBA Function That Returns ADO Recordset at Exit Function or End Function

Asked by: pique_tech

This doesn't seem like it should be difficult.  I want to return an ADO recordset from a function in VBA (as opposed to VB.net).  Here's the code I've used:

Public Function GetRS(NameOfTable As String) As ADODB.Recordset
On Error GoTo HandleError

    Dim rs As ADODB.Recordset
   
    Set rs = New ADODB.Recordset
   
    rs.Open NameOfTable, CurrentProject.Connection, adOpenStatic, adLockReadOnly, adCmdTableDirect
   
    'debugging code
    Do
        Debug.Print rs(0)
        rs.MoveNext
    Loop Until rs.EOF
    'end debugging code

    Set GetRS = rs
   
    'rs.Close
    Set rs = Nothing
   
ExitHere:
    Exit Function
   
HandleError:
    MsgBox Err.Number & ": " & Err.Description
    Resume ExitHere
   
End Function

Interestingly, the error handler never fires.  If I debug/single-step through the code, the error occurs on Exit Function (and it was on End Function before I added the error handler).  The debugging code dutifully prints out the first field in the table.  

WHAT INCREDIBLY SIMPLE THING AM I OVERLOOKING?!   Thanks in advance.

This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.

Subscribe now for full access to Experts Exchange and get

Instant Access to this Solution

  • Plus...
  • 30 Day FREE access, no risk, no obligation
  • Collaborate with the world's top tech experts
  • Unlimited access to our exclusive solution database
  • Never be left without tech help again

Subscribe Now

Asked On
2004-12-09 at 17:55:14ID21237364
Tags

vba

,

mismatch

,

function

,

recordset

,

type

Topic

Microsoft Access Database

Participating Experts
2
Points
500
Comments
6

Trusted by hundreds of thousands everyday for fast, accurate and reliable tech support.

  • "The time we save is the biggest benefit of Experts Exchange to Warner Bros. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange." Mike Kapnisakis, Warner Bros.
  • "Our team likes having a resource that is more secure than just using Google and most experts using this service really know their stuff. It's nice to look here first versus using Google." Dayna Sellner, Lockheed Martin
  • "Anytime that I've been stumped with a problem, 9 out of 10 times Experts Exchange has either the accepted solution or an open discussion of the potential solution to the problem." Kenny Red, eBay Inc.

See what Experts Exchange can do for you.

Got a question?

We've got the answer.

Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.

Screenshot of Experts Exchange Knowledgebase

Need individual assistance?

Our experts are ready to help.

If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.

Screenshot of Experts Exchange Knowledgebase

Want to learn from the best?

Read articles from industry experts.

Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.

Screenshot of an Article

Working on a long term project?

Store your work and research.

Save solutions to your questions, answers you’ve discovered through searching plus helpful articles in your personal knowledgebase for easy future access.

Screenshot of Experts Exchange Knowledgebase

Access the answers to your technology questions today.

Subscribe Now

30-day free trial. Register in 60 seconds.

What Makes Experts Exchange Unique?

Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Trusted by the world's most respected brands.

image of each brand's logo

Faithfully serving IT professionals since 1996.

Experts Exchange Logo

Try it out and discover for yourself.

Subscribe Now

30-day free trial. Register in 60 seconds.

Related Solutions

  1. connecting to sybase with ado in vba
    Hi, I'm trying to figure out how to connect to sybase with ado. So far I haven't been able to find many good resources online, as most tutorials seem to be for Access databases. I'm using Sybase ASE 12.x, and vba for Excel 2000. I've got the ADO 2.7 library. I know my driver ...
  2. ADO
    Is ADO a completly new language? Is there much to it?

Free Tech Articles

  1. WARNING: 5 Reasons why you should NEVER fix a computer for free.
    It is in our nature to love the puzzle. We are obsessed. The lot of us. We love puzzles. We love the challenge. We thrive on finding the answer. We hate disarray. It bothers us deep in our soul. W...
  2. SCCM OSD Basic troubleshooting
    SCCM 2007 OSD is a fantastic way to deploy operating systems, however, like most things SCCM issues can sometimes be difficult to resolve due to the sheer volume of logs to sift through and the dispe...
  3. Migrate Small Business Server 2003 to Exchange 2010 and Windows 2008 R2
    This guide is intended to provide step by step instructions on how to migrate from Small Business Server 2003 to Windows 2008 R2 with Exchange 2010. For this migration to work you will need the fo...
  4. Create a Win7 Gadget
    This article shows you how to create a simple "Gadget" -- a sort of mini-application supported by Windows 7 and Vista. Gadgets can be dropped anywhere on the desktop to provide instant information, ...
  5. Outlook continually prompting for username and password
    There have been a lot of questions recently regarding Outlook prompting for a username and password whilst using Exchange 2007. There are a few reasons why this would happen and I will try to cover t...
  6. Backup Exchange 2010 Information Store using Windows Backup
    There seems to be quite a lot of confusion around the ability to backup Exchange 2010 using the built in Windows Backup feature. This stems from the omission of this feature prior to Exchange 2007 s...

Cloud Class Webinars

  1. Avoiding Bugs in Microsoft Access
    Alison Balter takes and in-depth look at avoiding bugs in Access. In this webinar you will learn about using the immediate window to debug your applications, invoking the debugger, using breakpoints to troubleshoot, stepping through code, setting the next statement to execute, ...
  2. Top 10 Best New Features in Visio 2010
    Scott Helmers gives live demonstrations of the top 10 new features in Visio 2010. This webinar will teach you how to create compelling diagrams by adding shapes to the page with a single click, linking the shapes in a diagram to data in Excel (or SQL Server, or SharePoint), ...
  3. IT Consultant Business Secrets Revealed
    Michael Munger, Experts Exchange tech pro and IT consultant, pulls back the curtain on his very successful businesses and answers question on every IT consultant and business owner should know about. He shares secrets on what he did to solve the 5 most common problems in IT, ...
  4. Disaster Recovery and Business Continuity
    Quest CTO, Mike Billon, gives an overview of the steps involved in building a dunamic disaster recovery plan. Through case studies and an examination of software/hardware tooles for monitoring and testing, you'll gain a better understandin of where you are, where you want ...
  5. Organize Your Visio Diagrams with Containers and Lists
    Scott Helmers uses cross functional flowcharts, wireframe diagrams, data graphic legends and seating charts to teach you: how to ustilize all three new structured diagram components in Visio 2010, the best practices for organizeing shapes in previous version of Visio, how to organize ...
  6. How to Us Objects, Properties, Events and Methods in Microsoft Access
    Alison Dalter gives an in-depbth look at objects, properties, events and methods in Microsoft Access. In this webinar you will learn about using the object browser, referring to objects, working with properties and methods, working with object variables, understanding the ...

Join the Community

Give a Little. Get a Lot.

Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.

Join the Community

Answers

 

by: GreymanMSCPosted on 2004-12-09 at 18:16:51ID: 12789382

Since the error is triggering on exiting the function, the occurance is not actually in the function, but in the call line where the result of GetRS is being used that's producing the error.

You will have something like:   Set R = GetRS("ValidTableName")

Make sure that R is actually declared as ADODB.Recordset, because if it's just declared as a Recordset, it may actually be constructed as a DAO.Recordset.

(PS: definitely do not use the 'rs.Close' line inside the function!)

 

by: pique_techPosted on 2004-12-09 at 18:57:17ID: 12789507

Ok...I thought I had tested this all out.  I even THOUGHT about what you suggested before I posted and in hindsight, I know what I did wrong, and it was PROFOUNDLY dumb (just as I expected).

Anyway, based on your suggestion, this is what I came up with:

'the original function code, without the debugging stuff
Public Function GetRS(NameOfTable As String) As ADODB.Recordset
On Error GoTo HandleError

    Dim rs As ADODB.Recordset
   
    Set rs = New ADODB.Recordset
   
    rs.Open NameOfTable, CurrentProject.Connection, adOpenStatic, adLockReadOnly, adCmdTableDirect
   
    Set GetRS = rs
   
    'rs.Close
    Set rs = Nothing
   
ExitHere:
    Exit Function
   
HandleError:
    MsgBox Err.Number & ": " & Err.Description
    Resume ExitHere
   
End Function
-------------------------------------------------------------

'a new sub to accept the recordset and process it
Public Sub ReadRS(SomeRS As ADODB.Recordset)
   
    Do
        Debug.Print SomeRS(0)
        SomeRS.MoveNext
    Loop Until SomeRS.EOF

End Sub

So if I call my sub in the immediate window like so:
ReadRS GetRS("Product")
I get the list of values from the first column of the table--exactly what is expected.  The error I made earlier was to call the sub like this:
ReadRS(GetRS("Product"))
which for reasons that I might be able to explain with a great deal of reflection produces a Type Mismatch error (but at this instant, it's not at all clear to me).

So you've solved the problem.  I still have one lingering concern:  Why CAN'T I close the recordset in GetRS after I SET the function return, but I can SET it to Nothing?  You're correct, it absolutely will not work if the recordset is closed explicitly.  Any ideas?  (You'll get the points, but I'm interested in a more general conceptual discussion now).  Thanks again.

 

by: GreymanMSCPosted on 2004-12-09 at 20:34:20ID: 12789832

Think of object references as pointers to the location of the object in memory (it is a little more complex, but that is the basic principle).  
 
When you set one reference to another, you aren't copying the object, you are just copying the address.  Both references then point to the same object.  So it does not  matter which reference is used to call the close method, the object will be closed.
 
When you set a reference to something else, you don't change the objects, you just change which objects are referenced.  So if you set a reference to nothing, you do not close or destroy the object, you just stop referring to it through that reference.  (If an object has no references set to it, it still exists anonymously in memory until VBA's garbage collection decides to detroy it.)

Look at the following code:

Public Sub Dummy(SQL as String)
  Dim A as ADODB.Recordset, B As ADOBD.Recordset
  Set A=New ADODB.Recordset  '<-creates a new object
  A.Open SQL, CurrentProject.Connection, adOpenSnapshot '<-opens the object
  Set B=A  '<- sets a second reference to the same object
  A.Close  '<- closes the object
  Set A = Nothing '<- unsets the reference
  If Not B.EOF Then  '<!!! produces an error because the object is closed.
    B.MoveLast
  End if
  B.Close
  Set B = Nothing
End Sub

 

by: GreymanMSCPosted on 2004-12-09 at 20:56:55ID: 12789894

So if I call my sub in the immediate window like so:
   ReadRS GetRS("Product")
I get the list of values from the first column of the table--exactly what is expected.  The error I made earlier was to call the sub like this:
   ReadRS(GetRS("Product"))
which for reasons that I might be able to explain with a great deal of reflection produces a Type Mismatch error (but at this instant, it's not at all clear to me).
----

Yeap, that trips up programmers switching to VBA from another language all the time.  

The problem is that ReadRS(GetRS("Product")) looks entirely sensible.  That's the form of a procedure call in most other programming languages.  But these brackets aren't a part of the procedure call at all, they are part of the parameter being passed to the procedure.

It had me bamboozled too until I figured out what was going on.

When you put an object inside brackets, VBA does something you would not expect - it calls the default method!   In this case, putting a recordset inside brackets means that you are trying to pass the recordset's Fields collection to the calling function, not the recordset itself.

In the intermediate window, try executing the following two lines:

  ?TypeName( New ADODB.Recordset )
  ?TypeName( (New ADODB.Recordset) )

It is not weird?

 

by: flavoPosted on 2004-12-09 at 23:15:24ID: 12790314

Nice GreymanMSC! Nice insight mate.

 

by: pique_techPosted on 2004-12-10 at 04:14:41ID: 12791487

>>>Yeap, that trips up programmers switching to VBA from another language all the time.

I wish I could claim the whole "switching to VBA from another language" thing....unfortunately I'm just occasionally a little dense.

This is flat-out brilliant.  Where'd you learn this?  Or did you just figure it out in the hard, hard school of experience?  I feel like I felt when I finally understood the difference between dot (.) and bang (!).

Anyway, to remind myself of this lesson, I've added the following to my module of code for things to remenber:

Public Sub WhatDoParenthesesDo()

    Debug.Print TypeName(New ADODB.Recordset)
    Debug.Print TypeName((New ADODB.Recordset))
   
End Sub

20120131-EE-VQP-002

3 Ways to Join

30-Day Free Trial

The Experts

98% positive feedback on 31,087 answers since March 2000. angeliii is a Microsoft Most Valuable Professional for his work with MS SQL Server & Develoment.

He has also proven his knowledge of Visual Basic Programming, PHP Scripting and Oracle Databases.

The Experts

97% positive feedback on 10,752 answers since July 2000. lrmoore has more than 18 years experience in the networking industry.

The six-time Mircosoft MVPs specialties include firewalls, virtual private networking, and network management.

Testimonials

"...and excellent source for support... Kind of like having your very own IT dept." Electriciansnet

Testimonials

"I was apprehensive at signing up at first. However... it has already made my life as an IT administrator much easier." JaCrews

Testimonials

"WOW! You guys have great, active, and knowledgeable people on here." moore50

Business Clients

Business Clients

In the Press

"If you’ve got a question... Experts Exchange can supply an answer.”

In the Press

"...an invaluable aid for both IT professionals and those who require tech support."

In the Press

"where IT professionals provide quick answers on just about any topic"

Business Account Plans

Loading Advertisement...