Jakie są zasady używania nawiasów w wywołaniach funkcji VBA?

Właśnie miałem irytujące 30 minut na "błąd kompilatora" w VBA (Access 2003) spowodowany moim użyciem nawiasów wokół argumentów, które przekazuję do zdefiniowanego Sub.

Szukałem porządnego artykułu / poradnika/instrukcji, kiedy nawiasy są konieczne/odpowiednie/nieodpowiednie / zabronione, ale nie mogę znaleźć żadnych jasnych wytycznych.

Author: Tony Toews, 2011-03-24

6 answers

From Here :

Użycie instrukcji wywołania VBScript do wywołania podprogramu Użycie instrukcji Call jest opcjonalne, gdy chcesz wywołać podprogram. Celem instrukcji Call, gdy jest używana z Sub, jest umożliwienie załączenia listy argumentów w nawiasach. Jeśli jednak podprogram nie przekazuje żadnych argumentów, to nadal nie należy używać nawiasów podczas wywoływania podprogramu za pomocą instrukcji Call.

Call MySubroutine

Jeśli podprogram ma argumenty, musisz użyj nawiasów podczas używania instrukcji Call. Jeśli istnieje więcej niż jeden argument, należy oddzielić argumenty przecinkami.

Call MySubroutine(intUsageFee, intTimeInHours, "DevGuru") 

Wywołanie funkcji Istnieją dwa możliwe sposoby wywołania funkcji. Funkcję można wywołać bezpośrednio, tylko za pomocą nazwy, lub można ją wywołać za pomocą instrukcji wywołania VBScript.

Wywołanie funkcji po nazwie Podczas wywoływania funkcji bezpośrednio po nazwie i gdy nie ma przypisania do zwracanej wartości, wszystkie poniżej znajduje się składnia prawna:

MyFunction
MyFunction()
MyFunction intUsageFee, intTimeInHours, "DevGuru"

Jeśli chcesz zwrócić wartość, możesz przypisać funkcję do zmiennej. Zauważ, że jeśli jest jeden lub więcej argumentów, musisz użyć nawiasów.

returnval = MyFunction
returnval = MyFunction()
returnval = MyFunction(intUsageFee, intTimeInHours, "DevGuru") 
 22
Author: Mitch Wheat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-24 02:05:52

Istnieje doskonała logika reguły nawiasów w VB (A) i wygląda to tak.

Jeśli procedura (funkcja lub POD) jest wywoływana z argumentami, a wywołanie jest w linii z innymi wyrażeniami lub słowami kluczowymi, argumenty muszą być zawarte w nawiasach. Ma to na celu odróżnienie argumentów należących do wywołania procedury od reszty linii. Więc:

1:   If CheckConditions(A, B, C) = DONT_PROCEED Then Exit Sub

Jest poprawną linią; wywołanie CheckConditions wymaga nawiasów, aby wskazać, jakie inne bity linii są jego argumenty. Z drugiej strony, spowodowałoby to błąd składni:

2:   If CheckConditions A, B, C = DONT_PROCEED Then Exit Sub

Ponieważ nie można tego przeanalizować.

Z wywołaniem procedury jako jedynym oświadczeniem w linii, nawiasy nie są potrzebne, ponieważ jest jasne, że argumenty należą do wywołania procedury:

3:   SaveNewValues Value1, Value2, Value3

Podczas gdy powoduje to błąd składni (z powodów dźwiękowych omówionych poniżej):

4:   SaveNewValues(Value1, Value2, Value3)

Aby uniknąć nieporozumień co do nawiasów lub braku nawiasów (w rzeczywistości, aby uniknąć reguły nawiasów w przypadku takich wywołań zawsze dobrym pomysłem jest użycie słowa kluczowego Call; zapewnia to, że wywołanie procedury nie jest jedynym stwierdzeniem w linii, co wymaga nawiasów: {]}

5:   Call SaveNewValues(Value1, Value2, Value3)

Więc jeśli masz w zwyczaju poprzedzać samodzielne wywołania procedury za pomocą słowa kluczowego Call, możesz zapomnieć o regułach nawiasów, ponieważ możesz zawsze załączać swoje argumenty w nawiasach.

Sprawę myli dodatkowa rola w VB (a) (i wielu inne języki): wskazują również pierwszeństwo oceny dla wyrażeń. Jeśli używasz nawiasów w jakimkolwiek innym kontekście, ale do załączania argumentów wywołania procedury, VB (A) spróbuje obliczyć wyrażenie w nawiasach do wynikowej wartości prostej.

Tak więc w przykładzie 4, gdzie nawiasy są nielegalne do załączania argumentów, VB(a) spróbuje zamiast tego ocenić wyrażenie w nawiasach. Ponieważ (wartość 1, Wartość 2, Wartość 3) nie jest wyrażeniem, które można ocenić, a pojawia się błąd składni.

Wyjaśnia to również, dlaczego wywołania ze zmienną przekazaną przez ByRef zachowują się tak, jakby były wywołane Przezval, jeśli argument jest zamknięty w nawiasach. W powyższym przykładzie, gdzie funkcja p jest wywoływana z parametrem ByRef a, istnieje duża różnica między tymi dwoma wywołaniami do p:

6:  p a

I

7:  p(a)

Jak wspomniano powyżej, 6 jest poprawną składnią: wywołanie jest tylko w swojej linii, więc nawiasy nie powinny być używane do załączania argumentów.

W 7, argument jest zamknięty w nawiasach, co powoduje, że VB (A) ocenia zamknięte wyrażenie na prostą wartość. Co oczywiście jest samą definicją przechodzenia ByVal. Nawiasy zapewniają, że zamiast wskaźnika do a przekazywana jest wartość a, A a pozostaje niezmodyfikowana.

To wyjaśnia również, dlaczego reguła nawiasów nie zawsze wydaje się mieć wpływ. Najprostszym przykładem jest wywołanie MsgBox:

8:  MsgBox "Hello World!"

I

9:  MsgBox ("Hello World!")

Są poprawne, mimo że w nawiasach zasada mówi, że 9 powinno się mylić. Oczywiście tak jest, ale wszystko, co się dzieje, to to, że VB (A) ocenia wyrażenie w nawiasach. I literał Łańcuchowy jest obliczany na dokładnie ten sam literał Łańcuchowy, tak że rzeczywiste wywołanie ma wartość 8. Innymi słowy: wywołania procedur jednoargumentowych ze stałymi lub ciągowymi argumentami literalnymi mają identyczny wynik z nawiasami lub bez nich. (Dlatego nawet moje wywołania MsgBox są poprzedzone słowem kluczowym Call.)

Wreszcie, to wyjaśnia dziwne Wpisz błędy niedopasowania i dziwne zachowanie podczas przekazywania argumentów obiektu. Załóżmy, że Twoja aplikacja ma procedurę HighlightContent, która przyjmuje pole tekstowe jako argument (i, nigdy nie zgadniesz, podświetla jego zawartość). Wywołujesz to, aby zaznaczyć cały tekst w polu tekstowym. Można wywołać tę procedurę na trzy poprawne składniowo sposoby:

10: HighlightContent txtName
11: HighlightContent (txtName)
12: Call HighlightContent(txtName)

Załóżmy, że twój użytkownik wpisał "John" w polu tekstowym i aplikacja wywołuje HighlightContent. Co się stanie, które wezwanie będzie praca?

10 i 12 są poprawne; Imię John będzie podświetlone w polu tekstowym. Ale 11 jest poprawna składniowo, ale spowoduje błąd kompilacji lub uruchamiania. Dlaczego? Bo nawiasy są nie na miejscu. Spowoduje to poproszenie VB (A) o próbę oceny wyrażenia w nawiasach. A wynikiem oceny obiektu będzie najczęściej wartość jego domyślnej właściwości; .Tekst, w tym przypadku. Więc wywołanie procedury jak 11 nie przekaże obiektu TextBox do procedura, ale wartość łańcuchowa "John". Skutkuje niedopasowaniem typu.

 52
Author: Floris Kleijne,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-01 21:35:36

Znalazłem dziwne zachowanie wywołujące funkcję z / bez nawiasów. Google mnie tu zabrał.

sub test()
  dim a as double
  a = 1#
  p(a) 'this won't change a's value
  Debug.Print a '1
  p a  ' this is expected behavior
  Debug.Print a '2
  Call p(a) 'this is also valid
  Debug.Print a '3
end sub

Function p(a as Double) 'default is byref
  a = a + 1
end function

Mój wniosek jest taki, że musisz użyć wywołania lub pominięcia nawiasów podczas wywoływania funkcji z tylko jednym parametrem, w przeciwnym razie parametr nie jest przekazywany przez odniesienie(nadal jest wywoływany, jak już sprawdziłem).

 7
Author: alex1234231,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-30 18:00:05

Właśnie spędziłem 10 minut zastanawiając się nad wyjątkiem "types incompatible" podczas wywoływania Sub, który pobiera 1 argument przez

CallMe(argument)

Jak się okazuje, jest to nieprawidłowe, googlowanie prowadzi mnie tutaj i w końcu

Call CallMe(argument)

Lub

CallMe argument
Udało się. Nie wolno więc używać nawiasów podczas wywoływania sub bez instrukcji wywołania, która zajmuje tylko 1 argument.
 5
Author: metacircle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-13 08:53:07

Kiedy używasz Call MySub powinieneś używać nawiasów wokół parametrów, ale jeśli pominiesz wywołanie, nie potrzebujesz nawiasów.

 3
Author: Alexan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-24 02:06:08

1 - domyślnie nie używaj nawiasów podczas wywoływania procedur lub funkcji:

MsgBox "Hello World"

2 - jeśli wywołujesz funkcję i interesuje Cię jej wynik, musisz załączyć jej argumenty nawiasami:

Dim s As String
Dim l As Long 
s = "Hello World"
l = Len(s)

3-Jeśli chcesz użyć słowa kluczowego call z procedurą, musisz dołączyć argumenty nawiasami (np. gdy chcesz przypisać wynik do zmiennej lub użyć funkcji w wyrażeniu):

Call MsgBox("Hello World")

4-Jeśli chcesz wymusić Argument ByRef (domyślnie), który ma zostać przekazany przez ByVal, a następnie załącz argument ByRef nawiasami:

Sub Test
  Dim text As String
  text = "Hello World"

  ChangeArgument((text))

  MsgBox text
End Sub

Sub ChangeArgument(ByRef s As String)
    s = "Changed"
End Sub

Wyświetla "Hello World"

 2
Author: Christophe Keller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-24 10:16:24