How do I control my charts using check boxes? - vba

Fore-warning, I am teaching myself VBA as I work on this project, so I apologize if my coding is cringe-inducing and makes no sense. I am currently working on an excel chart that graphs four different series of 15 different categories. I would like to be able to make each series hidden on the chart whenever I click the assigned checkbox. Right now I have the four checkboxes next to the graph, one for each series, "2015", "2016", "2017", and "2018". I right-clicked on the first checkbox, "2015", and selected Assign Macro. The macro-name was filled in for my, so I selected edit, and the coding module popped up. So far my code looks like this:
Sub CheckBox25_Click()
If Cell("Q30").Value = "False" Then
Chart.Series("2015").Hidden = True
Else:
Chart.Series("2015").Hidden = False
End If
End Sub
"Q30" is the cell I have linked to the checkbox to display the true/false value.
I am aware that "Chart.Series("2015").xxx is not the proper way to call on the sereis.
If someone could please tell me how to properly call on the series so I can hide it from the chart that would be greatly appreciated. I'm also not sure that ".hidden" is the correct identifier to use, if you could point me in the right direction for that too that would be great.
Currently I get the "sub or function not defined error" but I believe that is because of my incorrect coding.

Instead of turning visibility, the code below simply filters the Chart series, remember to amend the Sheet name and the Chart name too, then do the same for other Series:
Sub CheckBox25_Click()
Dim ws As Worksheet: Set ws = Sheets("Sheet1")
'declare and set your worksheet, amend as required
If ws.Cell("Q30").Value = "False" Then
ws.ChartObjects("Chart 1").Chart.FullSeriesCollection("2015").IsFiltered = True
Else
ws.ChartObjects("Chart 1").Chart.FullSeriesCollection("2015").IsFiltered = False
End If
End Sub

Related

Sub that displays a line chart for a 2 entries table when a button is clicked

I am currently trying to create a sub (Excel VBA) that generates a form that displays a line chart for months and letters I want to freely select in a 2 entries table.
I want my sub to start when I click on a button that I already created (called Display Chart or Button1_Click).
Here is the code I came out with :
Sub Button1_Click()
GenerateChart.Show
End Sub
Sub GenerateChart()
On Error Resume Next
Dim MyChart As Chart
Dim DataRange As Range
If ActiveSheet.Name = "Sheet3" And Selection.Cells.Count > 0 Then
Set DataRange = Selection
Set MyChart = ActiveSheet.Shapes.AddChart.Chart
MyChart.SetSourceData Source:=DataRange
MyChart.ChartType = xlBarStacked
End If
End Sub
For some reason, this does not seem to work. I think I did something wrong regarding the button click part. Indeed, I do not understand how this event is called (Display Chart or Button1_Click) and how to code it. Therefore I cannot check if my other lines of codes are correct.
I hope someone will be able to help me out, thanks a lot !
Assign a Macro GenerateChart with the button and Select the data for which you need to create a Chart and click the button, I think you are not selected the data while you clicking the button here you used
Set DataRange = Selection

It is possible to trap AutoFilter as an Event?

I am trying to show the filter columns to users in the report. Excel gives a different icon but for large no. columns it will be good to color the columns in another color like blue.
I found code at Is there a way to see which filters are active in Excel, other than just the funnel icons?
It works for me, but how do start this code without any button
SheetChange and selection change do not work.
code
Sub test()
Call markFilter(ActiveSheet)
End Sub
Sub markFilter(wks As Worksheet)
Dim lFilCol As Long
With wks
If .AutoFilterMode Then
For lFilCol = 1 To .AutoFilter.Filters.Count
'/ If filter is applied then mark the header as bold and font color as red
If .AutoFilter.Filters(lFilCol).On Then
.AutoFilter.Range.Columns(lFilCol).Cells(1, 1).Font.Color = vbRed
.AutoFilter.Range.Columns(lFilCol).Cells(1, 1).Font.Bold = True
Else
'/ No Filter. Column header font normal and black.
.AutoFilter.Range.Columns(lFilCol).Cells(1, 1).Font.Color = vbBlack
.AutoFilter.Range.Columns(lFilCol).Cells(1, 1).Font.Bold = False
End If
Next
Else
'/ No Filter at all. Column header font normal and black.
.UsedRange.Rows(1).Font.Color = vbBlack
.UsedRange.Rows(1).Font.Bold = False
End If
End With
End Sub
I will use the same example I used in the answer that you mentioned in your post. I answered that. :)
There is no filter change event in excel. One work-around that I would use is trapping the calculate method of the worksheet or better the workbook.
So, in the worksheet with filter add a dummy formula like this: =SUBTOTAL(3,Sheet2!$A$1:$A$100) this counts only visible cells. But its up to you. Feel free to use any formula that responds to filter change.
After that, go to workbook's code and add this :
Private Sub Workbook_SheetCalculate(ByVal Sh As Object)
Call markFilter(Sh)
MsgBox "Filter changed"
End Sub
Boom. Now you are trapping the filter change events and it will update the filtered columns by firing the vba code.
Note markFilter is coming from the answer that you mentioned.
The key points from my article Trapping a change to a filtered list with VBA
A "dummy" WorkSheet is added with a single SUBTOTAL formula in A1 pointing back to the range being filtered on the main sheet.
A Worksheet_Calculate() Event is added to the "dummy" WorkSheet, this Event fires when the SUBTOTAL formula updates when the filter is changed.
The next two steps are only needed if it is desired to run the Workbook Calculation as Manual
Add a Workbook_Open Event to set the EnableCalculation property of all sheets other than "Dummy" to False.
Run the Workbook in Calculation mode

Turning the visibility of chart series on/off using excel Macros/vba

I am making a line graph (chart) in Excel with several data series being plotted onto the same chart.
I need to create a macro/VBA solution that can turn the visibilty of these series on/off via the pressing of a button (or tick box etc)
Similar to this picture (manually done through the excel menu system)
I have tried to look through all the member vars/methods on
https://msdn.microsoft.com/EN-US/library/office/ff837379.aspx
but haven't had much luck.
I have tried playing around with bits like
Charts("Chart1").SeriesCollection(1)
and
Worksheets("Graphical Data").ChartObjects(1)
but I can neither get the chart object ( I get a subscript out of range error) nor able to find any method that would allow me to turn on/off the visibility of individual series.
Any Ideas?
Whenever I don't know how to do something like this, I turn on the macro recorder.
I had a chart with four series, and I used the filter function in Excel 2013 to hide and show the second series, while the macro recorder was running.
Here's the relevant code:
ActiveChart.FullSeriesCollection(2).IsFiltered = True
' series 2 is now hidden
ActiveChart.FullSeriesCollection(2).IsFiltered = False
' series 2 is now visible
The series type (line or column) does not matter, this works for any of them.
I believe the property you are looking for is the SeriesCollection.Format.Line.Visible property. I quickly created an Excel workbook and added a simple data set (just 1-10) and added a line graph "Chart 2" to the sheet Sheet1.
This code turned the visibility of the line off:
Option Explicit
Private Sub Test()
Dim cht As Chart
Dim ser As Series
'Retrieve our chart and seriescollection objects'
Set cht = Worksheets("Sheet1").ChartObjects("Chart 2").Chart
Set ser = cht.SeriesCollection(1)
'Set the first series line to be hidden'
With ser.Format.Line
.Visible = msoFalse
End With
End Sub
And likewise, setting the ser.Format.Line.Visible property to msoTrue made the line visible again.
As for retrieving the chart itself I had to first activate it, then set my cht variable to the ActiveChart. To view the name of your chart, select it and look in the name box (near where you would enter the cell value / formula).
Update
When using the method above, the series name remains in the legend box. I couldn't find a visibility property for the SeriesCollection in the legend, however one workaround is to simply re-name the series as an empty string (this will make the series disappear from the legend) and then rename the series when you want to show it.
This code below will toggle the visibility of the line and series name in the legend.
Option Explicit
Private Sub Test()
Dim cht As Chart
Dim ser As Series
'Retrieve our chart and seriescollection objects'
Set cht = Worksheets("Sheet1").ChartObjects("Chart 1").Chart
Set ser = cht.SeriesCollection(1)
'Set the first series line to be hidden'
With ser.Format.Line
If .Visible = msoTrue Then
.Visible = msoFalse
ser.Name = vbNullString
Else
.Visible = msoTrue
ser.Name = "Series 1"
End If
End With
End Sub
And, whenever you use .Format.Line.Visible = msoTrue just remember to set ser.Name back to whatever the name for your series is.
There is a simple way to on & off the visibility of the series: using filter on your source data.
May it help you easily as follows.
You can insert a new Window. Setone of them to source data sheet and the other window to Chart sheet. Then arrange the two windows to see both at the same time. Now if you filter the series you like on the source data sheet simultaneously you will see the series you desired on the other sheet.

Use VLOOKUP to pass cell reference to a public variable?

I have a userform that opens on cell change in a column.
That userform contains checkboxes, which all trigger a second userform with a text box which looks up a cell on a hidden sheet for its contents. (The checkbox that's ticked determines which cell the textbox looks for). The user then edits the box, clicks a button, and the new text is written back to the same cell.
This is the VBA for when the checkbox is ticked. It works great. Hooray!
Dim vln As Variant
Dim reta As Worksheet
Set reta = ActiveWorkbook.Sheets("RetailerActivity")
Set vln = ActiveCell.Offset(-1, -3)
UserForm2.TextBox1.Text = Application.WorksheetFunction.VLookup(vln, reta.Range("A1:Z100"), 3, False)
UserForm2.TescoSave.Visible = True
UserForm2.Show
End Sub
When the textbox has been edited, I would like to write it back to the same cell it came from. I figure the easiest way to do that is to have a public variable (as range), and to pass the result of the vlookup into that variable so the second userform can have a line which reads
Private Sub ASave_Click()
publicvariable.Value = TextBox1.Value
userform1.hide
End Sub
Nice and easy, rather than doing a VLookup again. Right?
Either way, I can't seem to set the public variable as the lookup.
Outside of any sub I have
Public bums As Range
And in the code above, after the bit where I've set the text box, I've tried to add the line
Set bums = Application.WorksheetFunction.VLookup(vln, reta.Range("A1:Z100"), 3, False)
But the code errors with a "type mismatch".
If I try
Set bums = Range(Application.WorksheetFunction.VLookup(vln, reta.Range("A1:Z100"), 3, False))
I get method "Range" of object "_global" failed.
I code by cobbling bits off the internet, as you can probably tell, so this is I don't doubt a complete kludge.
Any advice would be super appreciated.
VLookup returns a value, not a Range. You could use Match to find the row and then Cells to get the actual reference - for example:
Dim vMatch
vMatch = Application.Match(vln, reta.Range("A1:A100"),0)
If Not IsError(vMatch) then
Set bums = reta.Cells(vMatch, "C")
else
msgbox "No match for " & vln
Exit Sub
End If
Personally I would also not use a public variable, but create a property for Userform2 to which you can assign the range.

How to refer to shapes in a module

I have created different shapes in excel and have assigned a macro to it which functions as activating another sheet. I want to put all these under one macro and then assign it to different shapes with different linking property. But this code doesn't work because obviously I am doing something stupid. Can someone please help?
Dim shp As ShapeRange, ws As Sheets, i As Integer
Set ws = ActiveWorkbook.Sheets(Array("Introduction", "S1 Fuel Consumption", "S1 Fugitive", "S2 Electricity Consumption"))
Set shp = ws(2).Shapes.Range(Array("Chevron1", "Chevron2"))
Select Case shp(i)
Case shp(1)
ws(1).Activate
Case shp(2)
ws(3).Activate
End Select
End Sub
There is a much easier way to do "buttons" in VBA (I assume this is what your trying to achieve)
First off, in a module, create the "Open Worksheet" code:
Sub Open_Sheet2
Sheets("Sheet2").visible = True
Sheets("Sheet2").Activate
End Sub
Then right click your shape, choose Assign Macro and assign Open_Sheet2 to that shape. Now when it is clicked, it will open Sheet2