How to find/run RefreshAll? - excel

I have a simple VBA code:
Private Sub Worksheet_Change(ByVal Target As Range)
Sheet1.RefreshAll
End Sub
This window pops up
Compile error:
Method or data member not found
It directs me to the RefreshAll function.
When I was writing the line, after the fullstop, the drop down list didn't show the RefreshAll function.

RefreshAll is the method for Workbook object. So, you cannot use with Worksheet object. Please see https://learn.microsoft.com/en-us/office/vba/api/excel.workbook.refreshall

As #Adisak said, RefreshAll is a method of Workbook object, not Worksheet object.
So, you need to do one of the following:
1: Refresh all for the whole workbook.
ThisWorkbook.RefreshAll
2: Loop through the objects you want to refresh within the sheet and refresh them one by one. (As mentioned here for pivot tables)
Sub RefreshPT()
Dim wsh As Worksheet
Dim pvt As PivotTable
Set wsh = Sheet1
For Each pvt In wsh.PivotTables
pvt.RefreshTable
Next pvt
End Sub

Related

Using For Loop to Call the Same Named Functions from Multiple Worksheets

I am trying to see if it's possible to click a button on a series of sheets with a function. For a single sheet, my code works fine, but I get an Runtime error 438 when I try to do the code below.
Public Sub Read_All_Data_Click()
Dim ws As Worksheet
For Each ws In Worksheets
ThisWorkbook.Sheets(ws.Name).Read_Data_Click
Next ws
End Sub
Read_Data_Click is not a built in property of a worksheet.
You have to write your Sub Read_Data_Click(MySheet as worksheet) in a module, and parse the referance to each wc from the loop. Then you only use the name of the sub like Read_Data_Click(ws)
ws is defined as worksheet, during the for loop the variable will be updated to be the current worksheet. Because of this using Sheets(ws.name) is redundant, instead your code should look like:
Public Sub Read_All_Data_Click()
Dim ws As Worksheet
For Each ws In Worksheets
ws.Read_Data_Click
Next ws
End Sub

Access Worksheet by name including ThisWorkbook

This has been bothering me for a while. I want to access Worksheet by name instead of "how worksheet has been named in Excel". I would like also to include ThisWorkbook in the line, to eliminate possibility of having several Workbooks open with Worksheets with the same name. However I am getting an error:
I have named my Worksheet CalculationItem1. Why following does not work?
Sub TestTest()
ThisWorkbook.CalculationItem1.Range("A1:A2").Copy
End Sub
Following error appears:
Following works but there is a possibility of having same named Worksheet in another opened Workbook? Then errors can appear?
Sub TestTest()
CalculationItem1.Range("A1:A2").Copy
End Sub
Here is the name:
As long as the sheet is in the same Workbook as the code ("ThisWorkbook"), you can access the sheet via it's code name. That is true even if the Workbook is not active - it's like you have an object-variable with that name. So using CalculationItem1.Range("A1:A2").Copy will always refer to the sheet with the code name CalculationItem1 of ThisWorkbook.
If you want to access a worksheet of another workbook via code name, you have to iterate the sheets and look for the property CodeName (as FaneDuru shows in his answer).
Not sure that is possible to directly define the sheet using a specific CodeName.
But you can avoid confusing about such a sheet and another one of the active workbook, similarly named, using a function like this:
Function SetShByCN(strCodeName As String, wb As Workbook) As Worksheet
Dim sh As Worksheet
For Each sh In wb.Worksheets
If sh.CodeName = strCodeName Then Set SetShByCN = sh: Exit Function
Next
End Function
It must be adapted to send a warning in case of not existing such a sheet, or to return Nothing and this to be checked in the code calling the function. This is only made for testing reason...
It will do the job being called like in the next test code:
Sub testSetShByCN()
Dim wks As Worksheet
Set wks = SetShByCN("CalculationItem1", ThisWorkbook)
Debug.Print wks.Name
sh.Range("A1:A2").Copy
End Sub
In your first piece of code, you need to tell Excel that you are referring to a worksheet:
Sub TestTest()
ThisWorkbook.WorkSheets("CalculationItem1").Range("A1:A2").Copy
End Sub
Regards,

Is there a possibility to run a macro in an excel-file (data-source) when data connection is refreshed by another excel-file (data-target)?

a lot of users in our network use an excel-workbook (.xlsm [office 2010]) created from a template.
Now, there are some important changes I've to do in the template and I want all the users to update their workbook but i'd like to avoid to contact all of them.
So, my Idea is to make an auto-update (copying the contents of their workbooks into new created workbooks and delete the former version).
Unfortunately there are no update-macros in the existing workbooks but they reference to a macro in another workbook.
Each time they open their workbooks the data connections become refreshed automatically.
Can I use this refreshing event to trigger a macro in the (data-source) excel-file (maybe by creating a WithEvents-class module)?
You can do something along these lines, where the user opens a workbook, but its job is to control the version. You can change this to have the code modify sheets etc.
The text file, correct, contains ver9, the workbook contains ver8 in the ver_cont worksheet.
Function get_version() As String
Open "c:\workspace\test_ver.txt" For Input As #1
Input #1, get_version
Close #1
End Function
Function check_version()
If get_version = Worksheets("Ver_cont").Range("a1") Then
' Open the workbook here
Else
' Copy the workbook
' Then open it
End If
End Function
You can try this. It uses withevents and runs when the data is updated.
First, you need to create a class name "clsQueryTable" and put this code in it
Option Explicit
Public WithEvents QTQueryTable As Excel.QueryTable
Private Sub QTQueryTable_BeforeRefresh(blnCancel As Boolean)
'Set blnCancel to true to stop the refresh
Debug.Print blnCancel
End Sub
Private Sub QTQueryTable_AfterRefresh(ByVal blnSuccess As Boolean)
'blnSuccess can be used to check for refresh success.
' I would put your update code here!
Debug.Print blnSuccess
End Sub
Then, you can put this code in your workbook_open event on ThisWorkbook
Option Explicit
Dim colQueryTables As Collection
Private Sub Workbook_Open()
Dim shtMySheet As Worksheet
Dim clsQT As clsQueryTable
Dim qtMyQuery As QueryTable
Dim loMyList As ListObject
Dim conn As WorkbookConnection
Set colQueryTables = New Collection
For Each shtMySheet In ThisWorkbook.Worksheets
For Each loMyList In shtMySheet.ListObjects
Set clsQT = New clsQueryTable
Set clsQT.QTQueryTable = loMyList.QueryTable
colQueryTables.Add clsQT
Next loMyList
Next shtMySheet
For Each conn In Connections
conn.Refresh
Next
End Sub

In Excel VBA, how to run a worksheet event from add-in to active workbook

I like to run code from an Excel add-in to the active workbook (xlsx). The code should apply some formatting to the active cell of the active workbook, when activated in the menu.
How can I achieve this?
Normally you can realize this by using the worksheet_change event in the active workbook, but this requires:
a macro-enabled workbook, AND
having the code in this particular workbook.
I like to have this applied via an add-in, independent of the workbook and thus without the need to insert code in this workbook and to make this a xlsm workbook first.
You can catch WorksheetChange events from one worksheet in another (class) module, but in this case you probably rather use Application.SheetChange as above (code in ThisWorkbook module in addin):
'Create an object to catch events
Dim WithEvents ExcelApp As Excel.Application
'Assign object when addin opens
Private Sub Workbook_Open()
Set ExcelApp = Application
End Sub
'Handle sheet changes in all workbooks
Private Sub ExcelApp_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Dim rng As Range
'Do some validation...
If Sh.Parent.Name = "Book1" And Sh.Name = "Sheet1" Then
'Ensure correct range
'Note: changes may occur in many cells at a time (delete, paste, ...)
Set rng = Intersect(Target, Workbooks("Book1").Worksheets("Sheet1").Range("A1:B2"))
If Not rng Is Nothing Then
rng.Interior.ColorIndex = vbRed 'Example
End If
End If
End Sub
Thanks both, seems I have new insights here I can test and try out.

How to clear all slicer only on one sheet?

I'm trying to clear all slicers on a specific worksheet but getting next error:
"object variable or with block variable not set" in this line: cache.ClearManualFilter.
My code:
Sub Clear_all_filters()
Dim cache As SlicerCache
Set mWS = Sheets("Specific_Sheet")
For Each cache In mWS.SlicerCaches
cache.ClearManualFilter
Next cache
End Sub
Just in case someone's still looking for a solution to this question, here is the code I'm using now:
Sub OnePageSlicersReset()
Dim slcrC As SlicerCache
Dim slcr As Slicer
Application.ScreenUpdating = False
For Each slcrC In ActiveWorkbook.SlicerCaches
For Each slcr In slcrC.Slicers
If slcr.Shape.Parent Is ActiveSheet Then
If slcrC.FilterCleared = False Then
slcrC.ClearManualFilter
Exit For
End If
End If
Next slcr
Next slcrC
Application.ScreenUpdating = True
End Sub
Firstly, you should go to Tools>Options and turn on Require Variable Declaration. This will add Option Explicit to the top of any new module (You'll need to add it yourself to any pre-existing module).
This will force you to declare mWS, which would need to be a Worksheet class according to the Set command. This will bring up the error 'Method or data member not found' when you try to run the code.
This is because SlicerCaches are a property in the Workbook class, not Worksheet (As described here: https://learn.microsoft.com/en-us/office/vba/api/excel.slicercache)
In this case we can remove all reference to mWS and just use ThisWorkbook. As this suggests it will loop through all slicers in the current workbook so you may need to do some extra digging if you want to limit it to those in just one sheet.
Option Explicit
Sub Clear_all_filters()
Dim cache As SlicerCache
For Each cache In ThisWorkbook.SlicerCaches
cache.ClearManualFilter
Next cache
End Sub

Resources