Change color of axis bars in an Excel pivotchart - excel

I have this PivotChart in Excel 2016
As you can see there are two properties in the axis field: "Date" and "Category".
There are two possible values for "Category": ASC and SBT.
Right now the bars related to either values are of the same colors (Red and Blue).
I want that if the "Category" is SBT, the colors of the bars must be different (for example, yellow and green). How can I achieve that?
Thanks

Try this.
Sub test()
Dim obj As ChartObject
Dim cht As Chart
Dim pnt As Point
Dim Ws As Worksheet
Dim s As String
Set Ws = ActiveSheet
Set obj = Ws.ChartObjects(1)
Set cht = obj.Chart
With cht
.ApplyDataLabels
For Each pnt In .SeriesCollection(1).Points
With pnt.DataLabel
.ShowCategoryName = True
.ShowValue = False
End With
s = pnt.DataLabel.Text
If InStr(s, "SBT") Then
pnt.Format.Fill.ForeColor.RGB = RGB(255, 2255, 0)
End If
With pnt.DataLabel
.ShowCategoryName = False
End With
Next pnt
For Each pnt In .SeriesCollection(2).Points
With pnt.DataLabel
.ShowCategoryName = True
.ShowValue = False
End With
s = pnt.DataLabel.Text
If InStr(s, "SBT") Then
pnt.Format.Fill.ForeColor.RGB = RGB(29, 219, 22)
End If
With pnt.DataLabel
.ShowCategoryName = False
End With
Next pnt
End With
End Sub

Related

VBA-Excel - Graph creator

I'm trying to create a code for generate some graphs with some data already stored in arrays.
The actual final result of the macro is this graph:
The code used for it is the following:
Dim sht As Worksheet
Set sht = ActiveSheet
Dim chtObj As ChartObject
Set chtObj = sht.ChartObjects.Add(100, 10, 500, 300)
Dim cht As Chart
Set cht = chtObj.Chart
If IsZeroLengthArray(yData_TSI) = False Then
Dim ser As Series
Set ser = cht.SeriesCollection.NewSeries
ser.Values = yData_TSI
ser.XValues = xData_TSI
ser.Name = "TSI Predicant"
ser.ChartType = xlXYScatterSmooth
End If
If IsZeroLengthArray(yData_Pallet) = False Then
Dim ser2 As Series
Set ser2 = cht.SeriesCollection.NewSeries
ser2.Values = yData_Pallet
ser2.XValues = xData_Pallet
ser2.Name = "Pallet Decant"
ser2.ChartType = xlXYScatterSmooth
End If
If IsZeroLengthArray(yData_Vendor) = False Then
Dim ser3 As Series
Set ser3 = cht.SeriesCollection.NewSeries
ser3.Values = yData_Vendor
ser3.XValues = xData_Vendor
ser3.Name = "Vendor Decant"
ser3.ChartType = xlXYScatterSmooth
End If
If IsZeroLengthArray(yData_Prep) = False Then
Dim ser4 As Series
Set ser4 = cht.SeriesCollection.NewSeries
ser4.Values = yData_Prep
ser4.XValues = xData_Prep
ser4.Name = "Each"
ser4.ChartType = xlXYScatterSmooth
End If
If IsZeroLengthArray(yData_Each) = False Then
Dim ser5 As Series
Set ser5 = cht.SeriesCollection.NewSeries
ser5.Values = yData_Each
ser5.XValues = xData_Each
ser5.Name = "Prep"
ser5.ChartType = xlXYScatterSmooth
End If
I have in other arrays (tData_XXX) numbers that I would like to add as a label to the bullet points in the graph. To make myself clear, for the same graph generated before, let's imagine than for the "Vendor Decant" data the tData_Vendor array has the numbers (34, 5, 12). The desired result should be something like this:
How can I do this on the code?
Thanks!
Note:
All the arrays (yData_XXX, xData_XXX and tData_XXX) are always the same size
Untested, but something like this should work:
Sub CreateChart()
Dim sht As Worksheet, chtObj As ChartObject, cht As Chart
Set sht = ActiveSheet
Set chtObj = sht.ChartObjects.Add(100, 10, 500, 300)
Set cht = chtObj.Chart
AddSeries cht, "TSI Predicant", yData_TSI, xData_TSI, tData_TSI
AddSeries cht, "Pallet Decant", yData_Pallet, xData_Pallet, tData_Pallet
AddSeries cht, "Vendor Decant", yData_Vendor, xData_Vendor, tData_Vendor
AddSeries cht, "Each", yData_Prep, xData_Prep, tData_Prep '???
AddSeries cht, "Prep", yData_Each, xData_Each, tData_Each '???
End Sub
Sub AddSeries(cht As Chart, seriesName As String, xVals, yVals, labelVals)
Dim i As Long
If Not IsZeroLengthArray(yVals) Then
With cht.SeriesCollection.NewSeries
.ChartType = xlXYScatterSmooth
.Values = yVals
.XValues = xVals
.Name = seriesName
.ApplyDataLabels
'loop over series points and apply label from array
For i = 1 To .Points.Count
.Points(i).DataLabel.Text = labelVals(i - 1) 'assuming arrays are zero-based
Next
End With
End If
End Sub
Note you can reduce your code volume by factoring out the repeated "add a series" steps into a separate method.

How can I print different charts for different data with Excel or VBA?

I am trying to print one graph for each row/table, the graphs should keep the same format, only the data should change among graphs. I need to do it for about 120 rows/tables so I would like to avoid doing it manually, also, I would prefer not to use the sparklines as its format is not appropriate for the purpose of the analysis.
I have tried to use a dynamic chart with the combo button but when I change the filtered line, every copied graph changes as well, making it impossible to have at the same time graphs showing different rows - one solution may be pasting it as image but it is not optimal as I would like to check the data for each graph if needed.
Below I show the example for two different "items", in the original dataset there are about 350/400 rows and about 120 "items", every 3 rows create one graph.
The graphs I have created manually are: (one for each 3 rows)
for "item" xxx:
For "item" yyy:
I need to print this type of graph for other different ~120 "items", all at once.
In terms of showing the format of the chart, see the below for the first graph:
The blank is:
The second quartile is:
The third quartile:
and the "item", which is the black point in the graph:
Same reasoning for the second graph, but considering the three rows with yyy.
I hope you can help me!
Sorry for the big amount of images, but I wanted it to be clear!
Thank you in advance!
Best,
Ema
It is easy to create a typical procedure for creating a chart and use parameters to iterate over the sheet.
Sub makeCharts()
Dim Ws As Worksheet
Dim Cht As Chart, Shp As Shape
Dim obj As ChartObject
Dim Target As Range, rngShp As Range
Dim r As Long, n As Long, i As Long
Set Ws = ActiveSheet
For Each obj In Ws.ChartObjects
obj.Delete
Next
r = Ws.Range("a" & Rows.Count).End(xlUp).Row
n = 1
For i = 3 To r Step 3
Set rngShp = Ws.Range("k" & n).Resize(10, 8)
Set Target = Ws.Range("a" & i)
Set Shp = Ws.Shapes.AddChart
With Shp
.Top = rngShp.Top
.Left = rngShp.Left
.Width = rngShp.Width
.Height = rngShp.Height
End With
Set Cht = Shp.Chart
setCharts Target, Cht
n = n + 12
Next i
End Sub
Sub setCharts(Target As Range, Cht As Chart)
Dim Srs As Series
Dim vColor
Dim i As Integer
vColor = Array(RGB(246, 246, 246), RGB(255, 224, 140), RGB(47, 157, 39), RGB(0, 0, 0))
With Cht
.ChartType = xlColumnStacked
.HasLegend = False
.HasTitle = True
.ChartTitle.Text = Target.Value
.Axes(xlValue, xlPrimary).HasTitle = True
.Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "OCF Percentiles"
.Axes(xlValue).MajorUnit = 20
For Each Srs In .SeriesCollection
Srs.Delete
Next Srs
For i = 0 To 2
Set Srs = .SeriesCollection.NewSeries
With Srs
.Values = Target.Offset(0, 1).Resize(3).Offset(0, i)
.XValues = Array("A", "D", "I")
.Format.Fill.ForeColor.RGB = vColor(i)
If i = 0 Then
.Format.Fill.Transparency = 1 '<~~~~~ Transparency was adjusted
End If
End With
Next i
Set Srs = .SeriesCollection.NewSeries
With Srs
.ChartType = xlXYScatter
.Values = Target.Offset(0, 4).Resize(1, 3)
.MarkerStyle = xlMarkerStyleSquare
.MarkerBackgroundColor = vColor(3) 'vbBlack
End With
End With
End Sub
Result image

Creating a Visual Basic chart

I'm trying to create a bar chart in VBA that will display a percent change for a specific month. The data would also need to be calculated within the macro. For example, the energy series show March-Feb/Feb rather than the just the month's data.
How would I go about doing this? I inserted an image of what I would like the display to be.
I appreciate any help. Thank you!
data:
what I would like the vba code to display:
Sub chart()
Dim i As Integer
Dim chart As ChartObject
With ActiveSheet.ChartObjects.Add _
(Left:=90, Width:=375, Top:=75, Height:=225)
.chart.SetSourceData Source:=Sheets("sheet1").Range("B2:D2", "B5:D5")
.chart.HasTitle = True
.chart.ChartTitle.Text = "1-month percent change for X month"
.chart.ChartType = xlBarClustered
.chart.HasLegend = False
End With
End Sub
Put the calculated percentages into an array and use the series.collection(1).values property.
Sub chart()
Dim i As Integer
Dim chart As ChartObject
Dim rng2 As Range
Set rng2 = Range("C5:E5")
' calculate percent
Dim cell As Range, pcent() As Single, prev As Single, curr As Single
ReDim pcent(rng2.Count - 1)
For Each cell In rng2
curr = CSng(cell)
prev = CSng(cell.Offset(-1, 0))
pcent(i) = (curr - prev) / prev
i = i + 1
Next
With ActiveSheet.ChartObjects.Add _
(Left:=90, Width:=375, Top:=100, Height:=225).chart
.SetSourceData Source:=Sheets("sheet1").Range("B2:E2,B5:E5")
.HasTitle = True
.ChartTitle.Text = "1-month percent change for " & ActiveSheet.Range("B5").Value
.ChartType = xlBarClustered
.HasLegend = False
.SeriesCollection(1).Values = pcent
.Axes(xlValue, xlPrimary).TickLabels.NumberFormat = "0.00%"
End With
End Sub

VBA Plot of box and whiskers chart

I'm trying to automate plotting of a box and whiskers chart. The code below compiles and runs but the error bars do not appear in the chart.
Dim ws As Worksheet
Dim datarange As Range
Dim chtChart As Chart
Dim objChrt As ChartObject
Set ws = Sheets("sheet1")
Set datarange = ws.Range("F8:G10")
Set chtChart = Charts.add
With chtChart
chtChart.ChartType = xlColumnStacked
chtChart.SetSourceData Source:=datarange, PlotBy:=xlColumns
With .Axes(xlCategory, xlPrimary)
.CategoryNames = ws.Range("A2:A13")
.TickLabels.Font.Bold = True
End With
.SeriesCollection(1).Format.Fill.Visible = msoFalse
.SeriesCollection(2).Format.Fill.Visible = msoTrue
Dim Sec1 As Series
Set Sec1 = .SeriesCollection.NewSeries
.SeriesCollection(3).HasErrorBars = True
.SeriesCollection(3).ErrorBars.EndStyle = xlCap
.SeriesCollection(3).ErrorBars.Format.Line.Visible = msoTrue
.SeriesCollection(3).ErrorBars.Format.Line.ForeColor.RGB = RGB(0, 0, 0)
.SeriesCollection(3).ErrorBars.Format.Line.Transparency = 0
.SeriesCollection(3).ErrorBars.Format.Line.Weight = 1.5
.SeriesCollection(3).ErrorBar Direction:=xlX, Include:=xlErrorBarIncludeBoth, Type:=xlErrorBarTypeCustom, Amount:="=CHART!F12:G12", MinusValues:="=CHART!F12:G12"
Solved.
.SeriesCollection(3).values= <data range for whisker length>
type variant, data values required to plot whiskers
IMPORTANT: this overwrites the series collection values (seriescollection(3) in this case)
values can be replaced after plotting whiskers

Modifying Data Labels from Center to Above in Excel VBA

I am trying to make some revisions to my DataLabels.
I would like the column width (Down, Up and Total) to match the size of the text. I would also like to make the data label text bolded and easier to see.
Does anyone know the best method to do this given my code and the existing chart that I have right now?
Thanks!
Sub Waterfall()
'
' Waterfall Macro
'
'
Range("A7").Select
Dim rngData As Range
Dim intCounter As Integer
Dim rngToSelect As Range
Dim srs As Series
Dim i As Long
Set rngData = ActiveCell.CurrentRegion
Set rngToSelect = Range(rngData.Cells(1, 1), rngData.Cells(rngData.Rows.Count, 1))
For intCounter = 1 To rngData.Columns.Count
If rngData.Cells(1, intCounter).Value <> "Values" Then
Set rngToSelect = Union(rngToSelect, Range(rngData.Cells(1, intCounter), rngData.Cells(rngData.Rows.Count, intCounter)))
End If
Next intCounter
rngToSelect.Select
ActiveSheet.Shapes.AddChart.Select
ActiveChart.SetSourceData Source:=rngToSelect
ActiveChart.ChartType = xlColumnStacked
ActiveChart.ChartGroups(1).GapWidth = 75
ActiveChart.SeriesCollection("Blank").Select
Selection.Format.Fill.Visible = msoFalse
For Each srs In ActiveChart.SeriesCollection
For i = 1 To UBound(srs.Values)
srs.Points(i).HasDataLabel = srs.Values(i) > 0
Next i
Next srs
ActiveChart.SeriesCollection("Blank").DataLabels.ShowValue = False
ActiveChart.SeriesCollection("Down").Interior.Color = RGB(255, 0, 0)
ActiveChart.SeriesCollection("Up").Interior.Color = RGB(0, 204, 0)
ActiveChart.Legend.LegendEntries(3).Select
Selection.delete
'Remove Gridlines
Dim axs As Axis
For Each axs In ActiveChart.Axes
axs.HasMajorGridlines = False
axs.HasMinorGridlines = False
Next
Range("A1").Select
End Sub
In order to change your data laebls text to bold try the following command:
ActiveChart.SeriesCollection("Down").DataLabels.Font.Bold = True

Resources