Vba hide pie chart slice - excel

I have some Pie charts created using a macro. I need to change the macro so that it hides certain slices of the pie charts - this is easy enough to do manually by going to 'select chart data' and unticking the points you wish to hide. However I can't figure out which objects and properties that translates to in vba, and I can't go doing this manually every time this report is run.
NB the simpler method of editing the base data that the chart is looking at isn't an option.
Below is a code snippet I've been trying, which I will copy into the main macro once it's working. I think I'm pretty close, narrowing down to the specific point object I want to hide. Any help completing the last step will be much appreciated, as I can't figure what property to change to accomplish this.
Sub HideDataPoints()
'Finding out how to hide a slice from a pie chart
Dim sht As Worksheet, chtobj As ChartObject
Set sht = ActiveSheet
With sht
For Each chtobj In .ChartObjects
If chtobj.Chart.ChartTitle.Caption Like "*Task*" Then
With chtobj.Chart.FullSeriesCollection(1)
For a = 1 To .Points.Count
If .Points(a).HasDataLabel = False Then
ElseIf .Points(a).DataLabel.Caption Like "*Markham*" Then
'Point identified - how do I hide this slice from the chart?
End If
Next
End With
End If
Next
End With
End Sub

Related

How to store PT Update Event for a sheet that gets deleted/recreated on opening?

Yesterday I wrote a VBA code within the Microsoft Object folder and within a sheet to reformat a pivot chart after filtering using Worksheets_PivotTableUpdate event and a private sub. It was working great!
I closed and reopened the file yesterday and it was gone, and the filtering didn't trigger the code despite it working when the VBA was open. I went to look in the sheet and there's no code there. I thought I had forgot to save or saved incorrectly so I wrote it again and this morning when I opened the file again... formatting after filtering code doesn't work, no code to be found. So... where is it? Why isn't it saving?
Multiple people will be using this file so I can't just redo it every time I need to, and plus it doesn't make sense for it to just disappear every time the file is closed/reopened. I know a lot of code for working in VBA and especially with PivotTables/Charts, but I'd still consider myself a beginner.
I am going to rewrite the code so I will post when I finish. This is the code that formats the pivot chart originally. The sheet code readds the data labels, adds some borders, and changes the size of the donut hole.
EDIT: I figured out the issue and it is a silly one. When the workbook macro runs, it deletes the sheet where the other code is stored. Here's my new question... how else can I store this so this doesn't happen?
Dim pc_utl As Chart
Dim chart_rng_2 As Range
Set chart_rng_2 = wsu.Range("B10:F35") 'Where to place Donut Chart on sheet
With chart_rng_2
Set pc_utl = wsu.ChartObjects.Add(Left:=.Left, Top:=.Top, Width:=.Width, Height:=.Height).Chart 'Creates donut chart if it doesn't exist already
End With
Application.ScreenUpdating = True
With pc_utl
.ChartType = xlDoughnut 'Sets chart type to donut
.ApplyDataLabels Type:=xlDataLabelsShowPercent 'Labels donut slices with % data from PTable
.HasTitle = True
.ChartTitle.Text = title_formula_2 'Dynamic chart title
.Legend.Position = xlLegendPositionBottom
.PlotBy = xlColumns
.DoughnutGroups(1).DoughnutHoleSize = 25
End With
Else 'Refresh PivotTable and PivotChart if they exist already
pt_utl.ChangePivotCache pivot_cache_2
pt_utl.RefreshTable
End If
Here's the code stored in the sheet:
Private Sub Worksheet_PivotTableUpdate(ByVal Target As PivotTable)
If Target = "%Utilization" Then
With Worksheets("Utilization")
With .ChartObjects("Chart 1").Chart
.ApplyDataLabels Type:=xlDataLabelsShowPercent
End With
End With
End If
End Sub

Can't find chart object despite having inserted one

I'm just starting to work with charts in VBA. The manual seemed straight forward: All Charts are contained in Workbook.Charts and/or (well, not THAT clear for a beginner, as it turns out) Worksheets(x).ChartObjects. Only, I have now a graph in my workbook that I can not find in either collection.
Where is the object hiding?
I'm running a Little Marco, which should set the Colors of all Graphs according to my definitions. There are two Graphs in the workbook, on different spreadsheets. The second one (the one that is "vanished") is of type waterfall.
?ThisWorkbook.Charts = 0.
?ThisWorkbook.Worksheets("Graph").ChartObjects.Count = 1
?ThisWorkbook.Worksheets("Charts").ChartObjects.Count = 0
Well the first two results are fine, the third should have been a 1 as well.
I doubt any code would be usefull - since I'm may just be looking in the wrong Corners?
What is a safe way, to cycle through all Charts in a workbook? Cycling over each worksheet's Charts in chartobjects doesn'T do the Job.
Why can I not find the Chart in the worksheet? Is this some specialty of waterfall?
I'm sorry if this may seem like a very basic question, I'm just starting into Charts.
Edit: Added the Loop:
Public Sub hrFormatAllCharts()
Debug.Print ("hrFormatAllCharts: Enter")
Dim ws As Worksheet
Dim cht As ChartObject
For Each ws In ThisWorkbook.Worksheets
Debug.Print ("Charts in worksheet " & ws.Name & " : " & ws.ChartObjects.Count & ".")
For Each cht In ws.ChartObjects
Call hrFormatChart(cht.Chart)
Next cht
Next ws
Debug.Print ("hrFormatAllCharts: Exit")
End Sub
Bonus Point Question: Since I can see the Chart, is there a way through the GUI to ask the object "Where do you live?"?
PS: I verified that this issue is related to the Chart type (waterfall). I removed the waterfall and used another - now that other Chart is in the above collection. Deleted that one and put in again a waterfall: Can't find it in ChartObjects...
PPS: I found the following question in stack Overflow and now I wonder if it relates...: Error copying waterfall charts with Excel macro
Hey please find my proposition of looping through charts.
Sub LoopThroughCharts()
Dim charts As ChartObjects
Dim chart As ChartObject
Dim sheetIterator As Integer
Dim loopSheet As Worksheet
For sheetIterator = 1 To ThisWorkbook.Worksheets.Count()
Set loopSheet = ThisWorkbook.Worksheets(sheetIterator)
Debug.Print loopSheet.Name
Set charts = loopSheet.ChartObjects
For Each chart In charts
Debug.Print chart.Name
Next chart
Next sheetIterator
End Sub

Excel VBA: Part of code only runs when stepping through. Does not run if called from other subroutine or when continuing

I am writing a chart formatting Excel add-in for my office.
To handle both embedded charts and chart sheets I wrote two loops in the first subroutine. Each time a chart is activated, a second subroutine is called to handle ActiveChart formatting.
Part of my goal is to apply data labels to line charts, however my code produces blank data labels as in figure 1 even when I have set DataLabel.ShowSeriesName = True. There are two cases where the labels are added correctly described below.
Option Explicit
Sub CESAR_style ()
Dim a as application
Dim wb As Workbook
Dim ws As Worksheet
Dim chtO As ChartObject
Dim cht As Chart
Set twb = ThisWorkbook
Set a = Application
' Turn off events
a.EnableEvents = False
' Loop through all chart sheets
For Each cht In a.Charts
cht.Activate
Call Format
Next
' Loop through all chart objects
For Each ws In ActiveWorkbook.Worksheets
For Each chtO In ws.ChartObjects
chtO.Activate
Call Format
Next
Next
a.EnableEvents = True
End Sub
Private Sub Format()
Dim i As Integer
Dim j As Integer
With ActiveChart
' Count the series in the chart
i = .SeriesCollection.Count
' Code here to add a new series used to make a 'Today' _
reference line dividing history and future
' Add series data labels, excluding the new series added above
' For each data series
For j = 1 To i
With .FullSeriesCollection(j)
' For Line charts
If .ChartType = xlLine Then
' Turn off leader lines for full series
.HasLeaderLines = False
' Add series data label to right of last point in series
With .Points(.Points.Count)
' If a label already exists remove it
If .HasDataLabel = True Then
.HasDataLabel = False
Else
End If
The code works properly to this point, but when .ApplyDataLabels runs, it creates blank data labels as seen in figure 1 [blank data labels]1
' Add a series data label
.ApplyDataLabels ShowSeriesName:=True, _
ShowValue:=False, _
HasLeaderLines:=False
End With
Else
' Code here to handle stacked area charts; working properly
End If
End With
Next
End With
End Sub
I have added a break point at .ApplyDataLabels. If I continue the code with F5 or the play button, it continues to give me blank labels. However, if i step the code with F8 or Step Into, the code executes successfully and I get the labels I want as seen in figure 2.
Correct data labels
A second confusing quality is when I move the .ApplyDataLabels segment to the CESAR_style subroutine, the code runs successfully.
I have tried delaying the code with sleep but without success.
Is there something I'm doing wrong in how I've set up the two subroutines?
Any help or insight is much appreciated. Let me know if additional information is needed to make the problem clearer.
Generally with VBA I find that if something works when you're stepping through it, but not when you're running it, it's a select/focus problem. When you're stepping through the code, you're likely selecting the worksheet the the chart is on so you can see what your code is doing, which is effectively doing a step for your macro. Try activating the worksheet the chart is on before activating the chart. If that doesn't work, try selecting a cell on the worksheet instead.

Is it possible to control charts in powerpoint using combo box?

The below image is an example of what i am trying to do. My chart shows the capacity of Resources over month. I choose the month for which i want to view data from the dropdown list. While this is in excel, im trying to do the same in Powerpoint using the charts and AxtiveX controls. Can anyone please guide me on this?
Chart and combobox example
Using a standard Microsoft Forms 2.0 ComboBox control (I do not use ActiveX controls), this is pretty much what you're looking for.
Insert the ComboBox control on the slide where the chart exists. This assumes that the chart data exists in the default ListBox item on the ChartData.Workbook.Worksheets(1) worksheet (i.e., this is what happens when you insert a chart directly in PPT) if you're copying a chart from Excel, this may need revision, but the general idea is the same:
When the user selects the combobox, (ComboBox1_GotFocus queries the chart's underlying data to populate the list. If your data is structured differently, this will need to be modified.
User can make a selection in the ComboBox.
After making the selection, the ComboBox1_Change event will identify the range of data which contains the selected series, and hides the other series, so that only the selected series is visible
Here's my default chart & data which I can view by right-click/Edit Data:
Displaying the slideshow, entering the ComboBox will display the list of series names:
Then, change the selection, and see only the selected series:
Option Explicit
'This code belongs in a SLIDE module in PowerPoint
Private Sub ComboBox1_Change()
'This procedure hides/unhides chart series, based on combobox value
Dim rng As Object 'Excel.Range object
Dim c As Long
With Me.Shapes("Content Placeholder 5").Chart.ChartData '## MODIFY YOUR SHAPE NAME
.Activate
.Workbook.Parent.WindowState = -4140
For c = 2 To .Workbook.Worksheets(1).ListObjects(1).HeaderRowRange.Columns.Count
Set rng = .Workbook.Worksheets(1).ListObjects(1).HeaderRowRange.Cells(c)
rng.EntireColumn.Hidden = (rng.Value <> ComboBox1.Value)
Next
.Workbook.Close
End With
End Sub
Private Sub ComboBox1_GotFocus()
'This procedure sets the list items in the combobox whenever it gets focus
Dim lst As Variant
Dim xlApp As Object
With Me.Shapes("Content Placeholder 5").Chart.ChartData '## MODIFY YOUR SHAPE NAME
.Activate
.Workbook.Parent.WindowState = -4140
Set xlApp = .Workbook.Parent
.Workbook.Worksheets(1).Columns("B:D").Hidden = False
lst = xlApp.Transpose(xlApp.Transpose(.Workbook.Worksheets(1).Range("B1:D1").Value))
.Workbook.Close
End With
ComboBox1.List = lst
End Sub

Import excel chart with spin button to powerpoint

I have a chart in excel with a spin button that changes a value to change the chart when pressed. I can import them into powerpoint by using insert -> object but this doesn't make the spin button usable.
I'm trying to get it so when showing the presentation I can click the spin button and the chart will correspondingly change, just like it does in excel. Is this possible?
THe spin button is connected to a macro and that's what's causing the chart to change in Excel.
You can copy the code from Excel and place it in a standard module in the Powerpoint file.
You will likely have to make some tweaks -- more or less, depending on how well the original macro was written (e.g., if it is full of ActiveSheet.This and ActiveChart.That then it's going to need a bit more tweaking than if it uses a Chart or ChartObject variable to represent the chart.
Here is an example of interacting with a powerpoint chart:
Sub TEST()
Dim sld As slide
Dim cht As Chart
Dim srs As Series
Set sld = ActivePresentation.Slides(1) 'Modify to be the correct slide #'
'You can hardcode the shape by index if you know it, otherwise'
' this method will apply to the FIRST chart object found on the slide'
For i = 1 To sld.Shapes.count
If sld.Shapes(i).Type = msoChart Then
Set cht = sld.Shapes(i).Chart
Exit For
End If
Next
'use a variable to interact with the Series:'
Set srs = cht.SeriesCollection(1) '<Modify as needed.'
'specify a particular formula for the series:'
'your macro likely changes the chart's source data/formula information'
' so something like this:'
srs.Formula = "=SERIES(Sheet1!$B$1,Sheet1!$A$2:$A$5,Sheet1!$B$2:$B$5,1)"
'Or you can display the series formula:'
MsgBox srs.Formula
'Or you can toggle the series axis group:'
With srs
If Not .AxisGroup = xlSecondary Then
.AxisGroup = xlSecondary
Else
.AxisGroup = xlPrimary
End If
'etc.'
'Basically anything you can do to an Excel chart in VBA, you can do in PPT.'
End With
End Sub
When you copy/paste anything from Excel to PowerPoint, you get an OLE object. What appears in PowerPoint is a Windows metafile picture of whatever you copied from Excel. You'd have to either activate the Excel content (doubleclick it within PPT's normal view or give it the appropriate Action Setting to have it activate during a slideshow). Then the spinner should also work within the instance of Excel that launches.
Or you could create another spinner in PPT and have it run code to modify the chart (using David's example code as a basis).

Resources