2017-05-04 87 views
1

因此,我想创建一个基本函数,该函数需要我在Excel中突出显示的平均值。我很清楚Excel中已经有了一个内置的函数,但我正在努力使其成为练习。通过VBA中的函数传递数组或范围

我的问题是我不知道如何通过一个范围,然后调用范围中的特定元素。

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

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 

回答

1

您不能假定Range会连续,也不能假设Range将是水平的,也不是垂直的。

A 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!)。
  • 函数仅对数值单元格进行计数,这意味着即使target范围包含错误值,它也能正常工作。如果遇到非数字值,注释掉的代码将退出并返回一个#VALUE!错误。

你如何“打发范围”是调用者的问题。有很多方法可以做到这一点 - 从Excel公式:

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

你也可以用它在VBA代码:

foo = Module1.AverageTest(ActiveSheet.Range("A1:D10")) 
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 

或者你也可以做到这一点 - 有没有真正的任何需要遍历细胞的数量,当你可以在rng.Cells集合中迭代Each单元格。我还改变从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 

作为奖励,这后一种方法将在2维范围正常工作。

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