2015-12-14 62 views
1

我的Excel工作表行单元格包含的数据类型的混合组合 - 数字,阿尔法和错误(例如,#REF!)。我想将这个范围传递给一个函数,该函数仅查找最大数量并忽略alpha和错误。我的代码:返回最大价值混合数据类型的范围

Public Function getRangeMax(passedRange As range) As Single 
'validate entries in passed range as numbers or skip 
'return max from validated numbers 

Dim i As Integer, arryLength As Integer 
Dim arry() 

getRangeMax = 0 

arry() = passedRange 
arryLength = UBound(arry) - LBound(arry) 

For i = 0 To arryLength 
    On Error Resume Next 
    If arry(i).value > getRangeMax Then 
     getRangeMax = arry(i).value 
    End If 
Next i 

'getRangeMax = Application.Max(passedRange) 

End Function 

函数调用是:= getRangeMax(C35:I35)。该特定范围的单元格中的数据为:dB,456.00,#REF !, 12.我希望代码忽略dB和#REF!条目并返回最大数量,在本例中为456.00。相反,该函数返回0.00。我究竟做错了什么?

+0

检查的元素。不要认为它持有你的想法。可能希望为'passedRange'中的每个c'存储到数组中。 – findwindow

+0

将范围存储到内存中的数组后,它是一个多维数组。在你的情况下,它会'arry(1到UBound(arry),1到1)'。 – PatricK

+0

@PatricK如果从单个列传递一个范围,则会是正确的。 OP是通过'C35:I35'所以第二个维度变化 –

回答

1

你的代码中包含多个错误,所有的隐藏你总是主动On Error Resume Next

这里的重构你的代码,修正错误,并用另一种类型检查

Public Function getRangeMax(passedRange As Range) As Double 
'validate entries in passed range as numbers or skip 
'return max from validated numbers 

    Dim i As Long, j As Long 
    Dim item As Variant 
    Dim arry() 

    getRangeMax = 0 
    arry() = passedRange 

    For i = 1 To UBound(arry, 1) 
    For j = 1 To UBound(arry, 2) 
     item = arry(i, j) 
     If VarType(item) = vbDouble Then 
      If item > getRangeMax Then 
       getRangeMax = item 
      End If 
     End If 
    Next j, i 
End Function 

注:
使用VarType要测试要处理的有效项目,将导致任何单元格为Text,但看起来像数字将被忽略。
使用IsNummeric来测试有效的项目过程将导致是文本,但样子数字转换为数字,并包含在测试的任何细胞。

+0

谢谢,克里斯。奇迹般有效。 – jmaz

1

试试这个:

Public Function Rng_Max_Get(rTrg As Range) As Double 
Dim aTrg As Variant, vItm As Variant, blTrg As Boolean 
    aTrg = rTrg.Value2 
    For Each vItm In aTrg 
     If IsNumeric(vItm) Then 
      If vItm <> Empty Then 
       If blTrg Then 
        If vItm > Rng_Max_Get Then Rng_Max_Get = vItm 
       Else 
        blTrg = True 
        Rng_Max_Get = vItm 
    End If: End If: End If: Next 
End Function 
0

既然你输入一个矩形范围,你可以使用.Rows.Count.Columns.Count而不是从UBound函数获得。试试这个:您的阵列的

Option Explicit 

Function getRangeMax(passedRange As Range) As Double 
    'validate entries in passed range as numbers or skip 
    'return max from validated numbers 

    Dim lRows As Long, lCols As Long, lR As Long, lC As Long 
    Dim uValue As Double, uMax As Double 
    Dim arry() As Variant 

    arry = passedRange 
    lRows = passedRange.Rows.Count 
    lCols = passedRange.Columns.Count 
    uMax = 0 
    For lR = 1 To lRows 
     For lC = 1 To lCols 
      If IsNumeric(arry(lR, lC)) Then 
       uValue = CDbl(arry(lR, lC)) 
       If uValue > uMax Then uMax = uValue 
      End If 
     Next 
    Next 
    getRangeMax = uMax 
End Function 
+0

使用'UBound'比显著快'Range.Rows/Columns.Count' –

+0

@PatricK,作品,感谢 – jmaz