Excel自身的函数:编译错误:子或函数未定义

时间:2019-01-23 16:09:29

标签: excel vba function

我们有一个始终以三位数的八位字节输出IP地址数据的系统。我试图在Excel中创建自己的函数,以便从这些IP地址中删除任何不必要的前导零。我有一个行之有效的公式可以完成此任务,但是在尝试创建函数时,出现编译错误:未定义Sub或Function。 任何帮助,将不胜感激。

有效的公式:

=SUBSTITUTE(SUBSTITUTE(SUBSTITUTE("@." & TRIM(A2), ".0", "."), ".0", "."), "@.", "") 

例如如果单元格A2包含010.110.009.254,则此公式将得出10.110.9.254

Public Function IPFix(IP)
IPFix = Substitute(Substitute(Substitute("@." & Trim(IP), ".0", "."), ".0", "."), "@.", "")
End Function

我希望= IPFix(A2)将导致有效的IP格式,没有前导零。 但是我只是遇到这个编译错误。

2 个答案:

答案 0 :(得分:2)

Substitute替换为Replace函数的VBA

Public Function IPFix(IP)
    IPFix = Replace(Replace(Replace("@." & Trim(IP), ".0", "."), ".0", "."), "@.", "")
End Function

答案 1 :(得分:2)

VBA在Excel中是托管,但它是完全不同的:VBA对Excel的工作表功能一无所知。至少不是本地的。

因此,Substitute并未在任何地方定义-与VLookup和许多其他工作表功能相同。某些VBA函数与Excel工作表函数具有相同的名称(或相似的名称),且行为不同

VBA标准库确实具有一个Strings模块,该模块公开了许多专门的String函数(其中一些也作为工作表函数存在,例如{{1} }与=LEFTLeft)。

Tom correctly specifies一样,与Excel的Left$函数等效的VBA标准库函数为Substitute-在Replace模块中定义的函数,您可以浏览通过按 F2 调出VBE的对象浏览器

VBE object browser showing definition for VBA.Strings.Replace

由于这些功能都是全局范围的,因此您没有完全限定它们的资格;这就是为什么以及如何合法书写VBA.Strings的原因。但是要知道,您始终可以键入Debug.Print Replace(string1, string2)并获取 IntelliSense 列出可用的功能-VBA.可以像VBA.Strings.Replace一样工作,或者仅{{1} }:

VBA.Replace

现在罗word了。不过,这样做的好处是,现在,如果您的VBA项目定义了一个Replace函数,则调用Public Function IPFix(ByVal IP As String) As String IPFix = VBA.Strings.Replace(VBA.Strings.Replace(VBA.Strings.Replace("@." & Trim(IP), ".0", "."), ".0", "."), "@.", "") End Function Replace的位置仍将调用该函数而不是您的VBA.Strings.Replace自定义函数-因为VBA中的标识符引用始终由编译器解析,并且从最小的可访问范围开始:因此,自定义函数可以存在于自定义模块中,并且可以“阴影”或“隐藏” VBA标准库函数(或任何其他函数)在其他任何引用的类型库中定义。)

很遗憾,请注意,有时您确实需要调用实际的工作表函数,则可以从Excel对象模型中进行操作-在这里使用VBA.Replace块来减少纠缠:

VBAProject.Module1.Replace

以这种方式调用的工作表函数将与实际的工作表函数完全一样;您可以通过这种方式使用WithPublic Function IPFix(ByVal IP As String) As String With Application.WorksheetFunction IPFix = .Substitute(.Substitute(.Substitute("@." & Trim(IP), ".0", "."), ".0", "."), "@.", "") End With End Function Index很多其他工作表函数,并通过早期绑定的标准VBA成员调用给出无效参数的标准VBA运行时错误。

您还可以直接针对Match对象对它们进行后期绑定-在这种情况下,无效参数不会 raise 错误,但是 return 一个-就像它们在实际工作表中一样(例如VLookup)-如果您想返回该工作表错误值,则您的函数需要返回一个Application(隐式的,如下所示) ,因为#VALUE!是无法强制转换为Variant值的VBA数据类型,所以返回赋值将引发 type mismatch 错误:

Error

请注意,因为这些调用是 late-bound ,所以它们只能在运行时解决,这意味着您必须非常小心输入错误。键入时,您也不会得到任何 IntelliSense 或“ parameter quick-info”来提供帮助。