I have three tables which pull data from SQL database.
When I click refresh all from the data menu, the connections refresh but only sum of the tables are refreshed.
When I right-click>refresh the tables themselves, they reflect the correct information (telling me that the connection was refreshed indeed).
I tried ActiveBook.RefreshAll and the following code too:
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
How can I refresh the table using VBA code?
You should access the connections through Workbook. Example,
Sub Test()
Dim con As WorkbookConnection
For Each con In ThisWorkbook.Connections
' Your Conditions, for example, check connection name etc.
' If con.Name = "MyConnection" Then
con.Refresh
' Else
' Do your thing
' End if
Next
End Sub
Related
I have an Excel file that comprises a sheet "DATA", which contains data extracted using a Power Query, and three other sheets containing pivot tables that are all dependent on these extracted data in "DATA".
I wantto create a VBA that (1) automatically refreshes/reruns the Power Query specified above when the Excel file is opened and (2) subsequently updates the three pivot tables to mirror the updated data.
I have made several attempts and looked for similar questions on stackoverflow, but without succeeding:
While it was possible for me to refresh the data by refreshing the connection, the Pivot tables were not updated accordingly.
One VBA code that, among others, did not yield the desired results (i.e. subsequently updating the Pivot table) is:
Sub test()
Dim ws As Worksheet
Dim pt As PivotTable
'ActiveWorkbook.RefreshAll 'make sure the refresh in bg property is false for all connections
ActiveWorkbook.Connections("Name of Query").Refresh
For Each ws In ActiveWorkbook.Worksheets
For Each pt In ws.PivotTables
pt.RefreshTable
Next pt
Next ws
End Sub
Thank you!
You must be sure that "background refresh" is set to false:
Sub Refresh_All_Data_Connections()
Dim objConnection, bBackground
For Each objConnection In ThisWorkbook.Connections
'Get current background-refresh value
bBackground = objConnection.OLEDBConnection.BackgroundQuery
'Temporarily disable background-refresh
objConnection.OLEDBConnection.BackgroundQuery = False
'Refresh this connection
objConnection.refresh
'Set background-refresh value back to original value
objConnection.OLEDBConnection.BackgroundQuery = bBackground
Next
ThisWorkbook.RefreshAll
End Sub
Update: added refreshall to refresh all pivot tables.
Rereading your question if you just want to refresh a specific query (assuming sh is set):
sh.ListObjects("Name of Table").QueryTable.refresh BackgroundQuery:=False
ThisWorkbook.RefreshAll
I am trying to write a vba only to refresh the local pivot tables. Since the pivot tables are getting data from a power query which links to a password locked excel file. In the past few days, I managed to write a vba to open the external excel file to refresh my query.
After refresh, my subroutine will close the excel file again, so other people of my team could access it without my holding up the file. Then, I would like to refresh all the pivot tables linked to the query. Since it links to password locked file, I don't want to refresh that query again. In one of your RefreshQueries suggestion stated such a code:
Sub RefreshQueries()
Dim ws As Worksheet
Dim qt As QueryTable
For Each ws In ThisWorkbook.Worksheets
For Each qt In ws.QueryTables
qt.Refresh
Next qt
Next ws
End Sub
You mentioned that I could write a similar subroutine to be called for updating Pivot Tables separately. Please advise how the other subroutine should be written.
Thanks!
You could use the following subroutine. It iterates over all the worksheets in the Workbook and then refreshes every pivotTable in the worksheet:
Sub RefreshPivotTables()
Dim ws As Worksheet
Dim pt As PivotTable
For Each ws In ThisWorkbook.Worksheets
For Each pt In ws.PivotTables
pt.PivotCache.Refresh
Next pt
Next ws
End Sub
I have a small program VBA which is fact a userform which allow me to display all the existing worksheet of one open workbook on which I am working. Via this userform I can select another sheet and by clicking the sheet via this userform, it reorients me to the desired worksheet.
Now I tried to modifiy a bit of part of this program in order to do it the same but with all my open workbooks. It means if I have several workbook open, I would like that my userform allows me to display all the existing open workbook and by selecting the desired workbook via the userform, it reorients me to this workbook (it means that the selected workbook in the userform is activated and selected). The problem is when I run the code, I have an error message 424 VBA Run-time error '424' Object Required Error…
PS:really sorry for the format of my Code but I do not manage to put it in the right format..
Thanks in advance for your help
Xavi
Here please find the original code which works for userform related to worksheet (this one works):
Sub UserForm_Initialize()
Dim n As Long
Dim msg As String
Dim i As Long
Dim s As String
Dim sht As Worksheet
Do
n = n + 1
Me.ListBox1.AddItem Sheets(n).Name
Loop Until n = Worksheets.Count
End Sub
Here please find the modified code for userform related to workbook (this one does not works: run time error 424):
Sub UserForm_Initialize()
Dim n As Long
Dim msg As String
Dim i As Long
Dim s As String
Dim Wb As Workbook
Do
n = n + 1
Me.ListBox1.AddItem Workbooks(n).Name
Loop Until n = Worksbooks.Count
End Sub
If there is no reason for the actual number to be parsed in your code, then why not just loop the sheets directly?
Sub UserForm_Initialize()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
Me.ListBox1.AddItem ws.Name
Next ws
End Sub
May I propose a simple for loop ?
Dim i As Long
For i = 1 To Application.Workbooks.Count
Debug.Print Application.Workbooks(i).Name
Next
Then, if you have different instances of Excel (different Application objects then the one your Userform came from), this become a little bit more complex. (This is probably not the case if you are working in Excel 2010 or newer). But, if this is the case, it requires a couple of Win32 API calls and some insights on the "windows" of Excel. I've found my answers here in the past : Can VBA Reach Across Instances of Excel?
I have two tables, one with a list of cities( we'll call this City List), and another with data points that correspond with those cities ( Call this The Data Table). The Data Table, is connected to a Select query that I built in MS SQL Server. This Select query/ Data Table has a single Where clause in which I have substituted the SQL criteria and replaced a ? in order to make it a parameter when connected to Excel.
Now that I have that out of the way, I'll explain what I'm trying to accomplish. I want to loop through the City List and for each city in the list, update The Data Table to reflect the data points for the city. Ultimately, I would like to loop through and each time The Data Table is refreshed, it saves a copy of the workbook with that specific table.
I have posted my current code down below, but my issue is that the table never refreshes with the current data that corresponds with the city that is currently selected via the loop. With that being said, if I hit the escape key to break out of the VBA macro, the table will then refresh with whatever the last city was before I stopped the macro.
Code:
Sub Macro1()
Dim WS As Worksheet
Dim WS2 As Worksheet
Dim CT As Variant
Dim MSG As String
Set WS = Sheets("Sheet1")
Set WS2 = Sheets("Sheet2")
CT = Range("A1").CurrentRegion
For i = 2 To UBound(CT, 1)
MSG = ""
For J = 1 To UBound(CT, 2)
WS.Range("$D$2").Value = CT(i, J) //Places the city into Cell $D$2 which is where The Data Table looks to for the parameter.
Exit For
Next J
ActiveWorkbook.Connections("Query from Database").Refresh
WS2.ListObjects(1).Refresh
Next i
End Sub
It's almost as though the macro is running too fast for the table to catch up and refresh. I've tried adding some wait times into the code, in hopes that it would give it enough time to allow the table to refresh, but that had no affect. I have also turned off Background Refresh, and that doesn't seem to do anything either. Right now it just loops through the city table, and with each city it shows that the query is refreshing, but after the query is finished refreshing, it goes onto the next city without ever updating The Data Table. HELP!
There are a couple of things I think you need to do -- maybe you've already done them.
When you set up your parameter/bind variable (which you have done), point it to a specific cell. Then, within your SQL Server query, make sure the parameter is bound to that range every time:
Forgive me if I'm overstating the obvious, but for those that don't know you get to this dialog by right-clicking the table and selecting Table->Parameters.
From there, as you iterate through your main table (the one with the cities in it), you can just take the value from each row in that table and update the cell with the binding parameter.
Something like this should work:
Sub RefreshAllCities()
Dim ws1, ws2 As Worksheet
Dim loCities, loDataTable As ListObject
Dim lr As ListRow
Set ws1 = ActiveWorkbook.Worksheets("Sheet1")
Set ws2 = ActiveWorkbook.Worksheets("Sheet2")
Set loCities = ws1.ListObjects("CityList")
Set loDataTable = ws2.ListObjects("DataTable")
' get rid of those pesky warnings to overwrite files
Application.DisplayAlerts = False
For Each lr In loCities.ListRows
ws2.Cells(1, 2).Value = lr.Range(1, 1).Value
loDataTable.QueryTable.Refresh BackgroundQuery:=False
ActiveWorkbook.SaveAs Filename:="C:\temp\" & lr.Range(1, 1).Value & ".xlsx", _
FileFormat:= xlOpenXMLWorkbook
Next lr
Application.DisplayAlerts = True
End Sub
I assume you wanted .xlsx files in this example. This will clobber any embedded VBA, which is actually a nice bonus, as the recipients of the filtered datasets won't have to be exposed to that. If you want xlsm or xlsb, that's easy enough to change.
By default Excel will "Enable Background Refresh" which will allow Excel to move on and continue execution before the query refresh is actually finished. Some people have been able to get it to work by calling .Refresh twice but it's pretty much random/arbitrary timing.
There should be an Excel option to uncheck in the Data Tables properties or you might be able to update the BackgroundQuery = False property from VBA through a reference to it
If you disable background refreshing then your code will sit and wait for the refresh to complete before moving on.
Although I am relatively seasoned excel user, I am fairly new to VBA and am trying to tackle a fairly complicated task (at least it's complicated to me).
I have data in tables in 5 workbooks that I am trying to aggregate into one master workbook. However, I don't want all of the data. I only want to pull the data ( about 6 columns worth) that failed one of the tests (cell reads: "Fail"). All of the source workbooks have the 6 columns in the same order and have say "Pass" or "Fail" in their own cells. I want to pull only the fails from each and paste into a master workbook. I would also like it to pull into a clean looking table (i.e no blank rows between each set of data).
I believe this is feasible, but it's above my skill level (right now). After hours and hours of research and trial and error that inevitably always ends in failure, I am about to wave the white flag. This is my last hope. Please help!
The approach would be to:
Open all the workbooks to merge (assumed to be done manually, but could be coded if required)
Get a reference to the Master Table
Loop through open workbooks
Find the Table in the current workbook (code below assumes onlt one Table in each book. IOf this is not the case, then it can be changed to use some distingusing feature of the required table)
Use AutoFilter to filter for "Fail" records.
Copy and Paste the data onto the end of the Master Table
This code demonstrates how to do this. You will need to adapt it to tour specific situation.
Place this code in a Module in the Master workbook.
Sub Demo()
Dim wb As Workbook
Dim ws As Worksheet
Dim lo As ListObject
Dim loMaster As ListObject
'Get Reference to Master table
Set loMaster = ThisWorkbook.Worksheets("Master").ListObjects(1)
' Loop through open workbooks
For Each wb In Workbooks
If wb.Name <> ThisWorkbook.Name Then
' Assumes only one Table in each workbook,
' so return the first one found
Set lo = Nothing
For Each ws In wb.Worksheets
If ws.ListObjects.Count > 0 Then
Set lo = ws.ListObjects(1)
Exit For
End If
Next
If Not lo Is Nothing Then
' Filter Table on column Result for Fail
lo.Range.AutoFilter _
Field:=lo.ListColumns("Result").Index, _
Criteria1:="Fail"
' Copy filterd data to Master Table
If loMaster.InsertRowRange Is Nothing Then
'Master table is not empty
lo.DataBodyRange.SpecialCells(xlCellTypeVisible).Copy _
loMaster.DataBodyRange.Cells(loMaster.DataBodyRange.Rows.Count + 1, 1)
Else
'Master table is empty
lo.DataBodyRange.SpecialCells(xlCellTypeVisible).Copy _
loMaster.InsertRowRange
End If
' Reset Autofilter
lo.Range.AutoFilter
End If
End If
Next
End Sub