I think I am missing something obvious but have been looking at it for so long I think I may be blind to it.
I have a sheet coded to create a pivot table from a downloaded report and apply specific filters to the pivot table - which I am aware will have some instances where there is only 1 item in the filter list so cannot apply and returns an error.
I have managed to add 'On Error GoTo...' a line past the code I know will not be able to process.
However, I also have a second Pivot Table on the same sheet which applies the same filter but in reverse - i.e. the filter will usually have 2 items, so the 2 pivot tables end up showing the breakdown of the contents of each item.
The problem is 'On Error GoTo...' is not working on the second item.
I have the GoTo locations name differently - the first pivot GoTo = 'NoOKL:' and the second = 'NoOKS:'.
Because an error on the first Pivot will mean an error on the second every time I am trying to get around this by adding 'P = 1' to the error handling of the first Pivot and then added the code below for the second:
If P = 1 Then GoTo NoOKS
With ActiveSheet.PivotTables("PivotTable11").PivotFields("CATEGORY")
.PivotItems("OKL_CONTRACTS").Visible = False
End With
ActiveSheet.PivotTables("PivotTable11").PivotFields("CATEGORY"). _
EnableMultiplePageItems = True
NoOKS:
End If
I have tried moving the GoTo location 'NoOKS' both inside the If statement and outside but get the same result.
Any help would be appreciated.
Here's an example of what your code might look like if you omit all GoTo's.
If P = 1 Then
With ActiveSheet.PivotTables("PivotTable12").PivotFields("CATEGORY")
.PivotItems("OKL_CONTRACTS").Visible = False
.EnableMultiplePageItems = False
End With
Else
With ActiveSheet.PivotTables("PivotTable11").PivotFields("CATEGORY")
.PivotItems("OKL_CONTRACTS").Visible = False
.EnableMultiplePageItems = True
End With
End If
This code presumes that you have 2 pivot tables of which you want to hide one subject to the number of items it will display (presumed to be P) and set the EnableMultiplePageItems property differently. This doesn't make much sense in the above example but the objective is to show the use of If and Else instead of GoTo.
I point out that EnableMultiplePageItems = (P = 1) would also set the property to either True or False depending upon the evaluation of the statement (P = 1). In the above example the property belongs to different objects but if you have to set the same property for the same object to different values in your project depending upon the value of P that method will avoid even the use of If, not to mention GoTo and reduce the amount of code as well.
Related
Good morning,
I am trying to create a macro that will filter data based on the month, quarter, or year-to-date. I have a column in my spreadsheet called "MONYR" which includes the month and year that data point was taken from. The problem that I am having is that I might not always have data for each month. For example, the code below keeps triggering a "Run-time error '1004': Unable to get the PivotItems property of the PivotField class" because there is no "Jan-2019" option in the MONYR field as I am missing that data. Is there a way to make the macro check if the "Jan-2019" option exists, and if it doesn't, to move on to the next line without throwing an error?
With ActiveSheet.PivotTables("PivotTable1").PivotFields("MONYR")
.PivotItems("Jan-2019").Visible = True
.PivotItems("Feb-2019").Visible = True
.PivotItems("Mar-2019").Visible = True
.PivotItems("Apr-2019").Visible = False
.PivotItems("May-2019").Visible = False
.PivotItems("Jun-2019").Visible = False
.PivotItems("Jul-2019").Visible = False
.PivotItems("Aug-2019").Visible = False
.PivotItems("Sep-2019").Visible = False
.PivotItems("Oct-2019").Visible = False
.PivotItems("Nov-2019").Visible = False
.PivotItems("Dec-2019").Visible = False
End With
Thanks in advance!
One of the rare cases where it is useful to use On Error Resume Next - but don't forget to put the statement On Error Goto 0.
On Error Resume Next tells VBA to continue code execution even if an error occurs. This is bad in most circumstances as it hides errors (and therefore problems with your code). But if you know exactly that a specific line can cause an error and it is okay to continue, this statement can help you out. But once these statements are done, you should change it back to the default behavior.
On Error Resume Next ' Skip to next line if pivot entry doesn't exist.
.PivotItems("Jan-2019").Visible = True
.PivotItems("Feb-2019").Visible = True
.PivotItems("Mar-2019").Visible = True
(...)
On Error Goto 0
I have a VBA macro in Access 2016 (actually, written for earlier version, but right now I'm working with 2016). What it does is adjusting several Excel spreadsheets, and moving them to another location, while also writing some logs into SQL table.
One of adjustments is unmerging some merged cells. The weird part is, those excel files fail to process at times (not always), when this Access DB is triggered programmatically (from another macro in another Access DB). When I launch it manually, or go into debug step-by-step, it always works - so I am confused, and can't find the reason.
I tried to replace "MergeCells = False" for "Unmerge" - it's the same. I also tried to make new ACCDE file - no result.
This is part of the code, where the unmerging occurs.
xlsh.Select
xlsh.Range("A1:D1").Select
xlsh.Outline.ShowLevels RowLevels:=2
With Selection
.UnMerge
End With
xlsh.Range("A1").Value = "Alfa"
xlsh.Range("B1").Value = "Bravo"
xlsh.Range("C1").Value = "Golf"
xlsh.Range("D1").Value = "Tango"
xlsh.Range("A1").Select
If xlsh.Range("A1").Value = "" Then GoTo error
When it fails to unmerge the cell, the value won't get assigned, and at the end it's empty, thus, continues to label 'error'.
Try this one:
xlsh.("A1:D1").Unmerge
Instead of
xlsh.Select
xlsh.Range("A1:D1").Select
xlsh.Outline.ShowLevels RowLevels:=2
With Selection
.UnMerge
End With
The last 2 lines are unnecesary as:
If xlsh.Range("A1").Value = "" Then GoTo error
Will not be true as you are assigning a value a few lines before. (xlsh.Range("A1").Value = "Alfa")
it's me again - I'll get to know this language better eventually.
Basically - I have a big table of data that has autofilter on - range "$B$5:$Z$1697"
However, there is an additional filter on the R column that I want to be toggled on or off.
Therefore I need an If statement that says when the additional filter is on, remove, whereas, if the filter is not on at the time you press the button - apply it.
I've played around with this and watched more videos that I care to admit. However, there must be something I'm overlooking or don't understand.
The code works up until the Else line, which returns:
"Compile Error, Syntax Error".
Can anyone explain what's happening?
If Sheets(4).Range("$B$5:$Z$1697").AutoFilter(Field:=17, Criteria1:="=") = True Then
'If there specific filter on column R is on then
Sheets(4).Range("$B$5:$Z$1697").AutoFilter Field:=17
'Turn off that filter.
Else: Sheets(4).Range("$B$5:$Z$1697").AutoFilter(Field:=17, Criteria1:="=")
'Else, if the filter is off, turn it on.
End If
End Sub
EDIT: I have corrected the code, amending this ELSE line to this
Else: Sheets(4).Range("$B$5:$Z$1697").AutoFilter(Field:=17, Criteria1:="=") = True
However, when I run this now it means that it turns the filter On and then Off again with one push of the button. How do I make it so it onl makes on change at a time.
I.e. if the filter is on when the button is pressed it ONLY turns it off.
And vice versa
The easiest way to toggle a filter on/off is to use an ActiveX Toggle button. When the toggle button is clicked (enabled) your filter will be applied, when clicked again (disabled) your filter is removed. Change the name of the toggle button and Criteria1 to meets your needs.
Private Sub ToggleButton1_Click()
'when selected(enabled) the filter for Col "Q" will be enabled
If ToggleButton1.Value = True Then
Sheets(4).Range("$B$5:$Z$1697").AutoFilter Field:=17, Criteria1:="2"
Else
'when selected again(disabled) the filter for Col "Q" will be Disabled
Sheets(4).Range("$B$5:$Z$1697").AutoFilter Field:=17
End If
End Sub
This is NOT a complete answer, but I can't fit all this into a comment...
I've found that continually using compound references to refer to different objects within Excel can really give me headaches. Using intermediate objects doesn't impose any significant performance penalty at all, so I am in the habit of breaking down the compound reference into a series of intermediate objects. Doing this gives me at least two advantages: 1) I can examine the intermediate objects to make sure of the data I think should be there, and 2) I get far fewer syntax errors because each step gets validated.
So, while I can't check if this is correct since I can't access your data, your logic could look like this
Sub Example()
Dim fourthWS As Worksheet
Dim filteredData As Range
Set fourthWS = ThisWorkbook.Sheets(4)
Set filteredData = fourthWS.Range("$B$5:$Z$1697")
Dim dataIsFiltered As Variant
dataIsFiltered = filteredData.AutoFilter(Field:=17, Criteria1:="=")
If dataIsFiltered Then
'--- turn off the filter
filteredData.AutoFilter Field:=17
Else
'--- turn on the filter
filteredData.AutoFilter Field:=17, Criteria1:="="
End If
End Sub
I am trying to hide and unhide series in a chart based on their name using excel vba and I have a error 1004 invalid parameter after the first run of the for cycle.
Sub macroChart3()
'
' macroChart3 Macro test
'
Dim i, n As Integer
For i = 1 To 96 Step 1
If ActiveChart.SeriesCollection(i).Name = "*contracted*" Then
ActiveChart.SeriesCollection(i).IsFiltered = False
Else
ActiveChart.SeriesCollection(i).IsFiltered = True
End If
Next i
End Sub
SeriesCollection.IsFiltered method seemed to toggle this check box:
I couldn't use that. I wanted to record macro and see if any other method is used but the checkbox is gone in 2010:
So it might be not possible to use that anymore. If you are using a different version where this method exists you might have a problem that the series is not listed in in seriesCollection anymore:
Remarks from MSDN
When a user filters out a series, the series IsFiltered property switches to True, and the series is transferred out of its parent SeriesCollection.
See if you can use FullSeriesCollection instead when you change the visibility of series:
ActiveChart.FullSeriesCollection(2).IsFiltered = True
If that doesn't work you might add and remove ranges instead of hiding them.
UPDATE:
Run your macro in step mode (F8) so you have full visibility of the execution steps. Add your evaluated expressions (ones that are used within IFs) to see their result and you will find out if they are incorrect or are evaluated as FALSE and try to figure out why.
And don't forget to up vote the answer if you find it helpful.
thanks for the quick reply, the error is fixed, but still not all the series are processed by the if clauses in the for cycle, for example this statement:
Else
ActiveChart.SeriesCollection(i).IsFiltered = True
End If
Isn't executed and I don't understand why.
I have scoured the web and this site looking for an answer on this, so I would really appreciate some help.
I'm creating a VBScript to do some modifications to a user-specified Excel spreadsheet. I have the first part of my script working fine, but the second part is driving me nuts. I need it to search the first column for a value and, if found, delete the row. Right now I'm not worrying about the deletion statement--I'm doing testing by seeing if I can get the For Each statement to run properly as well as the If Then statement. Here's the specific block of code:
For Each cell in objSheet.Columns("A:A").Cells
Set cell = objSheet.Columns("A:A").Cells
If cell.Value = "60802400040000" then
cell.font.bold = True
End If
Next
I have tried many variations of this and cannot find the right combination. Initially I was getting an "Object Required" messages, and after reading a number of posts, found that I needed to put in a Set statement for cell, which I did. Now I am getting a Mismatch Type error message.
The funny thing is, before I put in the Set statement, the code would execute, but it would throw the Object Required error when I closed the spreadsheet. After adding it, the error for the Type Mismatch pops up immediately.
Most examples I keep finding on the web are for VBA, and I try to modify them for VBS, which I don't know very well. Any assistance anyone can give me will be greatly appreciated.
You are redefining cell, cell is defined automatically in the For Each statement.
Delete this line
Set cell = objSheet.Columns("A:A").Cells
This is an example from Help, unfortunately Help doesn't have any examples that uses For Each, only For x = n to n and other means. For Each is the right thing to do.
Set r = Range("myRange")
For n = 1 To r.Rows.Count
If r.Cells(n, 1) = r.Cells(n + 1, 1) Then
MsgBox "Duplicate data in " & r.Cells(n + 1, 1).Address
End If
Next n
For vba to vbs, you have to create the object and use, as some objects are automatically available in VBA (like app object) - Set exceldoc = CreateObject("c:\blah\blah.xls) then to use Set r = exceldoc.worksheets(0).range("MyRange").
Also you have to use constant values not names as vbscript can't look them up.