Potprogrami su zapravo programi unutar programa. Naime, program može da se podeli na logičke celine od kojih je svaka zadužena za izvršavanje specifičnog zadatka. Moguće je da u programu postoji potreba da se isti zadatak obavi više puta, ali na različitim mestima. Umesto da se naredbe za izvršavanje takvog zadatka iznova navode, ideja je da se one izdvoje u posebnu imenovanu celinu, potprogram, i da se po potrebi pozivaju samo navođenjem imena potprograma i eventualnih ulaznih podataka.
Potprogramima se postiže ušteda, mogućnost da se isti niz naredbi ponovo iskoristi, a program postaje čitljiviji jer se ne posmatra samo kao niz naredbi, već i kao niz specifičnih zadataka. Takođe, prilikom pisanja programa, najlakše je tokom analize problema podeliti program na specifične zadatke, a onda za svaki od njih ispisati odgovarajući niz naredbi koji ga realizuju.
U okviru objektno-orijentisanih programskih jezika (kakav je VBA) često se koristi termin "metod" umesto potprogram.
Postoje dve vrste potprograma:
Definicija procedure izgleda ovako:
Sub imeProcedure(argumenti) naredba naredba … naredba End Sub
gde argumenti predstavljaju deklaracije promenljivih koje procedura koristi kao ulazne podatke.
Primer: napisati proceduru koja na osnovu zadate vrednosti, menja veličinu prvog pasusa tekućeg dokumenta.
Sub PromeniVelicinu(iSize as Integer) ActiveDocument.Paragraphs(1).Range.Font.Size = iSize End Sub
Da bi se naredbe neke procedure izvršile u programu, potrebno je da se procedura pozove i da se obezbede konkretne vrednosti za njene argumente. Npr. nakon sledećeg poziva
PromeniVelicinu 14vrednost argumenta iSize postaje 14 i naredba procedure menja veličinu prvog pasusa u 14pt.
Često je potrebno da procedura uradi nekakav posao bez dodatnih informacija, te joj ulazni podaci (argumenti) nisu neophodni.
Sub imeProcedure() naredba naredba … naredba End Sub
Primer: napisati proceduru koja formatira prvi pasus tekućeg dokumenta koristeći italic.
Sub PromeniUItalic() ActiveDocument.Paragraphs(1).Range.Italic = True End Sub
Važno! Prilikom poziva procedure ne koriste se zagrade oko konkretnih vrednosti za njene argumente!
Function imeFukcije(argumenti) As tipVrednosti naredba naredba … naredba imeFunkcije = vrednostFunkcije 'naredba kojom funkcija vraća vrednost End FunctionVažno! Prilikom poziva funkcije moguća su dva slučaja:
Function BrojVokala(niska as String) As Integer Dim pozicija As Integer 'pozicija slova u niski Dim brVokala As Integer 'brojac samoglasnika u niski Dim duzina As Long 'duzina niske Dim slovo As String 'slovo kao podniska duzina = Len(niska) brVokala = 0 For pozicija = 1 To duzina slovo = Mid(niska, pozicija, 1) If (slovo = "a") Or (slovo = "e") Or (slovo = "i") Or (slovo = "o") Or (slovo = "u") Then brVokala = brVokala + 1 End If Next BrojVokala = brVokala 'naredba kojom funkcija vraća vrednost End FunctionS obzirom da je poziv funkcije vrednost ona se može i mora koristiti u izrazu:
Dim brojSuglasnika as Integer brojSuglasnika = Len("maestro") - BrojVokala("maestro") 'u promenljivu se upisuje 7 - 3 = 4
U prethodnim odeljcima su prikazani primeri definisanja i pozivanja procedura i funkcija. Prilikom definisanja potprograma deklarisane su posebne promenljive koje treba da prihvate ulaz potprograma, a koje smo nazvali argumentima. Te promenljive se još nazivaju formalni parametri potprograma.
S druge strane, prilikom pozivanja potprograma potrebno je obezbediti konkretne vrednosti za argumente; te vrednosti se još nazivaju stvarni parametri potprograma. Stvarnih parametara mora biti koliko i formalnih, moraju biti navedeni u odgovarajućem redosledu, a odgovarajući formalni i stvarni parametri moraju biti istog tipa. (Ukoliko stvarni parametar nije istog tipa kao odgovarajući formalni parametar, VBA pokušava da obavi konverziju tipa, što nije uvek moguće).
Neka je definisana funkcija f. Ona računa izložilac najvećeg stepena broja 2 koji ne prelazi x; tj. vrednost f(x) je n, gde je 2n <= x < 2n+1. Npr, f(46) = 5 jer je 25 = 32 <= 46 < 64 = 26.
Function f(x as Integer) as Integer f = 0 While x >= 2 x = x \2 f = f + 1 Wend MsgBox x 'Ispisuje vrednost formalnog parametra x End Function
Neka procedura test poziva funkciju f.
Sub test() Dim m as Integer m = 46 MsgBox f(m) 'Ispisuje f(46) = 5 MsgBox m 'Ispisuje vrednost stvarnog parametra m End Sub
Postavlja se pitanje: kolika je vrednost promenljive m posle poziva funkcije f?
Postoje dva načina za prenos argumenata u VBA:
Prenos po adresi bi podrazumevao da formalni i njemu odgovarajući stvarni parametar predstavljaju istu memorijsku lokaciju. Stoga bi formalni i njemu odgovarajući stvarni parametar mogli imati različita imena, ali njihov sadržaj bi se nalazio na istoj adresi u memoriji. Tako bi svaka promena vrednosti formalnog parametra u okviru potprograma dovela i do promene vrednosti odgovarajućeg stvarnog parametra.
U ovom konkretnom primeru, prenos po adresi bi značio da su x i m jedno te isto, te bi prilikom ispisivanja njihovih vrednosti u oba slučaja MsgBox prikazao 1. Dakle, prenos po adresi bi doveo do toga da se vrednost promenljive m promeni u okviru poziva funkcije f(m).
S druge strane, prenos po vrednosti bi podrazumevao da se prilikom poziva potprograma kreira posebna memorijska lokacija za formalni parametar i da se u nju kopira vrednost odgovarajućeg stvarnog argumenta. Na taj način bi formalni i njemu odgovarajući stvarni parametar predstavljali dve različite memorijske lokacije i promena vrednosti formalnog parametra ne bi uticala na vrednost stvarnog parametra.
U ovom konkretnom primeru, prenos po vrednosti bi značio da promenljivama x i m odgovaraju dve različite memorijske lokacije, i promena vrednosti prve ne utiče na drugu, tj. MsgBox x bi prikazao 1, a MsgBox m - vrednost 46. Dakle, prenos po vrednosti ne bi doveo do toga da se vrednost promenljive m promeni u okviru poziva funkcije f(m).
VBA omogućava oba navedena prenosa argumenata, tj. i prenos po referenci i prenos po vrednosti. Da bi se zadao odgovarajući prenos argumenata, prilikom deklaracije formalnog parametra navodi se ByRef (za prenos po adresi/referenci) ili ByValue (za prenos po vrednosti). Ukoliko se ekplicitno ne navede ni ByRef ni ByValue, efekat je isti kao da je navedeno ByRef (tj. u VBA je prenos po adresi podrazumevani način za prenos argumenata potprograma).
Prema tome, u gore navedenom primeru efekat je isti kao da je funkcija definisana sa:
Function f(ByRef x as Integer) as Integer f = 0 While x >= 2 x = x \2 f = f + 1 Wend MsgBox x 'Ispisuje vrednost formalnog parametra x End Function
Stoga je vrednost na kraju vrednost promenljive m ista kao i za x, tj. 1. Ako ne želimo da se vrednost promenljive m promeni prilikom poziva funkcije f, koristićemo sledeću definiciju:
Function f(ByValue x as Integer) as Integer f = 0 While x >= 2 x = x \2 f = f + 1 Wend MsgBox x 'Ispisuje vrednost formalnog parametra x End Function