Building a query without using a query table

Glory

Well-known Member
Joined
Mar 16, 2011
Messages
640
http://www.excel-vba.com/vba-code-2-12-SQL.htm

I need to be able to run an SQL query without generating any result in my Excel worksheet. That's because I'll be returning so many rows, I won't be able to fit them onto a single sheet... I need to Inner Join multiple tables and then reference the result like an external database to create a Pivot Table.

eg:

Code:
Select * From C:\DOCUMENTS AND SETTINGS\DESKTOP\Book1.xls`.'Sheet1$'
UNION ALL C:\DOCUMENTS AND SETTINGS\DESKTOP\Book2.xls`.'Sheet1$'


All I need to know is how to modify code like what's at the link above to build a table that I can work with using SQL through VBA.

Can anyone help with that?
 

Excel Facts

Can you sort left to right?
To sort left-to-right, use the Sort dialog box. Click Options. Choose "Sort left to right"
For clarity, this is the code I'm talking about:

Code:
Sub proSQLQuery1()
Dim varConnection
Dim varSQL
       Range("A1").CurrentRegion.ClearContents
       varConnection = "ODBC; DSN=MS Access Database;DBQ=C:\test.mdb; Driver={Driver do Microsoft Access (*.mdb)}"
       varSQL = "SELECT tbDataSumproduct.Month, tbDataSumproduct.Product, tbDataSumproduct.City FROM        tbDataSumproduct"
       With ActiveSheet.QueryTables.Add(Connection:=varConnection, Destination:=ActiveSheet.Range("A1"))
               .CommandText = varSQL
               .Name = "Query-39008"
               .Refresh BackgroundQuery:=False
       End With
End Sub

The code generates a query table, which I can't do. I need to know if there are any other ways to generate a working table using Excel's VBE... preferably one that's not visible to the user, that's just stored somewhere and can be grabbed by a pivot table as an external database.​
 
Upvote 0
Simplest: Use a SQL query that already performs the inner joins or filtering that you want to do.

It is possible to have "invisible tables" in a recordset but they aren't for permanent data storage and cannot be themselves queried. You could however, have a recordset with more records than there are rows in Excel, and use it in a pivot table. Some example is here: http://www.ozgrid.com/forum/showthread.php?t=25473&page=1 On using ADO to get recordsets (in general) see: http://www.erlandsendata.no/english/index.php?t=envbadac If your data is Access I think you can also connect the pivot table to Access as an (external) data source, and not bring the data into Excel so that's another way to avoid the query table.
 
Upvote 0
Great links. Those connection strings in the second one especially are great because I never even understood what the different parts of the connection string were.

But I just don't understand how to use SQL in VBA. I can't type it directly in, and I don't know what method I have to employ to get the string I build to work. Is there not another one that's simple, like that querytable method?

Can you give me a brief example of what I would do to access sheets on two external workbooks, and then join them together?
 
Upvote 0
When you say "they cannot be themselves queried", do you mean I couldn't draw "tables" from five or six different worksheets, then join them into a final table, then reference them from a pivot table?
 
Upvote 0
When you say "they cannot be themselves queried", do you mean I couldn't draw "tables" from five or six different worksheets, then join them into a final table, then reference them from a pivot table?

correct.

You could resolve more of this in your sql query:

Select Fld1 FROM Table1
UNION
Select Fld1 FROM Table2
UNION
SELECT Fld1 FROM Table3
UNION
SELECT Fld1 FROM Table4
...

I personally wouldn't want to work with data in so many different excel spreadsheets, though. If possible organize the data so it's centralized first, or push it to one data store to be queried. Perhaps work with it in Access.
 
Upvote 0
Glory

I've got to agree with xenou, working with all this data spread over multiple workbooks/worksheets just sounds like trouble.

It wouldn't be too difficult to take the data from the worksheets, transfer it to Access or some other database and consolidate it there.

You could even do that with code.

Once you've got the data you could use it for the source of the pivot table, or perhaps have a look into using it for a crosstab/TRANSFORM query.

I suppose you could say a crosstab query is the database equivalent of a pivot table - I think it can actually be referred to as a pivot query.

You won't get as many options as you would have automatically with a pivot table in Excel but you can do the basics and with a little effort recreate some of the
functionality of Excel pivot tables.

If you don't want to use a query in the database you could try something like this.
Code:
Option Explicit
 
Sub CreatepPivotTableWithExtData()
Dim conn As New ADODB.Connection
Dim cmd As New ADODB.Command
Dim rst As New ADODB.Recordset
Dim ptCache As PivotCache
Dim ptTbl As PivotTable
Dim ptFld As PivotField
Dim ws As Worksheet
Dim arrFields
Dim strPath As String
Dim strDBName As String
     
    ' reference to workbook pivot will go on
    Set ws = ThisWorkbook.Worksheets("Accidents")
 
    strPath = "C:\AccessStuff\"
 
    strDBName = "TestPadDB.mdb"
 
    With conn
        .Provider = "Microsoft.ACE.OLEDB.12.0"
        .ConnectionString = "Data Source=" & strPath & strDBName & ";Mode=Share Deny None"
    End With
 
    conn.Open
 
    Set cmd.ActiveConnection = conn
 
    With cmd
        .CommandText = "SELECT * FROM Accidents"
        .CommandType = adCmdText
        .Execute
    End With
 
    Set rst.ActiveConnection = conn
 
    rst.Open cmd
 
    Set ptCache = ThisWorkbook.PivotCaches.Add(SourceType:=xlExternal)
 
    Set ptCache.Recordset = rst
 
    Set ptTbl = ws.PivotTables.Add(PivotCache:=ptCache, TableDestination:=ws.Range("A1"), TableName:="CountOfAccidents")
 
    Set ptFld = ptTbl.PivotFields("Year")

    ptFld.Orientation = xlColumnField

    ptFld.Position = 1
 
    Set ptFld = ptTbl.AddDataField(ptTbl.PivotFields("Severity"), "Count", xlCount)

    ptFld.Orientation = xlDataField

    ptFld.Position = 1
    
    Set ptFld = ptTbl.PivotFields("Severity")

    ptFld.Orientation = xlRowField

    ptFld.Position = 1
 
    Set rst = Nothing

    Set cmd = Nothing

    Set conn = Nothing
    
End Sub
This code runs a simple query on a table in an Access database and creates a pivot table using the resulting recordset it as a data source.

By the way it's quite old code, I don't know why I used Command for the query - I think the code might have been used for something else previously.
 
Upvote 0
Code:
   ' Open a connection by referencing the ODBC driver.
   cnn.ConnectionString = "driver={SQL Server};"

From MSDN.

How do I know what the driver is supposed to be? Some people use Jet, and up there I see the "Provider" is "Microsoft.ACE.OLEDB.12.0".

It seems really hard to use documentation to pick a method and stick with it, because it's like there are thirty different ways of doing this and nobody explains from start to finish how to do any one of them.

Norie, your post about the pivot table has me wondering why code I just posted in this thread won't work.
 
Upvote 0
Also, what's the trouble I can expect if I'm forced to do this using a bunch of different workbooks?

Having to consolidate everything into an MDB file would be a problem, it would add extra time to the code's runtime (I can't say how much) and I've never done that before either so it's just one more thing to have to learn and convince my employer we need to do.

Whereas MSDN indicates that when you grab from a sheet as though it were a table, it automatically grabs the entire used range. So what's more volatile about just grabbing "tables" from multiple workbooks, instead of doing it from a database or a non-excel pivot table?
 
Upvote 0
1) on providers: There's no right or wrong. Use a provider that works. If you're using Access 2007/10 or Excel 2007/10 you probably must use ACE. If you're using Access 2003 or Excel 2003 (or earlier) both ACE and Jet will work.

2) on centralizing data: there's no right or wrong. Do what works for you.
 
Upvote 0

Forum statistics

Threads
1,224,526
Messages
6,179,322
Members
452,906
Latest member
Belthazar

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top