Table of contents
在这篇文章中,我们将看看你在工作簿中使用自定义函数时可能面临的问题。 我将尝试向你展示导致这些问题的原因以及如何轻松解决这些问题。
下面是我们要谈的内容。
前面我们谈到了什么是自定义函数,如何创建和使用它。 如果你觉得你需要提前温习一下UDF的基本知识,请暂停一下,看看我以前的文章。
为什么Excel UDF不能重新计算?
当你在工作簿中做任何改动时,Excel不会重新计算你的每一个公式。 它只会更新那些与改动的单元格相关的公式的结果。
但这涉及到标准的Excel函数。 至于自定义的,Excel无法验证VBA代码,也无法识别其他可能影响自定义函数结果的单元格。 因此,当你对工作簿进行修改时,你的自定义公式可能不会改变。
要解决这个问题,你只需要使用 应用。挥发性 声明:请查看下一章,了解如何应用它的步骤说明。
挥发性与非挥发性的自定义功能
默认情况下,Excel中的自定义函数是不稳定的。 这意味着UDF只有在它所指的任何单元格的值发生变化时才会重新计算。 但如果单元格的格式、工作表的名称、文件的名称发生变化,那么UDF就不会发生变化。
让我们从文字转换到例子。 例如,你需要在一个单元格中写下你的工作簿的名称。 要做到这一点,你创建一个自定义函数。
Function WorkbookName() As String WorkbookName = ThisWorkbook.Name End Function
现在想象一下下面的情况。 你写了自定义公式 =WorkbookName() 过了一会儿,你决定重新命名该文件,并以不同的名字保存它。 但你看了看单元格中的值,发现它并没有改变。 仍然有一个旧的文件名,这已经不对了。
由于该函数中没有参数,所以该函数不会被重新计算(即使你改变了工作簿的名称,关闭它,然后重新打开它)。
注意:要重新计算文件中的所有函数,你可以使用Ctrl + Alt + F9快捷键。
有没有更简单的方法? 为了使公式在工作表每次变化时都能重新计算,你需要多写一行代码。 在函数的开头粘贴以下代码。
应用。挥发性
因此,你的代码将看起来像这样。
Function WorkbookName() As String Application.Volatile WorkbookName = ThisWorkbook.Name End Function
现在你的UDF是不稳定的,因此如果工作表中的任何单元格被重新计算,或者工作簿中发生了任何变化,它就会自动重新计算。 只要你改变了文件的名称,你就会立即看到这个更新。
注意:请记住,太多的波动函数会使你的Excel变慢,毕竟有太多的自定义函数在不断地进行复杂的计算和对大数据范围进行操作。
因此,我建议只在真正需要的地方使用波动性。
为什么不能使用自定义函数
当你输入自定义函数名称的第一个字母时,它就会出现在输入单元格旁边的下拉列表中,就像标准Excel函数一样。
然而,这并不总是发生。 哪些错误会导致这种情况?
如果你有Excel 2003-2007,那么UDF永远不会出现在下拉列表中。 在那里你只能看到标准函数。
但是,即使你使用的是较新版本的Excel,还有一个错误你可能会不小心犯。
你看,自定义函数必须在一个叫做Modules的标准VBA模块中。 当你添加一个新的模块来编写函数代码时,会自动创建一个Modules文件夹,所有的模块都写在其中。
但有时会发生新模块没有被创建的情况。 在下一张截图中,你可以看到自定义函数代码和ThisWorkbook一起被放在 "Microsoft Excel Objects "模块中。
重点是,你不能将自定义函数放在工作表或工作簿的代码区。 在这种情况下,该函数将无法工作。 此外,它将不会出现在函数的下拉列表中。 因此,代码应始终放在文件夹中的 模块 .
Excel自定义函数帮助文本不显示
另一个可能出现的问题是当你粘贴自定义函数时看到的提示。 如果你使用一个标准的函数,你将总是看到一个关于该函数及其参数的工具提示。 但是UDFs呢?
如果你有很多自定义函数,你将非常难以记住每个函数做什么计算。 要记住使用哪些参数就更难了。 我认为对你的自定义函数做一个描述作为提醒会是一个好主意。
对于这一点,我建议使用 Application.MacroOptions 它将帮助你在函数向导窗口中不仅显示函数的描述,而且显示它的每个参数的描述。 当你点击公式栏中的Fx按钮时,你会看到这个窗口。
让我们看看如何在你的UDFs中添加这样的提示。 在上一篇文章中,我们看了GetMaxBetween自定义函数,它在指定的范围内寻找最大的数字,需要三个参数:一个数值范围,以及要搜索的最大和最小值。
现在我们要为这个自定义函数添加一个描述。 要做到这一点,创建并运行 Application.MacroOptions 命令。 对于 读取最大间隔时间 函数,你可以运行以下命令。
Sub RegisterUDF () Dim strFuncName As String '你要注册的函数的名称 Dim strDescr As String '函数本身的描述 Dim strArgs () As String '函数参数的描述 ' 注册GetMaxBetween函数 ReDim strArgs (1 To 3) '你的函数中的参数数 strFuncName = "GetMaxBetween" strDescr = "指定范围内的最大数量" strArgs (1) ="数值范围" strArgs (2) = "下区间边界" strArgs (3) = "上区间边界" Application.MacroOptions Macro: = strFuncName, _ Description: = strDescr, _ ArgumentDescriptions: = strArgs, _ Category: = " My Custom Functions " End Sub
或
Sub RegisterUDF () Application.MacroOptions Macro: = "GetMaxBetween" , _ Description: = "指定范围内的最大数字" , _ Category: = "My Custom Functions" , _ ArgumentDescriptions: = Array (_ "数值范围" , _ "下区间边界" , _ "上区间边界" ) End Sub变化的 str FuncName 是该函数的名称。 strDescr - 功能描述。 strArgs 变量包含每个参数的提示。
你可能想知道Application.MacroOptions的第四个参数是什么。 这个可选参数名为 类别 并指出我们自定义的Excel函数的类别。 获取最大间隔()。 你可以用现有的任何一个类别来命名它:数学& Trig, Statistical, Logical, 等等。 如果你不使用Category参数,那么自定义函数将自动被放在 "用户定义 "类别中。
将函数代码粘贴到模块窗口。
然后点击 "运行 "按钮。 该命令将执行所有设置,以使用 罚款 按钮与你的 GetMaxBetween() 功能。
如果你试图在一个单元格中插入一个函数,使用 插入功能 工具,你会看到,有你的 读取最大间隔时间 函数是在 "我的自定义函数 "类别中。
你可以简单地开始在单元格中输入函数名称,你会在函数的下拉列表中看到你的自定义函数,以便从中选择。
然后调用 功能向导 用Fx按钮。
提示:你也可以使用组合键CRTL+A来打开功能向导。
在 功能向导 如果你把光标放在第二个或第三个参数上,你也会看到它们的提示。
如果你想改变这些提示的文本,请改变以下的值 strDescr 和 strArgs 中的变量。 注册UDF()。 代码,然后运行 注册UDF()。 再一次命令。
如果你想撤销所有的设置并清除函数描述,请运行这段代码。
Sub UnregisterUDF () Application.MacroOptions Macro: = "GetMaxBetween" , _ Description: = Empty , ArgumentDescriptions: = Empty , Category: = Empty End Sub
还有一种方法可以在输入自定义函数时得到提示。 输入函数的名称,然后按Ctrl + Shift + A 。
=GetMaxBetween(
+ Ctrl + Shift + A
你会看到一个所有函数参数的列表。
不幸的是,在这里你不会看到函数及其参数的描述。 但如果参数的名称是相当有信息量的,那么它们也可能是有帮助的。 不过,这总比没有好 :)
要为UDF创建像标准Excel函数一样工作的智能提示,还需要更多的工作。 不幸的是,微软没有提供任何选项。 目前唯一的解决方案是Excel-DNA智能提示扩展。 你可以在开发者的网站上找到更多信息。
希望这些准则能帮助你解决你的自定义函数不能工作或不能如你所愿的问题。 但是,如果你的UDF仍然不能工作,请在评论区准确描述你的问题。 我们会努力弄清楚并为你找到解决方案;)