我写了一个宏来生成一个直方图,给定一定的选择。宏的代码如下所示
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
我目前正在使用看起来像这样的WorkBook:
最终,我想生成一个自动迭代每列的宏,为每列调用Histogram Helper函数,在多个工作表上生成多个直方图。现在,我只想测试将两个范围放入HistogramHelper中,如下所示:
Sub GenerateHistograms()
HistogramHelper Range("D3:D30")
HistogramHelper Range("E3:E30")
End Sub
然而,在运行宏时,我得到一个错误号为400
的对话框,其中一个工作表成功生成,工作表标题为Speaker,另一个工作表生成了数字标题,没有内容
发生了什么事?
修改:相关工作簿:https://docs.google.com/file/d/0B6Gtk320qmNFbGhMaU5ST3JFQUE/edit?usp=sharing
编辑2主要WTF?:
为了调试目的,我将开始FOR块切换到此:
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
每当你运行它时,无论你作为第二个Macro调用放置哪个范围(在本例中为E3:E30),程序都会打印出每个单元$ E $ 3- $ E $ 30是一个非文本字符。为什么哦为什么?
答案 0 :(得分:2)
你不需要这个吗?
Sheets(title).Activate
提示:对于这种递归实现意味着许多创建/删除并且每天都变得越来越复杂,我不会依赖“活动”元素(工作表,范围等),而是依赖于特定的元素(表(“不管”))避免问题并简化调试。
------------------------ UPDATE
不,显然,你不需要它。
然后,更新selected_range.Cells(1, 1).Value
,使其为每个新工作表采用不同的值,因为这会引发错误:创建两个具有相同名称的工作表。
------------------------更新2(下载电子表格后)
问题就在于我的想法:用同一个名字创建的两个工作表(嗯......不完全是:其中一个spreadhsheets意图在一个null变量之后调用)。这个问题的原因,我也想到了:依靠“活跃元素”。但问题不是在使用ActiveSheet时,而是在传递参数时:范围是在没有电子表格的情况下给出的,而是从最后创建的电子表格中获取的。因此,解决方案:
HistogramHelper Sheets("Sheet1").Range("D3:D30")
HistogramHelper Sheets("Sheet1").Range("E3:E30")
底线:在复杂情况下,不要依赖“活动”/未正确定义的元素。