473,397 Members | 1,985 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,397 software developers and data experts.

Closing a recordset in VBA

Seth Schrock
2,965 Expert 2GB
I have read that every recordset that you open should be explicitly closed. In this particular case, I have opened the recordset in the following way:
Expand|Select|Wrap|Line Numbers
  1. Dim intPronounCount as Integer
  2. intPronounCount = CurrentDb.OpenRecordset("SELECT * FROM tblProunouns").RecordCount
I have no variables set as DAO.Recordset, so how do I close this recordset? Do I just put
Expand|Select|Wrap|Line Numbers
  1. CurrentDb.OpenRecordset("SELECT * FROM tblPronouns").Close
Or do I need to worry about closing the recordset since I haven't set it to a variable?

*Another Thought*
Or do I just need to add the little bit of extra code like this:
Expand|Select|Wrap|Line Numbers
  1. Dim rstPronoun as DAO.Recordset
  2. Dim intPronounCount as integer
  3.  
  4. Set rstPronoun = CurrentDb.OpenRecordset("SELECT * FROM tblProunouns")
  5. intPronounCount = rstPronoun.RecordCount
  6.  
  7. rstPronoun.close
  8. Set rstPronoun = Nothing
Dec 28 '12 #1

✓ answered by NeoPa

Your *Another Thought* was basically the answer Seth. You do need to close recordsets. Setting the variable to Nothing is less important, but recordsets need to be closed. Another thing to avoid is using the return value of the function CurrentDb() as a reference as you have. This should be assigned to a DAO.Database variable and that variable used.

Expand|Select|Wrap|Line Numbers
  1. Dim dbVar As DAO.Database
  2. Dim rstPronoun As DAO.Recordset
  3. Dim intPronounCount As Integer
  4.  
  5. Set dbVar = CurrentDb()
  6. Set rstPronoun = dbVar.OpenRecordset("SELECT * FROM [tblProunouns]")
  7. intPronounCount = rstPronoun.RecordCount
  8. rstPronoun.Close
Of course, a much more straightforward approach altogether, would be :
Expand|Select|Wrap|Line Numbers
  1. Dim intPronounCount As Integer
  2.  
  3. intPronounCount = DCount(Expr:="*", Domain:="[tblPronouns]")
Clearly though, that misses out on the learning process involved with the DAO Recordsets ;-)

14 21107
NeoPa
32,556 Expert Mod 16PB
Your *Another Thought* was basically the answer Seth. You do need to close recordsets. Setting the variable to Nothing is less important, but recordsets need to be closed. Another thing to avoid is using the return value of the function CurrentDb() as a reference as you have. This should be assigned to a DAO.Database variable and that variable used.

Expand|Select|Wrap|Line Numbers
  1. Dim dbVar As DAO.Database
  2. Dim rstPronoun As DAO.Recordset
  3. Dim intPronounCount As Integer
  4.  
  5. Set dbVar = CurrentDb()
  6. Set rstPronoun = dbVar.OpenRecordset("SELECT * FROM [tblProunouns]")
  7. intPronounCount = rstPronoun.RecordCount
  8. rstPronoun.Close
Of course, a much more straightforward approach altogether, would be :
Expand|Select|Wrap|Line Numbers
  1. Dim intPronounCount As Integer
  2.  
  3. intPronounCount = DCount(Expr:="*", Domain:="[tblPronouns]")
Clearly though, that misses out on the learning process involved with the DAO Recordsets ;-)
Dec 28 '12 #2
ADezii
8,834 Expert 8TB
Another point that I feel is worth mentioning is that you may not know if a Recordset was actually created in the first place. This can typically occur in a Local Procedure with Error Trapping whereas an Error can occur either prior to, or after, a Recordset was actually created. In this scenario, you need to check for the existence of the Recordset Object itself, as in:
Expand|Select|Wrap|Line Numbers
  1. Private Sub cmdRecordsetClose_Click()
  2. On Error GoTo Err_cmdRecordsetClose_Click
  3. Dim MyDB As DAO.Database
  4. Dim rst As DAO.Recordset
  5.  
  6. 'Potentially Error producing Code intentionally omitted
  7.  
  8. Set MyDB = CurrentDb
  9. Set rst = MyDB.OpenRecordset("SELECT * FROM Products", dbOpenDynaset)
  10.  
  11. 'Potentially Error producing Code intentionally omitted
  12.  
  13. Exit_cmdRecordsetClose_Click:
  14.   If Not rst Is Nothing Then
  15.     rst.Close
  16.       Set rst = Nothing
  17.   End If
  18.     Exit Sub
  19.  
  20. Err_cmdRecordsetClose_Click:
  21.   MsgBox Err.Description
  22.     Resume Exit_cmdRecordsetClose_Click
  23. End Sub
  24.  
Dec 28 '12 #3
Seth Schrock
2,965 Expert 2GB
@ADezii I have actually run into having errors when trying to close a recordset that due to the path the code ran through If/Then statements was never opened. I couldn't think of a way to test to see if it was opened so I just moved the opening code to where it would always run. Your code helps me with that angle, so thank you for point this out.

@NeoPa I do think that your second post will be the avenue that I choose for my database, but I will choose your first as the answer as it answers my question the best.

Possibly, better asked in a different thread, but why is it better to declare a variable for the CurrentDb instead of just using CurrentDb.OpenRecordset? I have often seen a variable used in examples online, but I just figured that it was so that less would have to be typed if it was needed multiple places (often db or dbs was the variable used). I didn't think that there was a difference between using a variable and using the straight value.
Dec 28 '12 #4
NeoPa
32,556 Expert Mod 16PB
Seth:
@NeoPa I do think that your second post will be the avenue that I choose for my database, but I will choose your first as the answer as it answers my question the best.
You're right Seth. It made more sense to merge them into a single post in the end though. I should have seen that earlier.
Dec 28 '12 #5
zmbd
5,501 Expert Mod 4TB
Possibly, better asked in a different thread, but why is it better to declare a variable for the CurrentDb instead of just using CurrentDb.OpenRecordset?
Not too far off topic as we're still talking about recordsets..

Notice that the variable is a specific type of database DAO, ADO, or ADODB. By type casting the specific record set you ensure that the expected functionality will be implemented. The following has a chart comparing the different types and available functionality: Choosing ADO or DAO for Working with Access Databases
Dec 29 '12 #6
Seth Schrock
2,965 Expert 2GB
Ah... so the purpose of using the variable is so that you can explicitly choose which type of database (something that I know you are supposed to do and I try to always do). That makes sense.
Dec 29 '12 #7
TheSmileyCoder
2,322 Expert Mod 2GB
I would argue its a bit more complicated then that, allthough it is a valid point made.

First off, its important to understand that CurrentDB() is a function call, that returns a DB variable. It is not a DB. So it has more overhead then using a variable, if you use it multiple times.

Example:
Expand|Select|Wrap|Line Numbers
  1. set RS1=CurrentDB.Openrecordset("....")
  2. set RS2=CurrentDB.Openrecordset("....")
  3. set RS3=CurrentDB.Openrecordset("....")
  4. set RS4=CurrentDB.Openrecordset("....")
Would be written more efficient as:

Expand|Select|Wrap|Line Numbers
  1. Dim oDB as Dao.Database
  2. Set oDB=CurrentDB()
  3. set RS1=oDB.Openrecordset("....")
  4. set RS2=oDB.Openrecordset("....")
  5. set RS3=oDB.Openrecordset("....")
  6. set RS4=oDB.Openrecordset("....")
  7. Set oDB=Nothing

That is just a matter of efficiency, and of course as mentioned clarity of type of DB being used.

Another example could be that you are using information from more then 1 access backend. If you use linked tables you can stick to using CurrentDB, but if you sometimes open information from a backend without using linked tables you can do it using a secondary database object (Or from the currentdb, depending on syntax). I realize it may be confusing, but its simply because the choices are quite many, and different ways of doing it can provide benefits in some conditions.

Example:
Expand|Select|Wrap|Line Numbers
  1. Dim oPrimaryDB as Dao.Database
  2. Set oPrimaryDB=CurrentDB()
  3. Dim oSecondaryDB as dao.Database
  4. set oSecondaryDB=OpenDatabase("C:\Example.Mdb")

Yet another reasons is that CurrentDB does not return the same handle to the database each time its called. This can be be desribed by the following example:

Expand|Select|Wrap|Line Numbers
  1. Currentdb.Execute "Update Table...."
  2. Msgbox "Records updated:" & Currentdb.RecordsAffected
The records affected will always be listed as 0, because the handle used to run the SQL is not the same handle as is being used to get the number of records affected.

Try this instead:
Expand|Select|Wrap|Line Numbers
  1. Dim oDB as dao.database
  2. Set oDB=CurrentDB
  3. oDB.Execute "Update Table...."
  4. Msgbox "Records updated:" & oDB.RecordsAffected
This will correctly return the number of records affected. I realise that this concept can also be a bit hard to grasp, and I myself must admit I am still a bit fuzzy on it.

Finally a topic I would consider a bit too far off topic would be getting into Transactions, workspaces and database objects, but that is quite a large subject in itself, so that will be for another time.

Best of luck with your project!
TheSmileyCoder
Dec 29 '12 #8
Seth Schrock
2,965 Expert 2GB
That makes it a little clearer. Thanks Smiley.
Dec 29 '12 #9
TheSmileyCoder
2,322 Expert Mod 2GB
Heheh, I hope I managed to clear it up, more then I managed to muddy it up. :)
Dec 29 '12 #10
Seth Schrock
2,965 Expert 2GB
I got the important part: Always use the variable and not the straight CurrentDb because there is a good reason. :)

I think that I understood several of your arguments fairly well. The rest of it is a little over my head at this point, but hopefully I will be able to come back once my level of knowledge gets a little higher and I will understand everything.
Dec 29 '12 #11
NeoPa
32,556 Expert Mod 16PB
I was going to jump in on this one as using the variable instead of the function call is absolutely about more than simply stipulating the type of the object (CurrentDb() returns a DAO.Database object specifically), but Smiley has made pretty well all the points I would have, very well. Not that Z's post wasn't helpful too, but I just felt it gave the impression that there was little more to worry about than the type of object in use (which is far from true).

This issue comes up over and over again because many fail to realise that it is an object returned by a function. The point Smiley made about the object being different every time it's called is very pertinent. Making code work together is very difficult without the realisation of this point. Furthermore, the resource overheads involved maintaining multiple copies of this object (I understand that the object is not too trivial) is such that many people have dbs that run out of resources simply due to using CurrentDb() in their loops rather than using a variable worked out once at the start. It is not a trivial problem and you will certainly be better off for understanding these points, and if not quite understanding all the issues, at least knowing to avoid the reuse of the function wherever you can in your code.

Seth:
I got the important part: Always use the variable and not the straight CurrentDb because there is a good reason. :)
If you get no further than that then you've still picked up the most important point.
Smiley:
Heheh, I hope I managed to clear it up, more then I managed to muddy it up. :)
Definitely. A very good job I thought.
Dec 31 '12 #12
zmbd
5,501 Expert Mod 4TB
I purposely simplified the need to type casting and the variable assignment.
For most people the additional information doesn't add to the understanding of how/why to call. This is sort-of like ignoring the small x in the pH function in General Chemistry so as to avoid the quadratic equation. The error is small, and the full equation distracts from the underlying need.
Dec 31 '12 #13
NeoPa
32,556 Expert Mod 16PB
I'm not sure I follow that very well Z, but as I was certainly not attempting to cast any aspersions on your post I'm not too sure I need to. I was merely anxious to ensure the points related to resources etc were put down and emphasised as they are the crux of the matter from my point of view. If my wording sounded critical of your post them I must accept responsibility for that of course, and I apologise for my clumsiness.
Dec 31 '12 #14
Seth Schrock
2,965 Expert 2GB
I think that I have understood most of the reasons for using the variable and I certainly am going to check all of my previous dbs to find all the places where I took the shortcut and didn't use the variable. Thankfully, I don't think that I ever used it in a loop.

Thanks to everyone for explaining this to me. I always like to understand the reason for doing things a certain way as I feel that I will remember it better and be able to more easily use my knowledge to decide the proper way to do something depending on the circumstances.
Dec 31 '12 #15

Sign in to post your reply or Sign up for a free account.

Similar topics

8
by: dmiller23462 | last post by:
My brain is nuked....Can anybody tell me right off the bat what is wrong with this code? Along with any glaring errors, please let me know the syntax to display a message (Response.Write would be...
4
by: James | last post by:
Quick question about closing recordsets and connection objects. We're in the process of rewriting a TON of bad code. None of it is even remotely tabbed properly, it's impossible to read half the...
1
by: andrewdreib | last post by:
I am still very new to ASP and am trying to create an ASP page that gets records from a database. Right not I can successfully get one field of information at a time and randomize it, but I need...
7
by: Arpan | last post by:
Assume that an ASP page has 3 SQL queries. Can a recordset object be populated with the records of all these 3 queries at the same time? Please note that the 3 queries are distinct queries, not...
5
by: Simone | last post by:
Hello I hope you guys can help me. I am very new to ADO... I am creating a ADODB connection in a module and trying to access it from a command button in a form. Function fxEIDAssgn(plngEID As...
12
by: (Pete Cresswell) | last post by:
Say I've got a RecordSet: ----------------------------------------------------------- Set myRS = CurrentDB.OpenRecordset(SomeSQL, dbOpenDynaset)...
1
by: Uros | last post by:
When closing some forms in MSAccess 2003 Access is crashed (Microsoft Office Access has encounteres a problem and needs to close. We are sorry .......). If I close form without changes work OK, but...
18
by: Darryl Kerkeslager | last post by:
When I open an ADO Recordset, I close it. However, it seems that there may be some difference in this manner of opening a Recordset: Dim rL As ADODB.Recordset Set rL = New ADODB.Recordset ...
10
by: Roger Withnell | last post by:
I'm using ASP, VBScript and SQL Server. I'm also using UTF-8 character set and so my codepage is 65001 and SQL Server datatype nvarchar. I can insert unicode characters correctly into the...
6
by: blue875 | last post by:
Hello helper people who are smarter than me: I have a form that needs to submit multiple queries to different tables during one Sub's execution. Some sections are as simple as: 1| With rst 2|...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.