PivotTable Show Details Destination - excel

I know this may be solved with a more complicated script, but I simply want to have the .ShowDetails action for any PivotTable in my workbook (I have 15+) to send the associated data for a particular Pivot Item to a designated worksheet every time. I have this script, but I believe I have coded something incorrectly (I am receiving a procedure declaration compiling error when I attempt to execute it).
Sub Workbook_SheetBeforeDoubleClick()
Dim WS As Worksheet
If Application.Range(ActiveCell.Address).PivotCell.PivotCellType = xlPivotCellValue Then
For Each WS In ThisWorkbook.Worksheets
If WS.Name = "PivotTable Details" Then
WS.Delete
End If
Next WS
Selection.ShowDetails
ActiveSheet.Name = "PivotTable Details"
End If
End Sub

Couple things...
I believe it should be ShowDetail, not ShowDetails.
ShowDetail
is a property that needs to be set to True if you want to display
the data for the selected cell.
The following line should work.
Selection.ShowDetail = True

Related

VBA conflicting sheet name checking via an IF function

I have two subroutines that seem to conflict one with each other. Each one of them is for creating and formatting a new worksheet if it doesn't already exist and I ran into a problem where I can only create one of them and not the other (whichever one is the first one I call to create). I found taht it seems to skip the end sub function in an if function:
For Each Worksheet In Application.ActiveWorkbook.Worksheets
Application.DisplayAlerts = False
If Worksheet.Name = "Machine Layout" Then
Exit Sub
Else:
Sheets.Add.Name = "Machine Layout"
End If
Next
And gives an error that sheet with such name already exists.
Both subroutines use this same code except the worksheet name changes.
I'm wondering what's teh problem with that? Could someone, please, help?
Logic is wrong.
set wb = ActiveWorkbook
For Each ws In wb.Worksheets
If ws.Name = "Machine Layout" Then Exit Sub
next ws
Sheets.Add.Name = "Machine Layout"
I did not test my answer...

Copy formatting to macro

I have a workbook that the workbook formatting is changed regularly, however once changed (maybe weekly or monthly) then going forward until it is changed again a macro needs to replicate that format. Changing the VBA to account for the new formatting each time is very time consuming. Is it possible to format a workbook and then copy the formatting easily to VBA (after the fact not like a macro record) for future use?
In the past I have since used a hidden sheet within the workbook where the macro runs and I essentially copy/paste that into the sheet I am working with. This works but has the downside of when making changes I first need to copy data over to the "template" sheet to ensure everything is correctly aligned with new data.
Possibly some kind of macro that iterates through all cells of a range and outputs to the immediate window the VBA code needed to re-create the formatting?
Basically any ideas will help :)
There are so many formatting options that simply storing them as separate options will take far more space than just a duplicate template sheet. Just run the first code to update your template, and the second to copy it back:
option Explicit
Const TemplatesheetName = "mytemplate"
Sub CopyFormatting
dim ws as worksheet
dim source as worksheet
set source = activesheet
for each ws in worksheets
if ws.name = templatesheetname then
exit for
end if
next ws
if ws is nothing then
set ws = worksheets.add
ws.name = templatesheetname
end if
ws.usedrange.clearformats
source.usedrange.copy
ws.range("a1").pastespecial xlpasteformats
ws.visible = xlveryhidden
end sub
Sub BringBackFormats
dim ws as worksheet
for each ws in worksheets
if ws.name = templatesheetname then
exit for
end if
next ws
if ws is nothing then
msgbox "No template found",vbokonly,"Unabl;e to run"
else
ws.cells.copy
activesheet.range("a1").pastespecial xlpasteformats
end if
exit sub
(written on my phone, can't check the code, there may be typos)

Why wont VBA Next go to next Worksheet

So I've been looking on here for a while and I'm trying to make code that goes through every sheet in the workbook unless the sheets are named Summary, Archive, or Template. When running the code it seems to skip the code when I start on a sheet with any of these three names but never goes to the next sheet. (It may be important to mention that my code involves going to another workbook to gather data).
Here's what I have:
For Each rs In ActiveWorkbook.Worksheets
If rs.Name <> "Summary" And rs.Name <> "Archive" And rs.Name <> "Template" Then
'my Code to do
End If
Next rs
Any help would be greatly appreciated.
Thanks
You are using Activesheet or no parent worksheet at all in the actual processing code that you omitted from your question. Use rs instead.
For Each rs In ActiveWorkbook.Worksheets
WITH RS '<~~ use rs
select case lcase(.Name)
case "summary", "archive", "template"
'do nothing
case else
rs.Select '<~~ not considered 'best practice'
'my Code to do with stuff .Range("A1") or .Cells(1, "A") on rs
end select
END WITH
Next rs
Notice that when in a With ... End With you precede all the worksheet members with a . that pushes the parent worksheet to the one described in the With ... End With.
When you meet something unexpected like what you describe, I find it is best to get a visual check of what's going on. Try this:-
Sub Ryan_S()
Dim Ws As Worksheet
For Each Ws In ActiveWorkbook.Worksheets
Debug.Print Ws.Name
If Ws.Name <> "Summary" And Ws.Name <> "Archive" And Ws.Name <> "Template" Then
Debug.Print , "Executing my code"
'my Code to do
End If
Next Ws
End Sub
Except for my little revolt against calling a Worksheet "rs" (which would be a row in my book :-)) the code is exactly like yours. However, I added two lines of code which print something to the Immediate window (Ctl+G if it isn't visible by default). The first line just prints the name of each sheet being called, the second prints only on one of the selected sheets.
This test will guide you toward the error. You might find that you are looping through the wrong workbook (as someone did suggest above), or that your code actually runs but doesn't do what you expect. A common error for beginners is to have On Error Resume Next in it which prevents the code from crashing but doesn't force it to do as instructed.

Avoiding .Activate with ActiveX Form Control

I'm updating a macro that's used in lots of spreadsheets, and it's rather slow. While looking to speed it up, I noticed that at one point it goes through this loop:
For each wsLoop in ThisWorkbook.Worksheets
wsLoop.Activate
With ActiveSheet.Status_Text
If bStatus = True Then
.ForeColor = &HC000&
.Caption = "ONLINE"
Else
.ForeColor = &HFF&
.Caption = "OFFLINE"
End If
End With
Next wsLoop
Where wsLoop is a worksheet, bStatus is a boolean and Status_Text is the name of an ActiveX label form control on each worksheet.
I know using .Activate is bad practice and can slow things down, so I dropped the wsLoop.Activate and changed the next line to With wsLoop.Status_Text, but now I get a "Method or data member not found" error message.
What's the proper way to do this?
Interesting question which seems to touch on some poorly-documented features of Excel VBA. It seems that maybe the expression ActiveSheet.Status_Text is operating as the name of the control, with the dot acting as a namespace qualifier, but that in wsLoop.Status_Text VBA is interpreting the dot as the method/property access operator and is correctly giving the error message that no such method or property exists. To reproduce the problem, I created a label named Status_Text on each sheet and then ran
Sub test1()
Dim ws As Worksheet
For Each ws In Worksheets
Debug.Print ws.Status_Text.Caption 'fails
Next ws
End Sub
It crashes with the error that you show. One workaround (although just why it works is mysterious) is to change the loop index from being a Worksheet to a Variant:
Sub test2()
Dim ws As Variant
For Each ws In Worksheets
Debug.Print ws.Status_Text.Caption 'succeeds
Next ws
End Sub
The odd thing about this last example is if you add the line Debug.Print TypeName(ws) in the for-each loop it prints Worksheet so ws.Status_Text works if ws is a variant which holds a worksheet but not if ws is actually a worksheet. The mystery is in some sense deepened but in another sense lessened when you step through this sub in the debugger, looking at the locals window. The type of ws in the loop is described as Variant/Object/Sheet1 (in the first pass through the loop). The specific sheet seems to be part of the current subtype of the variable.
Another workaround is to use a For-Next loop rather than a For-Each:
Sub test3()
Dim i As Long
For i = 1 To Worksheets.Count
Debug.Print Worksheets(i).Status_Text.Caption 'succeeds
Next i
End Sub
You could use either of these approaches to get a reference to the label without having to activate the sheet.

Excel 2013 VBA Clear All Filters macro

It seems older macros are not working. I have proper securtiy set to run VBA macros but when I have tried a few methods for clearing ALL filters on a worksheet, I get a compile error.
Here is what I have tried:
Sub AutoFilter_Remove()
'This macro removes any filtering in order to display all of the data but it does not remove the filter arrows
ActiveSheet.ShowAllData
End Sub
I have buttons on the sheets to clear all filters for ease of use for users since the sheets has a lot of columns that have filters on them.
Try this:
If ActiveSheet.AutoFilterMode Then ActiveSheet.ShowAllData
ShowAllData will throw an error if a filter isn't currently applied. This will work:
Sub ResetFilters()
On Error Resume Next
ActiveSheet.ShowAllData
End Sub
If the sheet already has a filter on it then:
Sub Macro1()
Cells.AutoFilter
End Sub
will remove it.
For tables try this to check if it's on and turn off:
If wrkSheetCodeName.ListObjects("TableName").ShowAutoFilter Then
wrkSheetCodeName.ListObjects("TableName").Range.AutoFilter
End if
To Turn back on:
wrkSheetCodeName.ListObjects("TableName").Range.AutoFilter
this works nice.!
If ActiveSheet.AutoFilterMode Then Cells.AutoFilter
That is brilliant, the only answer I found that met my particular need, thanks SO much for putting it up!
I made just a minor addition to it so that the screen didn't flash and it removes and subsequently reapplies the password on each sheet as it cycles through [I have the same password for all sheets in the workbook]. In the spirit of your submission, I add this to assist anyone else....
Sub ClearFilters()
Application.ScreenUpdating = False
On Error Resume Next
For Each wrksheet In ActiveWorkbook.Worksheets
'Change the password to whatever is required
wrksheet.Unprotect Password:="Albuterol1"
wrksheet.ShowAllData 'This works for filtered data not in a table
For Each lstobj In wrksheet.ListObjects
If lstobj.ShowAutoFilter Then
lstobj.Range.AutoFilter 'Clear filters from a table
lstobj.Range.AutoFilter 'Add the filters back to the table
End If
'Change the password to whatever is required
wrksheet.Protect Password:="Albuterol1", _
DrawingObjects:=True, _
Contents:=True, _
Scenarios:=True, _
AllowFiltering:=True
Next 'Check next worksheet in the workbook
Next
Application.ScreenUpdating = True
End Sub
I know this is a relatively old post and don't really like being a necromancer... But since I had the same issue and tried a few of the options in this thread without success I combined some of the answers to get a working macro..
Hopefully this helps someone out there :)
Sub ResetFilters()
On Error Resume Next
For Each wrksheet In ActiveWorkbook.Worksheets
wrksheet.ShowAllData 'This works for filtered data not in a table
For Each lstobj In wrksheet.ListObjects
If lstobj.ShowAutoFilter Then
lstobj.Range.AutoFilter 'Clear filters from a table
lstobj.Range.AutoFilter 'Add the filters back to the table
End If
Next 'Check next worksheet in the workbook
Next
End Sub
There are two types of filters in Excel:
Auto Filter
Advanced Filter
The Auto Filter feature lets you filter from the excel interface using those tiny dropdown buttons. And the Advanced filter feature lets you filter using a criteria range.
The ShowAll method removes the filters, as in, shows all the rows, but does not get rid of those Drop Down buttons. You have to set the AutoFilterMode property of the worksheet to FALSE to remove those buttons.
Here is a Sub that I use frequently to remove filters:
Sub RemoveFilters(ByRef WhichSheet As Worksheet)
If WhichSheet.FilterMode Then WhichSheet.ShowAllData
If WhichSheet.AutoFilterMode Then WhichSheet.AutoFilterMode = False
End Sub
This shows all the data, and removes the dropdown buttons. It comes in handy while stacking (copying and pasting) data from multiple sheets or workbooks. Hope this helps.
I found this workaround to work pretty effectively. It basically removes autofilter from the table and then re-applies it, thus removing any previous filters. From my experience this is not prone to the error handling required with the other methods mentioned here.
Set myTable = YOUR_SHEET.ListObjects("YourTableName")
myTable.ShowAutoFilter = False
myTable.ShowAutoFilter = True
This will work too:
If ActiveSheet.FilterMode Then cells.AutoFilter
I usually use this code
Sub AutoFilter_Remove()
Sheet1.AutoFilterMode = False 'Change Sheet1 to the relevant sheet
'Alternatively: Worksheets("[Your Sheet Name]").AutoFilterMode = False
End Sub
This will first check if AutoFilterMode is set (filtering is possible), then check if FilterMode is on (you are filtering on something) then turn off filtering.
Regarding Errors, i.e. protection - se other answers
Context added (my script is looping over sheets, which are then saved as CSV, hence the need to remove filters - but keep AutoFilterMode on, if set:
For Each WS In ActiveWorkbook.Worksheets
Select Case WS.Name
Case "01", "02", "03", "04", "05"
With WS
If WS.AutoFilterMode Then
If WS.FilterMode Then WS.ShowAllData
End If
' Processing data
End With
Case Else
' Nothing to see here
End Select
Next
Try something like this:
Sub ClearDataFilters()
'Clears filters on the activesheet. Will not clear filters if the sheet is protected.
On Error GoTo Protection
If ActiveWorkbook.ActiveSheet.FilterMode Or _
ActiveWorkbook.ActiveSheet.AutoFilterMode Then _
ActiveWorkbook.ActiveSheet.ShowAllData
Exit Sub
Protection:
If Err.Number = 1004 And Err.Description = _
"ShowAllData method of Worksheet class failed" Then
MsgBox "Unable to Clear Filters. This could be due to protection on the sheet.", _
vbInformation
End If
End Sub
.FilterMode returns true if the worksheet is in filter mode. (See this for more information.)
See this for more information on .AutoFilter.
And finally, this will provide more information about the .ShowAllData method.
Here's the one-liner I use. It checks for an auto-filter and if found, removes it.
Unlike some answers, this code won't create an auto-filter if used on a worksheet that is not auto-filtered in the first place.
If Cells.AutoFilter Then Cells.AutoFilter
All you need is:
ActiveSheet.AutoFilter.ShowAllData
Why? Like the worksheet, AutoFilter also has a ShowAllData method, but it doesn't throw an error even when auto filter is enabled without an active filter.
This works best for me.
I usually use the following before I save and close the files.
Sub remove_filters
ActiveSheet.AutofilterMode = False
End Sub
Simply activate the filter headers and run showalldata, works 100%. Something like:
Range("A1:Z1").Activate
ActiveSheet.ShowAllData
Range("R1:Y1").Activate
ActiveSheet.ShowAllData
If you have the field headers in A1:Z1 and R1:Y1 respectively.
Im using .filtermode if filter is on it returns true
Dim returnValue As Boolean
returnValue = worksheet1.FilterMode
if returnValue Then
worksheet1.ShowAllData
End If
Try this:
Sub ResetFilters()
Dim ws As Worksheet
Dim wb As Workbook
Dim listObj As ListObject
For Each ws In ActiveWorkbook.Worksheets
For Each listObj In ws.ListObjects
If listObj.ShowHeaders Then
listObj.AutoFilter.ShowAllData
listObj.Sort.SortFields.Clear
End If
Next listObj
Next ws
End Sub
This Code clears all filters and removes sorting.
Source: Removing Filters for Each Table in a Workbook, VBA
Here is some code for fixing filters. For example, if you turn on filters in your sheet, then you add a column, then you want the new column to also be covered by a filter.
Private Sub AddOrFixFilters()
ActiveSheet.UsedRange.Select
' turn off filters if on, which forces a reset in case some columns weren't covered by the filter
If ActiveSheet.AutoFilterMode Then
Selection.AutoFilter
End If
' turn filters back on, auto-calculating the new columns to filter
Selection.AutoFilter
End Sub
This thread is ancient, but I wasn't happy with any of the given answers, and ended up writing my own. I'm sharing it now:
We start with:
Sub ResetWSFilters(ws as worksheet)
If ws.FilterMode Then
ws.ShowAllData
Else
End If
'This gets rid of "normal" filters - but tables will remain filtered
For Each listObj In ws.ListObjects
If listObj.ShowHeaders Then
listObj.AutoFilter.ShowAllData
listObj.Sort.SortFields.Clear
End If
Next listObj
'And this gets rid of table filters
End Sub
We can feed a specific worksheet to this macro which will unfilter just that one worksheet. Useful if you need to make sure just one worksheet is clear. However, I usually want to do the entire workbook
Sub ResetAllWBFilters(wb as workbook)
Dim ws As Worksheet
Dim wb As Workbook
Dim listObj As ListObject
For Each ws In wb.Worksheets
If ws.FilterMode Then
ws.ShowAllData
Else
End If
'This removes "normal" filters in the workbook - however, it doesn't remove table filters
For Each listObj In ws.ListObjects
If listObj.ShowHeaders Then
listObj.AutoFilter.ShowAllData
listObj.Sort.SortFields.Clear
End If
Next listObj
Next
'And this removes table filters. You need both aspects to make it work.
End Sub
You can use this, by, for example, opening a workbook you need to deal with and resetting their filters before doing anything with it:
Sub ExampleOpen()
Set TestingWorkBook = Workbooks.Open("C:\Intel\......") 'The .open is assuming you need to open the workbook in question - different procedure if it's already open
Call ResetAllWBFilters(TestingWorkBook)
End Sub
The one I use the most: Resetting all filters in the workbook that the module is stored in:
Sub ResetFilters()
Dim ws As Worksheet
Dim wb As Workbook
Dim listObj As ListObject
Set wb = ThisWorkbook
'Set wb = ActiveWorkbook
'This is if you place the macro in your personal wb to be able to reset the filters on any wb you're currently working on. Remove the set wb = thisworkbook if that's what you need
For Each ws In wb.Worksheets
If ws.FilterMode Then
ws.ShowAllData
Else
End If
'This removes "normal" filters in the workbook - however, it doesn't remove table filters
For Each listObj In ws.ListObjects
If listObj.ShowHeaders Then
listObj.AutoFilter.ShowAllData
listObj.Sort.SortFields.Clear
End If
Next listObj
Next
'And this removes table filters. You need both aspects to make it work.
End Sub
This will clear only if you have filter and does not cause any error when there arent any filter.
If ActiveSheet.AutoFilterMode Then ActiveSheet.Columns("A").AutoFilter
I am using this approach for a multi table and range sheet as a unique way.
Sub RemoveFilters(Ws As Worksheet)
Dim LO As ListObject
On Error Resume Next
Ws.ShowAllData
For Each LO In Ws.ListObjects
LO.ShowAutoFilter = True
LO.AutoFilter.ShowAllData
Next
Ws.ShowAllData
End Sub
Wow. Logging in afterwards deleted all but a portion of the first line. My mistake. However, this will be terse.
For both tests
Enter text in A1 and A5 of Sheet1
Filter for blanks only.
Run either test
Enter text in A5
Try to filter!
Sub SubsequentFilterFails()
With Sheet1 'assumes code name is still Sheet1
.ShowAllData 'assumes a filter has been applied
.Range(.Cells(2, 1), .Cells(7, 1)).EntireRow.Delete
End With
End Sub
Sub SubsequentFilterWorks()
With Sheet1
.Cells.AutoFilter
.Range(.Cells(2, 1), .Cells(7, 1)).EntireRow.Delete
.Cells.AutoFilter
End With
End Sub
Thus, when filters are being cleared in order to clean the worksheet .Cells.AutoFilter will be used.
Loop AutoFilter columns, if column is activated(on) then reset a column filter, you may insert a new criteria after a loop. This code does not remove AutoFilter banner.
Dim iCol as Long
Dim ws as Worksheet
...
For iCol = 1 To ws.AutoFilter.Filters.count
If ws.AutoFilter.Filters(iCol).On Then ws.AutoFilter.Range.AutoFilter Field:=iCol
Next
...
ws.AutoFilter.Range.AutoFilter Field:=4, Criteria1:="AABBCC"
I found this answer in a Microsoft webpage
It uses the AutoFilterMode as a boolean .
If Worksheets("Sheet1").AutoFilterMode Then Selection.AutoFilter
You must select range of the table first before using ActiveSheet.ShowAllData

Resources