通过VBA中的函数传递数组或范围

时间:2017-05-04 17:52:41

标签: vba excel-vba excel

所以我想创建一个基本函数,它取平均值我在Excel中突出显示的值。我很清楚Excel中已经有一个内置函数,但我试图将其作为一个实践。

我的问题是我不知道如何传递范围,然后调用范围中的特定元素。

以下是我一直在玩的伪代码。我知道它可能写得很糟糕。我是初学者,我只是想练习一些。

Function averagetest(range As Range) '<------(Is this how I pass a Range into a function?)
      Dim N as Integer
      Dim i as Integer
      Dim average as Double
      average = 0 
      N = LengthofRange '<--------- (Is there a way to get the length of the 
      range like UBound or LBound for an array?)
      Do Until i = LengthofRange
          average = average + Range(i, i+1) '<--------(Is this how you call a 
          specific element in the range? I'm just adding every element in the 
          Range)
          i = i + 1
      Loop
average = average/N

End Function 

2 个答案:

答案 0 :(得分:1)

不要将range用作变量。

然后您可以使用rows.Count或Columns.Count来获取范围

Function averagetest(rng As Range)
      Dim N as Integer
      Dim i as Integer
      Dim average as Double
      average = 0 
      N = rng.rows.count 
      For  i = 1 to N 'use For loop
          average = average + rng.cells(i,1)'Cells will work here
      Next i
      averagetest= average/N

End Function 

或者你可以做到这一点 - 当你可以迭代Each集合中的rng.Cells单元格时,并不需要迭代单元格数。我还会将变量名称从average(这是误导性的)更改为更具描述性的内容,例如total

Option Explicit
Function averagetest(rng As Range)
    Dim cl As Range
    Dim total As Double

    For Each cl In rng.Cells
        total = total + cl.Value
    Next
    averagetest = total / rng.Cells.Count

End Function

作为奖励,后一种方法也适用于二维范围。

请注意,这会将空单元格视为0值(AVERAGE工作表函数忽略空单元格,因此结果可能会有所不同)如果范围内存在非数字值,则会引发错误。

答案 1 :(得分:1)

你不能假设Range是连续的,也不能假设Range是水平的,也不是垂直的。

Range是对象的集合,因此您使用For Each循环对其进行迭代以获得最佳性能。

假设该函数旨在用作UDF工作表函数,因此在标准模块(。bas)中定义:

Public Function AverageTest(ByVal target As Range) As Variant

    Dim total As Double
    Dim count As Double

    Dim cell As Range
    For Each cell In target
        If IsNumeric(cell.Value) Then
            total = total + cell.Value
            count = count + 1
        'Else
        '    AverageTest = CVErr(xlErrValue)
        '    Exit Function
        End If
    Next

    If count = 0 Then
        AverageTest = CVErr(xlErrDiv0)
    Else
        AverageTest = total / count
    End If

End Function

注意:

  • 参数传递ByVal,并且不以现有类型(Range)命名;我们不需要引用范围指针,它的副本就足够了。
  • 功能明确Public,并具有显式返回类型(Variant)。
  • 函数返回Variant,以便在适用的时候在“快乐路径”或适当的Double值(Error)中返回#Div/0!结果。< / LI>
  • 功能仅计算数字单元格,这意味着即使target范围包含错误值,它也能正常工作。如果遇到非数字值,注释掉的代码将会挽救并返回#VALUE!错误。

你如何“通过范围”是来电者的问题。有很多方法可以做到这一点 - 从Excel公式:

=AverageTest(A1:A10)
=AverageTest(A1:B12,F4:L4)

您也可以在VBA代码中使用它:

foo = Module1.AverageTest(ActiveSheet.Range("A1:D10"))