Wewnątrz danej pętli FOR można umieścić instrukcję Exit For, która powoduje przerwanie całej pętli. Exit For winno być umieszczane wewnątrz instrukcji warunkowej IF, dzięki czemu pętla będzie wcześniej zakończona przy założeniu spełnienie określonego warunku.
Przykłady:
For i = 1 To 20
a = a + 3
Next i
np = 1
nk = 15
krok = 2
stop = 10
For n = np To nk Step krok
Cells(n,1) = n
If n > stop Then Exit For
Next n
Wewnątrz danej pętli FOR można umieszczać (zagnieżdżać) kolejne pętle.
Przykład:
For I = 1 To 10
For J = 1 To 10
For K = 1 To 10
...
Next K
Next J
Next I
Sumowanie
Do zliczania i sumowania wykorzystuje się pomocnicze zmienne, które zmieniają swoje wartości w zależności od konkretnego zadania.
Przykład nr 1. Należy policzyć ile kolejnych 10 liczb ciągu Fibonacciego jest mniejszych od 12
ile = 0
kryterium = 12
For n = 1 To 10
If (n < 3) Then
Cells(n, 1) = n - 1
Else
Cells(n, 1) = Cells(n - 1, 1) + Cells(n - 2, 1)
End If
If (Cells(n, 1) > kryterium) Then ile = ile + 1
Next n
MsgBox ile & " liczb w podanym ciagu jest > od " & kryterium
Przykład nr 2. Należy obliczyć jaka jest średnia kolejnych 20 liczb parzystych.
ileliczb = 20
ile = 0
suma = 0
For n = 1 To ileliczb
liczba = 2 * n
'Cells(n, 1) = liczba 'to polecenie jest niepotrzebne, bo nie musimy wyświetlać
ile = ile + 1 'liczymy ile jest liczb
suma = suma + liczba 'dodajemy kolejne do sumy
Next n
srednia = suma / ile
MsgBox "w podanym ciagu srednia wartosci wynosi " & srednia
ZMIENNE TABLICOWE
Część I: wektory
Wektory domyślnie są indeksowane od zera, ale istnieje możliwość ustalenia zakresu indeksowania. Zazwyczaj elementy wpisujemy w pętli, która winna być tak skonstruowana, aby nawigować po wybranych elementach (nie zawsze celowe jest wykorzystanie wszystkich elementów).
Wartości możemy ale nie musimy wypisywać do komórek.
Przykład nr 1
Dim w1(9) As Single 'tworzymy wektor 10-elementowy, indeksowany od 0 do 9
Dim w2(1 To 10) As Integer 'tworzymy wektor 10-elementowy, indeksowany od 1 do 10
Randomize
For i = 1 To 10
w1(i - 1) = Rnd() 'wpisanie liczb losowych do 10-ciu elementów
w2(i) = 2 * i 'wpisanie kolejnych liczb parzystych do 10-ciu elementów
Next i
Przykład nr 2
Dim wek(99) As Single 'stworzenie wektora 100-elementowego
Randomize
For i = 0 To 49
wek(i) = Rnd() 'do pierwszych 50-ciu wpisujemy liczby losowe <0; 1)
wek(50 + i) = 2 * Rnd() 'do ostatnich 50-ciu wpisujemy liczby losowe <0; 2)
If i < 10 Then Cells(i + 1, 1) = wek(i) 'wypisujemy tylko pierwszych 10 elementów
' uwaga: i+1 przy Cells, bo i zaczyn się od zera, a nie ma zerowego wiersza!
Next i
Przykład nr 3
Dim tablica(1 To 20) As Integer ' tablica 20-elementowa, indeksowana od 1
tablica(1) = 5 'wpisanie pierwszego elementu
tablica(2) = -3 'wpisanie drugiego elementu
tablica(3) = 2 * tablica(1) 'wpisanie trzeciego elementu
MsgBox tablica(3) 'wyświetlenie bieżącej wartości trzeciego elementu
tablica(4) = Cells(1, 1) + 4 'wpisanie czwartego elementu
For k = 5 To 20 'wpisanie kolejnych piętnastu
tablica(k) = tablica(k - 1) + 4 + Cells(k - 4, 3)
Next n
For k = 1 To 20 'podwojenie każdego elementu tablicy
tablica(k) = 2 * tablica(k)
Next n
Część II: tablice 2-wymiarowe (macierze)
W przypadku tablic 2-wymiarowych mamy dodatkowy wymiar, zatem każdy element jest lokalizowany przez współrzędne wiersza i kolumny, analogicznie do macierzy. Operowanie na wszystkich elementach związane jest z zastosowanie pętli podwójnych. Podobnie jak w przypadku wektorów, elementy możemy (dla pewności) wypisywać w arkuszu, ale nie musimy.
Przykład nr 4
Dim m1(9, 9) As Integer ' tablica 10x10, 100 elementów
Dim m2(1 To 5, 1 To 5) As Single ' tablica 5x5, 25 elementów
Randomize
For i = 1 To 5
For j = 1 To 5
m2(i, j) = Rnd() 'do każdego elementu m2 wpisujemy liczbę losowa
' w tym przypadku nie wypisujemy
Next j
Next i
' pierwsza wersja indeksowania
For i = 1 To 10
For j = 1 To 10
m1(i - 1, j - 1) = i + j 'odejmujemy 1, bo indeksowane od zera
Cells(i, j) = m1(i - 1, j - 1) 'od razu wypisujemy, począwszy od A1
Next j
Next i
' druga wersja indeksowania
For i = 0 To 9
For j = 0 To 9
m1(i, j) = (i - 1) + (j - 1) 'tutaj nie odejmujemy, bo pętle idą od zera
Cells(i + 1, j + 1) = m1(i, j) 'do Cells trzeba dodać jedynki, bo nie ma zerowego wiersza i kolumny
Next j
Next i
m1(4, 7) = m1(4, 7) * 3 + 7 'ten element modyfikujemy
m2(1, 4) = m1(1, 1) + m1(3, 1) - m2(4, 1) 'ten element także modyfikujemy
For i = 1 To 5
For j = 1 To 2
m2(i, j) = 0 'zerujemy elementy w pierwszych 2 kolumnach
Next j
Next i
CZYSZCZENIE
Do czyszczenia zawartości arkusza (danego zakresu) można wykorzystać jedno z dwóch poleceń, np. w postaci:
Range("a1:g10").Clear
Range("a1:g10").ClearContents
MOD
Operator (działanie) modulo wykorzystywane jest m.in. do uzyskania reszty z dzielenia danej liczby a przez liczbę b.
Składnia:
wynik = a Mod b
Przykłady:
5 Mod 3 = 2 (1 x 3 i 2 reszty)
12 Mod 4 = 0 (3 x 4 i 0 reszty)
12 Mod 5 = 2 (2 x 5 i 2 reszty)
12 Mod 8 = 4 (1 x 8 i 4 reszty)
DO LOOP
Pętla Do...Loop (w innych językach określana często jako 'while') powoduje powtarzanie określonego zestawu instrukcji w sytuacji, gdy warunek (pętli) jest spełniony (prawdziwy) lub dopóki warunek nie jest spełniony (w zależności od konstrukcji).
Składnia:
Do [{While | Until} condition]
[statements]
[Exit Do]
[statements]
Loop
Lub
Do
[statements]
[Exit Do]
[statements]
Loop [{While | Until} condition]
gdzie:
condition |
Optional. Numeric expression or string expression that is True or False. If condition is Null , condition is treated as False. |
statements |
One or more statements that are repeated while, or until, condition is True. |
Zaletą stosowania tej pętli jest fakt, że nie jest określana maksymalna liczba iteracji, jak to ma miejsce w przypadku pętli For. Nie jest także określana minimalna liczba - w określonych sytuacjach pętla może mieć tylko jedną iterację albo nie mieć żadnej. A więc, w zależności od spełnienia (bądź nie) danego warunku w kolejnym przebiegu pętli, wykonywana jest kolejna iteracja lub pętla jest zakończona. Podobnie, jak w przypadku pętli For, jest możliwość wyjścia z pętli w każdym momencie z wykorzystaniem dedykowanej instrukcji (Exit Do), związanej z wykorzystaniem instrukcji warunkowej (If).
Konstrukcja pętli zależy od konkretnego zadania (celu). W pierwszym kroku należy wybrać, czy użyjemy Until bądź While. W drugim kroku należy zdecydować, czy instrukcja Until/While będzie obok Do czy obok Loop. Różne warianty powodują, że praktycznie mamy 4 warianty tej pętli, których znajomość jest obowiązkowa dla każdego studenta.
Oto kilka przykładów (jak zwykle - pominięcie rzeczy oczywistych, m.in. deklaracji zmiennych):
Liczba = 0
Do While (Liczba < 100)
Liczba = InputBox("Wpisz liczbę całkowitą", "Podaj liczbę")
Loop
Do
Liczba = InputBox("Wpisz liczbę całkowitą", "Podaj liczbę")
Loop While (Liczba < 100)
Liczba = 0
Do Until (Liczba >= 100)
Liczba = InputBox("Wpisz liczbę całkowitą", "Podaj liczbę")
Loop
Do
Liczba = InputBox("Wpisz liczbę całkowitą", "Podaj liczbę")
Loop Until (Liczba >= 100)
Warto zauważyć, że jeżeli warunek jest przy Do, wówczas musi być nadana wcześniej początkowa wartość zmiennej Liczba. W tym przypadku, gdy początkowa wartość nie spełnia warunku działania pętli, nie zostanie wykonany ani jeden przebieg. W związku z powyższym, 4 konstrukcje nie działają zupełnie tak samo. Różnica jest właśnie w zależności od tego, czy warunek umieszczony jest na początku, czy na końcu pętli.
Nawiasy przy warunku mogą, ale nie muszą występować.
Przykład 1.
Losowanie 2 różnych całkowitych liczb losowych.
Randomize
dol = 1
gora = 3
a = Int((gora - dol + 1) * Rnd() + dol)
Lkrokow = 0
Do
Lkrokow = Lkrokow + 1
b = Int((gora - dol + 1) * Rnd() + dol)
Loop While a = b 'powtarzaj losowanie, gdy b jest taka sama jak a
MsgBox "pierwsza liczba: " & a & ", druga liczba: " & b & Chr(10) & "Liczba krokow: " & Lkrokow
Poniższa modyfikacja obrazuje (w komórkach arkusza), jakie liczby były losowane w poszczególnych krokach.
Randomize
dol = 1
gora = 3
a = Int((gora - dol + 1) * Rnd() + dol)
Lkrokow = 0
Do
Lkrokow = Lkrokow + 1
b = Int((gora - dol + 1) * Rnd() + dol)
Cells(Lkrokow, 1) = a
Cells(Lkrokow, 2) = b
Loop While a = b 'powtarzaj losowanie, gdy b jest taka sama jak a
MsgBox "pierwsza liczba: " & a & ", druga liczba: " & b & Chr(10) & "Liczba krokow: " & Lkrokow
Zadanie: Powyższy przykład napisać w 3 kolejnych wersjach. Można zmienić wartość zmiennej gora na z 3 na 2, aby było więcej losowań.
Przykład 2.
Danych jest 100 liczb losowych w kolejnych komórkach od A1 do A100, całkowitych liczb losowych z przedziału od -5 do 5 (uwaga: zadanie można też zrobić z wykorzystaniem pętli For zamiast Do, użytego w jednym fragmencie programu). Policzyć:
ile jest liczb dodatnich
jaka jest średnia wszystkich liczb
ile jest liczb większych od średniej liczb z zakresu <-2; 2>
jaki jest numer wiersza pierwszej liczby, której wartość jest równa 5
dol = -5
gora = 5
Randomize
Ldodat = 0
ile = 0
suma = 0
ile2 = 0 'do liczenia sredniej w przedziale
suma2 = 0
' wiele rzeczy robimy na raz w jednej petli: generowanie, zliczanie, itd.
For w = 1 To 100
ile = ile + 1
a = Int((gora - dol + 1) * Rnd() + dol)
suma = suma + a 'uwaga: tutaj dodajemy wartosc zm.a, a NIE Cells! Niby to samo, ale...
If a >= -2 And a <= 2 Then
ile2 = ile2 + 1 'zliczamy tylko wybrane iteracje
suma2 = suma2 + 1 'sumujemy tylko wybrane elementy
End If
If a > 0 Then Ldodat = Ldodat + 1 'tutaj sprawdzamy, czy liczba dodatnia
Cells(w, 1) = a 'tutaj wyswietalmy w komórce
Next w
sr = suma / ile 'srednia wszystkich liczb
sr2 = suma2 / ile2 'srednia warunkowa
'kolejna petla - zliczamy ile elementow wiekszych od sr2
Lsr = 0
ilekom = 100
For w = 1 To ilekom
If Cells(w, 1) > sr2 Then Lsr = Lsr + 1
Next w
'tutaj przykladowa petla Do...Loop
'mozna to samo zrobic z uzyciem For: nowej petli, albo wplesc w ktoras z poprzednich
w = 0 'to samo w co wczesniej; przy okazji symulujemy dzialanie petli For
koniec = 0
Do
w = w + 1 'zwiekszenie wartosci, aby odczytac kolejna komorke (jak w przypadku For)
a = Cells(w, 1) 'mozna wykorzystywac zmienne uzywane wczesniej
If a = gora Then 'zamiast gora mozna dac po prostu 5
nrPierw = w
koniec = 1 'dzieki temu petla bedzie zakonczona
End If
If w = ilekom Then 'tutaj zabezpieczenie, w przypadku gdy nie ma takiej wartosci
nrPierw = 0 ' nie znaleziono takiej wartosci
koniec = 1 'dzieki temu petla bedzie zakonczona
End If
Loop While koniec = 0
'prezentacja wynikow
'znak Chr(10) - czyli kod Enter - powoduje przejscie do nastepnej linii
'znak '_' na koncu linii umozliwia pisanie instrukcji w kolejne linijce (zwiekszenie czytelnosci kodu)
MsgBox "Liczba dodatnich wartosci: " & Ldodat & Chr(10) & "Srednia wszystkich liczb: " _
& sr & Chr(10) & "Liczba wartosci wiekszych od sredniej z zakresu <-2; 2>: " & Lsr _
& Chr(10) & "Numer wiersza pierwszej liczby, której wartość jest równa 5: " & nrPierw
ZMIENNE PSEUDOLOSOWE
Do generowania liczb pseudolosowych wykorzystujemy polecenia:
Rnd() - losowanie dowolnej liczy rzeczywistej z przedziału <0; 1)
Rnd(number), gdzie number jest dodatkowym parametrem (patrz: pomoc VBA)
Randomize - należy użyć przed pierwszym wykorzystaniem Rnd() - uzyskanie "lepszej losowości" liczb
Aby wygenerować liczbę z dowolnego przedziału (od a do b) należy zastosować przykładowe przekształcenia:
Int((b - a + 1) * Rnd + a) - wylosowanie liczby całkowitej
Int((b - a + 1) * Rnd) + a - także wylosowanie liczby całkowitej
Int((b - a) * Rnd + a) - także wylosowanie liczby całkowitej
Int((b - a) * Rnd) + a - także wylosowanie liczby całkowitej
(b - a) * Rnd + a - wylosowanie liczby rzeczywistej
(b - a + 1) * Rnd + a - także wylosowanie liczby rzeczywistej
Pierwsze cztery polecenia różnią się tym, jaka część jest zaokrąglona. Sposób zaokrąglenia wpływa na to, czy liczba losowana jest z przedziału. Możemy mieć <a; b> czy <a; b), (a; b) czy (a; b>.
Przykład nr 1:
Randomize
liczba = Rnd()
MsgBox liczba
Przykład nr 2:
Randomize
For i = 1 To 10
liczba = Rnd()
Cells(i, 1) = liczba
Next i
Przykład nr 3:
Randomize
poczatek = 1
koniec = 5
liczba1 = Int((koniec - poczatek) * Rnd() + poczatek)
MsgBox liczba1
Przykład nr 4:
Randomize
poczatek = 1
koniec = 10
losowa = Rnd() 'losowana jest tylko jedna liczba, aby mozna bylo porownac
' program nalezy uruchomic kilka razy i porownac wyniki
liczba1 = Int((koniec - poczatek) * losowa + poczatek)
liczba2 = Int((koniec - poczatek) * losowa) + poczatek
liczba3 = Int((koniec - poczatek + 1) * losowa + poczatek)
liczba4 = Int((koniec - poczatek + 1) * losowa) + poczatek
MsgBox "Wynik: 1) " & liczba1 & ", 2) " & liczba2 & ", 3) " & liczba3 & ", 4) " & liczba1
Zaokrąglanie
Do zaokrąglania liczb do najbliższej liczby całkowitej wykorzystuje się funkcje Int lub Fix, zgodnie z poniższymi przykładami:
x = Int(99.8) 'zwraca 99
x = Fix(99.2) 'zwraca 99
x = Int(-99.8) 'zwraca -100
x = Fix(-99.8) 'zwraca -99
x = Int(-99.2) 'zwraca -100
x = Fix(-99.2) 'zwraca -99
Zaokrąglanie liczb rzeczywistych wykonuje się np. z wykorzystaniem funkcji Round:
x = 1.1111
a = Round(x, 2) ' zwraca 1.11
x = 1.7777
a = Round(x, 3) ' zwraca 1.778
Ostatnia modyfikacja: piątek, 4 kwiecień 2008, 11:47