How do I change the series names in vba? [duplicate] - vba

I have a series of charts I am creating using VBA (code below).
I am having trouble changing the names of the series from series 1 and series 2 to Current State and Solution State.
I keep getting an
Object Variable or With Block Variable not set
error.
However without the srs1 and srs2 code the charts work just fine (just with the wrong series names).
I looked up how to fix this and the answer I received however is not working for me.
Does anyone know another way to do this?
Sub MA()
Dim Srs1 As Series
Dim Srs2 As Series
Dim i As Integer
Dim MAChart As Chart
Dim f As Integer
f = 2 * Cells(2, 14)
For i = 1 To f Step 2
Set MAChart = ActiveSheet.Shapes.AddChart(Left:=750, Width:=400, Top:=130 + 50 * (i - 1), Height:=100).Chart
With MAChart
.PlotBy = xlRows
.ChartType = xlColumnClustered
.SetSourceData Source:=ActiveSheet.Range("Q" & 1 + i & ":Z" & 2 + i)
.Axes(xlValue).MaximumScale = 4
.Axes(xlValue).MinimumScale = 0
.HasTitle = True
.ChartTitle.Text = "Provider Load for " & Cells(i + 1, 15)
'where errors start- works fine up to this point
Set Srs1 = ActiveChart.SeriesCollection(1)
Srs1.Name = "Current State"
Set Srs2 = ActiveChart.SeriesCollection(2)
Srs2.Name = "Proposed Solution"
End With
Next i
End Sub

Try changing these lines ...
Set Srs1 = ActiveChart.SeriesCollection(1)
Srs1.Name = "Current State"
Set Srs2 = ActiveChart.SeriesCollection(2)
Srs2.Name = "Proposed Solution"
To ...
.SeriesCollection(1).Name = "Current State"
.SeriesCollection(2).Name = "Proposed Solution"
You are already using MAChart inside your With block so you should be able to access it's .SeriesCollection(x).Name properties in the same fashion as you have done for the other properties.

I believe the problem is with referencing - in the code you reference ActiveChart (I am guessing it does not exist), while you have created MAChart in the code above.
Set Srs1 = MAChart.SeriesCollection(1)
Srs1.Name = "Current State"
Set Srs2 = MAChart.SeriesCollection(2)
Srs2.Name = "Proposed Solution"

Related

vba only add new series to the chart if it does not exist

I have several sheets in my workbook which contains data to plot, every time I run a new analysis a new sheet is generated.
On my first sheet I plot all the data in the same graph, so to avoid re plotting all the series every time I append a new sheet I would like to just add a new series.
I thought that should be simple, but it is not for two reasons: When I first create the chart it adds somewhere between 1 and 9 series automatically:
Set myChart = ws.Shapes.AddChart.Chart
myChart.ChartType = xlXYScatterLinesNoMarkers
why does this generate any random series?
also if I delete the graph because I want to rerun one analysis, the graph will then be called 2 and so on... So I tried to give it a name and refer to its name instead, however that does not work:
Set myChart = ws.ChartObjects(ws.Name)
So in the first sheet(Orginal) I plot all data in the workbook, and in the rest I just plot the data for the current sheet as seen below. I use the same code function for both cases, where i just pass the argument all as true(orginal sheet) or false(sheet 1.....300)
Below is the code:
Sub createChart(ws As Worksheet, Optional all As Boolean = False)
Dim lastRow As Long
Dim myChart As Chart
Dim temp As Integer
Dim n As Integer
On Error Resume Next
' Delete the charts, just in case
If ws.ChartObjects.Count > 0 Then ' And Not all Then
ws.ChartObjects.Delete
End If
'If ws.ChartObjects.Count = 0 Then
Set myChart = ws.Shapes.AddChart.Chart
myChart.Name = ws.Name
'Else
'Set myChart = ws.ChartObjects(ws.Name) '''Fails why commented out
'End If
myChart.ChartType = xlXYScatterLinesNoMarkers
myChart.SetElement (msoElementPrimaryCategoryGridLinesMinor)
myChart.SetElement (msoElementPrimaryValueGridLinesMinorMajor)
myChart.SetElement (msoElementLegendBottom)
myChart.SetElement (msoElementChartTitleCenteredOverlay)
myChart.Parent.width = 800 ' px width graph
myChart.Parent.height = 500 ' px height graph
' it adds mysterious sometimes several random series, so we need to delete those that does not match sheet name
For n = myChart.SeriesCollection.Count To 0 Step -1
If Not SheetExists(myChart.SeriesCollection(n).Name) Then
myChart.SeriesCollection(n).Delete
End If
Next n
'*******************************************************************
'**************** FIRST PAGE CHART *********************************
'*******************************************************************
If all Then
Dim wsOther As Worksheet
Dim i As Integer
Dim fixRange As Boolean
Dim skipGraph As Boolean
fixRange = True
myChart.HasLegend = True
myChart.Legend.Position = xlLegendPositionRight
myChart.Parent.Top = 120
myChart.Parent.Left = 450
For Each wsOther In ThisWorkbook.Worksheets
If wsOther.Name <> ws.Name Then
lastRow = getLastRow(wsOther, 1)
skipGraph = False
'******* we only add graphs if it is not before ******************
If myChart.SeriesCollection.Count > 0 Then
For n = myChart.SeriesCollection.Count To 1 Step -1
If myChart.SeriesCollection(n).Name = wsOther.Name Then
skipGraph = True
Exit For
End If
Next n
End If
If Not skipGraph Then
With myChart.SeriesCollection.NewSeries
.Values = "=" & wsOther.Name & "!$E$2:$E$" & lastRow
.Name = wsOther.Name
.XValues = "=" & wsOther.Name & "!$B$2:$B$" & lastRow
End With
End If
If fixRange Then
' Range on axis
myChart.Axes(xlPrimary).MinimumScale = CDate(Application.WorksheetFunction.Min(Range(wsOther.Name & "!$B$2:$B$" & lastRow).Value2))
myChart.Axes(xlPrimary).MaximumScale = CDate(Application.WorksheetFunction.Max(Range(wsOther.Name & "!$B$2:$B$" & lastRow).Value2))
myChart.Axes(xlValue, xlPrimary).ScaleType = xlLogarithmic
fixRange = False
End If
End If
Next
'*******************************************************************************************************
'****************** SINGLE CHART ***********************************************************************
'*******************************************************************************************************
Else
myChart.HasLegend = False
myChart.Parent.Top = 40
myChart.Parent.Left = 300
lastRow = getLastRow(ws, 1)
With myChart.SeriesCollection.NewSeries
.Values = "=" & ws.Name & "!$E$2:$E$" & lastRow
.XValues = "=" & ws.Name & "!$B$2:$B$" & lastRow
End With
' Range on axis
myChart.Axes(xlPrimary).MinimumScale = CDate(Application.WorksheetFunction.Min(Range(ws.Name & "!$B$2:$B$" & lastRow).Value2))
myChart.Axes(xlPrimary).MaximumScale = CDate(Application.WorksheetFunction.Max(Range(ws.Name & "!$B$2:$B$" & lastRow).Value2))
End If
' *********************************************************************
' ******************* Sizing ******************************************
' *********************************************************************
With myChart.PlotArea
temp = .Top
temp = .height
.Top = 70
.height = 420
End With
'really dirty and crappy formatting of title
myChart.ChartTitle.Text = "Faraday Torr"
'X axis name
myChart.Axes(xlCategory, xlPrimary).HasTitle = True
myChart.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "Time [s]"
'y-axis name
myChart.Axes(xlValue, xlPrimary).HasTitle = True
myChart.Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "Pressure[Torr]"
Set myChart = Nothing
Set wsOther = Nothing
ws.Select
ws.Range("A1").Select
End Sub

Dynamic referencing the UsedRange in VBA

I have a code that gets data from a sheet and creates a graph. In the source sheet, each column is a series, and the number of series may change.
What my code does: it reads the used ranges so that it can graph the values.
Obs1: For 2 of the time series I create, the data is annualized, so as I count backwards for the calculation, if the data before is less than one year, the code shows as "Not Enough Data".
Problem: If I run the code with 2 time series (2 columns), I get two lines in the charts. But if I then delete one of the series and run it again, I get one line with values and a second empty line in the chart.
Question: How can this problem be solved?
What I already tried: I am trying to change the way I reference the ranges, so that it rerun the code, it returns to the graph only lines that have values. Issue is I cannot find a way to properly reference the range like that.
Relevant part of the code:
Function Grapher(ChartSheetName As String, SourceWorksheet As String, ChartTitle As String, secAxisTitle As String)
Dim lColumn As Long, lRow As Long
Dim LastColumn As Long, LastRow As Long
Dim RetChart As Chart
Dim w As Workbook
Dim RetRange As Range
Dim chrt As Chart
Dim p As Integer
Dim x As Long, y As Long
Dim numMonth As Long
Dim d1 As Date, d2 As Date
Dim i As Long
Set w = ThisWorkbook
'find limit
LastColumn = w.Sheets(SourceWorksheet).Cells(1, w.Sheets(SourceWorksheet).Columns.Count).End(xlToLeft).column
LastRow = w.Sheets(SourceWorksheet).Cells(w.Sheets(SourceWorksheet).Rows.Count, "A").End(xlUp).Row
'check for sources that do not have full data
'sets the range
i = 3
If SourceWorksheet = "Annualized Ret" Or SourceWorksheet = "Annualized Vol" Then
Do While w.Worksheets(SourceWorksheet).Cells(i, 2).Text = "N/A"
i = i + 1
Loop
'##### this is the part I believe is giving the problem:
'##### the way to reference the last cell keeps getting the number of columns (for the range) from the original column count.
Set RetRange = w.Worksheets(SourceWorksheet).Range(w.Worksheets(SourceWorksheet).Cells(i, 1), w.Worksheets(SourceWorksheet).Cells.SpecialCells(xlLastCell)) '****************
Else
Set RetRange = w.Sheets(SourceWorksheet).UsedRange
'Set RetRange = w.Sheets(SourceWorksheet).Range("A1:" & Col_Letter(LastColumn) & LastRow)
End If
'''''''''''''''''''''''
For Each chrt In w.Charts
If chrt.Name = ChartSheetName Then
Set RetChart = chrt
RetChart.Activate
p = 1
End If
Next chrt
If p <> 1 Then
Set RetChart = Charts.Add
End If
'count the number of months in the time series, do the ratio
d1 = w.Sheets(SourceWorksheet).Range("A2").Value
d2 = w.Sheets(SourceWorksheet).Range("A" & LastRow).Value
numMonth = TestDates(d1, d2)
x = Round((numMonth / 15), 1)
'ratio to account for period size
If x < 3 Then
y = 1
ElseIf x >= 3 And x < 7 Then
y = 4
ElseIf x > 7 Then
y = 6
End If
'create chart
With RetChart
.Select
.ChartType = xlLine
.HasTitle = True
.ChartTitle.Text = ChartTitle
.SetSourceData Source:=RetRange
.Axes(xlValue).MaximumScaleIsAuto = True
.Axes(xlCategory, xlPrimary).HasTitle = True
.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "Date"
.Axes(xlValue, xlPrimary).HasTitle = True
.Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = secAxisTitle
.Name = ChartSheetName
.SetElement (msoElementLegendBottom)
.Axes(xlCategory).TickLabelPosition = xlLow
.Axes(xlCategory).MajorUnit = y
.Axes(xlCategory).MajorUnitScale = xlMonths
'sets header names for modified sources
If SourceWorksheet = "Drawdown" Then
For lColumn = 2 To LastColumn
.FullSeriesCollection(lColumn - 1).Name = "=DD!$" & Col_Letter(lColumn) & "$1"
.FullSeriesCollection(lColumn - 1).Values = "=DD!$" & Col_Letter(lColumn) & "$3:$" & Col_Letter(lColumn) & "$" & LastRow
Next lColumn
ElseIf SourceWorksheet = "Annualized Ret" Then
For lColumn = 2 To LastColumn
.FullSeriesCollection(lColumn - 1).Name = "='Annualized Ret'!$" & Col_Letter(lColumn) & "$1"
Next lColumn
ElseIf SourceWorksheet = "Annualized Vol" Then
For lColumn = 2 To LastColumn
.FullSeriesCollection(lColumn - 1).Name = "='Annualized Vol'!$" & Col_Letter(lColumn) & "$1"
Next lColumn
End If
End With
End Function
Obs2: My code is currently functional (there are some functions I haven't added, so as not to waste more space).
Obs3: This is the problem when I decrease the number of columns (data series):
Since I could find no better, more elegant way to approach this problem (even the tables where yielding the same error), I corrected, by explicitly deleting the extra series in the end, based on their names.
Obs: If the Series contained no data, the new inserted code will change that series name to one of the ones below, and delete that series altogether.
Code to be added to the end:
'deleting the extra empty series
Dim nS As Series
'this has to be fixed. For a permanent solution, try to use tables
For Each nS In RetChart.SeriesCollection
If nS.Name = "Series2" Or nS.Name = "Series3" Or nS.Name = "Series4" Or nS.Name = "Series5" Or nS.Name = "Series6" Or nS.Name = "Series7" Or nS.Name = "Series8" Or nS.Name = "" Then
nS.Delete
End If
Next nS

How to change series name in VBA

I have a series of charts I am creating using VBA (code below).
I am having trouble changing the names of the series from series 1 and series 2 to Current State and Solution State.
I keep getting an
Object Variable or With Block Variable not set
error.
However without the srs1 and srs2 code the charts work just fine (just with the wrong series names).
I looked up how to fix this and the answer I received however is not working for me.
Does anyone know another way to do this?
Sub MA()
Dim Srs1 As Series
Dim Srs2 As Series
Dim i As Integer
Dim MAChart As Chart
Dim f As Integer
f = 2 * Cells(2, 14)
For i = 1 To f Step 2
Set MAChart = ActiveSheet.Shapes.AddChart(Left:=750, Width:=400, Top:=130 + 50 * (i - 1), Height:=100).Chart
With MAChart
.PlotBy = xlRows
.ChartType = xlColumnClustered
.SetSourceData Source:=ActiveSheet.Range("Q" & 1 + i & ":Z" & 2 + i)
.Axes(xlValue).MaximumScale = 4
.Axes(xlValue).MinimumScale = 0
.HasTitle = True
.ChartTitle.Text = "Provider Load for " & Cells(i + 1, 15)
'where errors start- works fine up to this point
Set Srs1 = ActiveChart.SeriesCollection(1)
Srs1.Name = "Current State"
Set Srs2 = ActiveChart.SeriesCollection(2)
Srs2.Name = "Proposed Solution"
End With
Next i
End Sub
Try changing these lines ...
Set Srs1 = ActiveChart.SeriesCollection(1)
Srs1.Name = "Current State"
Set Srs2 = ActiveChart.SeriesCollection(2)
Srs2.Name = "Proposed Solution"
To ...
.SeriesCollection(1).Name = "Current State"
.SeriesCollection(2).Name = "Proposed Solution"
You are already using MAChart inside your With block so you should be able to access it's .SeriesCollection(x).Name properties in the same fashion as you have done for the other properties.
I believe the problem is with referencing - in the code you reference ActiveChart (I am guessing it does not exist), while you have created MAChart in the code above.
Set Srs1 = MAChart.SeriesCollection(1)
Srs1.Name = "Current State"
Set Srs2 = MAChart.SeriesCollection(2)
Srs2.Name = "Proposed Solution"

Data is graphing in Excel 2010, but not in Excel 2013

I'm using VBA to graph data in a program I created in Excel 2010. I sent it to another computer, which has Excel 2013 instead, and I found that everything worked perfectly except for this graphing issue.
My code will create the graphs, and size them perfectly, but it won't actually graph any of the data points. In my code, I also add and delete series, and I notice that the number of series is correct on the side, but that the series didn't retain the custom names I gave them.
But here's the twist. When I right click on the chart and click "select data", all of the data immediately pops up, including all of my custom names for the series. I don't even go into select data or anything. The moment I click it, all of the values just pop up immediately.
Here is an imgur album of what it looks like before/after. Note that I do absolutely nothing other than right click and select the option "select data". It's like the data is already selected, but just doesn't show up until I click 'select data".
Why would Excel 2013 be doing this? How do I make these values actually show up via VBA methods? I'll add a sample of the graphing code I use below.
'Setting the range the chart will cover
Set rngChart = ActiveSheet.Range(Cells(Counter + 3, 4), Cells(Counter + 27, 10))
'Dimensioning the chart and choosing chart type
Set co = ActiveSheet.Shapes.AddChart(xlXYScatter, rngChart.Cells(1).Left, rngChart.Cells(1).Top, rngChart.Width, rngChart.Height)
Set cht = co.Chart
Set sc = cht.SeriesCollection
'Remove any default series
Do While sc.Count > 0
sc(1).Delete
Loop
'Setting chart data
'Series 1
With sc.NewSeries
.Name = "=Sheet1!$C$1"
.XValues = "=Sheet2!$A$2:$A$" & SimpleTracker + 1
.Values = "=Sheet2!$B$2:$B$" & SimpleTracker + 1
.MarkerSize = 3
.MarkerStyle = xlMarkerStyleCircle
End With
'Series 2
With sc.NewSeries
.Name = "=Sheet1!$B$1"
.XValues = "=Sheet1!$A$2:$A$" & Counter + 1
.Values = "=Sheet1!$B$2:$B$" & Counter + 1
.MarkerSize = 5
.MarkerStyle = xlMarkerStyleCircle
.MarkerBackgroundColorIndex = 10
.MarkerForegroundColorIndex = 10
End With
'Setting chart labels
With cht
.HasTitle = True
If n = 0 Then
.ChartTitle.Characters.Text = "Simple Fit - CFL Over Time"
ElseIf Range("I" & n) = "Regression Title" Then
.ChartTitle.Characters.Text = Range("J" & n).Text
Else
.ChartTitle.Characters.Text = "Simple Fit - CFL Over Time"
End If
.Axes(xlCategory, xlPrimary).HasTitle = True
If DayTracker = 1 Then
.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "Time (Days)"
ElseIf HourTracker = 1 Then
.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "Time (Hours)"
Else
.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "Time (Minutes)"
End If
.Axes(xlValue, xlPrimary).HasTitle = True
.Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "CFL"
.Axes(xlCategory).HasMajorGridlines = True
.Axes(xlCategory).HasMinorGridlines = True
End With
I also want to note that this code still works perfectly in Excel 2010, and that the graphing still works there. It just doesn't work in Excel 2013.
Thank you for reading! If you have any questions or need any clarification, just let me know.
Replace
With sc.NewSeries
with
With cht.SeriesCollection.NewSeries
I had the same issue in Excel 2013. I don't know why, but this solution works for me.
The short story is I wasn't able to replicate the misbehavior.
The long story: I assumed that your code was the body of a Sub, so I created a module that contained the following:
Sub DoItOriginal()
'Setting the range the chart will cover
Set rngChart = ActiveSheet.Range(Cells(Counter + 3, 4), Cells(Counter + 27, 10))
'Dimensioning the chart and choosing chart type
Set co = ActiveSheet.Shapes.AddChart(xlXYScatter, rngChart.Cells(1).Left, rngChart.Cells(1).Top, rngChart.Width, rngChart.Height)
Set cht = co.Chart
Set sc = cht.SeriesCollection
'Remove any default series
Do While sc.Count > 0
sc(1).Delete
Loop
'Setting chart data
'Series 1
With sc.NewSeries
.Name = "=Sheet1!$B$1"
.XValues = "=Sheet2!$A$2:$A$" & SimpleTracker + 1
.Values = "=Sheet2!$B$2:$B$" & SimpleTracker + 1
.MarkerSize = 3
.MarkerStyle = xlMarkerStyleCircle
End With
'Series 2
With sc.NewSeries
.Name = "=Sheet1!$B$1"
.XValues = "=Sheet1!$A$2:$A$" & Counter + 1
.Values = "=Sheet1!$B$2:$B$" & Counter + 1
.MarkerSize = 5
.MarkerStyle = xlMarkerStyleCircle
.MarkerBackgroundColorIndex = 10
.MarkerForegroundColorIndex = 10
End With
'Setting chart labels
With cht
.HasTitle = True
If n = 0 Then
.ChartTitle.Characters.Text = "Simple Fit - CFL Over Time"
ElseIf Range("I" & n) = "Regression Title" Then
.ChartTitle.Characters.Text = Range("J" & n).Text
Else
.ChartTitle.Characters.Text = "Simple Fit - CFL Over Time"
End If
.Axes(xlCategory, xlPrimary).HasTitle = True
If DayTracker = 1 Then
.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "Time (Days)"
ElseIf HourTracker = 1 Then
.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "Time (Hours)"
Else
.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "Time (Minutes)"
End If
.Axes(xlValue, xlPrimary).HasTitle = True
.Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "CFL"
.Axes(xlCategory).HasMajorGridlines = True
.Axes(xlCategory).HasMinorGridlines = True
End With
End Sub
Next, I needed some data to work with, so in another module I wrote a data generator that populated Sheet1 and Sheet2. Here is the content of that module:
Option Explicit
Sub Setup()
SetupSheet "Sheet1", 5
SetupSheet "Sheet2", 2.5
End Sub
Sub SetupSheet(nm As String, divisor As Double)
Dim i As Long
With ThisWorkbook.Worksheets(nm)
.[A2].CurrentRegion.ClearContents
.[B1].Value = "Chart" & Right(nm, 1)
With .[A1]
For i = 1 To SimpleTracker
.Offset(i).Value = i
.Offset(i, 1).FormulaR1C1 = "=1-EXP(-RC[-1]/" & divisor & ")"
Next i
End With
End With
End Sub
I then executed Setup() from the VB Editor, and created a third worksheet and activated it.
Then I ran DoItOriginal() from the VB editor, and I did not observe the issue you described. It occurred to me that one possible explanation is that switching back to the Excel user interface from the VBE did something to hide the misbehavior, so I installed a button on the sheet and executed DoItOriginal from there, and still did not observe the behavior in 2010, 2011, or 2013.
On thing I noticed is the line
.Name = "=Sheet1!$B$1"
in the setup for Series 1 probably wants to refer to Sheet2.
Try the code above and see if you still observe the misbehavior. If you do and I don't that might be interesting. If you don't, then the puzzle is how does this arrangement differ from the context in which you do see the misbehavior. Since you didn't post that, I'll wait in suspense. -hth
Try adding
DoEvents
After adding each chart element, especially after adding each series.

VBA Macro to automate histogram throwing error 400

I wrote a macro to produce a histogram, given a certain selection. The code for the macro looks like this
Sub HistogramHelper(M As Range)
Dim src_sheet As Worksheet
Dim new_sheet As Worksheet
Dim selected_range As Range
Dim r As Integer
Dim score_cell As Range
Dim num_scores As Integer
Dim count_range As Range
Dim new_chart As Chart
Set selected_range = M
Set src_sheet = ActiveSheet
Set new_sheet = Application.Sheets.Add(After:=src_sheet)
title = selected_range.Cells(1, 1).Value
new_sheet.Name = title
' Copy the scores to the new sheet.
new_sheet.Cells(1, 1) = "Data"
r = 2
For Each score_cell In selected_range.Cells
If Not IsNumeric(score_cell.Text) Then
'MsgBox score_cell.Text
Else
new_sheet.Cells(r, 1) = score_cell
End If
r = r + 1
Next score_cell
num_scores = selected_range.Count
'Creates the number of bins to 5
'IDEA LATER: Make this number equal to Form data
Dim num_bins As Integer
num_bins = 5
' Make the bin separators.
new_sheet.Cells(1, 2) = "Bins"
For r = 1 To num_bins
new_sheet.Cells(r + 1, 2) = Str(r)
Next r
' Make the counts.
new_sheet.Cells(1, 3) = "Counts"
Set count_range = new_sheet.Range("C2:C" & num_bins + 1)
'Creates frequency column for all counts
count_range.FormulaArray = "=FREQUENCY(A2:A" & num_scores + 1 & ",B2:B" & num_bins & ")"
'Make the range labels.
new_sheet.Cells(1, 4) = "Ranges"
For r = 1 To num_bins
new_sheet.Cells(r + 1, 4) = Str(r)
new_sheet.Cells(r + 1, 4).HorizontalAlignment = _
xlRight
Next r
' Make the chart.
Set new_chart = Charts.Add()
With new_chart
.ChartType = xlBarClustered
.SetSourceData Source:=new_sheet.Range("C2:C" & _
num_bins + 1), _
PlotBy:=xlColumns
.Location Where:=xlLocationAsObject, _
Name:=new_sheet.Name
End With
With ActiveChart
.HasTitle = True
.HasLegend = False
.ChartTitle.Characters.Text = title
.Axes(xlCategory, xlPrimary).HasTitle = True
.Axes(xlCategory, _
xlPrimary).AxisTitle.Characters.Text = "Scores"
.Axes(xlValue, xlPrimary).HasTitle = True
.Axes(xlValue, xlPrimary).AxisTitle.Characters.Text _
_
= "Out of " & num_scores & " responses"
' Display score ranges on the X axis.
.SeriesCollection(1).XValues = "='" & _
new_sheet.Name & "'!R2C4:R" & _
num_bins + 1 & "C4"
End With
ActiveChart.SeriesCollection(1).Select
With ActiveChart.ChartGroups(1)
.Overlap = 0
.GapWidth = 0
.HasSeriesLines = False
.VaryByCategories = False
End With
r = num_scores + 2
new_sheet.Cells(r, 1) = "Average"
new_sheet.Cells(r, 2) = "=AVERAGE(A1:A" & num_scores & _
")"
r = r + 1
new_sheet.Cells(r, 1) = "StdDev"
new_sheet.Cells(r, 2) = "=STDEV(A1:A" & num_scores & ")"
End Sub
I am currently using a WorkBook that looks like this:
Eventually, I want to produce a macro that automatically iterates over each column, calling the Histogram Helper function with each column, producing multiple histograms over multiple worksheets. For now, I'm just trying to test putting in TWO ranges into HistogramHelper, like so:
Sub GenerateHistograms()
HistogramHelper Range("D3:D30")
HistogramHelper Range("E3:E30")
End Sub
However, upon running the Macro, I get a dialog box with the error number 400, one of the sheets is produced successfully with the worksheet title Speaker, and another sheet is produced with a numerical title and no content.
What is going on?
Edit: The workbook in question: https://docs.google.com/file/d/0B6Gtk320qmNFbGhMaU5ST3JFQUE/edit?usp=sharing
Edit 2- Major WTF?:
I switched the beginning FOR block to this for debugging purposes:
For Each score_cell In selected_range.Cells
If Not IsNumeric(score_cell.Text) Then
MsgBox score_cell.Address 'Find which addresses don't have numbers
Else
new_sheet.Cells(r, 1) = score_cell
End If
r = r + 1
Next score_cell
Whenever you run this, no matter which range you put as the second Macro call (in this case E3:E30) the program prints out that each cell $E$3- $E$30 is a non-text character. Why oh why?
Don't you need this?
Sheets(title).Activate
TIP: for this kind of recursive implementations implying many creations/deletions and getting every day more and more complex, I wouldn't ever rely on "Active" elements (worksheet, range, etc.), but in specific ones (sheets("whatever")) avoiding problems and easing the debugging.
------------------------ UPDATE
No, apparently, you don't need it.
Then, update selected_range.Cells(1, 1).Value such that it takes different values for each new worksheet, because this is what is provoking the error: creating two worksheets with the same name.
------------------------ UPDATE 2 (after downloading the spreadsheet)
The problem was what I thought: two worksheets created with the same name (well... not exactly: one of the spreadhsheets was intended to be called after a null variable). And the reason for this problem, what I thought too: relying on "Active elements". But the problem was not while using the ActiveSheet, but while passing the arguments: the ranges are given without spreadsheet and were taken from the last created spreadsheet. Thus, solution:
HistogramHelper Sheets("Sheet1").Range("D3:D30")
HistogramHelper Sheets("Sheet1").Range("E3:E30")
Bottom line: don't rely on "Active"/not-properly-defined elements for complex situations.