0

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

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

我目前正在使用一个看起来像这样的工作簿: 在此处输入图像描述

最终,我想生成一个自动迭代每一列的宏,对每一列调用 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

每当您运行此程序时,无论您将哪个范围作为第二个宏调用(在本例中为 E3:E30),程序都会打印出每个单元格 $E$3-$E$30 是一个非文本字符。为什么哦为什么?

4

1 回答 1

2

你不需要这个吗?

Sheets(title).Activate

提示:对于这种意味着许多创建/删除并且每天变得越来越复杂的递归实现,我永远不会依赖“活动”元素(工作表、范围等),而是依赖特定的元素(工作表(“不管什么”)) 避免问题并简化调试。

- - - - - - - - - - - - 更新

不,显然,你不需要它。然后,更新selected_range.Cells(1, 1).Value以便为每个新工作表采用不同的值,因为这是引发错误的原因:创建两个具有相同名称的工作表。

------------------------ 更新 2(下载电子表格后)

问题是我的想法:创建了两个同名的工作表(嗯......不完全是:其中一个电子表格旨在在空变量之后调用)。而这个问题的原因,我也是这么想的:依赖“活动元素”。但问题不是在使用 ActiveSheet 时,而是在传递参数时:范围是在没有电子表格的情况下给出的,并且是从最后创建的电子表格中获取的。因此,解决方案:

HistogramHelper Sheets("Sheet1").Range("D3:D30")
HistogramHelper Sheets("Sheet1").Range("E3:E30")

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

于 2013-06-17T20:28:01.103 回答