Arkusze kalkulacyjne i VBA Uniwersytet Łódzki Wydział Matematyki i Informatyki Justyna Walewska Lekcja 2. Dalsze elementy VBA Studia Podyplomowe Analiza danych i data mining Rok akademicki 2018/19
Zmienne Zmienne (dowolna nazwa zaczynająca się od litery np. num, j23, JP2, ). Może reprezentować liczby, zakresy, wartości logiczne, obiekty. Nadajemy im wartości za pomocą znaku równości: x = 1 num = 0.3 WartoscLogiczna = True x = x + 1 Myname = "Justyna" Dat = #12/14/2016# Set Tab = Range("A1:D4") kluczowe słowo Set do obiektów Możemy deklarować typ zmiennych. Nie jest to konieczne, np. Dim MojaZmienna As Integer Dim x As Double Dim MojaTablica(1 To 10, 1 To 100) As Integer - Zmienna tablicowa. Domyślnie bez deklaracji zmienne mają typ Variant.
Typy zmiennych:
Ćwiczenie 1. Zadeklarować zmienną xx jako całkowitą, nadać jej wartość całkowitą i obliczyć z niej pierwiastek (użyć funkcji Sqr) i wyświetlić w MsgBox wartość tej zmiennej i jej pierwiastka. Wypróbować inne warianty: nadać xx wartość niecałkowitą, zadeklarować wynik jako całkowity. Ćwiczenie 2. Zadeklarować zmienną Zakres jako Range, (Range jest obiektem, a więc należy przy definiowaniu zmiennej obiektowej użyć słowa kluczowego Set) nadać jej wartość np. w kwadracie komórek wpisać wartość np. 100.
Zasięg zmiennych Przykłady deklarowania zasięgu zmiennych: Sub makro1() Dim x1 as Integer.Instrukcje End Sub Zmienna x1 jako liczba całkowita dostępna tylko w tym makro Dim x2 as String Sub makro1().instrukcje End Sub + Kolejne makra Zmienna x2 jako ciąg symboli dostępna tylko w tym module
Public x3 as String Sub makro1().instrukcje End Sub + Kolejne makra Zmienna x3 jako ciąg symboli dostępna we wszystkich modułach (globalna). Const Proc as Integer = 3 Deklaracja stałej Proc równej 3. Ćwiczenie 3. Zadeklarować zmienną xxx jako całkowitą dla całego modułu, nadać jej wartość w pewnym makro i w innym makro wyświetlić ją (w MsgBox).
Zakresy i odwoływanie się do komórek W większości przypadków makra wykonują operacje na zakresach komórek. Podstawowym obiektem jest Range, nie ma obiektu Cells jest to własność obiektu Range Zakresy (Range) Najczęściej instrukcje, funkcje, polecenia dotyczą zakresów (pewnego zbioru komórek). Możemy je w makrach określać na różne sposoby: Range("A2:C7") prostokąt komórek to samo [A2:C7] Range("A2","C7") prostokąt Range("A2:C7, D1:E5") 2 prostokąty komórek Range("A2:C7 C1:E5") część wspólna 2 prostokątów komórek Range("A:A") kolumna Range("A:F") kolumny Range("1:5") wiersze Range("A2:C7").Columns(1) 1 kolumna w zakresie Range("A2:C7").Rows(3) 3 wiersz w zakresie Range("A2:C7").Cells(2,3) komórka o numerze (2,3) w zakresie Range("A2:C7").Cells(3) komórka o numerze 3 w zakresie, liczonych od lewej do prawej Range("B7").Offset(-1,2) komórka przesunięta o jeden wiersz w górę i dwie kolumny w prawo.
Aby nazwać zakres Set xx= Range("A2:C7"), dalej np. xx.cells(6) Cells(3,5) komórka o współrzędnych 3 wiersz, 5 kolumna w aktywnym arkuszu, czyli E3 Cells(Rows.Count,1) ostatnia komórka w 1 kolumnie (Count liczba obiektów w danej kolekcji). Cells(Rows.Count,2).End(xlUp) ostatnia niepusta komórka w kolumnie 2. Range("B3").Resize(10,3) rozciągnięcie zakresu 10 razy w dół i 3 w prawo. CurrentRegion - aktualnie wykorzystany zakres komórek z aktualną komórką w tym zakresie. UsedRange - aktualnie wykorzystany zakres komórek w całym arkuszu. Ćwiczenie 4. Wypróbować 5 lub więcej sposobów określenia zakresów wykorzystując metodę Select do zaznaczenia zakresu np. Range("A1:B3").Select Ćwiczenie 5. Napisać makro, które w kwadratowy zakres (8 na 8) wpisuje kwadraty kolejnych liczb naturalnych. Wykorzystać pętlę For i=1 to 64... Next i Ćwiczenie 6. Napisać makro, które w kwadratowy zakres (6 na 6) koloruje na jakiś kolor (własność Interior.Color obiektu Range) i wpisuje po przekątnej kwadraty kolejnych liczb naturalnych. Uwaga. Kolory określamy przez RGB(1,100,255) wartości kolorów: czerwony (R od 0 do 255), zielony (G od 0 do 255), niebieski (B od 0 do 255) lub przez wybrane stałe np. vbyellow lub numer koloru od 0 do 255*255*255.
Ćwiczenie 7. Napisać program typu Sub wpisujący kolejne liczby 1,2,,1000 w komórkach B1,B2,,B1000 i wyświetlający okno z napisem Koniec. Wsk. Wykorzystać właściwość Cells obiektu Range. Ćwiczenie 8. Napisać program typu Sub usuwający co drugą liczbę z poprzedniego zadania. Wsk. Wykorzystać metodę Clear. Ćwiczenie 9. Utwórz makro, które wykorzystuje InputBox i MsgBox do pojawienia się tekstu powitalnego w oknie, gdy podamy swoje nazwisko i tekstu zniechęcającego lub o ponowną próbę, gdy podamy nieprawidłowe nazwisko. Wskazówka. Składnia InputBox ("Zapytanie", "Tytuł okna", "Wartość domyślna w oknie") MsgBox ("Zapytanie", Możliwe przyciski, "Tytuł okna") MsgBox "Tekst" - wyświetla tekst MsgBox Zmienna - wyświetla wartość zmiennej Różnica między tymi oknami polega na tym, że w InputBoxie na zapytanie wprowadzamy wartość, a w MsgBoxie mamy zadane zapytanie i udzielamy standardowej odpowiedzi (Yes, No, Cancel, ). Użyć polecenia If Then Else
Przykład 2. Makro, które w oknie dialogowym pyta o wiek a następnie po przekątnej od danej komórki wypisuje kolejne lata od wieku do wiek +4. Sub Przyklad2() Dim i As Integer, wiek As Integer wiek = InputBox("Podaj liczbę:", "Wiek", "18") For i = 1 To 4 ActiveCell.Offset(i, i).font.bold = True ActiveCell.Offset(i, i).value = i + wiek Next i End Sub Ćwiczenie 10. Napisać makro, które wpisuje Nazwisko w pierwszą pustą komórkę w prawym dolnym rogu użytego zakresu. Wsk. Wykorzystać własność CurrentRegion Użyty zakres Nazwisko
Makra związane ze zdarzeniami Możemy uruchamiać pewne makra (które sami napiszemy), gdy wystąpi pewne zdarzenie. Inaczej, gdy pewne zdarzenie nastąpi np. otworzymy arkusz, dodamy arkusz, dwa razy klikniemy pewien przycisk, zmienimy wartość w komórce itp., to uruchamia się automatycznie makro. Makra związane ze zdarzeniami umieszczamy w odpowiednim module: Zdarzenia związane z danym skoroszytem (np. podczas otwierania danego skoroszytu chcemy by pojawiło się okno z ostrzeżeniem lub okno powitalne) umieszczamy w module związanym z Ten skoroszyt (dwa razy klikamy ten moduł i wybieramy zdarzenie w rozwijanych 2 oknach: Workbook i w Declarations np. Open lub inne), Zdarzenia związane z danym arkuszem (np. by przed zamknięciem danego arkusza pojawiło się ostrzeżenie) zapisujemy je w module arkusza o odpowiednim numerze, np. Arkusz1. Zdarzenia związane z danym oknem dialogowym UserForm (np. kliknięcie okna dialogowego) zapisujemy je w module tego okna dialogowego (dwa razy klikamy samo okno dialogowe w edytorze). Są również zdarzenia związane z całym Excelem AppEvents i z Wykresami ChartEvents
Ćwiczenie 11. Utwórz makro, które po otwarciu Arkusza 2 wyświetla okno MsgBox z zapytaniem np. Ten arkusz już jest wypełniony. Czy chcesz kontynuować? Jeśli odpowiedź będzie Tak to można pracować w Arkuszu 2, jeśli Nie to otwierany jest Arkusz 1. Użyć polecenia If MsgBox = vbyes Then Else Ćwiczenie 12. Utwórz makro, które w Arkuszu 3 po każdej zmianie wyboru komórki wyświetla okno z zapytaniem np. Czy jesteś pewny tego? Ćwiczenie 13. Utwórz nowy skoroszyt i wpisz makro, które wymusza podanie hasła podczas jego otwierania.
Makra typu Function zapisujemy w zwykłym module. Podstawowa składnia makra typu Function: Makra typu Function Function NazwaFunkcji(Arg1,x1) np. od 2 argumentów Instrukcje NazwaFunkcji = Wyrażenie od argumentów Arg1,x1 End Function
Jak stosować makro typu Function: W arkuszu Excela tak jak zwykłą funkcję Excela, tzn. 1. Zaznaczamy komórkę w której ma pojawić się wartość naszej funkcji. Klikamy Wstaw funkcję Wybieramy Zdefiniowane przez użytkownika. Z listy wybieramy nazwę funkcji. Wpisujemy argumenty. 2. W oknie Immediate Wpisujemy? NazwaFunkcji(Argumenty) 3. W innym makro Sub aaaa() Instrukcje Makra xy= NazwaFunkcji(Argumenty) Inne Instrukcje End Sub
Ćwiczenie 14. Napisać makro z prostą funkcją dodającą dwie liczby. Function Summa(x1 As Integer, x2 As Variant) As Variant Summa= x1+x2 End Function Ćwiczenie 15. Napisać makro typu Function podającą aktualny czas lub datę w odpowiednim formacie: Date to liczba, reprezentująca numer dnia od 1900 roku, Format(Date, "Long Date") normalny format dnia Podobnie dla Now: Now - to liczba, reprezentująca numer dnia od 1900 roku z ułamkiem dziesiętnym, reprezentującym część dnia jaka upłynęła od północy. Format(Now, "Short Time") - normalny format dnia.
Przykład. Funkcja która usuwa z danego słowa samogłoski Function UsunSam(Tekst) As String Wymagane: słowo Function, nazwa makra, argument w nawiasach, deklaracja typu zmiennych Dim i As Long Opcjonalnie: deklaracja typu zmiennej i UsunSam = "" For i = 1 To Len(Tekst) If Mid(Tekst, i, 1) Like "[AEIOUYaeiouy]" Then W funkcji Mid wymagana zmienna i typu Long UsunSam = UsunSam & "" Else UsunSam = UsunSam & Mid(Tekst, i, 1) End If Next i End Function Ćwiczenie 16. Wykorzystaj powyższą funkcję do uruchomienia (poprzez makro) okien dialogowych InputBox do wprowadzenia tekstu i MsgBox do otrzymania wyniku działania funkcji.
Ćwiczenie 18. Napisać makro, które po przekątnej wpisuje liczby od 1 do 100 i koloruje na kolor czerwony vbred komórki obok. Głos w VBA VBA ma wbudowany generator mowy do odczytywania na głos Function Mowa(tekst) Application.Speech.Speak (tekst) End Function Ćwiczenie 17. Napisać makro, które wywołuje InputBox z poleceniem, by wpisać dowolne słowo i które zostaje odczytane. Standardowe pętle w VBA: Pętle i instrukcje warunkowe Podstawowa składnia: For Next Sub Petla1() For i=1 To 100 Step 2 (domyślnie Step =1) Instrukcje Next i End Sub
Ćwiczenie 19. Napisać makro, które w kolumnie 3 koloruje komórki, aż do ostatniego zapisanego wiersza (Cells(Rows.Count,3).End(xlUp).Row ), zawierające liczby >10. For Each Next Podobna pętla do For Next ale dla obiektów np. dla arkuszy w skoroszycie, zakresów w arkuszu itp. Na przykład, For Each xx In Worksheets Instrukcje Next xx For Each komorka In Range("A2:C6") Instrukcje Next komorka Ćwiczenie 20. Napisać makro, które we wszystkich arkuszach aktywnego skoroszytu wpisuje w komórce B5 nazwisko.
With End With Podobna do powyższej przeznaczona do obiektów i kolekcji np. zmiana parametrów czcionki w wybranym zakresie Sub Zmiana() zmienia własności czcionki w zakresie With Range("A1:D6").Font.Name = "Arial".Bold = True.Size = 14 End With End Sub
Select Case Używana gdy mamy więcej opcji a nie tylko dwie (gdy dwie to używamy If Then Else) np. Sub Petla4() wybór Liczba = InputBox("Podaj liczbę kupowanych książek: ") Select Case Liczba Case 0 To 3 Rabat = 10 Case Is >=4 Rabat = 20 End Select MsgBox "Rabat wynosi "&Rabat&"%" End Sub Ćwiczenie 21. Napisać makro, które w zależności od danego dnia pokazuje nam inne polecenie do wykonania (użyć funkcji WeekDay(Now) zwracającej numer dnia (od 1 do 7; od niedzieli do soboty).
Do Loop Pętla używana do wykonania pewnych czynności o nie zawsze określonej liczbie Przykład. Wartość co drugiej komórki w pionowym zakresie przenosi do komórki obok.
Sub Petla6() Do If Selection.Value = " " Then Exit Do ActiveCell.Offset(1, 0).Range("A1").Select Selection.Cut ActiveCell.Offset(-1, 1).Range("A1").Select ActiveSheet.Paste ActiveCell.Offset(1, -1).Range("A1").Select Selection.EntireRow.Delete ActiveCell.Select Loop End Sub Do While i < 10 Loop wykonywane dla i < 10 Do Until i > 10 Loop wykonywane dla i <= 10 Inne wersje pętli Do Loop z warunkami Ćwiczenie 22. Napisać makro, które koloruje komórki w wierszu dopóki wartość jest <10. Makro Pętla7
If Then [Else] Składnia If warunek Then Instrukcje [Else] Instrukcje End If Może być składnia prostsza w jednym wierszu: If warunek Then Gdy chcemy rozdzielić na więcej niż dwa warunki używamy konstrukcji: If warunek Then Instrukcje ElseIf Instrukcje ElseIf Instrukcje Else Instrukcje End If
Przykład. W zależności od wartości w komórce wykonujemy inne instrukcje. Jednocześnie przykład skoku do innej instrukcji: Sub Petla8() If Range("A10").Value > 10 Then GoTo Instr1 ElseIf Range("A10").Value <= 10 And Range("A10").Value > 5 Then GoTo Instr2 ElseIf Range("A10").Value <= 5 Then GoTo Instr3 Instr1: MsgBox "Za duża liczba" Exit Sub Instr2: MsgBox "W sam raz" Exit Sub Instr3: MsgBox "Za mała suma" Exit Sub Else End If End Sub
Gdy chcemy przerwać działanie makro lub pętli: Exit Sub, Exit For, Exit Do. Dodatkowe pożyteczne instrukcje: Gdy chcemy przejść do innej instrukcji:... GoTo Podprogram3... Podprogram3: Instrukcje... Nie ma End Podprogramu wykonywane są dalsze instrukcje Ćwiczenie 23. Napisać proste makro z dwiema instrukcjami i następnie drugie identyczne, z wstawionymi między instrukcjami Exit Sub Makro Petla8.
Debugowanie Gdy chcemy wykonać makro krok po kroku (obserwując np. w innym oknie co się dzieje) to debugujemy makro: 1. Umieszczamy kursor w kodzie makro. 2. Zmniejszamy okno Visual Editor by widzieć odpowiednią część arkusza 3. Klikamy Debug/Step Into lub F8. 4. I tak dalej klikamy F8. 5. Wyłączamy debugowanie Step Out Ćwiczenie 24. Wypróbować działanie debugowania na dowolnym makro (najlepiej pętli). Dodatkowe opcje: 1. Na szarym marginesie okna z makrami możemy umieszczać punkty brązowe. Uruchomione makro działa do tego punktu. 2. Na szarym marginesie okna z makrami możemy przesuwać żółtą strzałkę.
Podstawowe instrukcje w makro obsługujące błędy: On Error Resume Next pomiń ten błąd. Przykład. Sub Bledy1() Worksheets("Arkusz5").Name = "Dane" On Error Resume Next Worksheets("Arkusz5").Range("A5").Select End Sub Obsługa błędów Instrukcja On Error Resume Next pomija wszystkie dalsze błędy w makro. By wyłączyć to musimy wpisać instrukcję On Error GoTo 0
Przykład. Sub Bledy2() Worksheets("Arkusz5").Name = "Dane" On Error Resume Next Worksheets("Arkusz5").Range("A5").Select On Error GoTo 0 Worksheets("Arkusz5").Range("A5").Select End Sub On Error GoTo Instrukcja przeskok do specjalnej instrukcji np. MsgBox z ostrzeżeniem. Przykład Sub Bledy3() Worksheets("Arkusz5").Name = "Dane" On Error GoTo Ostrzezenie Worksheets("Arkusz5").Range("A5").Select Exit Sub Ostrzezenie: MsgBox "Zmieniłeś nazwę arkusza" End Sub
Zadania dodatkowe do samodzielnego zrobienia Ćwiczenie 1. Napisz program, oceniający testy uczniów. Program powinien w zależności od wpisanej przez Ciebie liczby punktów wyświetlać ocenę: punkty 91 do 100 cel punkty 81 do 90 bdb punkty 71 do 80 db punkty 61 do 70 dst punkty 51 do 60 dop punkty 0 do 50 ndst > 100 lub < 0 błąd Ćwiczenie 2. Napisz program obliczający prowizję dla sprzedawcy. Miesięczna sprzedaż 0-9999 złotych 8,0% 10000-19999 złotych 10,5% 20000-39999 złotych 12,0% Powyżej 40000 złotych 14,0% Stawka prowizji
Pobierz plik lekcja2.xlsx. Ćwiczenie 3. Napisz funkcję VBA, która sprawdza czy liczba (Arkusz1 plik lekcja2.xlsx) z kolumny A jest dodatnia, ujemna czy zero i wypisuje odpowiedni komunikat w kolumnie B (dotyczy podpunktu a)) i C (w przypadku b)). Zadanie rozwiąż dwoma sposobami: a) Użyj instrukcji warunkowej If Then b) Użyj instrukcji Select Case Ćwiczenie 4. Napisz funkcję VBA, która wyznaczy datę ważności danego produktu (Arkusz2 plik lekcja2.xlsx). Wykorzystaj instrukcję Select Case. Ćwiczenie 5. Napisz funkcję VBA o nazwie lata_pracy1 zwracającą wartość ilości przepracowanych lat obliczanych na podstawie różnicy lat pomiędzy rokiem bieżącym a rokiem, w którym pracownik został zatrudniony. Do zadania wykorzystaj funkcje Year() oraz Now(). Czy uzyskane w ten sposób wyniki są dokładne? Napisaną przez siebie funkcję wykorzystaj do uzupełnienia odpowiedniej kolumny w tabeli z Arkusza3 (plik lekcja2.xlsx.). Ćwiczenie 6. Napisz funkcję VBA o podobnym nagłówku, lecz nazwie lata_pracy2, która zwraca wartość ilości faktycznie przepracowanych lat obliczanych za pomocą funkcji WorksheetFunction.YearFrac(). Zapoznaj się w pomocy Visual Basic z opisem tej funkcji. Użyj funkcji Int do odrzucenia części ułamkowej wartości zwracanej przez funkcję YearFrac. Wykorzystaj napisaną przez siebie funkcję do uzupełnienia odpowiedniej kolumny w tabeli z Arkusza3 (plik lekcja2.xlsx.).
Ćwiczenie 7. Zaprojektuj funkcję VBA o nagłówku Function Wysługa1(lata As Integer, pensja As Currency) As Currency Za pomocą której będzie można uzupełnić odpowiednią kolumnę w tabeli z Arkusza3 (plik lekcja2.xlsx.) Uwaga: Dodatek do pensji o nazwie wysługa jest przyznawany po pięciu pełnych latach pracy i stanowi 5% pensji zasadniczej; zwiększa się co roku o 1% aż do 20%. Oznacza to, że osoba, której staż pracy wynosi np. 25 lat otrzymuje dodatek w wysokości 20% * pensja zasadnicza. Osoby, które pracują krócej niż 5 lat nie otrzymują dodatku. W zadaniu wykorzystaj instrukcję warunkową If. Wykorzystaj napisaną przez siebie funkcję do uzupełnienia kolumny Wysługa1 w tabeli z Arkusza3 (plik lekcja2.xlsx.). Ćwiczenie 8. Napisz funkcję VBA o nagłówku: Function Wysługa2(data As Date, pensja As Currency) As Currency wyznaczającą podobnie jak poprzednia wysługę lat. Wywołaj funkcję lata_pracy1 wewnątrz tej funkcji, w celu wyznaczenia lat pracy na podstawie argumentu data. Ponadto zastosuj zamiast instrukcji If instrukcję Select Case. Wykorzystaj napisaną przez siebie funkcję do uzupełnienia odpowiedniej kolumny w tabeli z Arkusza3 (plik lekcja2.xlsx.).
Ćwiczenie 9. Zaprojektuj funkcję VBA o nazwie Dodatek_szkodliwy, która wyznaczy wartość dodatku szkodliwego zgodnie z tabelą: Stanowisko Lata pracy Dodatek szkodliwy Spawacz, ślusarz, malarz <10 500 złotych Spawacz, ślusarz, malarz >=10 1000 złotych Inne dowolna 0 złotych Wykorzystaj napisaną przez siebie funkcję do uzupełnienia odpowiedniej kolumny w tabeli z Arkusza3 (plik lekcja2.xlsx.). Ćwiczenie 10. Zaprojektuj funkcję VBA które na podstawie kolumn Imię i Nazwisko wyznaczają płeć (wypisuje napisy mężczyzna albo kobieta), inicjały. Wykorzystaj napisaną przez siebie funkcję do uzupełnienia odpowiedniej kolumny w tabeli z Arkusza3 (plik lekcja2.xlsx.).