Reputation: 139
This works for .xls books, but can it be altered for .xlsx workbooks as well? Or is their syntax that will work for both?
Option Explicit
Public Sub RefreshQueries()
Dim wks As Worksheet
Dim qt As QueryTable
For Each wks In Worksheets
For Each qt In wks.QueryTables
qt.Refresh BackgroundQuery:=False
Next qt
Next wks
Set qt = Nothing
Set wks = Nothing
End Sub
EDIT -- So it seems my syntax does refresh .xlsx workbooks, but not queries that are from sql server. How can those be refreshed via VBA.
Upvotes: 6
Views: 46356
Reputation: 21
ActiveWorkbook.RefreshAll
Objects that have the BackgroundQuery
property set to True
are refreshed in the background
Upvotes: 1
Reputation: 3205
The answer from @nekomatic throws error 1004 for me (although it apparently works for others). I use this instead:
Public Sub RefreshAllQueries()
' Refresh all queries (tables querying data from another source).
Dim iWorksheet As Excel.Worksheet
Dim iTable As Excel.ListObject
Dim iQueryTable As Excel.QueryTable
' Check each worksheet.
For Each iWorksheet In Excel.ActiveWorkbook.Worksheets
' Check each table.
For Each iTable In iWorksheet.ListObjects
If iTable.SourceType = Excel.XlListObjectSourceType.xlSrcQuery Then
' Table is a query table.
With iTable.QueryTable
.BackgroundQuery = False ' setting to wait for query to refresh
.Refresh
End With
End If
Next iTable
For Each iQueryTable In iWorksheet.QueryTables
iQueryTable.Refresh BackgroundQuery:=False ' wait for query to refresh
Next iQueryTable
Next iWorksheet
End Sub
Upvotes: 4
Reputation: 6284
First, no macro will work in a .xlsx
workbook because .xlsx workbooks can't contain macros - you need to save as a macro-enabled workbook which has the extension .xlsm
.
In Excel 2007 and later, user created external data connections to SQL Server data sources (amongst others) will result not in a QueryTables member, but in a ListObject which will possess a QueryTable object that can be accessed via the ListObject.QueryTable
property - see Dick Kusleika's answer to this question. The following code should refresh both types of queries:
Option Explicit
Public Sub RefreshQueries()
Dim wks As Worksheet
Dim qt As QueryTable
Dim lo As ListObject
For Each wks In Worksheets
For Each qt In wks.QueryTables
qt.Refresh BackgroundQuery:=False
Next qt
For Each lo In wks.ListObjects
lo.QueryTable.Refresh BackgroundQuery:=False
Next lo
Next wks
Set qt = Nothing
Set wks = Nothing
End Sub
I wasn't previously familiar with the ListObject
type so I don't know if you can have a ListObject
on a worksheet that doesn't have a QueryTable
, which might cause an error in the above code - you might need to check for this.
Upvotes: 10