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
Related
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
I would like to loop through four sets of data arranged in rows. I'd like to make a chart from each dataset and apply a trendline, let excel show the equation of the trendline and copy the "m" part of the equation of the trendline (y=mx+b) in a cell after the end of the row. I recorded a macro while doing the whole process with the first dataset and modified it a little to introduce the loop. My problem is that though the code creates the four charts with the trendlines and equations, but it copies the "m" value of the first chart after all the four lines. I tried to fix the problem, but failed. Now - in the same form, so I guess that it was the oroginal problem - this code prints after each dataset the first row of whatever is copied to the clipboarb from the code and after all the four datasets, and the remaining part of the copied part under it (only once).
It might seem to make no sense, so it is best to try this code in the following way: Fill the range C3:K6 with numbers and run the code. After, copy the code to the clipboard and run the code again.
So, my thwo questions are: 1. How to make the code to copy the "m" value of each dataset after them and 2. Why does it behave so crazy now?
Sub Lasttest()
Dim i As Integer
For i = 3 To 6
Range("C" & i).Select
ActiveCell.Range("A1:I1").Select
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlXYScatter
ActiveChart.SetSourceData Source:=ActiveCell.Range("Sheet1!A1:I1")
ActiveChart.SeriesCollection(1).Select
ActiveChart.SeriesCollection(1).Trendlines.Add
ActiveChart.SeriesCollection(1).Trendlines(1).Select
Selection.DisplayEquation = True
ActiveChart.SeriesCollection(1).Trendlines(1).DataLabel.Select
ActiveCell.Offset(0, 10).Range("A1").Select
ActiveSheet.Paste
Next
End Sub
Ferenc
Did some code cleanup and this works for me:
Sub InsertChartsAndPrintEquations()
Dim i As Integer
Dim rng As Range
For i = 3 To 6
Set rng = Range("C" & i & ":K" & i)
' insert chart
ActiveSheet.Shapes.AddChart.Select
With ActiveChart
.ChartType = xlXYScatter
.SetSourceData Source:=rng
With .SeriesCollection(1)
.Trendlines.Add
.Trendlines(1).DisplayRSquared = False
.Trendlines(1).DisplayEquation = True
End With
' grab & insert equation
With ActiveSheet.ChartObjects(i - 2)
.Activate
Range("M" & i) = .Chart.SeriesCollection(1).Trendlines(1).DataLabel.Text
End With
End With
Next
End Sub
Apparently, you have to use a range object when defining the source data and you have to activate the chart before you can grab the equation from it.
Edit #1
This code should be more robust:
Sub InsertChartsAndPrintEquations2()
Dim i As Integer
Dim rng As Range
Dim cht As ChartObject
' add charts
For i = 3 To 10
Set rng = Range("C" & i & ":K" & i)
ActiveSheet.Shapes.AddChart.Select
With ActiveChart
.ChartType = xlXYScatter
.SetSourceData Source:=rng
With .SeriesCollection(1)
.Trendlines.Add
.Trendlines(1).DisplayRSquared = False
.Trendlines(1).DisplayEquation = True
End With
End With
Next
' grab & insert equations
i = 3 ' set to same starting value as in the for next loop above
For Each cht In ActiveSheet.ChartObjects
cht.Activate
Range("M" & i) = cht.Chart.SeriesCollection(1).Trendlines(1).DataLabel.Text
i = i + 1
Next cht
End Sub
I'm having some problems using VBA in Excel to create charts using dynamic ranges. What I need to do is chart the results of each of the compounds for each sample. Both the number of samples and the number of compounds can vary. An example of the datasheet can be found here.
A sample of the code I tried to write, however my range has not been properly defined:
Sub Graph()
Dim r As Range
Dim c As Range
Dim wks As Worksheet
Set wks = ActiveSheet
'
' Graph Macro
'
Set r = Range("B2").End(xlDown)
Set c = Range("D2").End(xlToRight)
ActiveSheet.Shapes.AddChart2(201, xlColumnClustered).Select
ActiveChart.SetSourceData Source:=Range("wks!$B$2:B" & r, "wks!$P$2:P" & c)
'
End Sub
Could anyone point me in the right direction?
Try this sub instead:
Sub Graph()
ActiveSheet.Shapes.AddChart2(201, xlColumnClustered).Select
With [a1].CurrentRegion
ActiveChart.SetSourceData Source:=Range(.Resize(, 1).Offset(, 1), .Offset(, 3).Resize(, .Columns.Count - 3))
End With
End Sub
This program is intended to be used to copy data from a pivot table on another sheet (varying number of rows for each data set). Each set of pasted data is used to create its own waterfall chart, for which I have templates already made on a different sheet.
There are a couple of issues I am having with this code.
1) For some reason, it no longer runs (I refactored the code from a macro) and gives me the error 'Compile Error: Sub or Function not defined'
- I've tried making a new module and a new macro but to no avail
2) Also, I want to change the range that the chart graphs based on the size of the data set. Here's what I have currently hardcoded:
Selection.Formula = "=SERIES(,Sheet5!R8C1:R17C1,Sheet5!R8C4:R17C4,1)"
So, Sheet5!R8C1:R17C1 would need to become SheetN!Start:End
Complete Code below:
Sub WF_New_Sheet()
Dim copyFrom As Range
Dim wS As Worksheet 'use as current worksheet
Dim cht As Chart
'Paste and format data
Set wS = Sheets("Pivot 1")
copyFrom = wSRange("C82:D90")
Set wS = Sheets.Add(After:=Worksheets.Count)
wS.Range("A9").Select
Selection.PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Operation:= _
xlNone, SkipBlanks:=False, Transpose:=False
Selection.Columns.AutoFit
Application.CutCopyMode = False
Range("A9", Range("B" & Rows.Count).End(xlUp).Address).sort Key1:=[b9], _
Order1:=xlAscending, Header:=xlNo 'sorts in 2 lines
Range("A8").Value = "Total"
Range("B8").Value = "=SUM(R[1]C:R[9]C)"
Dim rNum As Integer: rNum = Range("A9", Range("B" & Rows.Count).End(xlUp).Address).Rows.Count
'Paste data template and chart
copyFrom = Sheets("Sheet4").Range("D2:G15") 'sheet 4 is hardcoded and contains templates
wS.Range("D6").Resize(copyFrom.Rows.Count).Value = copyFrom.Value
Sheets("Sheet4").ChartObjects("Chart 1").Activate
Application.CutCopyMode = False
ActiveChart.ChartArea.Copy
wS.Range("I7").Select
ActiveSheet.Paste
ActiveSheet.ChartObjects("Chart 1").Activate
'Set appropriate ranges for chart data; format data for display
ActiveChart.SeriesCollection(2).Select
Selection.Formula = "=SERIES(,Sheet5!R8C1:R17C1,Sheet5!R8C5:R17C5,2)" 'How to make this dynamic?
ActiveChart.SeriesCollection(1).Select
Selection.Formula = "=SERIES(,Sheet5!R8C1:R17C1,Sheet5!R8C4:R17C4,1)" 'How to make this dynamic?
Range("B8").Value = "=SUM(R[1]C:R[9]C)*-1"
With Range("b9", "b17")
.Value = Evaluate(.Address & "*" & -1)
End With
End Sub
*edit code fixed to include sub and end sub
Figured out how to adjust the chart size. Added these lines:
Dim rowStart As Integer: rowStart = InputBox("Please enter starting row of your dataset.")
Dim rowEnd As Integer: rowEnd = InputBox("Please enter ending row of your dataset.")
Set copyFrom = Sheets("Pivot 1").Range(Sheets("Pivot 1").Cells(rowStart, colOne), Sheets("Pivot 1").Cells(rowEnd, colOne))
Set wS = Sheets.Add
wS.Move After:=Sheets(ActiveWorkbook.Sheets.Count)
wS.Range("A9").Resize(copyFrom.Rows.Count, copyFrom.Columns.Count).Value = copyFrom.Value
Set copyFrom = Sheets("Pivot 1").Range(Sheets("Pivot 1").Cells(rowStart, colTwo), Sheets("Pivot 1").Cells(rowEnd, colTwo))
wS.Range("B9").Resize(copyFrom.Rows.Count, copyFrom.Columns.Count).Value = copyFrom.Value
I'm trying to make a macro that will run through an excel sheet and go through a set of rows and make a graph for each row.
I've got a bit of code that kind of does what I need, but puts it all on one graph when I need an individual graph for each row.
`Dim i As Integer
Dim ws As Worksheet
Set ws = Sheets("Master Sheet")
For Row = 1 To 20
Dim my_cell
Dim rng As Range
Set rng = Sheets("Master Sheet").Range("J8:Y8")
For Each my_cell In rng
If my_cell <> "" Then
ActiveSheet.Shapes.AddChart.Select
ActiveChart.SetSourceData Source:=Range("'Master Sheet'!$J$8:$Y$8")
ActiveChart.ChartType = xlLineMarkers
ActiveChart.Location Where:=xlLocationAsNewSheet
ActiveSheet.Activate
ActiveChart.PlotArea.Select
ActiveChart.SeriesCollection(1).XValues = "='Master Sheet'!$J$2:$Y$2"
ActiveChart.SeriesCollection(1).Name = "=""FP"""
ActiveChart.SeriesCollection.NewSeries
ActiveChart.SeriesCollection(2).Name = "=""Progress"""
ActiveChart.SeriesCollection(2).Values = _
"='Master Sheet'!$J$8,'Master Sheet'!$AF$8:$AH$8"
ActiveChart.DisplayBlanksAs = xlInterpolated
ActiveSheet.Activate
ActiveChart.ChartArea.Select
Else
Exit For ' Blank cell found, exiting
End If
Next
Next Row
End Sub`
If anyone can give me a hand to see where I'm going wrong that would be great.
Not really sure you have structured your For Next and For Each loops well. Ideally you'd like to step through ranges and actually use the value you define in your For Each statement. Without seeing your workbook I just adapted a small range of data to simulate creating a graph.
I just took your same code and generate a graph on the same worksheet for each row of numbers. You can take these principles and apply it to your logic.
Sub test()
Dim Row As Integer
Dim ws As Worksheet
Dim rng As Range
Set ws = Sheets("Sheet1") 'Change this to: Set ws = Sheets("Master Sheet")
For Row = 1 To 6
Set rng = ws.Range("B1:D1").Offset(Row, 0) 'Change to (I'm guessing here): ws.Range("$J$7:$Y$7").Offset(Row, 0)
ActiveSheet.Shapes.AddChart.Select
ActiveChart.SetSourceData Source:=Range(ws.Name & "!" & rng.Address)
ActiveChart.ChartType = xlLineMarkers
ActiveChart.PlotArea.Select
ActiveChart.SeriesCollection(1).XValues = "='Sheet1'!$B$1:$D$1" 'Change to "='Master Sheet'!$J$2:$Y$2"
ActiveChart.SeriesCollection(1).Name = ws.Range("A1").Offset(Row, 0).Value 'Change this to whatever you want to name the graphs. This is currently set to dynamicly name each graph by the series name set in Column A.
'ActiveChart.Location Where:=xlLocationAsNewSheet 'uncomment this line to put on new sheet
'ws.Select 'Need to go back to worksheet
Next Row
Set ws = nothing
Set rng = nothing
End Sub
Here are a couple links that may help;
Creating and positioning graphs in a for loop VBA and
Excel VBA: Chart-making macro that will loop through unique name groups and create corresponding charts?
Google also has many other links.
If I've misunderstood your question or need anything else please let me know.
Cheers