Должен ли я использовать ключевое слово Call в VB / VBA? - PullRequest
45 голосов
/ 04 апреля 2010

Я использую ключевое слово Call при вызове подпрограмм в VB / VBA. Я знаю, что это необязательно, но лучше ли его использовать или оставить? Я всегда думал, что это было более явно, но, возможно, это просто шум.

Кроме того, я читал это на другом форуме: использование ключевого слова Call происходит быстрее, поскольку он знает, что не собирается возвращать какие-либо значения, поэтому ему не нужно устанавливать какое-либо стековое пространство, чтобы освободить место для возврата. значение.

Ответы [ 9 ]

27 голосов
/ 11 марта 2014

Ах, ха. Я давно задумывался над этим, и даже читая книгу на VBA толщиной в два дюйма, в основном говорится, что не используйте ее, если вы не хотите использовать функцию Найти в VBE, чтобы легко находить вызовы в крупных проектах.

Но я только что нашел другое применение.

Мы знаем, что возможно объединить строки кода с символом двоеточия, например:

Function Test(mode as Boolean) 
    if mode = True then x = x + 1 : Exit Sub
    y = y - 1
End Sub

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

Function Test()
Function1 : Function2
End Function

Использование оператора Call позволяет объединять вызовы процедур при сохранении отступов кода:

Function Test()
    Call Function1 : Call Function2
End Function

Если вы не используете оператор Call в приведенном выше примере, VBE примет, что «Function1» является меткой, и выровняет его по левому краю в окне кода, даже если это не приведет к ошибка.

11 голосов
/ 04 апреля 2010

Для VB6, если есть вероятность, что он будет конвертирован в VB.NET, использование Call означает, что синтаксис не меняется. (Скобки требуются в VB.NET для вызовов методов.) (Лично я не думаю, что это стоит того - любой конвертер .NET, по крайней мере, сможет ставить скобки, когда это необходимо. Я просто перечисляю его как причина.)

В противном случае это просто синтаксический сахар.

Обратите внимание, что ключевое слово Call, скорее всего, не будет быстрее при вызове какого-либо другого метода / функции, потому что функция все равно возвращает свое значение, и VB не нужно было создавать локальную переменную для ее получения, даже когда Call не используется.

10 голосов
/ 06 апреля 2010

Я всегда использую Call в VBA. Для меня это выглядит чище. Но, я согласен, это просто синтаксический сахар, который прямо определяет его в личных предпочтениях. За последние несколько лет я встречал, наверное, дюжину полностью занятых ребят из VBA, и ни один из них не использовал Call. Это имело дополнительное преимущество: я всегда знал, какой код мой. : Р

4 голосов
/ 06 апреля 2010

Нет, это просто добавит 7 символов за вызов без какой-либо выгоды.

3 голосов
/ 05 апреля 2010

Я использую Call для всех VBA-разработок общих библиотечных функций, которые я, возможно, буду использовать в VB.NET. Это позволяет мне перемещать код, используя копирование и вставку между всеми разновидностями VB. Я делаю это, чтобы избежать синтаксических ошибок, которые создает редактор кода, когда он «форматирует» или «красиво печатает» вставленный код. Единственными правками обычно являются Set оператор включения / исключения.

Если вы не планируете перемещать код VB / VBA в VB.NET, тогда нет необходимости использовать оператор Call.

1 голос
/ 16 июня 2019

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

Большой вывод для вас заключается в том, что если вы действительно используете круглые скобки вокруг аргументов процедуры, возможно, наизусть или по привычке, даже если они не требуются, тогда вы ДОЛЖНЫ ИСПОЛЬЗОВАТЬ Call, чтобы убедиться, что неявная или явная процедура ByRef подпрограммы не является игнорируется в пользу ByVal; или вместо этого вы должны использовать присвоение «знака равенства» возвращаемого значения для предотвращения игнорирования (в этом случае вы не будете использовать Call).

Опять же, это защищает вас от неблагоприятного получения ByVal от рутины. И наоборот, если, конечно, вы ХОТИТЕ интерпретацию ByVal независимо от объявления процедуры, тогда оставьте вызов (и используйте скобки).

Обоснование: обобщение https://msdn.microsoft.com/en-us/library/ee478101%28v=vs.84%29.aspx «Параметры ByRef и ByVal»

Если
1. есть назначение возврата вызова функции, e. г.
iSum = myfunc (myArg)
или
2. Используется «Call», e. г.
позвоните myFunc (myArg)
или
позвоните mySub (myArg)

тогда круглые скобки строго разграничивают список вызывающих аргументов; объявление процедуры определяет ByVal или ByRef. В противном случае скобки заставляют ByVal использоваться подпрограммой - даже если ByVal не был указан в подпрограмме. Таким образом,
mySub (myArg) 'использует ByVal независимо от объявления процедуры
в то время как
Вызов mySub (myArg) использует ByRef, если подпрограмма не объявляет ByVal

Также обратите внимание, что Call синтаксически требует использования скобок. Вы можете пойти
mySub myArg
но ты не можешь идти
позвони mySub myArg
но вы МОЖЕТЕ пойти
позвоните mySub (myArg)
(и синтаксически необходимы скобки для присвоения возвращаемого значения функции)

ОБРАТИТЕ ВНИМАНИЕ, однако, что ByVal в объявлении процедуры переопределяет все это. И к вашему сведению, ByRef всегда подразумевается в декларации, если вы молчите; Таким образом, TMK ByRef не имеет никакого очевидного значения, кроме документального.

Повторение сверху: Большой вывод для вас заключается в том, что если вы действительно используете круглые скобки вокруг аргументов процедуры, возможно, наизусть или по привычке, даже если они не требуются, то вы ДОЛЖНЫ ИСПОЛЬЗОВАТЬ Call, чтобы убедиться, что процедура неявна или явный ByRef не игнорируется в пользу ByVal; или вместо этого вам следует использовать присвоение «знака равенства» возвращаемого значения, чтобы предотвратить игнорирование (в этом случае вы не будете использовать Call).

Опять же, это защищает вас от неблагоприятного получения ByVal от рутины. И наоборот, если, конечно, вы ХОТИТЕ интерпретацию ByVal независимо от объявления процедуры, тогда оставьте вызов (и используйте скобки).

1 голос
/ 05 марта 2018

Единственный случай, когда я обнаружил, что "call" полезен - это случайность, о некоторых специальных операторах.

Dim c As IAsyncOperation(Of StartupTask) = StartupTask.GetAsync("Startup")
……
(Await c).Disable()

Я получил синтаксическую ошибку для второй строки, точно так же, как вы получите с оператором «New». Я действительно не хочу новую переменную, которая слишком не элегантна для меня. Итак, я попробовал:

DirectCast(Await c, StartupTask).Disable()

Это синтаксически правильно. Но затем IDE намекнул, что «DirectCast» не нужен, и дал упрощение. Да, это:

Call (Await c).Disable()

Вот почему я люблю VS2017 Preview. ?

1 голос
/ 22 сентября 2017

Я опоздал на вечеринку на 7 лет, но я случайно наткнулся на ключевое слово Call несколько минут назад, когда что-то читал в MSDN. В частности, он использовался для того, чтобы сделать что-то, что я считал невозможным в VB.NET (в отличие от C #), что связано с ответом @ FCastro.

Class Test
    Public Sub DoSomething()
        Console.WriteLine("doing something")
    End Sub
End Class

Sub Main()
    Call (New Test()).DoSomething()
End Sub

В нечетном случае вам не нужен фактический экземпляр объекта, но требуется один из его методов, вы можете использовать Call для сохранения строки. Обратите внимание, что это не нужно, если это правая сторона операции:

Class Test
    Public Function GetSomething() As Integer
        Return 0
    End Function
End Class

Sub Main()
    Dim x As Integer = (New Test()).GetSomething()
End Sub
1 голос
/ 04 апреля 2017

Если вы прочитали страницу поддержки MSDN для оператора вызова , для конкретного случая o VBA, по крайней мере, он говорит, что Вызов является необязательным, но что очень важно об этом, и никто, кажется, не замечает, это цитируемая строка:

" Если вы используете синтаксис Call для вызова какой-либо встроенной или определенной пользователем функции, возвращаемое значение функции отбрасывается. "

Вот почему Звонить далеко не бесполезен. Допустим, вы пишете Sub SupportTasks , который делает для вас очень важные вещи Main Subs (например, он импортирует данные из файла, который будет использоваться различными процедурами). Теперь обратите внимание, что, поскольку SupportTasks читает внешние данные, всегда существует большая вероятность того, что эти данные не будут стандартными, и подчиненное устройство не сможет выполнять свою роль. Что ты делаешь?

Вы можете, например, использовать логические функции, которые возвращают False , если что-то идет не так. Вместо вызова подпрограммы, вызовите функцию SupportTasks внутри и Если оператор, который будет выходить из подпрограммы Main, если есть аномалия:

If Not SupportTasks(SomeArgument) Then
    Application.ScreenUpdating = True
    Exit Sub
'Else continue the Main sub regularly without writing anything in here
End If

Если вам интересно, что, черт возьми, это имеет отношение к Call , учтите следующее: в другом сабвуфере я вызываю SupportTasks , но мне не нужно его возвращенное логическое значение значение (например, я уверен, что ошибка не произойдет). Что ж, если я не введу это в оператор If или не назначу функцию бесполезной переменной, VBA не скомпилирует и не выдаст мне ошибку ( вызов процедуры недействителен, бла-бла-бла, необходимо присвоить значение к чему-то бла-бла-бла ). Вот где Позвоните , чтобы спасти день!

Call SupportTasks(SomeArgument) '<< "Call Function" call doesn't return an error

Если вы все еще думаете, что это бесполезно, думайте об этом как о ресурсе, чтобы оставаться организованным. Написание отдельных процедур для подпрограмм, используемых многими процедурами, делает ваш код короче и более понятным , особенно когда вы пишете действительно большие приложения. Например, ERP, построенные на основе интеграции Excel-Access, могут быть проще в эксплуатации, ремонте и настройке, если ваш ИТ-отдел не спешит доставить / внедрить реальную систему ...

В заключение немного интернет-мудрости:

Всегда пишите свой код, как если бы человек, который будет проверять его, был убийственным психопатом, который знает, где вы живете.

Аминь.

...