Reputation: 527
Note: 1) I don't want to use Application.Worksheetfunction.Min; 2) I want to reject array elements that are not vbDouble; 3) I do not know ahead of time how many elements are in the passed array
Public Function getArrayMin(ByRef passedArray() As Double) As Double
'return min of valid numbers in an array
Dim element As Variant
Dim i As Integer
getArrayMin = 1E+25
i = 0
For Each element In passedArray
If VarType(element) = vbDouble Then
i = i + 1
If element < passedArray(i) Then
getArrayMin = passedArray(i)
End If
End If
Next
End Function
JNevill's edited version, which still does not work:
Function getArrayMin(passedArray() As Double) As Double
Dim minVal As Double
Dim element As Variant
minVal = 1E+25
For Each element In passedArray
If element < minVal Or element = passedArray(0) Then
minVal = element
End If
Next element
getArrayMin = minVal
End Function
Upvotes: 0
Views: 252
Reputation: 527
Figured it out:
Public Function getArrayMin(passedRange As range) As Double
'return min of valid numbers in an array
Dim myarray() As Variant
Dim cell As Variant
Dim i As Integer
myarray = passedRange.value
getArrayMin = 1E+25
For Each cell In passedRange
If VarType(cell) = vbDouble Then
If getArrayMin > cell Then
getArrayMin = cell
End If
End If
Next
End Function
Upvotes: 0
Reputation: 50034
i = 0
For Each element In passedArray
If VarType(element) = vbDouble Then
i = i + 1
If cell < passedArray(i) Then
passedArray(i) = element
End If
End If
Next
This seems odd. You are looping through elements in the array, testing it to see if the next element is larger, and if the next element is larger you set the next element to the current element. Then you do it again.
So... after this runs, the "min" should theoretically be in passedArray(ubound(passedArray))
.
I guess that will work, but it feels odd because it blows away your array and fills it with intermediate garbage except for the first and last elements.
The gotcha is that you don't have a next element once you hit the uBound of your array. That last element is going to cause problems, but you don't really need to analyze it since it will contain the min already. To get around the error this will cause you could change that if
statement to be:
If VarType(element) = vbDouble and i < uBound(passedArray) Then
At the end of your function just stick in the following so that your function returns a value.
getArrayMin=passedArray(uBound(passedArray)).
You could also not have it return anything since you used byRef
, but it means after you call this function, you would need to get the last element, so it would look like:
getArrayMin(myArray)
minOFArray=myArray(Ubound(myArray))
Just keep in mind that you are using byRef
and that your original array that you pass to the function is going to be blown away by the function rewriting all the elements. Personally, I would use byVal and insure that the function returns a min.
As a total rewrite, I would do something like this instead:
Function getArrayMin(passedArray AS Double) as Double
Dim minVal as double
Dim element as variant
For each element in passedArray
if element < minVal or element = passedArray(0) Then minVal = element
Next element
getArrayMin = minVal
End Function
It's more concise and there is no monkeying around with your array. I didn't check for a double since the passedarray
parameter is already declared as a double. It shouldn't allow a string or some other element through.
Lastly, the rewrite above will give you a jumping off point if your logic needs to get more complicated. But the easiest way to do what your doing would be to just use Application.Min():
getArrayMin = Application.Min(passedArray)
Upvotes: 1