VBA宏自动化直方图投掷错误400

时间:2013-06-17 18:57:02

标签: excel vba excel-vba

我写了一个宏来生成一个直方图,给定一定的选择。宏的代码如下所示

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: enter image description here

最终,我想生成一个自动迭代每列的宏,为每列调用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是一个非文本字符。为什么哦为什么?

1 个答案:

答案 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")

底线:在复杂情况下,不要依赖“活动”/未正确定义的元素。