将范围对象传递给VBA中的子对象

时间:2016-01-27 22:42:17

标签: excel vba excel-vba range

尝试创建一个子程序,该子程序接受范围单元格并计算该列中单元格的平均值。但我得到错误:对象必需

我该如何纠正?

    Sub test()

    Dim rg As Range

    Set rg = ThisWorkbook.Worksheets(1).Range("B1")
    ColumnAverageToTop (rg)

    End Sub

    Sub ColumnAverageToTop(rg As Range)
    'calculates the average of the data in column and puts it above the data
    Cells(1, rg.Column).End(xlDown).Offset(1, 0).Value =  Application.WorksheetFunction.Average(rg.Columns(rg.Column))
    End Sub

1 个答案:

答案 0 :(得分:1)

很好,有一条评论说明了这个子应该做什么:我把它读作:如果我运行“Test()”,会发生以下情况:在第一行的传递范围列中,平均值为列的值应该出现。

您的代码中存在三个问题。 前面的评论中提到了第一个:在测试例程中使用call ColumnAverageToTop(rg)ColumnAverageToTop rg。解决方案:

Sub test()
    Dim rg As Range
    Set rg = ThisWorkbook.Worksheets(1).Range("B1")
    ColumnAverageToTop rg
End Sub

现在我们将成功进入ColumnAverageToTop例程,将参数传递给WorkSheetFunction.Average会出现问题 它需要在此处记录的参数:https://msdn.microsoft.com/en-us/library/office/ff836809.aspx所以为了保持简单,只需确保将Range对象传递给执行计算的Range对象。

最后,在使用End和Offset时,请确保按正确的顺序使用它们。这些函数中的每一个都将提供一个新的范围对象。我看到你尝试将单元格放在传递的参数下面,然后向下移动并获取所有其他值来计算该范围的平均值。

如果你真的总是需要整个列的平均值,我会建议:

Sub ColumnAverageToTop(rg As Range)
    'calculates the average of the data in column and puts it in row 1 of column
    'We declare where we put the value: Cells(1,1) of the column of the Range passed
    'E.g. "B1" passed means that the average will be in "B1".
    'Same fore passing "B323"
    rg.EntireColumn.Cells(1, 1).Value = WorksheetFunction.Average(rg.EntireColumn)
End Sub

这将包括传递范围的同一列的第1行中的任何数值,即使它将被结果覆盖。因此,多次运行相同的测试将改变结果。

如果你真的需要第一行以下的所有内容的平均值,直到第一个空白行,它应该是:

.rg.EntireColumn.Cells(1,1).value = WorksheetFunction.Average(rg.EntireColumn.Range(Cells(2, 1), Cells(2,1).End(xlDown)))

如果您需要参考单元格下方填充单元格的平均值:

.rg.EntireColumn.Cells(1, 1).Value = WorksheetFunction.Average(rg.Offset(1, 0).Resize(rg.Offset(1, 0).End(xlDown).Row - rg.Offset(1, 0), 1))

希望这可以帮助你。