无论计算模式如何,您将如何编写手动计算的 excel udf?
Posted
技术标签:
【中文标题】无论计算模式如何,您将如何编写手动计算的 excel udf?【英文标题】:how would you write an excel udf that's manually calculated regardless of calculation mode? 【发布时间】:2012-01-05 16:36:59 【问题描述】:我目前有一个使用表格的宏,以便在外部程序的帮助下执行一些计算。它所做的只是将一些工作表值写入文件以供另一个程序(外部 .exe)使用作为输入(该程序是封闭源代码)。所述程序然后编写自定义格式输出,我用 VBA 将其废弃,然后将返回值传递回工作表。 宏是通过指定源和目标范围的用户窗体调用的。
我想要做的是将通过用户窗体调用计算的方法替换为 UDF。使用GUI方式,更新计算比较麻烦;也不可能知道在目标范围数据中执行了哪些计算。出于性能考虑,选择此路径而不是 UDF。 由于计算速度很慢,我不能重用作为 UDF 调用外部程序的用户表单代码部分并完成它,因为它太慢了。 VBA 中似乎没有异步执行(与 Excel 2010 中的 xll 不同)。
一个可能的解决方案是在 UDF 开始执行时立即退出它,除非将全局设置为 true。除非从特定的功能区按钮调用重新计算,否则该全局总是错误的。问题是它不断地执行 UDF,一直将这些范围发送到 #N/A 值,所以我无法引用这些范围。另一种方法是创建假公式,即在指定参数和目标范围的单元格上添加注释。这也有很多问题。
所以。关于如何实现假异步计算 UDF 的任何想法?
谢谢!
【问题讨论】:
我很困惑。您谈论 UDF 和 GUI?我不明白这个? 这个我也不懂。 “UDF”的含义似乎有些混乱。 目前离线计算是通过 GUI 完成的。将显示一个表单,您可以在其中使用 refedit 控件选择起点和终点范围。我想要做的是用 UDF 替换 GUI。使用GUI方法更新计算很麻烦;也不可能知道在目标范围数据中执行了哪些计算。出于性能考虑,选择此路径而不是 UDF。感谢您的评论,很抱歉造成混乱。 【参考方案1】:如果我对您的理解正确,您希望有一个 VBA UDF,如果全局为 false,则返回上一次计算中的值,否则执行完整的慢速计算。 有几种不同的可能方法,这都是有不同的缺点:
使用application.caller.value
。这将导致循环引用并要求您打开迭代计算
使用application.caller.text
。这很简单,无需迭代计算即可工作,但会获取格式化的值,因此您需要确保您的 UDF 不会丢失精度等
在 udf 退出时将值存储在由
完整的呼叫单元地址并在 udf 入口处检索它。这会
除非您存储全局数组,否则不会保留在已保存的工作簿中
在某处保存/关闭并在打开时检索。
编写一个XLL
或XLM
宏等效的UDF,用于检索
以前的值
【讨论】:
我认为要走的路是使用application.caller.text
。尽管它仍然会不必要地执行很多次,但它似乎是最好的调用。我不知道你能做到这一点。这是我在看到您的帖子后找到的另一个参考。 dailydoseofexcel.com/archives/2011/11/30/udf-for-cumulative-sum。似乎“总是选择 .Value2 而不是 .Text”并不完全正确。谢谢!
.Text 很有用,只要您可以接受格式化的值。有关 .Value 与 .Value2 与 .Text 的讨论,请参阅 fastexcel.wordpress.com/2011/11/30/…
Application.Caller.Text
技巧不适用于数组,对吧?这仅对单个单元格参数有用。
Application.Caller 返回 UDF 占用的范围,因此如果将 UDF 作为数组公式输入到多个单元格中,您可以使用 application.caller.cells 获取每个单元格的 .TEXT 属性(j,k).text 或类似的
Function Async5(vKey, Refresh);将 vOut() 调暗为变体;将 j 变暗;将 nRows 变暗;将 k 变暗; Dim nCols 只要; Dim oCaller As Range;设置 oCaller = Application.Caller; nRows = oCaller.Rows.Count; nCols = oCaller.Columns.Count; ReDim vOut(1 到 nRows,1 到 nCols);对于 j = 1 到 nRows;对于 k = 1 到 nCols;如果不刷新则; vOut(j, k) = Val(oCaller.Cells(j, k).Text);别的; vOut(j, k) = Rnd;万一;下一个 k;下一个 j;异步5 = vOut;结束函数;以上是关于无论计算模式如何,您将如何编写手动计算的 excel udf?的主要内容,如果未能解决你的问题,请参考以下文章