Using charts with VBA - vba

I'm trying to generate two charts using VBA. The problem is most examples use ActiveChart but I want multiple charts on multiple sheets. If I inserted a blank chart how do I rename that chart to reference it. I don't want a new chart to be generated each time I run the macro and I want it to be in the sheet. I'm struggling with the code but am assuming it will be something like the code below. I've attached the desired graph (I made this through excel, but I need to do it through VBA).
macro1()
lastrow2 = Sheet1.Cells(Sheet1.Rows.Count, "A").End(xlUp).Row
dim chart1 as chart
dim chart2 as chart ' ect
chart1.title = "test"
chart1.xaxis = sheet1.cell(lastrow2,1)
chart1.yaxis = "manhours"
end sub
using a the record function, i got the code commented below. I tried to change it but i'm still having issues
Sub Macro7()
Dim Chart2 As ChartObject
Dim chartb As Chart
Chart2 = Sheet1.chartb.SeriesCollection(2)
chartb.Select
Formula = "=SERIES(Master!R3C3,Master!R4C1:R18C1,Master!R4C3:R19C3,2)"
' ActiveChart.SeriesCollection(2).Select
' Selection.Formula =_
'"=SERIES(Master!R3C3,Master!R4C1:R18C1,Master!R4C3:R19C3,2)"
End Sub
I really just need this formula converted to i can reference my lastrow function and individual sheets
ActiveChart.SeriesCollection(2).Select
Selection.Formula =_
"SERIES(sheet1.cells(3,3),sheet1.cells(4,1):sheet1.cells(18,1)_
,sheet1.cells(4,3):sheet1.cells(4,19),2"
' Selection.Formula"_
' =SERIES(Master!R3C3,Master!R4C1:R18C1,Master!R4C3:R19C3,2)"

this was what i was trying to do. It declares the sheet name and references an existing chart named chart 1.
Dim cht As ChartObject
Dim rng As Range
Set cht = Sheets("Master").ChartObjects("Chart 1")
Set rng = Sheets("Master").Range("A4", Range("D4").End(xlDown).Offset(-1))
cht.Chart.SetSourceData Source:=rng
cht.Chart.HasTitle = True
cht.Chart.ChartTitle.Text = "Bird Report - By Cost Code/Activity" ' title
cht.Chart.SeriesCollection(1).Name = "=Master!$B$3"
cht.Chart.SeriesCollection(2).Name = "=Master!$C$3"
cht.Chart.SeriesCollection(3).Name = "=Master!$D$3"

Related

Add and remove rows for bar chart created by VBA

I need to create Bar chart in Excel VBA. I used the code below, but when I am ADDING or DELETING A ROW it is not working.
I need that chart on fixed range (K1). Because when I am calculating for the second time it creates another chart.
How can I change the code to prevent a new chart being added when I adjust the data source?
Private Sub CommandButton2_Click()
Sheets("Sheet7").Range("F2:H12").Select
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlBarClustered
ActiveChart.SetSourceData Source:=Range("Sheet7!$F$2:$H$12")
ActiveChart.SeriesCollection(1).Name = "=Sheet7!$G$1"
ActiveChart.SeriesCollection(2).Name = "=Sheet7!$H$1"
End Sub
In the sample code below it checks to see if a chart called TheChart already exists, and if not, creates a new one. You can now add and remove rows and the chart should will update. Additionally, if you add a new row at the bottom and click the button it will redraw TheChart without creating a new one.
The chart is always located at the top-left of K1 per the rngChartTopLeft variable - which you can adjust if required.
The code assumes that it is running in a Sheet module (hence Set ws = Me) and if you were running it in a standard module you can set the sheet with Set ws = ThisWorkbook.Worksheets("your_sheet").
Option Explicit
Private Sub CommandButton1_Click()
Dim ws As Worksheet
Dim chto As ChartObject
Dim rngChartTopLeft As Range
Dim rngData As Range
' assumes the code is in a sheet object
Set ws = Me
' top left of chart
Set rngChartTopLeft = ws.Range("K1")
' create chart or get existing chart
If ws.ChartObjects.Count = 0 Then
Set chto = ws.ChartObjects.Add( _
Left:=rngChartTopLeft.Left, _
Width:=500, _
Top:=rngChartTopLeft.Top, _
Height:=500)
chto.Name = "TheChart"
Else
Set chto = ws.ChartObjects("TheChart")
End If
' set chart type
chto.Chart.ChartType = xlBarClustered
' get data range per last row of data
Set rngData = ws.Range("F2:G" & ws.Cells(ws.Rows.Count, "G").End(xlUp).Row)
' set new chart range
chto.Chart.SetSourceData rngData
End Sub
please check the below code:
Option Explicit
Private Sub CommandButton1_Click()
Dim mychart As Shape
Dim lastrow As Long
lastrow = Sheet7.Cells(Rows.Count, "F").End(xlUp).Row
For Each mychart In ActiveSheet.Shapes
If mychart.Name = "CommandButton1" Then GoTo exit_
mychart.Delete
exit_:
Next
Sheets("Sheet7").Range("F2:H" & lastrow).Select
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlBarClustered
ActiveChart.SetSourceData Source:=Range("Sheet7!$F$2:$H$" & lastrow)
ActiveChart.SeriesCollection(1).Name = "=Sheet7!$G$1"
ActiveChart.SeriesCollection(2).Name = "=Sheet7!$H$1"
End Sub

Chart not generated from vba code unless another chart already exists

I have a table in excel with multiple columns and rows. I have written this simple code to generate a Line chart from my table:
Sub DrawLine()
Dim cht As ChartObject
For Each cht In Worksheets(Sheets.Count).ChartObjects
cht.Chart.Type = xlLine
Next cht
End Sub
However, when I execute this code I can't see my chart, unless if I have another chart on my worksheet generated manually. In this case, when I execute the code, the chart changes to display what my sub is doing.
Does anyone know what could be the problem ?
You're not creating any charts with your code. What you're doing is changing any chart currently there to become a line chart.
There are many things missing in your code. Pl see example below.
Sub Test()
Dim LastRow As Long
Dim Rng1 As Range
Dim ShName As String
With ActiveSheet
LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
Set Rng1 = .Range("A2:A" & LastRow & ", B2:B" & LastRow)
ShName = .Name
End With
Charts.Add
With ActiveChart
.ChartType = xlLine
.SetSourceData Source:=Rng1
.Location Where:=xlLocationAsObject, Name:=ShName
End With
End Sub

Why does my code work for ActiveChart but not for the chart name?

At the moment, my code reads:
Private Sub Worksheet_Activate()
' This Macro Code for this sheet updates the x axis range for the graph in 'Dashboard' automatically
Dim V_900_SPC As Worksheet
Set V_900_SPC = Sheets("AR Data 900A SPC")
Dim chart1values As String, chart1_xvalues As String
chart1values = Cells(2, 10)
chart1_xvalues = Cells(3, 10)
V_900_SPC.ChartObjects("Chart 1").Activate
ActiveChart.SeriesCollection(1).Values = "='AR Data 900A SPC'!" & chart1values
ActiveChart.SeriesCollection(1).XValues = "='AR Data 900A SPC'!" & chart1_xvalues
Cells(1, 1).Activate
End Sub
However if I replace "ActiveChart." with "V_900_SPC.ChartObjects("Chart 1")." (and obviously delete the line that activates the chart object) then the code doesn't work. What's going on??
Try:
V_900_SPC.ChartObjects("Chart 1").Chart.SeriesCollection(1).Values = "='AR Data 900A SPC'!" & chart1values
The reasoning being that ChartObject and Chart isn't the same thing. ChartObject is a container for Chart, and SeriesCollection belongs to Chart.
I recently made a post on SO that is relevant to this, that also contains more information and examples, as well as MSDN links.

VBA Excel 2010 - Assign unknown chart to varible

Im trying to set a chart to a varible, however since I have multiple charts in my spreadsheet I need to be able to activate a chart and assign it to a varible.
Ffor the record ChartHandel = ActiveSheet.ChartObject(1) doesn't work,I have also tried .Shape(1) and Chart("Name of chart") and these too dont work
Dim ChartHandel2 As Chart
ActiveSheet.ChartObjects(1).Activate
ChartHandel2 = ActiveChart
Even this gets error '91, Object Variable or with block varible not set' which it looks like it should work and I was sure I had had this working at one point(as a workaround)
My question is basicly can you assign a chart to a varible if it isnt active (and if possible how)?
when assigning object you must use the Set keyword in the left part of the assignment statement
furthemore Chart object is a member of the ChartObject object
here's a small example of dealing with them
Option Explicit
Sub ChartObjects()
Dim chartObj As ChartObject
With ThisWorkbook.Worksheets("charts")
For Each chartObj In .ChartObjects
With chartObj ' to deal with current "ChartObject" object
With .Chart ' to deal with "Chart" object of "ChartObject" object
.ChartType = xlXYScatter ' or another XlChartType Enumeration (https://msdn.microsoft.com/en-us/library/office/ff838409.aspx)
MsgBox .ChartArea.Name
.HasLegend = False
.ChartTitle.Caption = "chart title you need"
End With
End With
Next chartObj
End With
End Sub
You can use for each to loop through charts if you arent sure with indexes. Something like this
Sub testChart()
Dim testSheet As Worksheet
Set testSheet = Sheets("Sheet1")
Dim myChart As ChartObject
Dim chartVariable As Chart
With testSheet
For Each myChart In .ChartObjects
Set chartVariable = myChart.Chart
Next myChart
End With
End Sub
warning: its only demo version, it will need further changes depends on what you need

Change Height of PivotChart to match height of PivotTable

I work heavily with PivotCharts, but have absolutely zero VBA experience. I have excel templates that are uploaded to a database, then can be downloaded as a report with the data from that database. I have a pivotTable/PivotChart combo on one sheet. Sometimes the table has 5 rows of data, and sometimes is has 1200 rows of data, depending on the database, timeframe, etc.
What I'd like to do, is have the chart take up the same number of rows as the table + 3 in height, and always display in D3:J3 for width and starting position. This aligns the data with the charts.
I have found a similar ? from last year here: Resize pivot chart when selecting different less/more values
It has not gotten me any results (or I'm doing something wrong).
Relevant info: table/chart is on Sheet4 ("Summary"), and under PivotTable Options, it is called "IdleSummary".
I appreciate any help that can be given, thanks!
One way to do it, is to use a range object to size your chart like so:
Sub test()
Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets("Summary")
Dim vPiv As PivotTable
Dim vRowCount As Long
Dim graphSizer As Range
Dim theChart As ChartObject
Set vPiv = ws.PivotTables("IdleSummary")
vRowCount = ws.Range(vPiv.TableRange2.Address).Rows.Count + 3
Set graphSizer = ws.Range("D3:J" & vRowCount)
Set theChart = ws.ChartObjects.Add(Left:=graphSizer.Left, Top:=graphSizer.Top, Width:=graphSizer.Width, Height:=graphSizer.Height)
With theChart.Chart
.SetSourceData vPiv.TableRange2
.ChartType = xlArea 'replace with desired chartType
End With
End Sub
EDIT, to answer comments:
Modifying the above code, and using the worksheet PivotTableUpdate event you could do like so:
Private Sub Worksheet_PivotTableUpdate(ByVal Target As PivotTable)
If Target.Name = "IdleSummary" Then
Call Resize
End If
End Sub
Sub Resize()
Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets("Summary")
Dim vPiv As PivotTable
Dim vRowCount As Long
Dim graphSizer As Range
Dim theChart As ChartObject
Dim charObj As ChartObject
Set vPiv = ws.PivotTables("IdleSummary")
vRowCount = ws.Range(vPiv.TableRange2.Address).Rows.Count + 3
Set graphSizer = ws.Range("D3:J" & vRowCount)
Set theChart = ws.ChartObjects(1)
With theChart.Chart.Parent
.Left = graphSizer.Left
.Top = graphSizer.Top
.Width = graphSizer.Width
.Height = graphSizer.Height
End With
End Sub
This is assuming you have just one chart, else you can replace the index (1) with the chart name, e.g. ("Chart 1"). If you interested in reading about events you can find an introduction here: http://www.cpearson.com/excel/Events.aspx