InStr перегружен параметрами Variant.
Функция InStr
имеет 4 необязательных параметра во время разработки, но во время выполнения необходимо указать как минимум 2 аргумента. Первые 3 параметра InStr
— это все Variant
, что позволяет InStr
поддерживать два разных синтаксиса и эффективно имитировать перегруженную функцию. Это одна из причин, по которой String1
и String2
определяются как типы Variant
, а не как типы String
. Start
может быть Long
, но это также и Variant
тип.
В следующих 4 примерах x
всегда присваивается значение 4
.
Вариант 1. Использование определенного порядка параметров или значений имен
Сигнатура функции ведет себя так, как она определена:
Функция InStr([Start], [String1], [String2], [Compare As VbCompareMethod = vbBinaryCompare])
x = VBA.InStr(1, "food", "D", vbTextCompare) '4
x = VBA.InStr(Start:=1, String1:="food", String2:="D", Compare:=vbTextCompare) '4
Вариант 2. Использование альтернативного порядка или значения имени
Сигнатура функции ведет себя так, как если бы она была определена следующим образом:
Функция InStr([String1], [String2], , [Сравнить как VbCompareMethod = vbBinaryCompare])
Фактически это означает, что Start
следует использовать так, как если бы это было String1
, а String1
следует использовать так, как если бы это было String2
. Аргумент String2
должен быть опущен, иначе вы получите ошибку Type Mismatch
.
x = VBA.InStr("food", "D", , vbTextCompare) '4
x = VBA.InStr(Start:="food", String1:="D", Compare:=vbTextCompare) '4
Использование именованных параметров
Но, как вы обнаружили, функция InStr
страдает от ошибок синтаксиса и/или компиляции при использовании именованных параметров:
Синтаксическая ошибка: ожидаемый разделитель списка
Когда названы все параметры:
x = InStr(Start:=1, String1:="foo", String1:="foo", Compare:=vbBinaryCompare)
Вы получаете:
Синтаксическая ошибка: ожидаемый разделитель списка
Ошибка компиляции: объект не поддерживает именованные аргументы
Когда некоторым параметрам присвоено имя:
x = InStr(1, String1:="foo", String2:="foo", Compare:=vbBinaryCompare)
Вы получаете:
Ошибка компиляции: объект не поддерживает именованные аргументы.
Те же ошибки с функцией StrComp
Функция StrComp
, по-видимому, не имеет какой-либо функциональности перегруженного типа, но имеет те же проблемы с ошибками синтаксиса и компиляции:
x = StrComp(String1:="foo", String2:="foo", Compare:=vbBinaryCompare) 'Syntax Error: Expected List Separator???
x = StrComp("foo", String2:="foo", Compare:=vbBinaryCompare) 'Compile error: Object doesn't support named arguments
Но, как обнаружил ОП, ошибка не возникает с InStrRev
.
Итак, что общего у InStr
и StrComp
, что отличается от InStrRev
и казалось бы всех остальных функций VBA?
Что ж, InStr
и StrComp
оба имеют эти общие черты:
- Функции определены в первой библиотеке типов, на которую ссылаются.
- Функции определены в модуле TLB/COM.
- Все параметры, кроме последнего, относятся к типу
Variant
.
- Последний параметр — это
Enum
со значением по умолчанию.
- Возвращаемое значение является вариантом
Я не могу найти какие-либо другие функции в библиотеке VBA, которые имеют такие же характеристики, поэтому я подозреваю, что это ошибка компиляции, связанная с этими характеристиками.
Квалификация функции устраняет проблему!?!?
И InStrRev
, и StrComp
могут использоваться со всеми/некоторыми именованными параметрами, если функция уточняется по имени библиотеки или имени модуля:
'InStr Vanilla usage:
x = Strings.InStr(Start:=1, String1:="food", String2:="D", Compare:=vbTextCompare) '4
x = VBA.InStr(Start:=1, String1:="food", String2:="D", Compare:=vbTextCompare) '4
'InStr Alternate usage:
x = Strings.InStr(Start:="food", String1:="D", Compare:=vbTextCompare) '4
x = VBA.InStr(Start:="food", String1:="D", Compare:=vbTextCompare) '4
'StrComp usage
x = Strings.StrComp(String1:="food", String2:="D", Compare:=vbTextCompare) '1
x = VBA.StrComp(String1:="food", String2:="D", Compare:=vbTextCompare) '1
person
ThunderFrame
schedule
16.09.2016