Funkcje c.d. Strukturalność. Algorytmy. Ćwiczenia przed kolokwium. Programowanie w VBA Funkcje c.d. Strukturalność. Algorytmy. Ćwiczenia przed kolokwium.
Wstęp do funkcji bloków UBound(<tablica>, <wymiar>) – zwraca ostatni indeks tablicy w podanym wymiarze (1 to wiersze (y), 2 to kolumny (x)); LBound(<tablica>, <wymiar>) – zwraca pierwszy indeks tablicy w podanym wymiarze; Wymiar tablicy to (UBound-LBound+1);
Funkcje bloków komórek (wektorów, tablicy) Funkcja bloku: Function przyklad(zakres As Range) As String Dim tablica As Variant Dim x As Integer Dim y As Integer If IsArray(zakres) Then tablica = zakres x = UBound(tablica, 2) – LBound(tablica, 2) + 1 y = UBound(tablica, 1) – LBound(tablica, 1) + 1 przyklad = "Tablica ma " & x & " kolumn i " & y & " wierszy" Else przyklad = "Argument nie jest zakresem." Endif
Funkcje bez zdefiniowanej liczby argumentów Używa się ich na przykład do operacji na rozdzielonych blokach komórek; Funkcja opiera się na tablicy ParamArray; Function <nazwa>(Paramarray <zmienna>) As <typ> Np.: Function Przyklad(Paramarray parametry()) As String ‘() bo musi być typu Variant Dim arg1 As Variant Dim arg2 As Variant Dim arg3 As Variant If IsArray(parametry) Then If (Ubound(parametry,1)-LBound(parametry,1)+1) > 3 Then Przyklad = "Za duzo argumentów." Else arg1 = parametry(0) arg2 = parametry(1) arg3 = parametry(2) Przyklad = "Argument 1: " & arg1 & ", Argument 2: " & arg2 & ", Argument 3: " & arg3 End If Przyklad = "Brak argumentów." End Function
Funkcje zwracające tablice Funkcja musi być typu Variant i przypisywana jej wartość w kodzie musi być typu tablicy; Tworzenie takiej funkcji: zaznaczenie zakresu, wpisanie nazwy funkcji, naciśnięcie razem: ctrl+shift+enter; Function Przyklad() As Variant Dim tablica(0 To 2, 0 To 2) As Integer Dim i As Byte Dim j As Byte For i = 0 To 2 For j = 0 To 2 tablica(i, j) = (i + j) Next j Next i Przyklad = tablica End Function
Strukturalność Względność opisu i szczegółowości operacji: Wyobraźmy sobie operacje parzenia herbaty: Nalej wodę do czajnika; Zagotuj wodę; Wrzuć herbatę do kubka; Zalej herbatę. Na przykład trzeci element w rzeczywistości składa się z operacji: Otwórz szafkę; Weź pudełko z szafki; Otwórz pudełko; Weź torebkę z pudełka; Zamknij pudełko; Odłóż pudełko do szafki; Zamknij szafkę; Włóż torebkę do kubka;
Strukturalność c.d. Także czynność otwarcia szafki oznacza w rzeczywistości podniesienie ręki, złapanie za uchwyt, itd. Podniesienie ręki również oznacza wysłanie sygnałów przez mózg do nerwów, mięśni, itd. Odpowiednikami sygnałów mózgu są sygnały procesor-pamięć-peryferia, oraz przerzucanie danych do rejestrów, pamięci, itd. (to nas nie interesuje jako programistów VBA), podniesienie ręki to podstawowe komendy, czynności to proste operacje jak instrukcje w pętlach czy instrukcje warunkowe, a wykonanie całych algorytmów (jak zrobienie herbaty) to odpowiednie dobranie kolejnych operacji które składają się na program realizujący dany algorytm.
Procedury Sub, End Sub (makra); Private Sub (makra niedostępne z poziomu Excela, tylko z poziomu VBA); Wywoływanie podprocedur (normalne procedury, ale robiące tylko jakąś czynność mającą sens dopiero w większej całości (robi się to po to, żeby był czytelniejszy kod): Call <nazwa procedury> (<ew. zmienne które mają być dane procedurze>) Funkcji napisanych przez siebie w danym arkuszu (grupie modułów) można używać normalnie jak innych poleceń (naturalnie podając argumenty); Zwrócą one wartość takiego typu, jakiego typu jest funkcja;
Odwołania do procedur Sub przyklad1() Dim dana As Variant Call podprogram1(dana) MsgBox ("Wszystko ok, wynik to " & dana & ".") dana2 = funkcja1(dana) MsgBox ("Wszystko ok, wynik to " & dana2 & ".") End Sub Private Sub podprogram1(dana) dana = dana * 2 Function funkcja1(dana) As Integer funkcja1 = dana * 3
Odwołania do procedur c.d. Odwołanie standardowe, jeśli podprogram operuje na zmiennej, zmieni ją i dalszy ciąg programu głównego będzie już używał nowej wartości zmiennej; Aby podprogram mógł operować na przydzielonej zmiennej, a żeby główny program nadal używał starej wartości w dalszym ciągu wykonywania, używa się opcji byVal, wówczas na potrzeby podprocedury/funkcji tworzy się kopia zmiennej;
Odwołania do procedur c.d. Sub glowny() Dim x As Integer x = 5 Call podprogram(x) MsgBox (x) End Sub Sub podprogram(ByVal dana) dana = dana ^ 2 MsgBox (dana)
Trik – odwołanie funkcji do samej siebie Function siln(wartosc As Integer) wartosc = wartosc - 1 If wartosc = 0 Then siln = 1 Exit Function End If siln = (wartosc + 1) * siln(wartosc) End Function
Zadania Znaleźć najmniejszy element zbioru (podanych w wierszu); Znaleźć największy element zbioru; Sortujące od najmniejszego do największego elementy zbioru liczb (podanych w wierszu); Funkcja tablicowa – zaznaczamy obszar do poddania funkcji tablicowej, wpisujemy w róg obszaru funkcję, wciskamy ctrl+shift+enter;
Znalezienie najmniejszego elementu w zbiorze Algorytm: Weź pierwszy element jako minimum pętla: czy i_element jest mniejszy od minimum? -> tak? minimum to i_element -> nie? minimum sie nie zmienia koniec pętli minimum to najmniejszy element zbioru
Sortowanie zbioru Algorytm: pętla zewnętrzna pętla wewnętrzna (przepychanie elementu) weź element(i) sprawdź czy jest większy od element(i+1) -> tak? Zamień je miejscami -> nie? Nic nie rób koniec pętli wewnętrznej koniec pętli zewnętrznej
Przedeklarowanie zmiennej Elementów tablicy będącej argumentem funkcji nie można zmieniać; Trzeba zadeklarować zmienną tablicową, a następnie przepisać zawartość zmiennej-argumentu do niej (przepisanie w formie pętli przepisującej element po elemencie); Aby zadeklarować zmienną tablicową, której wielkość będzie zależna od argumentu, trzeba wykonać następujące operacje: - zadeklarować zmienną tablicową (ale bez zakresów, puste nawiasy) typu takiego, jakiego mają być elementy tablicy; - PRZEDEKLAROWAĆ (komenda ReDim) zmienną tablicową bezwymiarową na zmienną tablicową zwymiarowaną zmiennymi (normalnie deklaracja musi mieć stałe wartości zakresów);
Sortowanie zbioru Function SORT(zakres_komorek As Range) As Variant Dim wynik() As Double Dim i As Integer Dim j As Integer Dim tmp As Double Dim element As Variant ReDim wynik(0 To zakres_komorek.Count - 1) i = 0 j = 0 <przepisanie tablicy zakres_komorek do tablicy wynik po elemencie> <podwójna pętla, w której wewnętrzna pętla będzie przepychała elementy po jednym> SORT = wynik End Function
Zadania Napisz program: Sprawdzający ile liczb podzielnych przez liczbę podaną przez użytkownika (inputbox) znajduje się w zaznaczonym w arkuszu zakresie (selection); Rysujący od wskazanej komórki tabliczkę mnożenia od 1 do 10 (samą zawartość, czyli obszar 10x10);