An empty XLM loop ran slower than the VBA so its maybe best to avoid XLM if you need to loop
I don’t think Ms are talking publicly about 14 or 15 yet (apart from scotching death of VBA rumours), but I have heard those death of XLM rumours (unscotched so far!)
]]>I have not yet tested using the array formula or SUMPRODUCT in the XLM function, but presumably its faster than AvToTol2 but still not as fast as the VBA udf.
BTW I am sure I remember someone from MSoft publicly saying that XLM was going away in XL14 or 15?
]]>=SUM(IF(ISNUMBER(theRange)*ABS(theRange)>dTolerance,theRange,0))
=SUM(IF(ISNUMBER(theRange)*ABS(theRange)>dTolerance,1,0))
would be faster than
=AVERAGE(IF(ISNUMBER(theRange)*ABS(theRange)>dTolerance,theRange,0))
?
Also, is some entry in theRange is neither a number nor numeric text, I believe ISNUMBER(theRange)*ABS(theRange)>dTolerance won’t produce the results you intend.
]]>This one whups your vba for sparse data sets, but is a disaster in large dense ones:
 XLM AvToTol2
Result type  =RESULT(19)

arg1(range)  =ARGUMENT(“theRange”,8)
arg2 (num)  =ARGUMENT(“dTolerance”,1)

initialise sum  =SET.VALUE(G10,0)
initialise count  =SET.VALUE(G11,0)

accumulate sum  123
accumulate count  10

 =FOR.CELL(“x”,theRange,TRUE)

get the sum  =IF(ISNUMBER(x),IF(ABS(x)>dTolerance,x,0),0)
get the count  =IF(ABS(G15)>dTolerance,1,0)

wrap out errors  =IF(ISERROR(G15),0,G15)
wrap out errors  =IF(ISERROR(G16),0,G16)

set the val  =SET.VALUE(G10,G10+G18)
set the count  =SET.VALUE(G11,G11+G19)

 =NEXT()

 =RETURN(G10/G11)

Use text to cols to split the comments
This one is better than the first for dense sets but nowhere near your VBA:
XLM AvToTol3
=RESULT(19)
=ARGUMENT(“theRange”,8)
=ARGUMENT(“dTolerance”,1)
=SUM(IF(ISNUMBER(theRange)*ABS(theRange)>dTolerance,theRange,0))
=SUM(IF(ISNUMBER(theRange)*ABS(theRange)>dTolerance,1,0))
=RETURN(J7/J8)
(those sums should be array entered, otherwise it runs fast but wrong)
I’m sure there is a better way, I’ll have a think. Suggestions welcome.
This bears out my experience that looping in XLM is sloooow.
]]>A1: =RESULT(3)
A2:
A3:
A4:
A5: =ARGUMENT(“TheRange”,64)
A6: =ARGUMENT(“dTol”,1)
A7: =SET.VALUE(s,0)
A8: =SET.VALUE(n,0)
A9: =FOR(“ri”,1,ROWS(TheRange),1)
A10: = FOR(“ci”,1,COLUMNS(TheRange),1)
A11: = SET.VALUE(v,INDEX(TheRange,ri,ci))
A12: = IF(ISNUMBER(v))
A13: = IF(ABS(v)>dTol)
A14: = SET.VALUE(s,s+v)
A15: = SET.VALUE(n,n+1)
A16: = END.IF()
A17: = END.IF()
A18: = NEXT()
A19: =NEXT()
A20: =RETURN(IF(n>0,s/n,”no numbers in the range”))
where A1 is the named FUNCTION foo, A2 is the local named range v, A3 the local named range s, and A4 the local named range n.
]]>d = CDbl(v)
converts numeric text into numbers. SUMIF won’t. If your range should contain only numbers and empty cells, wouldn’t a bushier
If VarType(v) = vbDouble Then
d = v
If Abs(d) > dTol Then
:
be faster than using an error trap around
d = CDbl(v)
?
]]>This particular UDF is from one of a series of experiments comparing different ways of writing UDFs with equivalent formulae (and different technologies for UDFs), which is why it would be interesting to play with a wellwritten XLM version.
It turns out that reasonably optimised VBA UDFs are often a lot faster than equivalent array formulae, but VBA UDF speed is very sensitive to the way the UDF is written (the slowest averagetol VBA UDF is about 100 times slower than the fastest), and if you are using many instances of a UDF you also need to avoid the VBE refresh slowdown bug.
AVERAGETOLE is about 2.5 to 3.5 times faster than your particular array formulae (depends on the number of rows) when calculation is initiated from VBA, but is about twice as slow as the equivalent SUMIF()/COUNTIF() formula.
]]>=AVERAGE(IF(ISNUMBER(1/(ABS(TheRange)>dTol)),–TheRange))
Would array formuas, even those needing a half dozen builtin function calls, run faster than any single udf?
This formula would return #VALUE! rather than #N/A on overflow, but that’s about the only difference with your udf I can see.
]]>Yes for each is faster, but its not usually a significant factor in the overall times.
@Marcus,
.Value2 makes no difference when handling strings or Booleans
When handling numbers there are several advantages:
– its 1520% faster than .value and often the time to get the data into a variant array is the largest time component.
– you don’t get the truncation of decimal places for cells formatted as currency that is caused by .Value implicitly converting to Currency datatype.
– it does not convert Dates to the VBA epoch: this may be an advantage or disadvantage.