How to create Chart with source from a different Worksheet - excel

Before coming to ask I searched the web a lot, and the answers I found did not solve the problem.
The "Data" Worksheet is in the same Workbook as the "Reports" Worksheet.
This is the part of my code that matters for this question:
Private Function CreateChart(ByVal DataRow As Integer, ByVal DataCol As Integer)
Dim ChartRowOffset As Integer
Charts.Add
ActiveChart.ChartType = xlPie
ActiveChart.SetSourceData Source:=Sheets("Data").Range(Cells(2, DataCol), Cells(DataRow - 1, DataCol + 1)), PlotBy:=xlColumns
ActiveChart.Location Where:=xlLocationAsObject, Name:="Report"
ActiveChart.HasTitle = True
ActiveChart.ChartTitle.Select
ActiveChart.ChartTitle.Text = ThisWorkbook.Sheets("Data").Cells(1, DataCol).Value
If DataCol > 1 Then
ChartRowOffset = (DataCol - 1) * 2
Else
ChartRowOffset = 2
End If
With ActiveChart.Parent
.Top = ThisWorkbook.Sheets("Report").Cells(ChartRowOffset, 1).Top
.Left = ThisWorkbook.Sheets("Report").Cells(ChartRowOffset, 1).Left
End With
End Function
I am getting error code 1004 "Application-defined or Object-defined error" when I try to select a source from a different worksheet in this line:
ActiveChart.SetSourceData Source:=Sheets("Data").Range(Cells(2, DataCol), Cells(DataRow - 1, DataCol + 1)), PlotBy:=xlColumns
If I do it without Sheets("Data"), it gives no error and creates the chart, but it selects cells from the "Reports" sheet, not the Worksheet I need.
I tried selecting the "Data" Worksheet, activating it, nothing worked so far.
Any help would be appreciated.

Please try the following to fix the referencing style issue -
ActiveChart.SetSourceData Source:= _
Sheets("Data").Range(Cells(2, DataCol).Address, Cells(DataRow - 1, DataCol + _
1).Address), PlotBy:=xlColumns
The infamous Error: 1004 will haunt you to the death over stuff like this. Also, if I may, your code would be faster, shorter, and easier to read if you used With statements wherever applicable.
Ex:
With ActiveChart
.Location Where:=xlLocationAsObject, Name:="Report"
.HasTitle = True
.ChartTitle.Select
.ChartTitle.Text = ThisWorkbook.Sheets("Data").Cells(1, DataCol).Value
End WIth
-******UPDATE*******-
After testing, I found I had to re-Set the variable... Seemed crazy to me, however, tested and worked for me:
Private Function CreateChart()
Dim cht As Chart
Dim rng As Range
Set rng = ThisWorkbook.Worksheets("Sheet1").UsedRange
Set cht = Charts.Add
With cht
.SetSourceData Source:=rng, PlotBy:=xlColumns
.ChartType = xlPie
.Location Where:=xlLocationAsObject, Name:="Sheet1"
End With
Set cht = ActiveChart
With cht
.HasTitle = True
.ChartTitle.Text = ThisWorkbook.Sheets(1).Name
End With
End Function
Danny,
ExcelVBADude

Related

Finding and highlighting the last data point in a series/column VBA

I have a macro for creating a graph and part of it identifies and highlights the final data point like below:
This works all well and good when there's data in the final row of a column, but in some cases the final row is empty therefore no point is highlighted like so:
I was wondering if there was a way to make it highlight the last point that has actual data, so even though the last row may be empty, it highlights the last row with data.
Could the following be incorporated into my code? it finds the last data point in column B:
Dim lRow As Long
lRow = Cells(Rows.Count, 2).End(xlUp).Row
Here is my code:
With co.Chart
.FullSeriesCollection(1).ChartType = xlXYScatter
.FullSeriesCollection(1).AxisGroup = 1
.FullSeriesCollection(2).ChartType = xlLine
.FullSeriesCollection(2).AxisGroup = 1
.SetSourceData Source:=my_range
.Axes(xlCategory).TickLabels.NumberFormat = "m/yy"
'highlight final dot of data
.FullSeriesCollection(1).Points(.FullSeriesCollection(1).Points.Count).ApplyDataLabels Type:=xlShowValue
.FullSeriesCollection(1).Points(.FullSeriesCollection(1).Points.Count).MarkerSize = 7
.FullSeriesCollection(1).Points(.FullSeriesCollection(1).Points.Count).MarkerStyle = xlCircle
.FullSeriesCollection(1).Points(.FullSeriesCollection(1).Points.Count).MarkerBackgroundColorIndex = 6
.FullSeriesCollection(1).Points(.FullSeriesCollection(1).Points.Count).MarkerForegroundColorIndex = 1
.HasTitle = True
.ChartTitle.Text = t
ResolveSeriesnames co.Chart
.Location Where:=xlLocationAsObject, Name:="Graphs"
I found this code on https://peltiertech.com/label-last-point-for-excel-2007/ and made a couple adjustments which works
Sub LastPointLabel2()
Dim srs As Series
Dim iPts As Long
Dim cht As ChartObject
Dim vYVals As Variant
Dim vXVals As Variant
Set ws = ActiveSheet
If ActiveChart Is Nothing Then
MsgBox "Select a chart and try again.", vbExclamation
Else
Application.ScreenUpdating = False
For Each cht In ws.ChartObjects
Set srs = cht.Chart.SeriesCollection(1)
With srs
vYVals = .Values
'vXVals = .XValues
' clear existing labels
.HasDataLabels = False
For iPts = .Points.Count To 1 Step -1
If Not IsEmpty(vYVals(iPts)) Then
' add label
srs.Points(iPts).ApplyDataLabels _
ShowSeriesName:=False, _
ShowCategoryName:=False, ShowValue:=True, _
AutoText:=True, LegendKey:=False
Exit For
End If
Next
End With
Next
' legend is now unnecessary
Application.ScreenUpdating = True
End If
End Sub

VBA Compile error: Syntax error while trying to set range for chart

I am trying to make a macro that creates a chart from three selected columns. It works fine but I am trying to make column 1 (A:A) always apart of the range and then just select the remaining to columns I need as there are multiple charts i need to make from a data sheet
Sub Charter()
Dim my_range As Range
Set my_range = ("A:A", Selection)
ActiveSheet.Shapes.AddChart2(201, xlColumnClustered).Select
ActiveChart.FullSeriesCollection(1).ChartType = xlColumnClustered
ActiveChart.FullSeriesCollection(1).AxisGroup = 1
ActiveChart.FullSeriesCollection(2).ChartType = xlLine
ActiveChart.FullSeriesCollection(2).AxisGroup = 1
ActiveChart.FullSeriesCollection(1).ChartType = xlXYScatter
ActiveChart.FullSeriesCollection(1).AxisGroup = 1
ActiveChart.SetSourceData Source:=my_range
Cells(1, 1).Select
End Sub
I get an
"Compile error: Syntax error"
at the Set my_range = ("A:A", Selection)
Perhaps use Union:
Set my_range = Union(Selection, ActiveSheet.Range("A:A"))

How can I plot charts in excel at a predefined location, everytime I run a macro to plot the charts?

I need to plot charts at a predefined position in my worksheet when I run the macro to plot the charts. The problem is that the charts are automatically plotted in a weird manner and I don't like that. I want to make sure I can predefine the exact positions at which I want the charts to be plotted on running the macro. I have attached 2 images here, 1 image shows how it's currently plotted and the other shows how I want the charts to be plotted. Any kind of help would be highly appreciated.
This is how I want the charts to be shown on the sheet:
This is how it's currently showing up, with one pie chart overlapping the other and the line chart obscuring the macro buttons as well
This is the code I used, starting with the line chart, followed by the pie charts. I'm new to VBA and coding so please excuse the code structure.
' CHART Code
Dim chart As chart
Dim k As Integer
Dim p As Integer
Dim j As Integer
Dim arrDEM() As Long
Dim arrDATE() As Integer
ReDim arrDEM(1 To 65) As Long
ReDim arrDATE(1 To 65) As Integer
Dim DEM As Integer
j = findcell.Select
ActiveCell.Offset(0, 1).Select
For DEM = 1 To 65
arrDEM(DEM) = ActiveCell.Value
ActiveCell.Offset(0, 1).Select
Next DEM
Debug.Print arrDEM(65)
Range("B1").Activate
For p = 1 To 65
arrDATE(p) = ActiveCell.Value
ActiveCell.Offset(0, 1).Select
Next p
Debug.Print arrDATE(65)
Range("B31:B031") = arrDEM
Range("B31:B031").Select
Set cht1 = ActiveSheet.ChartObjects.Add(Left:=200, Width:=4500, Top:=200, Height:=4000)
ActiveSheet.Shapes.AddChart.Select
Set chart = ActiveChart
chart.ChartType = 4
chart.SeriesCollection(1).Name = x
chart.SeriesCollection(1).XValues = arrDATE
chart.SeriesCollection(1).Values = arrDEM
With ActiveChart
'chart name
.HasTitle = True
.ChartTitle.Characters.Text = "Demand Distribution"
'X axis name
.Axes(xlCategory, xlPrimary).HasTitle = True
.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "Weeks"
'y-axis name
.Axes(xlValue, xlPrimary).HasTitle = True
.Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "Demand"
'Copy chart from Original file
ActiveChart.ChartArea.Copy
'Paste chart in destination file
Worksheets("Model Calculations").Paste
'Deleting Charts
Worksheets("Sheet1").ChartObjects.Delete
'Activating destination chart
Worksheets("Model Calculations").Activate
Application.DisplayAlerts = False
End With
' PieC Macro
Range("C10:D11").Select
ActiveSheet.Shapes.AddChart2(262, xl3DPie).Select
ActiveChart.SetSourceData Source:=Range("'Model Calculations'!$C$10:$D$11")
With ActiveChart
'chart name
.HasTitle = True
.ChartTitle.Characters.Text = "Continuous Review"
' .Name = "Continuous Chart"
End With
' PieP Macro
'
Range("C10,D10,C12,D12").Select
ActiveSheet.Shapes.AddChart2(262, xl3DPie).Select
ActiveChart.SetSourceData Source:=Range("'Model Calculations'!$C$10,'Model Calculations'!$D$10,'Model Calculations'!$C$12,'Model Calculations'!$D$12")
With ActiveChart
'chart name
.HasTitle = True
.ChartTitle.Characters.Text = "Periodic Review"
'.Name = "Periodic Chart"
End With
End Sub
Your code could use some help in a number of ways. To answer your question, I'll ignore all that, and fix one piece of code. Here is what I'm replacing:
' PieC Macro
Range("C10:D11").Select
ActiveSheet.Shapes.AddChart2(262, xl3DPie).Select
ActiveChart.SetSourceData Source:=Range("'Model Calculations'!$C$10:$D$11")
With ActiveChart
'chart name
.HasTitle = True
.ChartTitle.Characters.Text = "Continuous Review"
' .Name = "Continuous Chart"
End With
I'll start by declaring and assigning a few variables, then create, populate, and position a chart.
Dim WkSht As Worksheet
Set WkSht = Worksheets("Model Calculations")
WkSht.Activate
Dim rChartData As Range
Set rChartData = WkSht.Range("C10:D11")
Dim rChartCover As Range
Set rChartCover = WkSht.Range("F10:K18")
Dim NewChart As Chart
Set NewChart = WkSht.Shapes.AddChart2(262, xl3DPie).Chart
With NewChart
.SetSourceData rChartData
With .Parent
.Left = rChartCover.Left
.Top = rChartCover.Top
.Width = rChartCover.Width
.Height = rChartCover.Height
End With
End With
You could replace this:
Set WkSht = Worksheets("Model Calculations")
WkSht.Activate
with this:
Set WkSht = ActiveSheet
to make it more general, and if you know the position and size of the resulting chart, you can plug those in instead of using the position and size of a given range (like I used rChartCover above).

How can I write a loop in vba for this code

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.

Get last cell with data in column in excel 2007

I'm trying to write a macro to create graphs in excel 2007. I don't know the number of cells that will be in the range for one of the series of data (it could be anywhere from 50 - 1000). I've googled this and I've found answers but they are all over the map and the few I've tried haven't helped me at all.
I'm a newb at vba macros but am an experienced programmer.
I've found examples such as:
Sub FindLast2()
x = ActiveSheet.UsedRange.Rows.Count
ActiveCell.SpecialCells(xlLastCell).Select
End Sub
I'm not sure if this works & if it does work how would I incorporate that into my macro
Here's my macro as it stands now:
Sub temp_graph_5()
'
' temp_graph_5 Macro
'
'
Sheets.Add After:=Sheets(Sheets.Count)
Sheets(2).Select
Sheets(2).Name = "Temperature"
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlLine
ActiveChart.SetSourceData Source:=Sheets(1). _
Range("B2:B324")
ActiveChart.SeriesCollection(1).Name = "=""Temperature"""
End Sub
The 'B324' is the section that I need to be variable.
Any help is greatly appreciated.
This code may help achieve what you need:
Sub temp_graph_5()
Dim myRng As Range
Dim lastCell As Long
//Get range to be plotted in chart
lastCell = Worksheets(1).Range("B2").End(xlDown).Row
Set myRng = Worksheets(1).Range("B2:B" & lastCell)
//Add worksheet and name as "Temperature"
Dim newSheet As Worksheet
Set newSheet = Worksheets.Add(After:=Worksheets(Worksheets.Count))
newSheet.Name = "Temperature"
newSheet.Select
//Add a new chart in Temperature and plot values from sheet 1
Charts.Add
With ActiveChart
.ChartType = xlLine
.SetSourceData Source:=myRng, PlotBy:=xlColumns
.Location Where:=xlLocationAsObject, Name:="Temperature"
End With
End Sub
sub test()
last_row_all = Range("A65536").End(xlUp).Row
msgbox last_row
end sub

Resources