JenniferMurphy
Well-known Member
- Joined
- Jul 23, 2011
- Messages
- 2,676
- Office Version
- 365
- Platform
- Windows
What's the best way to handle invalid data passed to UDFs?
I have a number of UDFs that do unique and sometimes complex calculations on the data passed to them, usually data contained in other cells. I usually define these parameters as numeric (Double, Long). But if I do and there is text in any of the referenced cells, Excel returns a Value error and the UDF never gets called. Or, if the cell is empty, Excel puts zero in that parameter, which is not what I want.
Here's an example. This UDF calculates the Z Score.
Here's an example of it in use.
The Rtg in D6 is not a number. The UDF never gets called.
The Rtg in D14 is empty. Excel passes a zero to the UDF.
Is the correct solution to define all parameters as Variant and then test the type in the UDF?
If so, can someone post some sample code to do that?
Thanks
I have a number of UDFs that do unique and sometimes complex calculations on the data passed to them, usually data contained in other cells. I usually define these parameters as numeric (Double, Long). But if I do and there is text in any of the referenced cells, Excel returns a Value error and the UDF never gets called. Or, if the cell is empty, Excel puts zero in that parameter, which is not what I want.
Here's an example. This UDF calculates the Z Score.
VBA Code:
Function ZScore(pValue As Double, pMean As Double, pStdDev As Double _
, Optional pHiLo As Boolean = True) As Double
' If std dev is zero, return 0; else calculate Z Score
If pStdDev = 0 Then 'If std dev = 0,
ZScore = 0 'Return 0
Else 'Else
ZScore = (pValue - pMean) / pStdDev 'Calculate the ZScore
If Not pHiLo Then ZScore = -ZScore 'If range order is reversed, reverse ZScore
End If
End Function
Here's an example of it in use.
Kitchen Scrap Bins.xlsx | |||||||
---|---|---|---|---|---|---|---|
B | C | D | E | F | |||
2 | Mean | $27.14 | 4.6 | ||||
3 | Std Dev | 10.669 | 0.19024 | ||||
4 | |||||||
5 | Price | Price Z | Rtg | Rtg Z | Z Sum | ||
6 | $25.00 | +0.20 | n/a | #VALUE! | #VALUE! | ||
7 | $23.99 | +0.30 | 4.8 | +1.28 | +1.57 | ||
8 | $13.95 | +1.24 | 4.6 | +0.23 | +1.46 | ||
9 | $21.95 | +0.49 | 4.7 | +0.75 | +1.24 | ||
10 | $35.12 | -0.75 | 4.6 | +0.23 | -0.52 | ||
11 | $15.00 | +1.14 | 4.2 | -1.88 | -0.74 | ||
12 | $38.29 | -1.04 | 4.5 | -0.30 | -1.35 | ||
13 | $45.99 | -1.77 | 4.5 | -0.30 | -2.07 | ||
14 | $25.00 | +0.20 | -23.95 | -23.75 | |||
MrExcel |
Cell Formulas | ||
---|---|---|
Range | Formula | |
C2 | C2 | =AVERAGE(MrExcel[Price]) |
C3 | C3 | =STDEV.S(MrExcel[Price]) |
E2 | E2 | =AVERAGE(MrExcel[Rtg]) |
E3 | E3 | =STDEV.S(MrExcel[Rtg]) |
E6:E14 | E6 | =ZScore([@Rtg],@Mean,@StdDev) |
F6:F14 | F6 | =[@[Price Z]]+[@[Rtg Z]] |
C6:C14 | C6 | =ZScore([@Price],@Mean,@StdDev,FALSE) |
The Rtg in D6 is not a number. The UDF never gets called.
The Rtg in D14 is empty. Excel passes a zero to the UDF.
Is the correct solution to define all parameters as Variant and then test the type in the UDF?
If so, can someone post some sample code to do that?
Thanks