Home » excel » vba – Excel Geomean returns #value! sometimes?

vba – Excel Geomean returns #value! sometimes?

Posted by: admin May 14, 2020 Leave a comment

Questions:

I’ve modified the function below to suit my needs.

I have many workbooks with sheets that contain 4500+ rows, and I use the function to search for two given values (as boundaries). Then, it selects the rows as the range. Finally, do whatever on that range. The function:

Function GeoM(A, B)

Application.Volatile    
Dim x As Integer
Dim y As Integer
Dim rng As Range

x = Application.WorksheetFunction.Match(A, Range("B:B"), 0) ' looking in col B
y = Application.WorksheetFunction.Match(B, Range("B:B"), 0) ' looking in col B

Set rng = Range(Cells(x, 18), Cells(y, 18)) 'Im working on col 18
GeoM = Application.WorksheetFunction.GeoMean(rng)
End Function

The problem is, this code works just fine except with GeoMeann. I noticed when the range of data is relatively small (number of data cells) it returns a value. However, if the range is larger than approx. 126 cells, it returns #value!.

I’m stuck and working on solving this issue. Is the GeoMean function limited to a given number of data?

Thanks

How to&Answers:

There appears to be a 170 character limit on my testing for earlier Excel versions (I tested in xl03), validated in this Mr Excel thread

(Xl10 worked fine on the longer dataset)

I also tried:

  • Using Evaluate
  • Using a 1D array

failed samples

Dim X
Set rng1 = Range("A1:A171")
MsgBox Evaluate("GeoMean(A1:A171)")
X = Application.Transpose(rng1)
MsgBox Application.WorksheetFunction.GeoMean(X)

to no avail.

So I think your two workarounds are either:

  1. Inserting a formula via VBA into Excel and using this result
  2. As per the MrExcel thread use the derivation of GeoMean, ie =EXP(AVERAGE(LN(Range)))

Suggested Approach

MsgBox Evaluate("EXP(AVERAGE(LN(A1:A171)))")

Answer:

Thanks to brettdj, I fixed the function and it works now:

Function GeoM(A, B)

Application.Volatile
Dim x As Integer
Dim y As Integer
Dim rng As Range
Dim LnValue As Double
Dim count As Integer

x = Application.WorksheetFunction.Match(A, Range("B:B"), 0) 'look in col. B
y = Application.WorksheetFunction.Match(B, Range("B:B"), 0) 'look in col. B

Set rng = Range(Cells(x, 18), Cells(y, 18)) 'set range of rows on col# 18

Do
  LnValue = LnValue + Math.Log(Cells(x, 18)) 'calculates sum of ln(value)
  x = x + 1
  count = count + 1   'calculates the total number of values
Loop Until x > y      'stop when x (upper row#) is greater than y (lower row#)

GeoM = Math.Exp((1 / count) * LnValue) 'GeoMean formula

End Function

This function searches a specified column for two values as upper and lower limits (Note: that means you shouldn’t have repeated values in that column. In another words, the column should have unique values). Then, it finds the GeoMean of the values on other column, which has values fall in the same range of rows.