2010-04-04 3 views
38

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

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

+10

В некоторых случаях использование ключевого слова вызова очень полезно, например, когда вы просто хотите использовать класс один раз. Я использую его сегодня для генерации случайной соли. Вызов New RNGCryptoServiceProvider(). GetBytes (salt) 'без' Call'. Мне пришлось бы иметь переменную как 'RNGCryptoServiceProvider' сначала –

+1

Это легко лучший (если не единственный) повод использовать для использования звонка, о котором я когда-либо слышал. – Pillgram

ответ

11

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

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

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

3

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

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

10

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

4

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

20

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

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

Мы знаем, что это можно сцепить строки кода с двоеточием, например:

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 

Использование вызова заявления позволяет конкатенацию вызовов процедур сохраняя при этом ваш код отступы:

Function Test() 
    Call Function1 : Call Function2 
End Function 

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

+10

+1 для легитимного случая ... хотя я бы сказал, что наличие нескольких инструкций/вызовов функций в одной строке является плохой практикой. –

1

Если вы читали MSDN Support page for the Call Statement, для конкретного случая O VBA, по крайней мере, это сказать, что вызов не является обязательным, но то, что является очень актуальным об этом, и никто не замечает это цитируемый линия:

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

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

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

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

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

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

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

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

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

Amen.

+3

Вы можете просто использовать 'SupportTasks SomeArgument', и он просто компилируется без использования' Call'. –

+0

Это правда. Он просто игнорирует возвращаемое значение. Угадай, что делает мое сочинение слегка отпущенным, а? ... – FCastro

1

Я на 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

Fun! Часть меня хочет попробовать, другая часть меня боится узнать другую плохую привычку :-) – SlowLearner

+0

@SlowLearner Я предлагаю просто держать ее в шляпе как мелочи. VB создает достаточно вредных привычек, как есть :) –

+0

Yup. Я фактически использую VBA и интригующе, как и было (AFAICT), он просто не близок к работе в VBA, но было интересно исследовать, тем не менее. Ура, – SlowLearner

0

Единственный случай, я нашел «вызов» полезно довольно случайно, о некоторых специальных операторов.

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

У меня есть синтаксическая ошибка для второй строки, точно так же, как то, что вы получите с оператором «Новый». Мне действительно не нужна новая переменная, которая слишком неуловима для меня. Поэтому я пробовал:

DirectCast(Await c, StartupTask).Disable() 

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

Call (Await c).Disable() 

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

Смежные вопросы