Update colours of pie chart segments to the cell fill colours - excel

I'm trying to colour my pie chart segments, according to the cells the data is drawn from, using Excel 2016.
I pinched code from a YouTube video but this is hard to read in places (1, l & i are particularly hard to differentiate) so I'm not convinced I have it right.
Private Sub SheetActivate(ByVal Sh As Object)
Dim cht As ChartObject
Dim i As Integer
Dim vntValues As Variant
Dim s As String
Dim mySeries As Series
For Each cht In ActiveSheet.ChartObjects
For Each mySeries In cht.Chart.SeriesCollection
If mySeries.ChartType <> xlPie Then GoTo SkipNotPie
s = Split(mySeries.Formula, ",")(2)
vntValues = mySeries.Values
For i = 1 To UBound(vntValues)
mySeries.Points(i).Interior.Color = Range(s).Cells(i).Interior.Color
Next l
SkipNotPie:
Next mySeries
Next cht
End Sub
Update: here is a snip showing the charts - I'm trying to update the chart segments to represent the cell fill colours in the second column.

With minor adjustments, this worked fine:
Private Sub SheetActivate()
Dim cht As ChartObject
Dim i As Long
Dim vntValues As Variant
Dim s As String
Dim mySeries As Series
For Each cht In ActiveSheet.ChartObjects
For Each mySeries In cht.Chart.SeriesCollection
If mySeries.ChartType <> xlPie Then GoTo SkipNotPie
s = Split(mySeries.Formula, ",")(2)
vntValues = mySeries.Values
For i = 1 To UBound(vntValues)
mySeries.Points(i).Interior.Color = Range(s).Cells(i).Interior.Color
Next i
SkipNotPie:
Next mySeries
Next cht
End Sub
Make sure you don't have Option Base 1 at the top of the module. If you do, then change
s = Split(mySeries.Formula, ",")(2)
to
s = Split(mySeries.Formula, ",")(3)
I haven't used Option Base 1 since I learned to count starting at zero.

Related

Change color of a chart series as the same as another series but with different line style

I am trying to make a code for changing colour of one series to match another series but with different linestyle (eg. dashed). Please see the code that I have made. I get error messages.
Thank you
Sub lineeditor()
Dim j As Integer
Dim wsheet As Worksheet
Dim cht As ChartObject
Dim serie As Series
For Each wsheet In ThisWorkbook.Worksheets
'Looping through chart in every chartobjects
For Each cht In wsheet.ChartObjects
cht.Activate
cht.Select
'Looping through second set of 9 series. totally 18 series are in the chart
For j = 1 To 9
cht.Chart.SeriesCollection(j + 9).Select
With Selection.Format.Line
.ForeColor = cht.Chart.SeriesCollection(j).Format.Line.ForeColor
.DashStyle = msoLineDashDot
End With
Next
Next
Next
End Sub
You cannot select a worksheet object that is not on the ActiveSheet. You should, however, only select or activate objects when absolutely necessary. Watch: Excel VBA Introduction Part 5 - Selecting Cells (Range, Cells, Activecell, End, Offset).
Sub lineeditor()
Dim j As Integer
Dim wsheet As Worksheet
Dim cht As ChartObject
Dim serie As Series
For Each wsheet In ThisWorkbook.Worksheets
For Each cht In wsheet.ChartObjects
For j = 1 To 9
With cht.Chart.SeriesCollection(j + 9).Format.Line
.ForeColor = cht.Chart.SeriesCollection(j).Format.Line.ForeColor
.DashStyle = msoLineDashDot
End With
Next
Next
Next
End Sub

how do i offset all the charts in the same worksheet in VBA?

Currently, all my charts are cramped together in the same spot in the same worksheet after running my code. So to view them i have to manually drag and move them to another spot. So is there a way such that i can place all the charts in a orderly manner as shown in expected output? If it is really impossible to do something like this, i am ok with offsetting the graph for every 20 cells even though it is abit inconvenient for viewing but still i attempted to do it but fail to make it happen when i include code with current output with the offsetting code.
Current output(looks like there is 1 chart but all the charts are in the same spot)
Below is the code for my current output
Sub plotgraphs()
'Call meangraph
Call sigmagraph
End Sub
Private Sub sigmagraph()
Dim i As Long, c As Long
Dim shp As Shape
Dim Cht As chart, co As Shape
Dim rngDB As Range, rngX As Range, rngY As Range
Dim Srs As Series
Dim ws As Worksheet
Set ws = Sheets("Data")
Set rngDB = ws.Range("A1").CurrentRegion
Set rngX = rngDB.Columns(1)
Set rngY = rngDB.Columns(4)
Do While Application.CountA(rngY) > 0
Set co = Worksheets("meangraphs").Shapes.AddChart
Set Cht = co.chart
With Cht
.ChartType = xlXYScatter
'remove any data which might have been
' picked up when adding the chart
Do While .SeriesCollection.Count > 0
.SeriesCollection(1).Delete
Loop
'add the data
With .SeriesCollection.NewSeries()
.XValues = rngX.Value
.Values = rngY.Value
End With
'formatting...
With Cht.Axes(xlValue)
.MinimumScale = 0
.MaximumScale = 0.5
.TickLabels.NumberFormat = "0.00E+00"
End With
Cht.Axes(xlCategory, xlPrimary).HasTitle = True
Cht.Axes(xlValue, xlPrimary).HasTitle = True
End With
Set rngY = rngY.Offset(0, 2) 'next y values
Loop
Code for offsetting chart for every 20 cells (fail to make it happen)
Dim OutSht As Worksheet
'
Dim PlaceInRange As Range
Set OutSht = ActiveWorkbook.Sheets("sigmagraphs") '<~~ Output sheet
Set PlaceInRange = OutSht.Range("B2:J21") '<~~ Output location
'
' To place charts at a distance between them
For Each chart In Sheets("sigmagraphs").ChartObjects
' OutSht.Paste PlaceInRange
' Code below changes the range itself to something 20 rows below
Set PlaceInRange = PlaceInRange.Offset(20, 0)
Next chart
Expected output
What you are looking for is the .Left and .Top properties of the Shape containing the Chart.
For example, a macro that would setup your charts into a 2-column grid would look like this:
Sub SetupChartsIntoGrid()
Const TopAnchor As Long = 50
Const LeftAnchor As Long = 50
Const HorizontalSpacing As Long = 10
Const VerticalSpacing As Long = 10
Const ChartHeight As Long = 211
Const ChartWidth As Long = 360
Dim shp As Shape
For Each shp In ActiveSheet.Shapes
If shp.Type = msoChart Then
Dim Counter As Long
Counter = Counter + 1
With shp
.Top = TopAnchor + (WorksheetFunction.RoundUp(Counter / 2, 0) - 1) * (VerticalSpacing + ChartHeight)
.Left = LeftAnchor + ((Counter + 1) Mod 2) * (HorizontalSpacing + ChartWidth)
End With
End If
Next
End Sub

Excel VBA code to set x-axis to minimum and maximum value in plotted range

I have a VBA code (below) that sets the min and max x-axis values to a specified cell (B4 and B15). However, I have many plots in my workbook, and all need a different min and max x-axis range. I want a VBA code that goes to the plotted x-axis range and then finds the min and max value in that range and sets the axis to those values. How can I alter the code below to do that?
Sub Resize_Fonts()
Dim Sht As Worksheet
Dim Cht As ChartObject
For Each Sht In ActiveWorkbook.Sheets
For Each Cht In Sht.ChartObjects
Cht.Chart.ChartArea.Font.Size = 9
Cht.Chart.ChartArea.Font.Name = "Cambria"
Cht.Chart.ChartArea.Border.LineStyle = xlNone
Cht.Chart.Axes(xlValue).MinimumScale = 0
Cht.Chart.Axes(xlCategory).MinimumScale = Range("B4").Value
Cht.Chart.Axes(xlCategory).MaximumScale = Range("B15").Value
Next Cht
Next Sht
End Sub
If the min and max are always within the range B14:B15 on Sht you can use:
Cht.Chart.Axes(xlCategory).MinimumScale = worksheetfunction.Min(Sht.Range("B4:B15"))
Cht.Chart.Axes(xlCategory).MaximumScale = worksheetfunction.Max(Sht.Range("B4:B15"))
Try using the WorksheetFunction.Min for this.
Cht.Chart.Axes(xlCategory).MinimumScale = WorksheetFunction.Min(Columns(2))
Cht.Chart.Axes(xlCategory).MaximumScale = WorksheetFunction.Max(Columns(2))
This assumes the x-axis values are in column 2.
You could add a dim count as long and put your min / max values in adjacent columns. Then increment your count in your For each loop and use Cells([row], [n+] count).value to get the cell value.
By the way, You can use:
With cht.Chart
[...]
End with
Try to use the With Cht.Chart statement, it will shorten and clear your coding style.
When looking for the Min and Max values in Column B, you need to make sure you fully qualify the Range, by adding Sht.Range.
Code
Sub Resize_Fonts()
Dim Sht As Worksheet
Dim Cht As ChartObject
For Each Sht In ActiveWorkbook.Sheets
For Each Cht In Sht.ChartObjects
With Cht.Chart
.ChartArea.Font.SIZE = 9
.ChartArea.Font.Name = "Cambria"
.cartArea.Border.LineStyle = xlNone
.Axes(xlValue).MinimumScale = 0
.Axes(xlCategory).MinimumScale = WorksheetFunction.Min(Sht.Range("B1:B" & Sht.Cells(Sht.Rows.Count, "B").End(xlUp).Row))
.Axes(xlCategory).MaximumScale = WorksheetFunction.Max(Sht.Range("B1:B" & Sht.Cells(Sht.Rows.Count, "B").End(xlUp).Row))
End With
Next Cht
Next Sht
End Sub
After reading your comments, as I first said with my other unregistered account, you can use this method:
Sub Resize_Fonts()
Dim Sht As Worksheet
Dim Cht As ChartObject
Dim count as Long
count = 2 ' For column B
For Each Sht In ActiveWorkbook.Sheets
For Each Cht In Sht.ChartObjects
With Cht.Chart
.ChartArea.Font.Size = 9
.ChartArea.Font.Name = "Cambria"
.ChartArea.Border.LineStyle = xlNone
.Axes(xlValue).MinimumScale = 0
.Axes(xlCategory).MinimumScale = Sht.Cells(4, count).Value
.Axes(xlCategory).MaximumScale = Sht.Cells(15, count).Value
End with
count = count + n ' with n your "pattern"
Next Cht
count = 2 ' reset the count when changing sheet
Next Sht
End Sub
This assume values are always row 4 and row 15.
Comment if you have any other queries

Resize width of all data labels in every chart in the worksheet

I'm trying to get the code to resize width in all data labels from the charts of a worksheet but I cannot manage to do it. Here I have the code to apply a number format and I'd want to add the width property to that (it's just valid for Excel 2013):
Sub FormatAllCharts()
Dim ChtObj As ChartObject
For Each ChtObj In ActiveSheet.ChartObjects
With ChtObj.Chart
For i = 1 To .SeriesCollection.Count
With .SeriesCollection(i)
.ApplyDataLabels
.DataLabels.NumberFormat = "0,0;-0,0;;"
End With
Next
End With
Next
End Sub
This is the code for changing the width size of data labels:
ActiveChart.FullSeriesCollection(1).DataLabels.Select
ActiveChart.FullSeriesCollection(1).Points(4).DataLabel.Select
Selection.Width = 19
Here, I have eventually found a solution:
Sub FormatAllCharts()
Dim i As Long
Dim oChtObj As ChartObject
For Each oChtObj In ActiveSheet.ChartObjects
With oChtObj.Chart
For i = 1 To .SeriesCollection.Count
With .SeriesCollection(i)
.ApplyDataLabels
.DataLabels.NumberFormat = "0,0;-0,0;;"
Values_Array = .Values
For j = LBound(Values_Array, 1) To UBound(Values_Array, 1)
.Points(j).DataLabel.Width = 19
Next
End With
Next
End With
Next
End Sub

How to change Orientation of bars in Excel Bar Chart created with VBA

I am creating a chart, in a form, using VBA Excel 2010. I have configured excel to use Chartspace and the chart is created using dynamic data correctly, but the presentation is not what I am looking for, but can't figure how to change it. Please see the section of code:
Private Sub UserForm_Initialize()
Dim row_count As Integer
Dim n As Long
Dim chart_data As Worksheet
Set chart_data = Worksheets("Sheet3")
row_count = chart_data.UsedRange.Rows.Count
Dim varCats()
Dim varVals()
ReDim varCats(row_count)
ReDim varVals(row_count)
'Set c = ChartSpace1.Constants
Set mychart = ChartSpace1.Charts.Add
mychart.Type = xlColumnClustered '51 'chChartTypeBarClustered 'c.chChartTypeBarClustered
For n = 2 To row_count
varCats(n) = ActiveWorkbook.Sheets("Sheet3").Range("A" & n).Value
varVals(n) = ActiveWorkbook.Sheets("Sheet3").Range("T" & n).Value
Next n
mychart.SeriesCollection.Add
With mychart.SeriesCollection(0)
.SetData chDimSeriesNames, chDataLiteral, "QAR Score"
.SetData chDimCategories, chDataLiteral, varCats
.SetData chDimValues, chDataLiteral, varVals
End With
End Sub
The bar chart is showing the bars horizontally and not vertically. So where I thought my variable "varCats" would go to the X-Axis is not but rather the Y-axis.
I know this is going to be a simple response from the community, but I have yet to find it through my searching.
Thanks,
C
Image from the answer provide:
Desired Results:
Revised to work with ChartSpace objects in UserForm
Private Sub UserForm_Initialize()
Dim row_count As Integer
Dim n As Long
Dim chart_data As Worksheet
Dim srs As ChSeries
Dim myChart As ChChart
Set chart_data = Worksheets("Sheet3")
row_count = chart_data.UsedRange.Rows.Count
ReDim varCats(1 To row_count)
ReDim varVals(1 To row_count)
varCats = Application.Transpose(chart_data.Range("A2:A" & row_count).Value)
varVals = Application.Transpose(chart_data.Range("T2:B" & row_count).Value)
'Set c = ChartSpace1.Constants
Set myChart = ChartSpace1.Charts.Add
myChart.Type = chChartTypeColumnClustered
Set srs = myChart.SeriesCollection.Add
With srs
.SetData chDimSeriesNames, chDataLiteral, "QAR Score"
.SetData chDimCategories, chDataLiteral, varCats
.SetData chDimValues, chDataLiteral, varVals
End With
End Sub

Resources