Read our blogs, tips and tutorials
Try our exercises or test your skills
Watch our tutorial videos or shorts
Take a self-paced course
Read our recent newsletters
License our courseware
Book expert consultancy
Buy our publications
Get help in using our site
538 attributed reviews in the last 3 years
Refreshingly small course sizes
Outstandingly good courseware
Whizzy online classrooms
Wise Owl trainers only (no freelancers)
Almost no cancellations
We have genuine integrity
We invoice after training
Review 30+ years of Wise Owl
View our top 100 clients
Search our website
We also send out useful tips in a monthly email newsletter ...
Posted by Andrew Gould on 09 April 2021
Looping through the collection of worksheets in a workbook is a standard technique in Excel VBA and easy to accomplish when the workbook is open. Did you know that you can do the same thing when the workbook is closed? This video explains how to do this using the ActiveX Data Objects library. You'll learn how to create a connection object and construct a connection string to talk to the closed Excel file. You'll learn how to query the schema of the workbook to return a list of the worksheets and loop through this list to read the name of each sheet. You'll also learn how to create a recordset object and populate it with data using an SQL Select statement. As a bonus you'll learn about the SQL Union All statement to select data from multiple tables at the same time and how to add criteria to a query using the Where clause.
See our full range of VBA training resources, or test your knowledge of VBA with one of our VBA skills assessment tests.
This video has the following accompanying files:
File name | Type | Description |
---|---|---|
Loop Through Worksheets in a Closed Workbook.xlsm | Excel workbook with macros | |
Movies By Year.xlsx | Excel workbook |
Click to download a zipped copy of the above files.
There are no exercises for this video.
You can increase the size of your video to make it fill the screen like this:
Play your video (the icons shown won't appear until you do), then click on the full screen icon which appears as shown above.
When you've finished viewing a video in full screen mode, just press the Esc key to return to normal view.
To improve the quality of a video, first click on the Settings icon:
Make sure yoiu're playing your video so that the icons shown above appear, then click on this gear icon.
Choose to change the video quality:
Click as above to change your video quality.
The higher the number you choose, the better will be your video quality (but the slower the connection speed):
Don't choose the HD option shown unless your connection speed is fast enough to support it!
Is your Wise Owl speaking too slowly (or too quickly)? You can also use the Settings menu above to change your playback speed.
From: | Jocaqu |
When: | 11 Feb 22 at 10:50 |
Hi Andrew!
Great video! Quick question though as I am fairly new to coding, how can I utilise the Sheet tabs of the closed workbook instead of the Sheet Names? I've got a closed workbook that I would like to import in order but if I use the names it just doesn't work as intended.
Example: Sheet Names: Hello, Hello (1), Hello (2) etc. (The space between the () and the original name changes the order of importing.
Also follow up question, I would like to extract a specific range within these sheets. The first sheet "Hello" I want range ("A12:P10000") and the rest range("A8:P10000"). I was wondering if it's possible while looping through the sheets.
Appreciate the help here and great tutorials!
Regards,
Jocelyn
From: | Jocaqu |
When: | 13 Feb 22 at 11:42 |
Thank you so much Andrew! I'll give it a go and will let you know how it turns out! Appreciate all the help I just received!
From: | Andrew G |
When: | 14 Feb 22 at 07:46 |
Good luck!
From: | Andrew G |
When: | 18 Feb 22 at 08:56 |
Hi Jocelyn, happy to hear that you got it working!
You can count the number of sheets by adding another loop through the rsSheets recordset before the loop to build the SQL string. So, after you've used the OpenSchema method to populate the rsSheets variable you can do this:
Do Until rsSheets.EOF
SheetCount = SheetCount + 1
rsSheets.MoveNext
Loop
Debug.Print SheetCount
rsSheets.MoveFirst
It would be nice if you could use the RecordCount property of the recordset to get the number of rows but sadly that property only works when using client side cursors and the OpenSchema method doesn't support client side cursors.
I hope it helps!
From: | Jocaqu |
When: | 17 Feb 22 at 09:45 |
Hi Andrew,
Just wanted to inform you that I managed and also to thank you for the inspiration. I simply made a sheet count which temporarily opens the file to count the sheets and then insert that sheet count into a loop when a is bigger than one then i = 2 to a and insert that into Hello (i) and loop through the dataset with the target range being the next available row.
One last question, is there a way to import the sheet count without opening the file?
From: | Andrew G |
When: | 12 Feb 22 at 09:42 |
Hi Jocelyn!
The OpenSchema method always returns tables sorted by name and I don't know a way around this.
You could apply sorting to your results after importing them. If you're importing everything into a single worksheet you could apply the Sort method to the range https://docs.microsoft.com/en-us/office/vba/api/excel.range.sort If you're importing data into different worksheets you could apply the Move method to the "Hello" sheet to place it at the beginning https://docs.microsoft.com/en-us/office/vba/api/excel.worksheet.move
Alternatively, if you can't reliably sort things after importing you could resort to the slower method of opening the source workbook and looping through the worksheets collection (this follows the tab order from left to right) https://youtu.be/jLepKYcFvxA
If you need to reference a specific range of cells on a worksheet you might find this chapter of this video useful https://youtu.be/FNjTCwV7VhM?t=330
You can use an If statement to check if the SheetName is "Hello" or not and select from the appropriate range of cells.
I hope that helps!
From: | Excel-sior |
When: | 27 Jun 21 at 21:23 |
Hey Andrew!
I started following you on YouTube, but finally found your site. I really enjoy what you've been able to produce so far. It's helped me a ton in my current role.
My question is...how do I reference an excel table in the sql select statement part of the code? I also tried a name range, but was unsuccessful. Any help would be appreciated!
Thanks!
From: | Andrew G |
When: | 28 Jun 21 at 07:00 |
Hi there, what an Excel-lent user name!
Sadly you can't reference Excel table names in an SQL query, but you can reference a range name like so:
SELECT * FROM [MyRangeName]
Make sure not to use the $ sign as you're not referencing a worksheet.
You might find this YouTube playlist useful https://youtube.com/playlist?list=PLNIs-AWhQzckUd5i0E1xeSFeBAonYIurK Part 58.1 includes information on referencing range names.
I hope that helps!
From: | Excel-sior |
When: | 29 Jun 21 at 23:56 |
Thank you very much! I'm also trying to use an input box result in my sql query. It's a number, but when I step through the process my input box value shows it at "123456789". Would the quotation cause an issue in the query?
Thanks!
From: | Andrew G |
When: | 30 Jun 21 at 07:58 |
Hi there,
When you say that the value is showing with quotes do you mean in the Locals window? A VBA inputbox always returns a string value so it will always be displayed with " " around it in tools like the Locals window. The quotes won't be included if you concatenate that value into your query string (I assume that's what you're trying to do?). Remember that you can always print your SQL string to the Immediate window to check that it's correct before you run it.
Just in case it helps, we have a module on working with VBA input boxes which you can find here.
Kingsmoor House
Railway Street
GLOSSOP
SK13 2AA
Landmark Offices
99 Bishopsgate
LONDON
EC2M 3XD
Holiday Inn
25 Aytoun Street
MANCHESTER
M1 3AE
© Wise Owl Business Solutions Ltd 2024. All Rights Reserved.