I'm using VBA to update my chart. With VBA I select the data that should be shown in the chart. My code does select the data, but somehow my chart doesn't show anything. When I click on my chart end select "Select data" it does show selected data, bu somehow my chart is still empty. Because my chart is empty, the rest of my code doesn't work
My chart is a combo chart with both dataranges as bars, absolute on the primary axis and relative on the secondary axis.
Dim DataSite As Range
Dim DataAbsolute As Range
Dim DataRelative As Range
Set DataSite = Range(Cells(7, 1), Cells(7, 1).End(xlDown))
Set DataAbsolute = Range(Cells(7, 4), Cells(7, 4).End(xlDown))
Set DataRelative = Range(Cells(7, 5), Cells(7, 5).End(xlDown))
GraphsFrames.Select
For Each serie In cht.Chart.SeriesCollection
serie.Select
serie.Delete
Next serie
With cht.Chart
With .SeriesCollection.NewSeries
.XValues = DataSite
.Values = DataAbsolute
.Name = "Absolute"
.AxisGroup = 1
End With
With .SeriesCollection.NewSeries
.Values = DataRelative
.Name = "Relative"
.AxisGroup = 2
End With
.ChartGroups(1).GapWidth = 50
.ChartGroups(2).GapWidth = 300
.Refresh
End With
What can I do to make sure my chart shows the data selected?
Well, I don't know what GraphFrames is, so I ignored it. I made only minor adjustments to your code, below, and it worked just fine. I assume the data is on the active sheet, and so is the chart object you're adding data to.
Sub DoChartData()
Dim DataSite As Range
Dim DataAbsolute As Range
Dim DataRelative As Range
With ActiveSheet
Set DataSite = .Range(.Cells(7, 1), .Cells(7, 1).End(xlDown))
Set DataAbsolute = .Range(.Cells(7, 4), .Cells(7, 4).End(xlDown))
Set DataRelative = .Range(.Cells(7, 5), .Cells(7, 5).End(xlDown))
End With
Dim cht As ChartObject
Set cht = ActiveSheet.ChartObjects(1)
Dim serie As Series
For Each serie In cht.Chart.SeriesCollection
serie.Delete
Next serie
With cht.Chart
With .SeriesCollection.NewSeries
.XValues = DataSite
.Values = DataAbsolute
.Name = "Absolute"
.AxisGroup = 1
End With
With .SeriesCollection.NewSeries
.Values = DataRelative
.Name = "Relative"
.AxisGroup = 2
End With
.ChartGroups(1).GapWidth = 50
.ChartGroups(2).GapWidth = 300
End With
End Sub
Related
I'm trying to create a dynamic Scatterchart in the worksheet("Graphs") using a button.
The Seriesname has to be equal to Worksheets("VS_P240_X").Cells(1,i), where i is a counter for the columns.
The XValues have to be equal to Worksheets("VS_P240_X").Range(cells(3,i).cells(1000,i)).
The YValues have to be equal to Worksheets("VS_P240_Y").Range(cells(3,i).cells(1000,i)).
When I Update the workbook the counter i will change, and I want that the chart will automatically update with the new series. I wrote this code but it is not working, do you have some suggestions?
Private Sub CommandButton5_Click()
'Graph generation NON COMPLETO
Dim i As Integer
Dim Chart1 As Chart
Set Chart1 = Sheets("Graphs").ChartObjects("Chart 1").Chart
For i = 1 To Lastcolumn
With Chart1
.ChartType = xlXYScatter
.SeriesCollection.NewSeries
'Change to what your series should be called
.SeriesCollection(i).Name = Worksheets("VS_P240_X").Cells(1, i).Value
.SeriesCollection(i).XValues = Worksheets("VS_P240_X").Range(Cells(3, i), Cells(1000, i))
.SeriesCollection(i).Values = Worksheets("VS_P240_Y").Range(Cells(3, i), Cells(1000, i))
End With
Next i
End Sub
To avoid confusion/bugs, it's best to specify a worksheet every time you use Range or Cells()
Something like this should work:
Private Sub CommandButton5_Click()
Dim i As Long, Lastcolumn As Long 'use long not integer
Dim Chart1 As Chart, wsX As Worksheet, wsY As Worksheet
Set wsX = Worksheets("VS_P240_X")
Set wsY = Worksheets("VS_P240_Y")
Set Chart1 = Sheets("Graphs").ChartObjects("Chart 1").Chart
Do While Chart1.SeriesCollection.Count > 0 'remove any existing data
Chart1.SeriesCollection(1).Delete
Loop
Chart1.ChartType = xlXYScatter 'do this outside of the loop...
Lastcolumn = wsX.Cells(1, wsX.Columns.Count).End(xlToLeft).Column
For i = 1 To Lastcolumn
With Chart1.SeriesCollection.NewSeries
.Name = wsX.Cells(1, i).Value
.XValues = wsX.Range(wsX.Cells(3, i), wsX.Cells(1000, i))
.Values = wsY.Range(wsY.Cells(3, i), wsY.Cells(1000, i))
End With
Next i
End Sub
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
I am trying to create a line chart through the use of VBA,i do this by using the attached code, I list the category i want in the rng, however it doesn't automatically select this to be the category, i want columns 4,5 to be displayed on the chart and 3 to be the category.
Sub CreateGBPChart()
'PURPOSE: Create a chart (chart dimensions are not required)
Dim rng As Range
Dim cht As Object
Dim wks As Worksheet, wks2 As Worksheet
Set wks = Sheet2
Set wks2 = Sheet5
'data range for the chart
lastrow = wks.Cells.Find("*", searchorder:=xlByRows, searchdirection:=xlPrevious).Row
Set rng = Range(wks.Cells(10, 3), wks.Cells(lastrow, 5))
'Create a chart
Set cht = wks2.ChartObjects.Add( _
Left:=wks2.Range("K18").Left, _
Width:=480, _
Top:=wks2.Range("K18").Top, _
Height:=200)
' chart data
cht.Chart.SetSourceData Source:=rng
'cht.Chart.Axes(xlCategory).CategoryNames = Range(wks.Cells(10, 3), wks.Cells(lastrow, 3))
'Determine the chart type
cht.Chart.ChartType = xlXYScatterLines
'chart title
cht.Chart.HasTitle = True
'Change title
cht.Chart.ChartTitle.Text = "GBP Price"
'Remove Legend
'cht.Legend.Delete
cht.Chart.Parent.Name = "GBPTable"
'adjust the min val
cht.Axes(xlValue).MinimumScale = 1
'format fontsize'
cht.Chart.ChartArea.Format.TextFrame2.TextRange.Font.Size = 8
'cht.Chart.chartSeriesCollection(1).Line.Width = 4
'cht.Chart.chartSeriesCollection(2).Format.Line.Width = 4
End Sub
Try this:
' cht.Chart.SetSourceData Source:=rng
cht.Chart.SetSourceData Source:=wks.Range(wks.Cells(10, 4), wks.Cells(LastRow, 5))
' Add lines
cht.Chart.SeriesCollection(1).XValues = wks.Range(wks.Cells(10, 3), wks.Cells(LastRow, 3))
cht.Chart.SeriesCollection(2).XValues = wks.Range(wks.Cells(10, 3), wks.Cells(LastRow, 3))
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
59.30 15 16 17
1 1,162,912,036.90 1,248,737,016.99 1,306,573,912.08
2 245,665,383.94 261,416,880.69 276,613,283.05
3 393,313,441.29 379,169,039.15 418,680,492.19
4 13,920,572.74 14,464,854.92 15,120,474.58
5 54,501,581.55 56,319,351.21 58,832,588.24
6 15,165,376.28 11,694,942.56 10,809,661.03
7 194,397,643.30 170,427,013.85 182,567,862.46
8 15,165,376.28 11,694,942.56 10,809,661.03
9 2,079,876,036.00 2,142,229,099.38 2,269,198,273.62
3% 6%
There are 7 tables like the above data in one excel tab in different area.I want to create a stacked column chart for each table. I wrote a code to create. Just want to know is that possiable to use loop to solve this problem? Code attached.
Sub FormatChartNIX()
'PURPOSE: Create a chart (chart dimensions are not required)
Dim rng As Range
Dim cht As Object
Dim ser As Series
Dim tmpCHR As ChartObject
'Chart1
'Your data range for the chart
Set rng = ActiveSheet.Range("B8:E17")
'Create a chart
Set cht = ActiveSheet.Shapes.AddChart
'Give chart some data
cht.chart.SetSourceData Source:=rng, PlotBy:=xlRows
'Determine the chart type
cht.chart.ChartType = xlColumnStacked
With ActiveSheet
.ChartObjects(1).Top = .Range("C24").Top
.ChartObjects(1).Left = .Range("C24").Left
End With
ActiveSheet.ChartObjects(1).Activate
ActiveChart.Axes(xlValue).Select
Selection.delete
ActiveChart.HasTitle = True
ActiveChart.ChartTitle.Text = ActiveSheet.Range("c1")
'Chart2
Set rng = ActiveSheet.Range("G8:J17")
Set cht = ActiveSheet.Shapes.AddChart
cht.chart.SetSourceData Source:=rng, PlotBy:=xlRows
cht.chart.ChartType = xlColumnStacked
With ActiveSheet
.ChartObjects(2).Top = .Range("H24").Top
.ChartObjects(2).Left = .Range("H24").Left
End With
ActiveSheet.ChartObjects(2).Activate
ActiveChart.Axes(xlValue).Select
Selection.delete
ActiveChart.HasTitle = True
ActiveChart.ChartTitle.Text = ActiveSheet.Range("h1")
'Chart3
Set rng = ActiveSheet.Range("L8:o17")
Set cht = ActiveSheet.Shapes.AddChart
cht.chart.SetSourceData Source:=rng, PlotBy:=xlRows
cht.chart.ChartType = xlColumnStacked
With ActiveSheet
.ChartObjects(3).Top = .Range("M24").Top
.ChartObjects(3).Left = .Range("M24").Left
End With
ActiveSheet.ChartObjects(3).Activate
ActiveChart.Axes(xlValue).Select
Selection.delete
ActiveChart.HasTitle = True
ActiveChart.ChartTitle.Text = ActiveSheet.Range("h1")
'Chart4
Set rng = ActiveSheet.Range("B82:E91")
Set cht = ActiveSheet.Shapes.AddChart
cht.chart.SetSourceData Source:=rng, PlotBy:=xlRows
cht.chart.ChartType = xlColumnStacked
With ActiveSheet
.ChartObjects(4).Top = .Range("C51").Top
.ChartObjects(4).Left = .Range("C51").Left
End With
ActiveSheet.ChartObjects(4).Activate
ActiveChart.Axes(xlValue).Select
Selection.delete
ActiveChart.HasTitle = True
ActiveChart.ChartTitle.Text = ActiveSheet.Range("c75")
'Chart5
Set rng = ActiveSheet.Range("G82:J91")
Set cht = ActiveSheet.Shapes.AddChart
cht.chart.SetSourceData Source:=rng, PlotBy:=xlRows
cht.chart.ChartType = xlColumnStacked
With ActiveSheet
.ChartObjects(5).Top = .Range("H51").Top
.ChartObjects(5).Left = .Range("H51").Left
End With
ActiveSheet.ChartObjects(5).Activate
ActiveChart.Axes(xlValue).Select
Selection.delete
ActiveChart.HasTitle = True
ActiveChart.ChartTitle.Text = ActiveSheet.Range("h75")
'Chart6
Set rng = ActiveSheet.Range("L82:o91")
Set cht = ActiveSheet.Shapes.AddChart
cht.chart.SetSourceData Source:=rng, PlotBy:=xlRows
cht.chart.ChartType = xlColumnStacked
With ActiveSheet
.ChartObjects(6).Top = .Range("M51").Top
.ChartObjects(6).Left = .Range("M51").Left
End With
ActiveSheet.ChartObjects(6).Activate
ActiveChart.Axes(xlValue).Select
Selection.delete
ActiveChart.HasTitle = True
ActiveChart.ChartTitle.Text = ActiveSheet.Range("m75")
'Chart7
Set rng = ActiveSheet.Range("Q82:T91")
Set cht = ActiveSheet.Shapes.AddChart
cht.chart.SetSourceData Source:=rng, PlotBy:=xlRows
cht.chart.ChartType = xlColumnStacked
With ActiveSheet
.ChartObjects(7).Top = .Range("R51").Top
.ChartObjects(7).Left = .Range("R51").Left
End With
ActiveSheet.ChartObjects(7).Activate
ActiveChart.Axes(xlValue).Select
Selection.delete
ActiveChart.HasTitle = True
ActiveChart.ChartTitle.Text = ActiveSheet.Range("r75")
End Sub
Using named ranges and some arrays you can loop through it.
First, create named ranges for the ranges for each chart.
I added a small table in the spreadsheet and named each one the text in the first cell of the range (i.e., Chart1,... Chart7). The other ranges each go in the next cell, so the range named "Chart 1" is 4 cells.
(I also used the same ranges and cells that you did in your code above)
Chart1 B8:E17 C24 C1
Chart2 G8:J17 H24 H1
Chart3 L8:O17 M24 H1
Chart4 B82:E91 C51 C75
Chart5 G82:J91 H51 H75
Chart6 L82:O91 M51 R75
Chart7 Q82:T91 R51 R75
Sub FormatChartNIX_Modified()
Dim rng As Range
Dim cht As Object
Dim ser As Series
Dim tmpCHR As ChartObject
Dim MyArray(1 To 7, 0 To 3) As String
Dim i As Integer
For i = LBound(MyArray) To UBound(MyArray)
'Set Values - possibly with named ranges
Dim vArray() As Variant
Dim strNamedRange As String
strNamedRange = "Chart" & i
Set rng = Worksheets("Sheet1").Range(strNamedRange)
vArray = rng
Dim j As Integer
For j = LBound(MyArray, 2) To UBound(MyArray, 2)
MyArray(i, j) = vArray(1, j + 1)
Debug.Print MyArray(i, j)
Next j
Next i
For i = LBound(MyArray) To UBound(MyArray)
With ActiveSheet
Set rng = .Range(MyArray(i, 1)) '1 represents the data range
Set cht = .Shapes.AddChart
cht.Chart.SetSourceData Source:=rng, PlotBy:=xlRows
cht.Chart.ChartType = xlColumnStacked
.ChartObjects(i).Top = .Range(MyArray(i, 2)).Top '0 represents the chart name
.ChartObjects(i).Left = .Range(MyArray(i, 2)).Left '2 represents the cell identifying the chart location
.ChartObjects(i).Activate
With ActiveChart
.Axes(xlValue).Select
.Axes(xlValue).Delete
.HasTitle = True
.ChartTitle.Text = ActiveSheet.Range(MyArray(i, 3)).Text '3 represents the cell where the title text is located
End With
End With
Next i
End Sub
Do that, run the sub and it will create 7 charts as described in the table - using a loop.