我们有一个始终以三位数的八位字节输出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格式,没有前导零。 但是我只是遇到这个编译错误。
答案 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} }与=LEFT
和Left
)。
与Tom correctly specifies一样,与Excel的Left$
函数等效的VBA标准库函数为Substitute
-在Replace
模块中定义的函数,您可以浏览通过按 F2 调出VBE的对象浏览器:
由于这些功能都是全局范围的,因此您没有完全限定它们的资格;这就是为什么以及如何合法书写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
以这种方式调用的工作表函数将与实际的工作表函数完全一样;您可以通过这种方式使用With
,Public 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”来提供帮助。