Zajęcia: VBA TEMAT: VBA PROCEDURY NUMERYCZNE Metoda bisekcji i metoda trapezów W ramach zajęć oprogramujemy jedną, wybraną metodę numeryczną: metodę bisekcji numerycznego rozwiązywania równania nieliniowego lub metodę trapezów numerycznego obliczania całki oznaczonej. Najpierw rozwiążemy wybrane zagadnienie w środowisku Visual Basic, a następnie napisaną procedurę przeniesiemy do Excela wykorzystując możliwość powiązania kodu programu z komórkami arkusza w celu wprowadzania danych i prezentacji wyników obliczeń. Zadania do wykonania (jedno do wyboru / w zależności od grupy): 1. Napisać w Visual Basic program, w którym będzie można numerycznie rozwiązać wybrane równanie nieliniowe, czyli znaleźć przybliżoną wartość pierwiastka równania: f(x)=0. Do rozwiązania zastosować metodę bisekcji (podziału). Następnie przenieść napisaną procedurę do Excela i dokonać takich zmian w kodzie, aby umożliwić wprowadzanie danych i wyprowadzanie wyników w arkuszu Excela. 2. Napisać w Visual Basic program, w którym będzie można numerycznie obliczyć całkę oznaczoną z wybranej funkcji w zadanych granicach. Do rozwiązania zastosować metodę trapezów. Następnie przenieść napisaną procedurę do Excela i dokonać takich zmian w kodzie, aby umożliwić wprowadzanie danych i wyprowadzanie wyników w arkuszu Excela. Poznawane elementy języka: Wykonanie zadań pozwala na wykorzystanie następujących elementów języka Visual Basic: Zastosowanie pętli Zastosowanie instrukcji warunkowych Wykorzystanie odwołań do obiektów arkusza Excel Zad.J1. Numeryczne rozwiązywanie równania nieliniowego metodą bisekcji (połowienia). Metoda bisekcji (połowienia) jest jedną z najprostszych metod numerycznego rozwiązywania algebraicznych równań nieliniowych, czyli znajdowania przybliżonej wartości pierwiastka równania: f(x)=0 O funkcji f(x) zakłada się, że jest ciągła na przedziale domkniętym <x A ; x B >, wewnątrz którego znajduje się dokładnie jeden, wyizolowany pierwiastek i, na którego końcach wartości funkcji f(x) mają przeciwne znaki (czyli f(x A )f(x B )<0 ). W metodzie bisekcji, aby znaleźć ten pierwiastek, dzielimy przedział <x A ; x B > na połowy punktem 1
x C = (x A + x B )/2 Jeżeli f(x C ) = 0, to x C jest szukanym pierwiastkiem, jeśli zaś f(x C ) <> 0, to z otrzymanych dwóch przedziałów <x A ; x C > oraz <x C ; x B >, wybieramy do dalszej analizy ten, na końcach którego funkcja f(x) ma przeciwne znaki. To znaczy, jeśli f(x A )f(x C )<0 to wybieramy przedział <x A ; x C >, zatem wartość x C podstawiamy w miejsce x B, w przeciwnym przypadku wartość x C podstawiamy w miejsce x A. Z kolei ten nowo wybrany przedział dzielimy na połowy wyznaczając nowy punkt x C, ponownie badamy wartość funkcji f(x) w punkcie x C i znaki funkcji f(x) na końcach przedziałów itd. W wyniku takiego postępowania po pewnej liczbie kroków albo otrzymany pierwiastek dokładny, tzn. dla pewnego n otrzymamy f(xc)=0, albo ciąg przedziałów takich że : f(x i A)f(x i B)<0. Punkty x i A oraz x i B są odpowiednio początkiem i końcem przedziału w i-tej iteracji, a jego długość wynosi x i A - x i B =(x B - x A )/2 i. Ponieważ lewe końce ciągu przedziałów tworzą ciąg niemalejący i ograniczony z góry, a prawe końce ciąg nierosnący i ograniczony z dołu więc z powyższego równania wynika, że istnieje ich wspólna granica i jest nią pierwiastek rozwiązywanego równania. Ostatnia obliczona wartość x C może stanowić jego przybliżenie. Jako kryterium zakończenia obliczeń można przyjąć wykonanie maksymalnej dopuszczalnej liczby iteracji, MaxIter, lub otrzymanie przedziału < x i A ; x i B > o długości mniejszej od zadanej dokładności epsilon, tzn. x i A - x i B < eps. 2
Pomocą przy wykonaniu tego zadania może być następujący projekt formularza: 3
oraz schemat blokowy: 4
Zad.J2. Przeniesienie procedury "bisekcja" z Visual Basic do Visual Basic for Applications w MS Excel. Zadanie polega na przeniesieniu procedury numerycznej obliczającej pierwiastek równania nieliniowego metodą bisekcji napisanej w Visual Basic do środowiska MS Excel i wykorzystaniu jej posługując się danymi pochodzącymi z odwołań bezpośrednio do komórek arkusza. Zadanie zostanie wykonane w trzech etapach, w każdym z nich wprowadzone będą uogólnienia etapu poprzedniego. Etap 1. Przeniesienie procedury numerycznej i wykorzystanie jej tylko dla jednej, ustalonej funkcji np. Sin(x). Etap 2. Umożliwienie wprowadzania różnych funkcji jako napisów w wybranej komórce arkusza. Etap 3. Wykorzystanie obiektu ComboBox na arkuszu do wprowadzenia nazwy funkcji. Uwaga: Aby zrobić to zadanie trzeba wiedzieć jak odwoływać się w kodzie programu napisanego w Visual Basic for Applications do obiektów arkusza kalkulacyjnego Excel (patrz zajęcia 10 i 11). Dla naszych potrzeb wystarczy wiedzieć, że w Visual Basic for Applications w MS Excel do obiektów Excela takich jak skoroszyt, arkusz, komórka czy zakres można się odwoływać podając odpowiedni indeks (numer) tego elementu z kolekcji, np. Worksheets(1) odnosi się do pierwszego arkusza roboczego w skoroszycie. Innym sposobem jest odwołanie się do jego nazwy, np. Worksheets( Arkusz1 )odnosi się do arkusza roboczego o nazwie Arkusz1. Podobnie dla obiektów typu Range, które pozwalają odwołać się do poszczególnych komórek, można stosować odwołania po adresie, np. Worksheets(1).Range( A9 ) wskazujące odwołanie do komórki o adresie A9 z pierwszego arkusza roboczego, albo po nazwach zakresów zdefiniowanych uprzednio w arkuszu. Np. jeśli w arkuszu zdefiniowano nazwę lewy odnoszącą się do komórki o adresie $A$9 to odwołanie z poprzedniego przykładu może wyglądać następująco: Worksheets(1).Range( lewy ). 5
Etap 1. Przeniesienie procedury numerycznej i wykorzystanie jej tylko dla jednej, ustalonej funkcji np. Sin(x). W tym etapie, dla uproszczenia zakłada się, że procedura numerycznego wyznaczania pierwiastka będzie działała tylko dla jednej wybranej funkcji Sin(x). Otwórz Excel i przygotuj arkusz, w którym podawać będziesz dane potrzebne do procedury numerycznej oraz zarezerwujesz miejsce, gdzie wyświetlany będzie wynik. Przykład takiego arkusza może wyglądać tak: Otwórz edytor Visual Basic w Excelu (z menu Narzędzia wybrać Makro a następnie Edytor Visual Basic lub bezpośrednio wcisnąć Alt+F11). Będąc już w edytorze wstaw moduł (z menu Wstaw wybrać Moduł). Skopiuj teraz procedurę Oblicz() oraz funkcję funk(x) z projektu, który wykonałeś w Visual Basicu w zadaniu poprzednim (J1) do wstawionego modułu. Dokonaj zmian w kodzie programu w taki sposób, aby odwołania dotyczyły komórek arkusza, a nie obiektów na formularzu. Ogranicz rozpatrywane funkcje w funk(x) tylko do funkcji Sin(x). Umieść na arkuszu Przycisk Polecenia, za pomocą którego będziesz wywoływać napisaną procedurę (makro). 6
Etap 2. Umożliwienie wykonania obliczeń dla różnych funkcji wprowadzanych jako napisy w wybranej komórce arkusza. W tym etapie rozszerzymy nasz program o możliwość wykonania obliczeń dla różnych funkcji, których nazwy będziemy podawać w odpowiedniej komórce arkusza. Dokonaj zmian w kodzie funkcji funk(x) tak, aby uwzględniała napisy znajdujące się w arkuszu w komórce zawierającej nazwę obliczanej funkcji. Etap 3. Wykorzystanie obiektu Pole kombi (ComboBox) do wybierania nazwy funkcji. W tym etapie ułatwimy wybieranie nazwy funkcji, dla której wykonamy obliczenia, wykorzystując do tego celu kontrolkę ComboBox. Excel pozwala na umieszczanie na arkuszu różnych kontrolek (formantów), które znamy już z tworzenia formularzy w Visual Basic. Kontrolowanie tych obiektów jest co prawda bardziej ograniczone, niż ma to miejsce w Visual Basic, nie mniej jednak kontrolki te w pewnych przypadkach usprawniają użytkowanie Excela. W naszym ćwiczeniu wykorzystaliśmy już kontrolkę Przycisk Polecenia do uruchamiania procedury Oblicz. Teraz wykorzystamy kontrolkę Pole kombi czyli ComboBox. Zad.J3. Numeryczne obliczanie całki oznaczonej metodą trapezów. Numeryczne obliczanie całek oznaczonych polega na przybliżeniu wartości całki za pomocą ważonej sumy wartości funkcji f(x) w wybranych węzłach, x i, pomnożonych przez odpowiednie wagi, w i,: Zarówno dobór węzłów, jak i wag zależy od konkretnej metody. Metoda trapezów, numerycznego obliczania wartości całki oznaczonej danej funkcji ograniczonej na przedziale (a; b), polega na podzieleniu pola podcałkowego na n trapezów, gdzie podstawy są równoległe do osi OY, natomiast wysokości trapezów są równoległe do osi OX (patrz rysunek), a następnie na zsumowaniu pól tych trapezów. 7
Przedział całkowania dzielimy na dowolna liczbę równych podprzedziałów. Przybliżeniem wartości całki będzie suma pól trapezów powstałych po podzieleniu przedziału całkowania. Pola trapezów można policzyć z wzoru S i =(y i-1 +y i )*h/2 gdzie y i-1 i y i to wartości funkcji na końcach przedziału (x i-1 ; x i ), natomiast h = x i x i-1. Przy założeniu, że przedział całkowania dzielimy na n równych podprzedziałów wartość h można obliczyć ze wzoru: h=(b-a)/n gdzie a i b to końce przedziału całkowania. Im liczba podziałów n jest większa tym wynik jest dokładniejszy. Aby uprościć sumowanie, można zauważyć, że Wynik = S 1 +S 2 +...+S n = = (y 0 +y 1 )*h/2 +(y 1 +y 2 )*h/2 +... + (y n-1 +y n )*h/2 = = (y 0 /2 + y 1 + y 2 +... +y n-1 +y n /2)*h = = ((y 0 + y n )/2 + y 1 + y 2 +... +y n-1 )*h 8
Pomocą przy wykonaniu tego zadania może być następujący projekt formularza: 9
oraz schemat blokowy: 10
Zad.J4. Przeniesienie procedury "trapezy" z Visual Basic do Visual Basic for Applications w MS Excel. Zadanie polega na przeniesieniu procedury numerycznej obliczającej całkę oznaczoną metodą trapezów napisanej w Visual Basic do środowiska MS Excel i wykorzystaniu jej posługując się danymi pochodzącymi z odwołań bezpośrednio do komórek arkusza. Zadanie zostanie wykonane w trzech etapach, w każdym z nich wprowadzone będą uogólnienia etapu poprzedniego. Etap 1. Przeniesienie procedury numerycznej i wykorzystanie jej tylko dla jednej, ustalonej funkcji np. Sin(x). Etap 2. Umożliwienie wprowadzania różnych funkcji jako napisów w wybranej komórce arkusza. Etap 3. Wykorzystanie obiektu ComboBox na arkuszu do wprowadzenia nazwy funkcji. Uwaga: Aby zrobić to zadanie trzeba wiedzieć jak odwoływać się w kodzie programu napisanego w Visual Basic for Applications do obiektów arkusza kalkulacyjnego Excel (patrz zajęcia 10 i 11). Dla naszych potrzeb wystarczy wiedzieć, że w Visual Basic for Applications w MS Excel do obiektów Excela takich jak skoroszyt, arkusz, komórka czy zakres można się odwoływać podając odpowiedni indeks (numer) tego elementu z kolekcji, np. Worksheets(1) odnosi się do pierwszego arkusza roboczego w skoroszycie. Innym sposobem jest odwołanie się do jego nazwy, np. Worksheets( Arkusz1 )odnosi się do arkusza roboczego o nazwie Arkusz1. Podobnie dla obiektów typu Range, które pozwalają odwołać się do poszczególnych komórek, można stosować odwołania po adresie, np. Worksheets(1).Range( A9 ) wskazujące odwołanie do komórki o adresie A9 z pierwszego arkusza roboczego, albo po nazwach zakresów zdefiniowanych uprzednio w arkuszu. Np. jeśli w arkuszu zdefiniowano nazwę lewy odnoszącą się do komórki o adresie $A$9 to odwołanie z poprzedniego przykładu może wyglądać następująco: Worksheets(1).Range( lewy ). Etap 1. Przeniesienie procedury numerycznej i wykorzystanie jej tylko dla jednej, ustalonej funkcji np. Sin(x). W tym etapie, dla uproszczenia zakłada się, że procedura całkowania numerycznego będzie działała tylko dla jednej wybranej funkcji Sin(x). Otwórz Excel i przygotuj arkusz, w którym podawać będziesz dane potrzebne do procedury numerycznej oraz zarezerwujesz miejsce, gdzie wyświetlany będzie wynik. Przykład takiego arkusza może wyglądać tak: 11
Otwórz edytor Visual Basic w Excelu (z menu Narzędzia wybrać Makro a następnie Edytor Visual Basic lub bezpośrednio wcisnąć Alt+F11). Będąc już w edytorze wstaw moduł (z menu Wstaw wybrać Moduł). Skopiuj teraz procedurę Oblicz() oraz funkcję funk(x) z projektu, który wykonałeś w Visual Basicu w zadaniu poprzednim (J1) do wstawionego modułu. Dokonaj zmian w kodzie programu w taki sposób, aby odwołania dotyczyły komórek arkusza, a nie obiektów na formularzu. Ogranicz rozpatrywane funkcje w funk(x) tylko do funkcji Sin(x). Umieść na arkuszu Przycisk Polecenia, za pomocą którego będziesz wywoływać napisaną procedurę (makro). Etap 2. Umożliwienie wykonania obliczeń dla różnych funkcji wprowadzanych jako napisy w wybranej komórce arkusza. W tym etapie rozszerzymy nasz program o możliwość wykonania obliczeń dla różnych funkcji, których nazwy będziemy podawać w odpowiedniej komórce arkusza. Dokonaj zmian w kodzie funkcji funk(x) tak, aby uwzględniała napisy znajdujące się w arkuszu w komórce zawierającej nazwę obliczanej funkcji. Etap 3. Wykorzystanie obiektu Pole kombi (ComboBox) do wybierania nazwy funkcji. W tym etapie ułatwimy wybieranie nazwy funkcji, dla której wykonamy obliczenia, wykorzystując do tego celu kontrolkę ComboBox. Excel pozwala na umieszczanie na arkuszu różnych kontrolek (formantów), które znamy już z tworzenia formularzy w Visual Basic. Kontrolowanie tych obiektów jest co prawda bardziej ograniczone, niż ma to miejsce w Visual Basic, nie mniej jednak kontrolki te w pewnych przypadkach usprawniają użytkowanie Excela. W naszym ćwiczeniu wykorzystaliśmy już kontrolkę Przycisk Polecenia do uruchamiania procedury Oblicz. Teraz wykorzystamy kontrolkę Pole kombi czyli ComboBox. 12