Синтаксическая ошибка вызова многопараметрической функции VBA - PullRequest
4 голосов
/ 16 апреля 2011

Я пытаюсь вызвать функцию в Excel VBA (2007) и получаю синтаксическую ошибку при вызове.У меня есть массив структур данных с именем ImportSets, который содержит рабочие листы и строки, и я пытаюсь передать элементы элементов этого массива в функцию, которая называется Import.

Код вызова выглядит следующим образом:

For n = 1 To 7  
    Debug.Print ("Destsheet: " & ImportSets(n).DestSheet.name)  
    Debug.Print ("Sourcesheet: " & ImportSets(n).SourceSheet.name)  
    Debug.Print ("Sourcecolumn: " & ImportSets(n).SourceColumn)  
    Import(CostAnalysisWorksheet.Sheets("Reimbursements"), ImportSets(n).DestSheet, ImportSets(n).SourceSheet, ImportSets(n).SourceColumn)  
Next n  

Все операторы Debug.Print возвращают значимые и правильные строки и проверяют наличие «Возмещений»возвращает истину.Вызов метода находится в одной строке.Вот код объекта ImportSet:

Public Type ImportSet
    DestSheet As Worksheet
    SourceSheet As Worksheet
    SourceColumn As String
    ...other code...
End Type

Тело функции выглядит следующим образом:

Function Import(ByRef ReimbursementSheet As Worksheet, ByRef DestSheet As Worksheet, ByRef ImportSheet As Worksheet, ByRef ImportSheetPriceColumn As String) As String  
    ....code here .....  
End Function

Я получаю выделенную красным цветом ошибку синтаксиса при вызове функции (впервый фрагмент).Я, наверное, скучаю по чему-то глупому.Что это?

Ответы [ 3 ]

7 голосов
/ 16 апреля 2011

Я не использовал VBA в Excel 2007, но более старые версии позволяют заключать в скобки параметры вызова функций только в том случае, если вы присваиваете возвращаемое значение переменной.Попробуйте это:

Import CostAnalysisWorksheet.Sheets("Reimbursements"), ImportSets(n).DestSheet, ImportSets(n).SourceSheet, ImportSets(n).SourceColumn
2 голосов
/ 17 апреля 2011

Важным моментом является то, как вы хотите, чтобы функция возвращала значение, и передавали ли вы переменные ByVal или ByRef.ByRef позволяет функции изменять переменную. ByVal означает, что функция не может изменить переменную.

Эти два примера, по сути, делают то же самое, но отмечают тонкость в манипулировании переменной ByRef и возвращении переменной из функции.

Sub test()
Dim lngX As Long, lngY As Long, Product As Long

   lngY = 10
   lngX = 5
   Product = multiply(lngX, lngY)
   MsgBox (Product)
End Sub

Function multiply(ByVal lngX As Long, ByVal lngY As Long) As Long
   multiply = lngY * lngX
End Function

или, альтернативно, передайте переменные ByRef и манипулируйте с помощью функции

Sub test()
Dim lngX As Long, lngY As Long, Product As Long

   lngY = 10
   lngX = 5
   Product = 0
   multiply lngX, lngY, Product
   MsgBox (Product)

End Sub

Function multiply(ByVal lngX As Long, ByVal lngY As Long, ByRef Product As Long)
  Product = lngY * lngX
End Function

Этот пример довольно тривиален, но часто объект, массив и т. Д. Может потребоваться передать функции для обработки ByRef, а недать ответ ByVal

1 голос
/ 22 мая 2019

Эти вопросы и ответы используются как дублирующая цель, но ни один из ответов не рассказывает всю историю.

Во-первых, это поведение не имеет ничего общего с версией Excel или каким-либо другим приложением хоста:это просто стандартный синтаксис VBA, и правила были такими же уже более 20 лет - JavaScript и Perl также имеют свои соответствующие изломы , как и каждыйкогда-либо созданный язык программирования .

Когда скобки ограничивают список аргументов , VBE ставит открывающую скобку сразу после вызываемой функции:

foo = MsgBox("test")
           ^^^

Когда скобки интерпретируются как часть первого аргумента (то есть выражение в скобках ), VBE помещает пробел между вызванной процедурой и списком ее аргументов:

MsgBox ("test")
     ^^^

Этот код не будет компилироваться:

MsgBox ("test", vbInformation)
     ^^^

Поскольку все выражение в скобках является первым аргументом , и нет никакого способа ("test", vbInformation) может быть оценено как значение - это синтаксическая ошибка, как в OP.

Если выражение может быть оценено как значение, то это значение затем передается значение (ByVal) независимо от сигнатуры вызванной процедуры с указанием этого параметра как ByRef - см. 5.3.1.11 Обработка аргумента вызова процедуры , семантика времени выполнения :

  • Если у параметра нет сопоставленного аргумента, параметром является ByVal, или параметр ByRef, а выражение сопоставленного аргумента классифицируется какзначение , функция, свойство или несвязанный член, локальная переменная определяется с экстентом процедуры в вызываемой процедуре с тем же значением имени и объявленным типом, что и параметр [...]

Решение, как другие пришли к выводу, состоит в том, чтобы убрать скобки при выполнении вызова процедуры :

MsgBox "test", vbInformation

... или последовательно используйте устаревшее явный синтаксис вызова :

Call MsgBox("test", vbInformation)

Скобки нужны только при выполнении вызова функции (т.е. при захвате возвращаемого значения в локальную переменную):

Dim result As vbMsgBoxResult
result = MsgBox("test", vbInformation Or vbOkCancel)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...