如何在vba中创建用户定义的函数?
学习 VBA 最酷的好处之一可能就是能够创建自己的函数。
Excel 中有超过 450 个函数,其中一些函数在您的日常工作中非常有用。但是 Excel 为您提供了使用 VBA 创建自定义函数的选项。是的你是对的。 USER DEFINED Function,缩写为 UDF,或者您也可以将其称为自定义 VBA 函数。
我可以自信地说,每个 VBA 新用户都想学习如何创建用户定义函数。不是你?如果您是想要创建自定义功能的人之一,请在评论部分说“是”。
我很高兴地告诉您,这是一个完整的指南,可帮助您使用 VBA 创建您的第一个自定义函数,除此之外,我还分享了一些用户定义函数的示例来帮助启发您。
- 在这里,我将交替使用“用户定义函数”、“自定义函数”和“UDF”这三个词。所以请跟着我,在接下来的几分钟内您将成为 VBA 摇滚明星。
- 要为 VBA 自定义函数创建代码,您需要编写它,不能 使用宏录制器录制它。
为什么应该创建自定义 Excel 函数
正如我所说,Excel 中有许多内置函数可以帮助您解决几乎任何问题并执行各种计算。但是,有时在特定情况下您需要创建 UDF。
并且,下面我列出了您应该使用自定义函数的一些原因或情况。
1. 当没有此功能时
这是使用 VBA 创建 UDF 的常见原因之一,因为有时您需要计算某些内容,但没有特定的函数。我可以给您举一个计算单元格中单词数的示例,为此我发现 UDF 可以是一个完美的解决方案。
2.替换复杂的公式
如果您使用公式,我相信您知道复杂的公式很难阅读,有时其他人也更难理解。因此,自定义函数可以解决这个问题,因为一旦创建了 UDF,就不需要一次又一次地编写这个复杂的公式。
3. 当你不想使用SUB例程时
尽管您可以使用 VBA 代码来执行计算,但 VBA 代码不是动态的*。如果您想更新计算,则必须再次运行此代码。但是,如果将此代码转换为函数,则无需一次又一次运行此代码,因为您只需将其作为函数插入即可。
如何在 Excel 中创建您的第一个用户定义函数
好吧那就看看吧。我把整个过程分为三个步骤:
- 将您的过程声明为函数
- 定义其参数及其数据类型
- 添加代码来计算所需的值
但让我告诉你:
您需要创建一个可以从日期值返回日期名称的函数。好吧,我们有一个返回星期几的函数,但不返回名称。你明白我所说的吗?是的?
因此,让我们按照以下步骤创建您的第一个用户定义函数:
- 首先,使用 ALT + F11 快捷键打开Visual Basic 编辑器,或者转到“开发人员”选项卡,然后单击“Visual Basic”按钮。
- 接下来是插入模块,因此右键单击VBA项目窗口,然后转到插入,然后单击“模块”。 (警告:您只能在标准模块中输入用户定义函数。Sheet 和 ThisWorkbook 模块都是特殊类型的模块,如果您在这两个模块中输入 UDF,Excel 不会识别您正在创建 UDF) 。
- 第三件事是定义函数的名称,这里我使用“myDayName”。所以你需要写“Function mydayName”。为什么功能在名称之前?创建 VBA 函数时,使用“函数”一词告诉 Excel 将此代码视为函数(请务必先阅读消息中的 UDF 范围)。
- 之后,您需要为您的函数定义参数。因此,插入前括号并写入“InputDate As Date”。这里,InputDate 是参数名称,date 是其数据类型。最好为参数定义数据类型。
- 现在关闭括号并写入“As String”。这里你定义了函数返回结果的数据类型,由于你想要的日期名称是一个文本,所以它的数据类型必须是“String”。如果您希望结果不是字符串,请确保相应地设置其数据类型。 (myDayName(InputDate As Date) As String 函数)。
- 最后,按 ENTER 键。此时,您的函数名称、其参数、参数数据类型和函数数据类型已设置,并且模块中具有如下所示的内容:
- 现在,在“Function”和“End Function”中,您需要定义计算,或者您可以说明该 UDF 的工作原理。在 Excel 中有一个名为“Text”的工作表函数,我们在这里使用相同的函数。为此,您必须编写下面的代码,并使用此代码定义函数应返回的值。 myDayName = WorksheetFunction.Text(InputDate, “dddddd”)
- 现在关闭 VB 编辑器并返回工作表,在单元格 B2 中输入“=myDayName(A2)”按 Enter 键,您将获得当天的名称。
恭喜!您刚刚创建了第一个用户定义函数。这是真正喜悦的时刻。不是吗?在评论区输入“欢乐”。
该函数如何工作并在单元格中返回值
您的第一个自定义函数就在这里,但重点是您需要了解它是如何工作的。如果我简单地说,它是 VBA 代码,但您将其用作函数过程。我们将其分为三个部分:
- 您将其作为函数输入单元格并指定输入值。
- Excel 运行函数后面的代码并使用您引用的值。
- 您在单元格中得到了结果。
但你需要从内部了解这个函数是如何工作的。因此,我将整个过程分为三个不同的部分,您可以在其中看到为该函数编写的代码实际上是如何工作的。
由于您已指定“InputDate”作为函数参数,并且当您在单元格中输入函数并指定日期时,VBA 会采用该日期值并将其提供给您在代码中使用的文本函数。
在我上面提到的示例中,单元格 A1 中的日期是 2019 年 1 月 1 日。
之后,TEXT 函数使用您在函数代码中提到的“dddddd”格式代码将此日期转换为日期。 TEXT 函数返回的这一天被分配给“myDayName”。
因此,如果 TEXT 函数的结果是 Tuesday,则该值将分配给“myDayName”。
到这里函数的运行就结束了。 “myDayName”是函数名称,因此分配给“myDayName”的任何值都将是结果值,并且您插入到工作表中的函数将在单元格中返回它。
当您为自定义函数编写代码时,必须确保将该代码返回的值分配给函数名称。
如何永久改进 UDF
好吧,您知道如何创建自定义 VBA 函数。
现在…
您需要做一件事来确保您使用的代码应该足以处理所有可能性。如果您正在谈论上面刚刚编写的函数,您可以从日期返回日期名称。
目的…
如果您指定的值不是日期怎么办?如果您引用的单元格为空怎么办?可能还有其他可能性,但我相信您明白我的意思。
正确的?因此,让我们尝试改进这个自定义函数,也许能够解决上述问题。好的。首先,您需要更改参数的数据类型并使用:
InputDate As Variant
这样,您的自定义函数就可以采用任何类型的数据作为输入。接下来,我们需要使用VBA IF 语句来检查 InputDate 是否符合某些条件。第一个条件是单元格是否为空。为此,您必须使用以下代码:
If InputDate = "" Then myDayName = ""
如果您引用的单元格为空,这将使该函数为空。
一个问题解决了,我们继续下一个问题。除了日期之外,您还可能有数字或文本。因此,为此您还需要创建一个条件来检查引用的值是否是真实日期。
代码是:
If IsDate(InputDate) = False Then myDateName = ""
这里我对这两个条件都使用空白,这样如果您有大量数据,您可以轻松过滤掉输入值无效的值。因此,添加上述条件后,代码将如下所示:
Function myDayName(InputDate As Variant) As String If InputDate = "" Then myDayName = "" Else If IsDate(InputDate) = False Then myDateName = "" Else myDayName = WorksheetFunction.Text(InputDate, "dddddd") End If End If End Function
现在它的工作原理如下:我确信您仍然可以对此功能进行更改,但我确信您清楚地理解我的观点。
如何使用自定义 VBA 函数
至此,您已经大致了解了如何在Excel中创建VBA函数。但一旦你拥有它,你需要知道如何使用它。在这篇文章的这一部分中,我将与您分享如何以及在何处使用它。那么,让我们开始吧。
1. 简单地在电子表格中
我们为什么要创建自定义函数?简单的。在电子表格中使用它。您只需使用等号和函数的类型名称将 UDF 输入到电子表格中,然后指定其参数即可。
您还可以从函数库中输入用户定义的函数。转到公式选项卡 ➜ 插入函数 ➜ 用户定义。
您可以从此列表中选择要插入的 UDF。
2. 使用其他子程序和函数
您还可以在其他函数或“Sub”过程中使用函数。下面是一个 VBA 代码,您在其中使用函数来获取当前日期的日期名称。
Sub todayDay() MsgBox "Today is " & myDayName(Date) End Sub
请务必阅读本文后面的“UDF 的范围”,以了解有关在其他过程中使用函数的更多信息。
3. 访问另一个工作簿中的函数
如果一个工作簿中有一个 UDF,并且想要在另一工作簿或所有工作簿中使用它,则可以通过为其创建加载项来实现。请按照以下简单步骤操作:
- 首先,您需要将文件(其中包含自定义函数代码)保存为加载项。
- 为此,请转至文件选项卡 ➜ 另存为 ➜ “Excel 加载项 (.xalm)”。
- 之后,双击该加载项并安装它。
就是这样。您现在可以在任何工作簿中使用所有 VBA 函数。
创建自定义 VBA 函数的不同方法 [高级]
至此,您已经知道如何在 VBA 中创建自定义函数了。但问题是,当我们使用内置函数时,它们带有不同类型的参数。
因此,在本指南的这一部分中,您将学习如何使用不同的参数类型创建 UDF。
- 没有任何争论
- 有一个参数
- 有几个论点
- 使用数组作为参数
… 向前进。
1. 没有任何论点
还记得像 NOW 和 TODAY 这样不需要输入参数的函数吗?
是的。您可以创建用户定义的函数,无需输入任何参数。让我们举个例子:
让我们创建一个可以返回当前文件位置的自定义函数。这是代码:
Function myPath() As String Dim myLocation As String Dim myName As String myLocation = ActiveWorkbook.FullName myName = ActiveWorkbook.Name If myLocation = myName Then myPath = "File is not saved yet." Else myPath = myLocation End If End Function
该函数返回当前文件存储位置的路径,如果工作簿没有存储在任何地方,则会显示一条消息“文件尚未保存”。
现在,如果您密切关注该函数的代码,您就不需要定义参数(在括号中)。您刚刚定义了函数结果的数据类型。
创建不带参数的函数的基本规则是您不必在其中键入任何内容的代码。
简而言之,您想要从函数返回的值应该自动计算。
在这个函数中你有同样的东西。
此 ActiveWorkbook.FullName 返回文件的位置,此 ActiveWorkbook.Name 返回名称。您无需输入任何内容。
2.只有一个参数
我们已经通过学习如何创建用户定义函数来介绍这一点。但让我们更深入地挖掘并创建一个不同的函数。这是我几个月前创建的函数,用于从超链接中提取 URL 。
Function giveMeURL(rng As Range) As String On Error Resume Next giveMeURL = rng.Hyperlinks(1).Address End Function
现在在这个函数中你只有一个参数。
当您将其输入到单元格中,然后指定具有超链接的单元格时,它将返回超链接的 URL。现在,在这个函数中,主要工作是通过以下方式完成的:
rng.Hyperlinks(1).Address
但 rng 是您需要指定的。如果您发现创建 UDF 很容易,请在评论部分说“简单”。
3.有几个论点
通常, 大多数 Excel 内置函数都有多个参数。因此,学习如何创建具有多个参数的自定义函数至关重要。
让我们举个例子:您想要从文本字符串中删除特定字母并希望保留该部分的其余部分。
好吧,您将在此自定义函数中使用 RIGHT 和 LEN 等函数。但在这里我们不需要这个。我们所需要的只是使用 VBA 的自定义函数。
所以,这是这个函数:
Function removeFirstC(rng As String, cnt As Long) As String removeFirstC = Right(rng, Len(rng) - cnt) End Functio
好吧然后看:
在此函数中,您有两个参数:
- rng:在此参数中,您必须指定要从中删除文本第一个字符的单元格。
- cnt:在参数中,您需要指定要删除的字符数(如果您想从文本中删除多个字符)。
当您在单元格中输入它时,它的工作原理如下:
3.1 创建带有可选参数和必需参数的用户定义函数
如果您考虑一下我们在上面的示例中刚刚创建的函数,其中有两个不同的参数,那么,两者都是必要的。而且,如果您错过其中任何一个,您都会收到这样的错误。
现在,如果您按逻辑思考,我们创建的函数是删除第一个字符。但这里需要指定要删除的字符数。所以我的观点是,这个参数应该是可选的,并且应该将其作为默认值。
你怎么认为?
如果您同意我的观点,请在评论部分说“是”。
好吧那就看看吧。要使参数可选,只需在其前面添加“可选”即可。就像这样:
但重要的是让你的代码在有或没有这个参数的值的情况下都能工作。因此,同一函数的新代码将如下所示: 现在在代码中,如果您忽略指定第二个参数。
4. 使用数组作为参数
有一些内置函数可以采用数组参数,您还可以创建自定义 VBA 函数来执行此操作。
让我们通过一个简单的示例来实现此目的,您需要创建一个函数,对包含数字和文本的范围的值进行求和。我们到了。
Function addNumbers(CellRef As Range) Dim Cell As Range For Each Cell In CellRef If IsNumeric(Cell.Value) = True Then Result = Result + Cell.Value End If Next Cell addNumbers = Result End Function
在上面的函数代码中,我们使用整数范围 A1:A10 而不是单个值或单元格引用。
使用 FOR EACH 循环,它将检查范围中的每个单元格,如果单元格包含数字,则对值求和。
用户定义函数的范围
简单来说,函数的作用域意味着它是否可以被其他过程调用。 FDU 可以有两种不同类型的范围。
1. 观众
您可以将自定义函数公开,以便可以在工作簿中的所有工作表中调用它。要使函数公开,只需使用“Public”一词,如下所示。
但是,如果您不将函数设为私有,则默认情况下该函数是公共函数。在我们介绍的所有示例中,它们都是公开的。
2. 私人
将函数设为私有后,可以在同一模块的过程中使用它。
假设您的 UDF 位于“Module1”中,则只能在“Module1”中的过程中使用它。它不会出现在工作表函数列表中(当您使用 = 符号并尝试键入名称时),但您仍然可以通过键入其名称并指定参数来使用它。
用户定义函数 [UDF] 的限制
UDF 非常有用。但它们在某些情况下受到限制。在 VBA 中创建自定义函数时,我希望您注意并记住以下几点。
- 您无法使用自定义函数编辑、删除单元格和范围或设置单元格和范围的格式。
- 也无法移动、重命名、删除工作表或将工作表添加到工作簿。
- 更改另一个单元格的值。
- 它也无法更改环境选项。
内置函数和用户定义函数有区别吗?
我很高兴你问了。好吧,为了回答这个问题,我想分享一些我认为对您来说很重要的观点。
- 比内置函数慢:如果比较内置函数和VBA函数的速度,你会发现前者快。其背后的原因是内置函数是用 C++ 或 FORTRAN 编写的。
- 共享文件困难:我们经常通过电子邮件和云共享文件。如果您正在使用任何自定义函数,则需要以“xlam”格式共享此文件,以便其他人也可以使用您的自定义函数。
但正如我在上面的“为什么应该创建自定义 Excel 函数”中所说,在某些特定情况下您可以选择 VBA 自定义函数。
结论
创建用户定义的函数很简单。您所需要做的就是在名称前使用“Function”将其定义为函数,添加参数,设置参数的数据类型,然后设置返回值的数据类型。
最后,添加代码来计算要从函数返回的值。我今天与您分享的本指南是学习如何在 VBA 中创建自定义函数的最简单的指南,我相信您会发现它很有用。
但现在告诉我一件事。
UDF 很有用,您觉得怎么样?
请在评论部分与我分享您的看法。我很想收到您的来信,请不要忘记与您的朋友分享这篇文章,我相信他们会很感激。