Ошибка компиляции VBA, если функция Instr используется с именованным параметром и возвращаемым значением, назначенным переменной
фон : в VBA, 'InStrRev' функция может вызываться без или с именованными параметрами.
'Call without named parameters
Call InStrRev("AB", "B") 'No compiler error
i = InStrRev("AB", "B") 'No compiler error
'Call with named parameters
Call InStrRev(StringCheck:="AB", StringMatch:="B") 'No compiler error
i = InStrRev(StringCheck:="AB", StringMatch:="B") 'No compiler error
забота : в VBA компилятор возвращает ошибку "Expected: list separator", если'InStr':
- вызывается с именованными параметрами и
-
возвращаемое значение присваивается переменной
'Call without named parameters Call InStr("AB", "B") 'No compiler error i = InStr("AB", "B") 'No compiler error 'Call with named parameters Call InStr(String1:="AB", String2:="B") 'No compiler error i = InStr(String1:="AB", String2:="B") 'Compiler error : "Expected: list separator"
вопрос : Почему возникает ли ошибка компилятора VBA, когда'Instr' используется с именованными параметрами и ее возвращаемое значение присваивается переменной ? Это ограничение языка или ошибка компилятора ?
ссылка : скриншот редактора VBA для 'InstrRev' и 'Instr инструмент подсказки. Различия выделены красным цветом.
Примечание : 'String1' & 'String2 'являются необязательными аргументами для'InStr' функция в соответствии с выше скриншот всплывающей подсказки квадратных скобок. Однако они необходимы, как указано ниже в ответе и в справочнике языка Visual Basic:https://msdn.microsoft.com/EN-US/library/office/gg264811.aspx
2 ответов
InStr
странно в том, что его первый аргумент (Start
) является необязательным, но его последующее String1
/String2
аргументов нет (несмотря на []
в подсказке) - если они были дополнительно InStr(1)
б анализировать но это не так и генерирует ту же ошибку, которую вы видите.
в частности, это странно, потому что VBA запрещает это; правило заключается в том, что необязательные аргументы не могут следовать необязательным аргументам, что имеет смысл, поскольку были бы случаи когда компилятор не смог сопоставить аргументы с тем, что ожидала функция. Это также заставляет все его аргументы быть вариантами.
VB6 / A имеет много багажа, перевезенного из QBASIC, и этот язык (который iirc не разрешал пользовательские необязательные аргументы) имеет точно такую же подпись для его INSTR()
поэтому я предполагаю, что поведение, которое вы видите, является артефактом специальных правил синтаксического анализа, которые должны существовать для вызовов InStr
.
любопытно его полностью полное имя
i = VBA.Strings.InStr(String1:="AB", String2:="B")`
не разобрать, но выдает ошибку во время выполнения, если Start
предназначен:
i = VBA.Strings.InStr(String1:="AB", String2:="B", Start:=1)`
, который работает, как ожидалось.
одной из причин Call
форма может показаться, что работает, это ее no-op и может быть оптимизирована.
VBA.X () vs X ()
это прекрасно:
ptr = VBA.CLng(AddressOf someFunc)
это генерирует время разбора Ожидается, Что Выражение ошибка:
ptr = CLng(AddressOf someFunc)
InStr перегружен с помощью параметров варианта
на InStr
функция имеет 4 необязательных параметра во время разработки, но во время выполнения должно быть предоставлено не менее 2 аргументов. Первые 3 параметра до InStr
are все Variant
, позволяющего InStr
для поддержки двух разных синтаксисов и эффективной имитации перегруженной функции. Это одна из причин того, что String1
и String2
определяется как Variant
типы, а не как String
типы. Start
может быть Long
, но это Variant
тоже тип.
в следующих 4 примерах,x
и всегда присваивается значение 4
Вариант 1-использование определенного порядка параметров или имен-значения
сигнатура функции ведет себя так, как она определена:
Функция InStr ([Пуск], [String1], [String2], [Сравнить Как 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
. The 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)
вы получаете:
ошибка компиляции: