how would you write an excel udf that's manually calculated regardless of calculation mode?

StackOverflow https://stackoverflow.com/questions/8755576

  •  14-04-2021
  •  | 
  •  

Pregunta

I currently have a macro that uses a form in order to perform some calculation with the help of an external program. All it does is writing some worksheet values to a file for use by another program, an external .exe, as input (that program is closed source). Said program then writes a custom format output, I scrap it with VBA and then pass the return back to the worksheet. The macro is invoked via a userform where the source and destination ranges are specified.

What I'm trying to do is to replace the method of invoking the calculation via a userform with a UDF. With the GUI method, updating the calculation is cumbersome; it is also impossible to know what computation was performed in the destination range data. This path was chosen over the UDF because of performance concerns. Since the calculation is quite slow, I can't just reuse the part of the userform code that invokes the external program as a UDF and be done with it, since it would be way too slow. There seems to be no async execution in VBA (as opposed to xll's in Excel 2010).

A possible solution would be to exit the UDF as soon as it begins executing unless a global is set to true. That global would always be false, unless a recalc is invocated from a specific ribbon button. The problem is that this executes constantly UDFs, sending those ranges to #N/A values all the time, so I can't reference to those ranges. Another would be to create fake formulas, ie a comment on the cell that specifies both the parameters and the destination range. This too has many problems.

So. Any idea on how to implement a fake-async calculating UDF?

Thanks!

¿Fue útil?

Solución

If I understand you correctly you want to have a VBA UDF that returns the value from the previous calculation if the global is false, otherwise do the full slow calculation.
There are several different possible approaches to this, which all have different drawbacks:

  • use application.caller.value. This will cause a circular reference and require you to switch on iterative calculation
  • use application.caller.text. This is simple and works without iterative calculation but gets the formatted value so you need to be sure that your UDF does not lose precision etc
  • at udf exit store the value in a global array indexed by the full calling cell address and at udf entry retrieve it. This will not persist in a saved workbook unless you store the global array somewhere at save/close and retrieve on open.
  • Write an XLL or XLM macro-equivalent UDF that retrieves the previous value
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top