Create multiple column stacked graphs with two series - vba

I want to create 40 different column stacked graphs using macros in Excel. Each graph has two series. So far I've done this:
Sub loopChart()
Dim mychart As Chart
Dim myRange As Range
Dim c As Integer
Dim d As Integer
c = 1
d = 2
While c <= 33 '1=dataSource1, 4=dataSource2, 7=dataSource3
While d <= 33
'set data source for the next chart
With Worksheets("Hoja1")
Set myRange = .Range(.Cells(1, c), .Cells(3, c + 1))
Set myRange2 = .Range(.Cells(1, d), .Cells(3, d + 1))
End With
'create chart
Sheets("Hoja1").Select
ActiveSheet.Shapes.AddChart.Select
With ActiveChart
.ChartType = xl3DColumnStacked
'sets source data for graph including labels
.SetSourceData Source:=myRange2, PlotBy:=xlColumns
'including legend
.SetElement (msoElementLegendRight)
.HasTitle = True
'dimentions & location:
'defines the coordinates of the top of the chart
.Parent.Top = 244
'defines the coordinates for the left side of the chart
.Parent.Left = c * 100
.Parent.Height = 200
.Parent.Width = 300
.ChartTitle.Text = "Porcenta-2014"
End With
c = c + 3
d = d + 3
Wend
Wend
End Sub
I want that insted of 1 and 2 my graphs use de name of the column A:

Sub tset()
Dim dataRange As Range
Dim dataNames As Range
Dim c As Integer
Set dataRange = Range("B1:C3")
Set dataNames = Range("A2:A3")
c = 1
For i = 1 To 40
ActiveSheet.Shapes.AddChart.Select
With ActiveChart
.SetSourceData Source:=dataRange, PlotBy:=xlColumns
.SeriesCollection(1).XValues = dataNames
.ChartType = xl3DColumnStacked
.SetElement (msoElementLegendRight)
.HasTitle = True
.Parent.Top = 244
.Parent.Left = c * 100
.Parent.Height = 200
.Parent.Width = 300
.ChartTitle.Text = "Porcenta-2014"
End With
c = c + 3
Set dataRange = dataRange.Offset(0, 2)
Next i
End Sub

Related

VBA Chart title does not populate

I have a list of data and I need to generate a chart for every two lines and give a chart title associated to the 1st line. Example of the data is:
Example
And so on.
The code I am using to create the charts is:
Sub loopChart()
Dim mychart As Chart
Dim myRange As Range
Dim c As Integer
Dim r As Integer
Dim s As Integer
Dim ttl As String
r = 2
While r <= 10 '1=dataSource1, 4=dataSource2, 7=dataSource3
'set data source for the next chart
With Worksheets("Sheet9")
Set myRange = .Range(.Cells(r, 2), .Cells(r + 1, 14))
End With
'create chart
Sheets("Chart").Select
ActiveSheet.Shapes.AddChart.Select
With ActiveChart
ttl = Range("A" & r)
.ChartType = xlLineMarkers 'xlLine
.SetSourceData Source:=myRange, PlotBy:=xlRows 'sets source data for graph including labels
.SetElement (msoElementLegendRight) 'including legend
.HasTitle = True
'dimentions & location:
.Parent.Top = 244 'defines the coordinates of the top of the chart
'.Parent.Left = r * 150 'defines the coordinates for the left side of the chart
.Parent.Height = 200
.Parent.Width = 300
.ChartTitle.Formula = ttl
End With
r = r + 2
Wend
End Sub
So, the 1st chart that generates should get the title on row 2, next chart should have title of row 4...
I always get the Chart title on 1st chart that generates but not on any of the other charts. Can anyone please help me on this?
Please fix below.
ttl = Range("A" & r)
to
ttl = Worksheets("Sheet9").Range("A" & r).Value
I think #Dy.Lee answer will do the trick but to go a bit further :
Try avoiding using .select
Proposed workaround :
Sub loopChart()
Dim Ch As Chart
Dim Sh1 As Worksheet: Set Sh1 = Sheets("Sheet9")
Dim Sh2 As Worksheet: Set Sh2 = Sheets("Chart")
Dim L As Integer
L = 0
For i = 2 To 18 Step 2
Set Ch = Sh2.Shapes.AddChart.Chart
Ch.SetSourceData Sh1.Range(Sh1.Cells(i, 2), Sh1.Cells(i + 1, 14))
Ch.ChartType = xlLineMarkers
Ch.SetElement (msoElementLegendRight)
Ch.HasTitle = True
Ch.Parent.Top = 244
Ch.Parent.Height = 200
Ch.Parent.Width = 300
Ch.Parent.Left = L
Ch.ChartTitle.Caption = Sh1.Cells(i, 1).Value
L = L + 300
Next i
End Sub
Your code will create each graph at the same location so you'll see only one (the last one) hence the Ch.Parent.Left line with variable value.

create several charts in Excel with VBA

I have a worksheet with 300 columns and would like to create one scatter plot for each column, bringing data from two other sheets that are in the same worksheet.
The problem is that I´m not familiar with VBA, and some error codes don't help at all.
Private Sub Create_Charts()
Dim sh As Worksheet
Dim chrt As Chart
For i = 1 To 300
Set sh = ActiveWorkbook.Worksheets("Graphs")
Set chrt = sh.Shapes.AddChart.Chart
With chrt
'Data
.ChartType = xlXYScatter
.SeriesCollection.NewSeries
.SeriesCollection(1).Name = "=""Scatter Chart"""
'With the following parameters it works:
'.SeriesCollection(1).XValues = "=OP!$c$4:$c$1588"
'.SeriesCollection(1).Values = "=PV!$c$4:$c$1588"
'But I need something like this:
.SeriesCollection(1).XValues = CStr(Worksheets("PV").Range(Cells(i, 4), Cells(i, 1588)))
.SeriesCollection(1).Values = CStr(Worksheets("OV").Range(Cells(i, 4), Cells(i, 1588)))
'Location
.ChartArea.Left = 380 * i - 380
.ChartArea.Top = 100
.ChartArea.Height = 360
.ChartArea.Width = 360
'Formatting
.Axes(xlCategory).HasMajorGridlines = True
.Axes(xlValue).HasMajorGridlines = True
.HasAxis(xlCategory, xlPrimary) = False
.HasAxis(xlValue, xlPrimary) = False
.HasLegend = False
End With
Next i
End Sub
This line references a column:
.SeriesCollection(1).XValues = "=OP!$c$4:$c$1588"
This references a row, row i from column 4 to column 1588:
.SeriesCollection(1).XValues = CStr(Worksheets("PV").Range(Cells(i, 4), Cells(i, 1588)))
But you also need to reference not only Range but Cells. And if you pass in a string address, you need the leading "="; it's easier to pass in a range. So try this:
Dim wsPV As Worksheet, wsOV As Worksheet
Dim rngX As Range, rngY As Range
Set wsPV = ActiveWorkbook.Worksheets("PV")
Set wsOV = ActiveWorkbook.Worksheets("OV")
Set rngX = wsPV.Range(wsPV.Cells(4, i), wsPV.Cells(1588, i)
Set rngY = wsOV.Range(wsOV.Cells(4, i), wsOV.Cells(1588, i)
chrt.SeriesCollection(1).XValues = rngX
chrt.SeriesCollection(1).Values = rngY

series deletion in chart

I have an table and would like to generate an chart out of it. the problem is I would like to have only the column Values of A, F, G, and H.
I tried seriescollection(1).deletion method,. but I am still getting the column B and C series in my chart.
Could anyone tell me how I can do it.
Any lead would be helpful
Sub chartstatus()
Dim Rng As Range
Dim cht As Object
Set Rng = ActiveSheet.Range("A2:H53")
ThisWorkbook.Sheets("Status").ChartObjects.delete
Set Sh = ActiveSheet.ChartObjects.Add(Left:=650, _
Width:=600, _
Top:=80, _
Height:=250)
Sh.Select
Set cht = ActiveChart
With cht
.SetSourceData Source:=Rng
.ChartType = xlColumnClustered
cht.Axes(xlSecondary).TickLabels.NumberFormat = "0.%"
End With
cht.SeriesCollection(6).Name = " % Missing "
cht.SeriesCollection(7).Name = " % OnTime"
cht.SeriesCollection(8).Name = " % Delayed"
cht.SeriesCollection(6).HasDataLabels = True
cht.SeriesCollection(7).HasDataLabels = True
cht.SeriesCollection(8).HasDataLabels = True
cht.SeriesCollection(1).Format.Fill.ForeColor.RGB = RGB(255, 255, 255) '<~~ Red
cht.HasTitle = True
cht.ChartTitle.Text = "Result "
End Sub
You can combine 2 range into 1 range
Dim Rng As Range
Dim Rng_A As Range
Dim Rng_FH As Range
Set Rng_A = ActiveSheet.Range("A2:A52")
Set Rng_FH = ActiveSheet.Range("F2:H52")
Set Rng = Union(Rng_A, Rng_FH)

VBA - Multiple series to a chart

I'm trying to make add two series to a single XYscatter chart via loop. Currently, my code creates two charts. The X values are constant but the Y values change so I added them to an array to preserve them.
Sub test()
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("Sheet1")
Dim thearray(9) As Double
Dim chrt As Chart
Dim n As Integer, i As Integer, q As Integer
For q = 1 To 2
For i = 0 To 9
thearray(i) = WorksheetFunction.RandBetween(1, 20)
Next
Set chrt = sh.Shapes.AddChart.Chart
With chrt
.ChartType = xlXYScatterLines
.SeriesCollection.NewSeries
.SeriesCollection(1).Name = "TEST"
.SeriesCollection(1).XValues = Range("B2:K2")
.SeriesCollection(1).Values = thearray
.SeriesCollection(1).MarkerSize = 4
For n = .SeriesCollection.Count To 2 Step -1
.SeriesCollection(n).Delete
Next n
End With
Next
End Sub
I appreciate any help offered.
Edit: I tried changing
.SeriesCollection(1)
To
.SeriesCollection(q)
But it doesn't work.
EDIT2: I figured it out. I took
Set chrt = sh.Shapes.AddChart.Chart
Out of the loop and replaced 1 with q in .SeriesCollection
The code that works.
Sub test()
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("Sheet1")
Dim thearray(9) As Double
Dim chrt As Chart
Dim n As Integer, i As Integer, q As Integer
Set chrt = sh.Shapes.AddChart.Chart
For q = 1 To 2
For i = 0 To 9
thearray(i) = WorksheetFunction.RandBetween(1, 20)
Next
With chrt
.ChartType = xlXYScatterLines
.SeriesCollection.NewSeries
.SeriesCollection(q).Name = "HFF " & q
.SeriesCollection(q).XValues = Range("B2:K2")
.SeriesCollection(q).Values = thearray
.SeriesCollection(q).MarkerSize = 4
For n = .SeriesCollection.Count To 3 Step -1
.SeriesCollection(n).Delete
Next n
End With
Next
End Sub

VBA chart position changes when rows inserted

I wrote the following code to add a chart and position it on a worksheet with data on it:
Dim sh As Worksheet
Dim chrteit As Chart
lastrows = Range("A2").End(xlDown).Row
Set sh = ActiveWorkbook.Worksheets("TraceTable")
Set chrteit = sh.Shapes.AddChart.Chart
With chrteit
.ChartType = xlXYScatter
.SeriesCollection.NewSeries
.SeriesCollection(1).XValues = sh.Range(Cells(2, 6), Cells(lastrows, 6))
.SeriesCollection(1).Values = sh.Range(Cells(2, 7), Cells(lastrows, 7))
.HasTitle = True
.ChartTitle.Text = "EIT"
.Parent.Height = Range("N2:N14").Height
.Parent.Width = Range("N2:T2").Width
.Parent.top = Range("N2").top
.Parent.Left = Range("N2").Left
End With
The problem is, later in my module I have a macro that will an entire row between two data points if the two data points are different, and it is as follows:
Private Sub Dividers()
Dim DividerRange As Range, lastrow As Long, k As Integer, counter As Integer
lastrow = Range("C2").End(xlDown).Row
Set DividerRange = Range(Cells(2, 3), Cells(lastrow, 3))
counter = 0
For k = 2 To DividerRange.Count
If DividerRange(k + counter).Value <> DividerRange(k + counter - 1).Value Then
DividerRange(k + counter).EntireRow.Insert
counter = counter + 1
Else
End If
Next k
End Sub
By adding the entire row, it changes the height of my graph and it's position. I want it to be a fixed position, how can I do this? I would PREFER not to change the second code, but rather the first but let me know any solutions you guys have, Thanks!
Add this line to the first procedure:
chrteit.Placement = xlFreeFloating
This is the same as right-click, format chart area, properties: Don't move or size with cells.
|
Or you could place that method inside the With block, thusly:
With chrteit
.ChartType = xlXYScatter
.SeriesCollection.NewSeries
.SeriesCollection(1).XValues = sh.Range(Cells(2, 6), Cells(lastrows, 6))
.SeriesCollection(1).Values = sh.Range(Cells(2, 7), Cells(lastrows, 7))
.HasTitle = True
.ChartTitle.Text = "EIT"
.Parent.Height = Range("N2:N14").Height
.Parent.Width = Range("N2:T2").Width
.Parent.top = Range("N2").top
.Parent.Left = Range("N2").Left
.Placement = xlFreeFloating
End With