I have a script that sets some ranges, then creates a chart. All goes well until .Axes(xlCategory, xlPrimary).Caption = "Time from Sent to Rec'd" where I get the error "Run-time error '438': Object doesn't support this property or method".
Here's my code:
Sub CreateChart()
dim avgWS as worksheet: set avgWS = activesheet
...[code here, setting the ranges and such]....
''' TIME TO CREATE THE CHART!!
with avgws
Dim newChart As Chart
' Set newChart = Charts.Add
Set newChart = Charts.Add.Location(xlLocationAsObject, avgWS.name)
With newChart
.ChartType = xlLineMarkers
.SeriesCollection.NewSeries
With .SeriesCollection(1)
.name = chartName
.Values = thePeopleChartValues
End With
.SeriesCollection.NewSeries
With .SeriesCollection(2)
.name = avgWS.Cells(1, dayLimitCol).Value
.Values = dayLimitValues
End With
.SeriesCollection.NewSeries
With .SeriesCollection(3)
.name = avgWS.Cells(1, overalltheAvgCol).Value
.Values = theAverages
End With
.HasTitle = True
.Axes(xlCategory).CategoryType = xlCategoryScale
.SetElement (msoElementPrimaryValueAxisTitleRotated)
.Axes(xlCategory, xlPrimary).Caption = "Time from the Sent to Shares Rec'd" '''' ERROR HERE!!
.SetElement (msoElementPrimaryCategoryAxisTitleAdjacentToAxis)
.Axes(xlCategory).Caption = "the Date"
.SetElement (msoElementChartTitleCenteredOverlay)
.Axes(xlCategory).Caption = "='CY 2014-15B Averages'!R1C2"
.SetElement (msoElementLegendRightOverlay)
.SetElement (msoElementLegendBottom)
End With
I've only included the Chart part, but if you would like/need more of the code just let me know. I have ranges and such set up, and get no errors there. It's only when I try to create the .Captions. If I walk through the code, via F8 and skip the three .caption lines, the chart gets created like I want....just how do I set those Axis captions? The macro recorder isn't much help (that's how I got to where I am now).
edit: Hm, if I use
.Axes(xlCategory, xlPrimary).HasTitle = True
.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "whatever whatever"
it sets the horizontal axis caption to "Whatever whatever". I guess I'm making progress, but I want that to be the vertical title, not horizontal and can't figure out how to do so.
Before you start formatting the axis title, create it:
.Axes(xlCategory, xlPrimary).HasTitle = True
Then to access the caption make sure you go through the AxisTitle object:
.Axes(xlCategory, xlPrimary).AxisTitle.Caption = ""
Then use
.Axes(xlCategory, xlPrimary).AxisTitle.Orientation = xlVertical
Hope that helps.
Related
I am attempting to plot multiple named ranges on to a chart. These named ranges (named for example Time_Series_1) are of the form:
=INDIRECT(Ranges!$AJ$3) where this argument Ranges!$AJ$3 is for example
="'Source Data'!"&ADDRESS(N3,(Comparisons!$G$28+5))&":"&ADDRESS(N3(Comparisons!$I$28+5))
The code I'm attempting to use to plot the these ranges (I have started with one as any more remain to be impossible as one is not working) is:
Sheets("Comparisons").Select
Sheet10.ChartObjects("Chart 2").Activate
Set Rng = range("Time_Series_1")
Set Date_Rng = range("Time_Series_Dates_1")
With ActiveChart
.SetSourceData Source:=Rng
.XValues = Date_Rng
End With
It's not working! The Chart remains blank. Completely empty. What am I not updating? What am I not activating?
Thanks
I have no way of testing your model, but try this:
Dim Chart_Sheet As Worksheet
Dim My_Chart As ChartObject
Dim Rng As Range
Dim Date_Rng As Range
Set Chart_Sheet = ThisWorkbook.Sheets("Comparisons")
Set My_Chart = Chart_Sheet.ChartObjects("Chart 2")
Set Rng = Range("Time_Series_1")
Set Date_Rng = Range("Time_Series_Dates_1")
With My_Chart.Chart
.SetSourceData Source:=Rng
.SeriesCollection(1).XValues = Date_Rng
End With
(I am assuming that your Indirect reference works properly)
ActiveChart.SeriesCollection(1).XValues = Date_Rng
ActiveChart.SeriesCollection(1).Values = Rng
ActiveChart.Axes(xlCategory, xlPrimary).HasTitle = True
ActiveChart.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "Dates"
ActiveChart.Axes(xlValue, xlPrimary).HasTitle = True
ActiveChart.Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "Pounds"
ActiveChart.Axes(xlCategory).HasMajorGridlines = True
I have written a macro to generate graph in excel but i want that graph to be generated in the next sheet not in the same sheet.i have pasted my macro below its working properly i just want it to be in the next sheet. please provide me some solution*
Sub LumData1()
If IsEmpty(Range("B2,D2")) = False Then
Range("B:B,D:D,H:H,I:I,J:J,M:M").Select
Range("M1").Activate
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlXYScatterSmoothNoMarkers
ActiveChart.SetSourceData Source:=Sheets(ActiveSheet.Name).Range( _
"$B:$B,$D:$D,$H:$H,$I:$I,$J:$J,$M:$M" _
)
ActiveChart.Location Where:=xlLocationAsObject, Name:=ActiveSheet.Name
With ActiveChart.ChartArea
.Width = 1060
.Height = 420
.Left = 0
End With
ActiveChart.SeriesCollection(1).Select
ActiveChart.SeriesCollection(1).AxisGroup = 2
ActiveChart.SeriesCollection(5).Select
ActiveChart.SeriesCollection(5).AxisGroup = 2
ActiveChart.Axes(xlCategory, xlPrimary).HasTitle = True
ActiveChart.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "Date"
ActiveChart.Axes(xlValue, xlPrimary).HasTitle = True
ActiveChart.Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "Value"
ActiveChart.Axes(xlCategory).TickLabels.Orientation = 45
End If
End Sub
My answer covers not only how to solve your question in your post, but how to automatically define and set-up charts in VBA in a “cleaner” and safer way.
It's better if you avoid using ActiveSheet, Select, and ActiveChart. Instead always use referenced objects, in this case Worksheets and ChartObject. E.g Dim ChtObj As ChartObject , and later set it with Set ChtObj = ShtCht.ChartObjects.Add(100, 100, 500, 500) , where ShtCht is the worksheet where you create your chart.
Once you defined and set your ChartObject, its quite easy to modify its properties by using the With ChtObj , and also nested properties, by adding With .Chart.ChartArea under the first With statement.
Code
Option Explicit
Sub LumData1()
Dim ChtObj As ChartObject
Dim ShtSrc As Worksheet
Dim ShtCht As Worksheet
' change "Sheet1" to your sheet's name (where you have your chart's data)
Set ShtSrc = Worksheets("Sheet1") ' <-- I preffer not to work with ActiveSheet
'Set ShtCht = Worksheets("Sheet2") ' <-- set the chart's destination worksheet
Set ShtCht = Worksheets.Add ' <-- create a new worksheet to place the chart
ShtCht.Name = "Chart"
If Not IsEmpty(ShtSrc.Range("B2,D2")) Then
Set ChtObj = ShtCht.ChartObjects.Add(100, 100, 500, 500)
With ChtObj
.Chart.ChartType = xlXYScatterSmoothNoMarkers
.Chart.SetSourceData ShtSrc.Range("$B:$B,$D:$D,$H:$H,$I:$I,$J:$J,$M:$M")
' set position of the chart to Cell M1
.Top = ShtCht.Range("M1").Top
.Left = ShtCht.Range("M1").Left
' modify chart position and dimensions
With .Chart.ChartArea
.Width = 1060
.Height = 420
.Left = 0
End With
With .Chart
.SeriesCollection(1).AxisGroup = 2
.SeriesCollection(5).AxisGroup = 2
.Axes(xlCategory, xlPrimary).HasTitle = True
.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "Date"
.Axes(xlValue, xlPrimary).HasTitle = True
.Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "Value"
.Axes(xlCategory).TickLabels.Orientation = 45
End With
End With
End If
End Sub
edited after OP's clarification he has to make a new sheet to host the chart into
to stick to your code as much as possible:
remove ActiveChart.Location Where:=xlLocationAsObject, Name:=ActiveSheet.Name
place the following code right before End if
Dim myChart As Chart: Set myChart = ActiveChart
Worksheets.Add
myChart.Location Where:=xlLocationAsObject, Name:=ActiveSheet.Name
I am trying to add a secondary vertical axis to my chart in VBA. I keep running into this error that says that the Method Axes of the Object _Chart has failed.
I have looked up solutions and implemented a few that stated to make sure that the secondary axis is first active. My code is below. The error occurs in the third to last line when I am trying to state that the secondary axis has a title. Any help is much appreciated since I am still a beginner in VBA.
Public Sub CreateChartForColumnsOneThreeandFive()
Dim myChartColumnsOneThreeandFive As ChartObject
Set myChartColumnsOneThreeandFive = ActiveSheet.ChartObjects.Add(Left:=150, Top:=150, Width:=500, Height:=400)
myChartColumnsOneThreeandFive.Chart.HasTitle = True
myChartColumnsOneThreeandFive.Chart.ChartTitle.Text = "Phase Detector Readback vs Substrate Forward Power"
myChartColumnsOneThreeandFive.Chart.Type = xlLine
myChartColumnsOneThreeandFive.Chart.SetSourceData Source:=ActiveWorkbook.Sheets("Sheet2").Range("C" & processRowBegin & ":C" & processRowEnd)
myChartColumnsOneThreeandFive.Chart.SetSourceData Source:=ActiveWorkbook.Sheets("Sheet2").Range("E" & processRowBegin & ":E" & processRowEnd)
myChartColumnsOneThreeandFive.Chart.SeriesCollection(1).Name = Range("C1")
myChartColumnsOneThreeandFive.Chart.SeriesCollection(1).Name = Range("E1")
myChartColumnsOneThreeandFive.Chart.SeriesCollection(1).Select
myChartColumnsOneThreeandFive.Chart.SeriesCollection(1).AxisGroup = 2
myChartColumnsOneThreeandFive.Chart.HasTitle = True
myChartColumnsOneThreeandFive.Chart.ChartTitle.Text = "Substrate Forward Power vs Phase Detector Readback"
myChartColumnsOneThreeandFive.Chart.Axes(xlCategory).HasTitle = True
myChartColumnsOneThreeandFive.Chart.Axes(xlCategory).AxisTitle.Caption = "Time"
myChartColumnsOneThreeandFive.Chart.Axes(xlValue, xlPrimary).HasTitle = True
myChartColumnsOneThreeandFive.Chart.Axes(xlValue, xlPrimary).AxisTitle.Caption = "Substrate Forward Power"
myChartColumnsOneThreeandFive.Chart.SeriesCollection(1).AxisGroup = xlSecondary
myChartColumnsOneThreeandFive.Chart.HasAxis(xlValue, xlSecondary) = True
myChartColumnsOneThreeandFive.Chart.Axes(xlValue, xlSecondary).HasTitle = True
myChartColumnsOneThreeandFive.Chart.Axes(xlValue, xlSecondary).AxisTitle.Select
myChartColumnsOneThreeandFive.Chart.Axes(xlValue, xlSecondary).AxisTitle.Text = _
"Phase Detector Readback"
End Sub
Even though not in this code, I assume processRowBegin and processRowEnd are defined somewhere else as Long and they have a numeric value.
Try the code below, it runs without errors, I am not sure what is your final goal and how your chart suppose to look like, but I think you can modify it easily to fit your needs.
Option Explicit
Public Sub CreateChartForColumnsOneThreeandFive()
Dim myChartColumnsOneThreeandFive As ChartObject
Set myChartColumnsOneThreeandFive = ActiveSheet.ChartObjects.Add(Left:=150, Top:=150, Width:=500, Height:=400)
With myChartColumnsOneThreeandFive.Chart
.HasTitle = True
.ChartTitle.Text = "Phase Detector Readback vs Substrate Forward Power"
.Type = xlLine
' create series 1, set values and name
.SeriesCollection.NewSeries
.SeriesCollection(1).Name = Range("C1")
.SeriesCollection(1).Values = ActiveWorkbook.Sheets("Sheet2").Range("C" & processRowBegin & ":C" & processRowEnd)
' create series 2, set values and name
.SeriesCollection.NewSeries
.SeriesCollection(2).Name = Range("E1")
.SeriesCollection(2).Values = ActiveWorkbook.Sheets("Sheet2").Range("E" & processRowBegin & ":E" & processRowEnd)
.SeriesCollection(1).AxisGroup = 2
.HasTitle = True
.ChartTitle.Text = "Substrate Forward Power vs Phase Detector Readback"
' set X-axis
.Axes(xlCategory).HasTitle = True
.Axes(xlCategory).AxisTitle.Caption = "Time"
' set Y-axis
.Axes(xlValue, xlPrimary).HasTitle = True
.Axes(xlValue, xlPrimary).AxisTitle.Caption = "Substrate Forward Power"
.SeriesCollection(1).AxisGroup = xlSecondary
' add a secondary Y-axis ans set it
.HasAxis(xlValue, xlSecondary) = True
.Axes(xlValue, xlSecondary).HasTitle = True
.Axes(xlValue, xlSecondary).AxisTitle.Select
.Axes(xlValue, xlSecondary).AxisTitle.Text = "Phase Detector Readback"
End With
End Sub
I ran into this issue and solved it by changing the order of my code. Here is the order that worked:
Delete previous chart series (optional)
Set chart type
Add primary y-axis series
Add secondary y-axis series
Format secondary y-axis
Format x axis
Format primary y-axis
I think what solved it was setting the chart type right near the beginning. There's definetly some flexibility in the order I've written here, but I haven't explored it.
I have a macro that creates a graph. I want VBA to read a range from the spreadsheet and use the values for horizontal axis labels. Basically I want to make this graph:
look like this (add the months on the bottom)
Thanks!
Macro:
Sub AddChartSheet()
'Variable declaration
Dim chtChart As Chart
Dim name1 As String
'Name is currently used for the title of the new tab where the chart is created and the chart title
name1 = "AHU-10-8"
'Create a new chart.
Set chtChart = Charts.Add
With chtChart
'.Name is the name of the tab where the new Chart is created
.Name = name1
.ChartType = xlLine
'Link to the source data range.
.SetSourceData Source:=Sheets(3).Range("A1:B5861"), _
PlotBy:=xlColumns
.HasTitle = True
.ChartTitle.Text = name1
.Axes(xlCategory, xlPrimary).HasTitle = True
.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "Time"
.Axes(xlValue, xlPrimary).HasTitle = True
.Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "Valve Position (-)"
myFileName = name1 & ".png"
chtChart.Export Filename:=ThisWorkbook.Path & "\" & myFileName, Filtername:="PNG"
End With
End Sub
To adjust the data series you are using for the Date (horizontal axes). You can either add the following
ActiveSheet.ChartObjects("Chart 15").Activate
ActiveChart.SeriesCollection(1).XValues = "=Sheet1!$D$5:$D$19"
Note: you will first need to select the chart and adjust the range that I have to the range that you need it to be.
OR you can add
.SeriesCollection(1).XValues = "=Sheet1!$D$5:$D$19"
Between your code
.SetSourceData Source:=Sheets(3).Range("A1:B5861"), _
PlotBy:=xlColumns
and
.HasTitle = True
Can you share your macro or workbook?
I am not sure how you have your data setup, but you can change the format of the data that you have selected for your horizontal labels to be a date format. Or, in VBA you can change the selection to a number format of "mmmm" to just show the months.
Selection.NumberFormat = "mmmm"
The following should work. Remember to adjust the chart name in the following code
ActiveSheet.ChartObjects("Chart 4").Activate
ActiveChart.Axes(xlCategory).Select
Selection.TickLabels.NumberFormat = "mmmm"
Here's the section of the code that is giving me trouble. I incorporated messagebox's to let me know that things are working up to that given point. So when I type "MsgBox xaxis.Address()" it comes out like $C$20:$C$42. Which is what im looking to graph on the x-axis. The issue is, my graph doesnt actually show up with that on the x-axis... it graphs like the entire sheet. I am guessing my issue lies with the syntax of xaxis that I am using.
Dim StartTime As Range
Dim EndTime As Range
Set StartTime = wb1.Sheets("Sheet2").Range("C:C").Find(wb1.Sheets("Sheet1").Range("$B$2").Text, MatchCase:=False, lookat:=xlWhole)
Set EndTime = wb1.Sheets("Sheet2").Range("C:C").Find(wb1.Sheets("Sheet1").Range("B3").Text, MatchCase:=False, lookat:=xlWhole)
'If Not StartTime Is Nothing Then
'End If
MsgBox StartTime.Address()
MsgBox EndTime.Address()
MsgBox StartTime.Value
MsgBox EndTime.Value
MsgBox "Hi"
Dim xaxis As Range
Dim yaxis As Range
Set xaxis = Range(StartTime.Address & ":" & EndTime.Address)
MsgBox xaxis.Address
'Set xaxis = Range("$C$16", Range("$C$16").End(xlDown))
Set yaxis = xaxis.Offset(0, ColumnOffset:=1)
MsgBox yaxis.Address
'''''''''''''''''''''''
'Dim x As String
'Dim y As String
' x = xaxis.Address
'MsgBox "Hi"
'y = yaxis.Address
'MsgBox x
Set Chrt = Charts.Add
With Chrt
.ChartType = xlXYScatter
.SeriesCollection.NewSeries
'.SeriesCollection(1).Name = "=""Scatter Chart"""
.SeriesCollection(1).Values = yaxis
.SeriesCollection(1).XValues = xaxis
'Titles
.HasTitle = True
.ChartTitle.Characters.Text = "Platen1"
.Axes(xlCategory, xlPrimary).HasTitle = True
.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "Time (Seconds)"
.Axes(xlValue, xlPrimary).HasTitle = True
.Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "Temp (Deg. C)"
.Axes(xlCategory).HasMajorGridlines = True
'Formatting
.Axes(xlCategory).HasMinorGridlines = False
.Axes(xlValue).HasMajorGridlines = True
.Axes(xlValue).HasMinorGridlines = False
.HasLegend = False
End With
My overall goal: I have a spreadsheet with data that gets updated daily. I need the user to be able to input a start time, end time, and then machine number. This needs to be used to generate a graph from that data. The start and end time are always in column C, but the specific rows are always changing. So what I do is I locate the matching start time and end time from the data, and then I create this range (StartTime or EndTime). The machine will determine the column of data to use for the y-axis which im just offsetting from the x-axis.
Any help would be greatly appreciated.
Edit: I fixed the above by adding the following code right under the chart creation:
Do Until .SeriesCollection.Count = 0
.SeriesCollection(1).Delete
Loop
The issue i realize is that the "xaxis" and "yaxis" are grabbing data from Sheet1 while i want it to grab data from Sheet 2. How do I go about declaring that it should be graphing from Sheet2?
Do it like this
Set xaxis = Sheets("Sheet2").Range(StartTime.Address & ":" & EndTime.Address)
Set yaxis = xaxis.Offset(0, ColumnOffset:=1)