• Nie Znaleziono Wyników

Ćwiczenie VB3.4 Struktura Try...Catch, obiekt Err, metoda Err.Raise (Strukturalna obsługa wyj

N/A
N/A
Protected

Academic year: 2021

Share "Ćwiczenie VB3.4 Struktura Try...Catch, obiekt Err, metoda Err.Raise (Strukturalna obsługa wyj"

Copied!
8
0
0

Pełen tekst

(1)

Ćwiczenie VB3.4 Struktura Try...Catch, obiekt Err, metoda Err.Raise

(Strukturalna obsługa wyjątków)

Jeśli wpiszemy do okna tekstowego zamiast cyfr – litery (np. abc), a następnie spróbujemy ten ciąg znaków przekonwertować na liczbę - instrukcją, np. CSng(txtLiczba.Text) lub

Single.Parse(txtLiczba.Text) działanie programu zostanie przerwane i wyświetlony zostanie komunikat

„Konwersja z ciągu ”abc” na typ Single nie jest prawidłowa” przy instrukcji A = CSng(TextBox1.Text)

lub

„Nieprawidłowy format ciągu wejściowego” przy instrukcji A = Single.Parse(TextBox1.Text)

patrz rys. 1 i 2.

Rysunek 1

Rysunek 2

(2)

Taką sytuację nazywamy błędem czasu wykonania (run time error), a środowisko pracy Visual Basic określa ją jako nie obsłuŜony wyjątek.

Po takim komunikacie program zatrzymuje się (zawiesza) - nie moŜe być dalej wykonywany i naleŜy go przerwać.

Aby program nie przerywał działania w sposób nieoczekiwany przez uŜytkownika lecz pozwolił dalej np. wprowadzać dane i posługiwać się nim - stosujemy własna strukturę obsługi błędów (tzw. wyjątków).

Struktura ta ma postać:

Try

'Kod chroniony Catch ex As Exception

'Instrukcje wykonywane przy błędzie.

'Własna obsługa błędów.

Finally

'Blok opcjonalny.

'Instrukcje wykonywane niezaleŜnie od tego 'czy błąd się pojawił czy nie pojawił.

End Try

Obiekt ex jest to obiekt wyjątek, którego właściwości moŜemy wykorzystywać.

Często strukturę tę skracamy – opuszczając blok Finally:

Try

'Kod chroniony Catch ex As Exception

'Instrukcje wykonywane przy błędzie 'Własna obsługa błędów.

End Try

lub jeszcze bardziej upraszczamy gdy nie zamierzamy korzystać z obiektu ex:

Try

'Kod chroniony Catch

'Instrukcje wykonywane przy błędzie 'Własna obsługa błędów.

End Try

Najprostsze wykorzystanie struktury Try... Catch

i jej efekt na rys. 3:

(3)

Po odczytaniu takiego komunikatu moŜemy poprawić wpisana wartość, kliknąć przycisk i program będzie kontynuował działanie.

Obiekt ex (Exception - wyjątek)

Aby posłuŜyć się obiektem ex (Exception - wyjątek) moŜemy wykorzystać jego właściwości Message lub wprost wyświetlić metodą ToString jego zawartość.

Kod Try

'Kod chroniony

n = CInt(TextBox1.Text)

TextBox3.Text = "N = " & n.ToString Catch ex As Exception

'Komunikat jak na rys. 4

MsgBox("ex.Message: " & ex.Message, MsgBoxStyle.Information, _ "Własna obsługa błędów 1")

'Komunikat jak na rys. 5

MsgBox("ex.ToString: " & ex.ToString, MsgBoxStyle.Exclamation, _ "Własna obsługa błędów 1")

End Try

przy braku danych w oknie tekstowym wyświetla komunikaty:

Rysunek 4. Własna obsługa błędów 1, ex.Message

Rysunek 5. Własna obsługa błędów 2, ex.ToString

Który rodzaj komunikatu wybrać autor programu moŜe zadecydować sam (podpowiadam, Ŝe wersja 1, rys. 4, jest bardziej zrozumiała).

(4)

Obiekt Err

Gdy pojawia się błąd czasu wykonania „wie o nim wszystko” obiekt Err. MoŜemy z tej wiedzy skorzystać. UŜytecznymi dla nas właściwościami tego obiektu są:

Err.Number – zwraca numer błędu

Err.Description – zwraca krótki opis błędu.

Np. kod:

Try

'Kod chroniony

A = CSng(TextBox1.Text)

TextBox3.Text = "A = " & A.ToString Catch

'Instrukcje wykonywane przy błędzie

MsgBox("Err.Number = " & Err.Number & vbCrLf & _ "Err.Description = " & Err.Description) End Try

wyświetli komunikat jak na rys. 6 (porównaj z rys. 4)

Rysunek 6 A jeśli komunikat zredagujemy jak w kodzie poniŜej:

MsgBox("Proszę poprawić dane." & vbCrLf & _

Err.Description, MsgBoxStyle.Information, "Błąd nr " & Err.Number) UŜytkownik zobaczy go jak na rys. 7

(5)

Komunikat zaleŜny od numeru błędu

W bloku instrukcji Catch wykonywanych przy błędzie, moŜemy instrukcją warunkową badać numer błędu (Err.Number) i w zaleŜności od numeru błędu wyświetlać odpowiedni komunikat.

Np. kod poniŜej oblicza silnię. Silnia liczby 13 przekracza wartość maksymalnej liczby mieszczącą się w zmiennej typu Integer.

Sytuacja taka moŜe generować komunikaty zwracające uwagę uŜytkownikowi na rodzaj błędu - mówiący o niezgodności typów, rys. 8 lub przepełnieniu, rys. 9.

Private Sub Button1_Click(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles Button1.Click Dim s As Integer = 1

Dim i, n As Integer Try

'Kod chroniony

n = CInt(TextBox1.Text) For i = 1 To n

s = s * i Next

TextBox3.Text = s.ToString Catch

'Instrukcje wykonywane przy błędzie If Err.Number = 13 Then

'Komunikat przy błędzie nr 13 (rys. 8) MsgBox("Niezgodność typów." & vbCrLf & _

"Proszę poprawić dane.", MsgBoxStyle.Information, _ "Błąd nr " & Err.Number)

ElseIf Err.Number = 6 Then

'Komunikat przy błędzie nr 6, rys. 9 MsgBox("Przepełnienie." & vbCrLf & _

"Liczba jest zbyt duŜa.", MsgBoxStyle.Question, _ "Błąd nr " & Err.Number)

Else

'Komunikat przy błędach o pozostałych numerach MsgBox("Proszę poprawić dane." & vbCrLf & _

Err.Description, MsgBoxStyle.Critical, _ "Błąd nr " & Err.Number)

End If End Try End Sub

Rysunek 8 Rysunek 9

(6)

Samodzielne (programowe) generowanie błędów i ich obsługa

Zadanie

Obliczyć objętość walca V mając dane: promień podstawy R i wysokość H. Formularz niech ma postać jak na rys. 10.

Gdy tworzymy tę aplikację – moŜemy przewidzieć sytuację, gdy uŜytkownik wprowadzi błędne dane, np. wartości spoza zakresu (w zadaniu są to wartości mniejsze lub równe zero). MoŜemy teŜ obsłuŜyć ją programowo bez struktury Try ... Catch:

R = CSng(txtR.Text) If R <= 0 Then

MsgBox("Błąd danych: R <= 0", MsgBoxStyle.Critical, "Złe dane") Exit Sub

End If

W takiej sytuacji naleŜałoby teŜ warunkowo przerwać dalsze wykonywanie programu instrukcją Exit Sub. Efekt takiego rozwiązania pokazuje rys. 11.

Podobnie naleŜałoby zabezpieczyć błędnie wprowadzone dane dla wysokości walca H.

Wygodniejszym jednak sposobem jest posłuŜenie się strukturą Try ... Catch, a pojawienie się sytuacji, którą uwaŜamy za błędną, zasygnalizować metodą Err.Raise().

Rysunek 10

Rysunek 11

(7)

Kod

Private Sub btnOblicz_Click(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles btnOblicz.Click Dim R, H, V As Single

Try

R = CSng(txtR.Text)

'If R <= 0 Then

' MsgBox("Błąd danych: R <= 0", MsgBoxStyle.Critical, _ "Złe dane")

' Exit Sub 'End If

If R <= 0 Then

Err.Raise(9000, "Test promienia. ", "Promień R <= 0") 'Err.Raise(Number, Source, Description)

End If

H = CSng(txtH.Text) If H <= 0 Then

Err.Raise(9001, "Test wysokości.", "Wysokość H <= 0") 'Err.Raise(Number, Source, Description)

End If

V = Math.PI * R ^ 2 * H txtV.Text = V.ToString Catch ex As Exception

MsgBox(Err.Source & Err.Description, _

MsgBoxStyle.Exclamation, "Błąd nr " & _ Err.Number)

'MsgBox("ex.Message: " & ex.Message, MsgBoxStyle.Information, _ "błąd nr " & Err.Number)

End Try End Sub

Posługiwanie się metodą Raise pozwala w strukturze Catch umieścić tylko jedną instrukcję (np.

pojedynczy Message Box) drukującą komunikaty o błędach i róŜnicować ją podczas własnego generowania błędu.

W kodzie pokazano teŜ „zakomentowane” fragmenty kodu do innej obsługi błędów. Proszę

„odkomentować” i zobaczyć róŜnicę w działaniu.

(8)

Programowe generowanie błędów i ich obsługa przy pracy z podprogramami

Gdy tworzymy aplikację składającą się z podprogramów i/lub funkcji - moŜliwość samodzielnego (programowego) określania numeru błędu, jego źródła i opisu jest najwygodniejszym sposobem

posłuŜenia się strukturą Try ... Catch. Tworzymy ją na jak najwyŜszym poziomie (tu w programie głównym), a pojawienie się błędu w procedurach lub funkcjach obsłuŜymy metodą Err.Raise().

Zadanie to samo

Obliczyć objętość walca V mając dane promień podstawy R i wysokość H. Formularz niech ma zatem postać jak na rys. 10.

Pole podstawy walca i jego objętość obliczymy posługując się oddzielnymi funkcjami, a błędy, które mogą powstać „gdzieś głęboko” w funkcjach – obsłuŜymy w programie głównym strukturą Try ... Catch z pojedynczą instrukcją drukującą (róŜnorodne) komunikaty o błędach.

Kod

Private Sub btnOblicz_Click(ByVal sender As _ System.Object, ByVal e As System.EventArgs) Handles btnOblicz.Click Dim R, H, V As Single

Try

R = CSng(txtR.Text) H = CSng(txtH.Text)

V = Objetosc(PolePodstawy(R), H) txtV.Text = V.ToString

Catch

MsgBox(Err.Source & " - błąd danych: " & Err.Description, _ MsgBoxStyle.Exclamation, "Błąd nr " & _

Err.Number) End Try

End Sub

Private Function PolePodstawy(ByRef R As Single) As Single If R <= 0 Then

Err.Raise(9000, "Funkcja PolePodstawy", "Promień R <= 0") 'Err.Raise(Number, Source, Description) End If

PolePodstawy = Math.PI * R ^ 2 End Function

Private Function Objetosc(ByVal pole As Single, _

ByVal wysokosc As Single) As Single If wysokosc <= 0 Then

Cytaty

Powiązane dokumenty

Każda automatyczna decyzja skutkująca powstaniem oferty, odrzuceniem wniosku lub skierowaniem wniosku do decyzji underwritera zostaje odnotowana w syste- mie i może wpływać na

class SamochódNaBenzynę extends Samochód { void jedź() throws BrakBenzyny {}. class SamochódONapędzieHybrydowym extends

• Jeśli kod wewnątrz metody moŜe spowodować wyjątek, a nie dostarczymy procedury jego obsługi zostaniemy. „zdyscyplinowani”

✓ Nabędzie umiejętności efektywnej komunikacji, negocjacji i mediacji w przestrzeni online. ✓ Pozna zasady i narzędzia współpracy, przeciwdziałania konfliktom wykorzystywane

• Za prawidłowo wykonane ćwiczenie uzyskujesz liczbę punktów wskazaną w kolumnie punktacja zadania.. Ostatnią kolumnę tabeli

Lepszym i bardziej zgodnym z ogólnie przyjętym działaniem funkcji jest implementacja w której czeka się na naciśnięcie klawisza, czyli „przemiatamy” aż do napotkania sytuacji

o tym, że zmienna errno jest ustawia- na przez funkcje, które wykrywają i sygnalizują sytuacje nienormalne, lecz nie zmienia wartości, gdy wynik działania funkcji jest poprawny (

Zagadnienia: źródła błędów, organizacja obsługi błędów, standardowe funkcje obsługi błędów, przeszukiwanie tablic: liniowe, binarne, sortowanie tablic: przez