VBA размещен в Excel, но он совершенно различен: VBA ничего не знает о функциях листа Excel.По крайней мере, не изначально.
Итак, Substitute
нигде не определено - то же самое для VLookup
и многих других функций рабочего листа.Некоторые функции VBA имеют то же имя (или похожее имя), что и функции листа Excel, и ведут себя по-разному .
Стандартная библиотека VBA имеет Strings
модуль, который предоставляет ряд специализированных String
функций (некоторые из которых также существуют как функции рабочего листа, например, =LEFT
против Left
и Left$
).
As Том правильно указывает , стандартная библиотека VBA, которая эквивалентна Substitute
функции Excel, - это Replace
- функция, определенная в модуле VBA.Strings
, которую вы можете изучить, нажав F2 , чтобы вызвать VBE Обозреватель объектов :

Поскольку все эти функции имеют глобальную область действия, у вас нет для их полной квалификации;вот почему и как вы можете легально написать Debug.Print Replace(string1, string2)
.Но знайте, что вы всегда можете набрать VBA.
и получить IntelliSense для просмотра списка доступных функций - VBA.Strings.Replace
работает, как и VBA.Replace
, или просто 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
Теперь это многословно.Однако преимущество заключается в том, что теперь, если ваш проект VBA определяет функцию Replace
, места, которые вызывают VBA.Strings.Replace
или VBA.Replace
, будут по-прежнему вызывать эту функцию вместо вашей пользовательской функции VBAProject.Module1.Replace
, поскольку ссылка на идентификатор в VBAвсегда разрешается компилятором, начиная с наименьшей доступной области видимости: так что пользовательская функция может существовать в пользовательском модуле и «скрывать» или «скрывать» функцию стандартной библиотеки VBA (или любую другую функцию, определенную в любой другой библиотеке ссылочных типов).
И наконец, обратите внимание, что для случаев, когда вам действительно необходимо вызвать фактическую функцию рабочего листа, вы можете сделать это из объектной модели Excel - здесь с помощью блока 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
, Match
, VLookup
и множество других функций рабочего листа с помощью стандартного вызова члена VBA с ранним связыванием, который вызовет стандартную ошибку времени выполнения VBA, заданную недопустимымАргументы.
Вы также можете вызывать их с поздним связыванием непосредственно с объектом Application
- в этом случае недопустимые аргументы не будут вызывать ошибку, но возвратят one - точно так же, как они это делают в реальных рабочих листах (например, #VALUE!
) - если вы хотите вернуть это значение ошибки рабочего листа, ваша функция должна вернуть Variant
(неявное, как у вас, или явное, как указано ниже), потому чтоError
- это тип данных VBA, который не может быть приведен к значению String
, поэтому при возвращении присваивается несоответствие типов ошибка:
Public Function IPFix(ByVal IP As String) As Variant
With Application
IPFix = .Substitute(.Substitute(.Substitute("@." & Trim(IP), ".0", "."), ".0", "."), "@.", "")
End With
End Function
Обратите внимание, что, посколькуэти вызовы с поздним связыванием , они разрешаются только во время выполнения, что означает, что вы должны быть очень осторожны с опечатками;вы также не получите никаких IntelliSense или "быстрой информации о параметрах", чтобы помочь при вводе.