Bieżący odcinek Akademii PC Kuriera rozpoczniemy od kontynuowania tematyki typu danych. Przypomnijmy może, że typy danych dzielą się na dwie grupy: typy wartościowe oraz typy referencyjne (wskaźnikowe). Visual Basic.NET podobnie jak wersji 6 nie wymaga jawnej deklaracji typu zmiennej (jawne deklarowanie typu danych nazywane jest silnym typowaniem). Jawne deklarowanie jest jednak mocno wskazane, gdyż zwiększa czytelność i stabilność kodu oraz zmniejsza zużycie pamięci, co owocuje szybszym wykonywaniem się skompilowanej aplikacji. Dodatkowo jawna deklaracja typu zapewni wsparcie ze strony technologii Intellisense. Wszystkie zmienne, których typ danych nie został jawnie zadeklarowany, domyślnie są typu Object (osoby posiadające doświadczenie zwrócą zapewne uwagę na różnicę w stosunku do wersji VB 6 w której zmienne te były typu Variant, który nie istnieje już w VB.NET) Zmienne w aplikacjach służą do przechowywania wartości, które zmieniają się w czasie działania. Przykładem zmiennej może być licznik wykonania pętli kodu, zmienna przechowująca wynik funkcji, nazwę użytkownika czy też ścieżkę dostępu do pliku. Każdą ze zmiennych (nawet jeśli nie jest to jawnie określone) definiuje sześć cech: Nazwa nazwa identyfikująca zmienną w danym obszarze kodu Adres adres pamięci pod którym zmienna jest przechowywana Typ danych typ danych i domyślna wartość inicjująca zmienną Wartość wartość zmiennej Zakres widoczności określenie obszaru kodu, dla którego zmienna jest widoczna Czas życia okres czasu, w którym zmienna istnieje i w którym jest dostępna Nazewnictwo zmiennych Nazwy zmiennych powinny być dobierane zgodnie ze strategią przyjętą w projekcie. Zwiększa to nie tylko czytelność kodu, ale również pomaga szybciej wdrożyć do projektu nowych programistów. Nazwa każdej ze zmiennej powinna spełniać trzy warunki: rozpoczynać się od litery lub znaku podkreślenia, nie powinna zawierać spacji i znaków symboli, nie może również identyczna jak jedno ze słów kluczowych języka. Wybierając nazwę dla zmiennej staraj się, aby była ona intuicyjna i opisowa. Jeśli złożona jest z kilku słów rozpoczyna każde z nich z wielkiej litery (tzw. PascalCasing konwencja Pascala) np. IdentyfikatorKlienta. Unikaj niejednoznacznych skrótów oraz powtórnego deklarowania zmiennej o tej samej nazwie i zakresie widoczności. Nazwy dla zmiennych lokalnych rozpoczynaj od małej litery, a każde kolejne słowo w nazwie zmiennej rozpoczynaj od wielkiej litery (jest to tzw. konwencja wielbłada (camelcasing) np. nazwiskoklienta. Deklarowanie zmiennych Bez względu na typ danych deklarację zmiennej w bloku, procedurze czy też module rozpoczyna się słowem kluczowym Dim. Następnie należy określić nazwę deklarowanej zmiennej. Po nazwie należy użyć słowa kluczowego As, po którym należy określić typ danych: Przykłady deklaracji zmiennych: Dim NawaKlienta As tring Dim DataUrodzenia As Date Dim ZaplaconoFakture As Boolean Dim NumerKasy As ingle Dim FormularzLogowania As Form Dim NazwaZmiennej As TypDanych Wymuszenie silnego typowania w środowisku Jak już wiesz, możesz nie deklarować typu zmiennej przed jej użyciem, choć nie jest to zalecane. Domyślnie Visual Basic.NET w przeciwieństwie do Visual Basic 6 wymusza na
programiście konieczność deklarowania typu danych dla każdej z użytych w kodzie aplikacji zmiennych przed ich pierwszym użyciem. Aby wyłączyć tę konieczność należy skorzystać z opcji Option Explicit Off. Opcję tę można ustawić korzystając z samego środowiska (kliknąć prawym przyciskiem w oknie olution Explorer na projekcie, rozwinąć katalog Common Properties, kliknąć na Build, i wybrać opcję Option Explicit znaleźć można wśród opcji Compile Defaults) lub wpisując ją jawnie przed kodem procedur obsługujących zdarzenia. Aby powrócić do domyślnego ustawienia należy analogicznie zmienić ustawienie opcji Option Explicit na On. Poniższy przykład demonstruje, dlaczego korzystanie z opcji Option Explicit Off jest nie wskazane: Dim Naleznosc as ingle Dim Znizka as ingle Dim DoZaplaty as ingle Naleznosc=1500 Znizka=15 '15 procent 'w poniższej linii znajduje się błąd wskutek pomyłki literowej DoZaplaty=((100-Znizka)/100)*Nalenzosc MessageBox.how(dozaplaty) Każdorazowe uruchomienie tego kodu spowoduje, że obliczona do zapłaty kwota będzie zawsze równa zeru. Dzieje się tak, gdyż wskutek pomyłki jeden z wierszy odwołuje się do niezadeklarowanej zmiennej Nalenzosc. Ponieważ dla nowej zmiennej Nalenzosc nie został określony typ danych zostanie użyty domyślny typ Object, który następnie zostanie skonwertowany do typu liczbowego i wartości 0. Jeśli opcja ta ustawiona byłaby na On kompilator wyświetliłby informację o błędzie. Jak widać z przedstawionego przykładu opcja Option Explicit On pomaga ustrzec się przed popełnieniem popularnego i trudnego do odkrycia (zwłaszcza dla początkujących programistów) błędu logicznego w aplikacji). Przypisywanie wartości do zmiennych, inicjowanie zmiennych Zmienne służą do przechowywania wartości lub referencji. Aby do dane jzmiennej przypisać określoną wartość należy skorzystać z operatora przypisania (podstawienia) =. Po operatorze należy określić wartość, jaka ma być przypisana do zmiennej, Wartość ta może być zarówno prostą wartością liczbową, jak i wartością określoną przez ciąg operacji i funkcji posiadających określony wynik. Przykłady: Dim Liczba as ingle Dim podwojonaliczba as ingle Dim potrojonawartowsczmiennejliczba as ingle Liczba=20 podwojonaliczba=20*2 potrojonawartowsczmiennejliczba=liczba*3 Należy pamiętać, że zmienna, do jakiej zostanie przypisana wartość znajduje się zawsze po lewej stronie operatora przypisania, natomiast przypisywana wartość znajduje się po stronie prawej. Jeśli przypisujemy wartość do zmiennej innego niż liczbowy typu, przypisywaną wartość należy rozpocząć i zakończyć dodatkowo określonymi znakami. Dla zmiennych typu string znakiem tym jest (cudzysłów), dla dat jest to natomiast znak #. Przykłady: Dim nazwiskoklienta as tring Dim datazamowienia as Date nazwiskoklienta= Kowalski datazamowienia =#5/9/2003# Oczywiście pomiędzy deklaracją zmiennej a przypisaniem jej wartości zmienna musi posiadać również jakąś wartość. Domyślną wartością dla typów liczbowych jest 0, dla typu tring jest to łańcuch złożony z zera znaków ( ), a dla dat jest to 1 stycznia 1 roku. W Visual Basic.NET można również połączyć deklarację zmiennej wraz z inicjalizacją jej wartości. Demonstrują to następujące przykłady:
Dim nazwiskoklienta as tring = Kowalski Dim datazamowienia as Date = #5/9/2003# tałe Kod aplikacji często może korzystać z wartości, które są niezmienne. Przykładem takich wartości mogą być stałe używane we wzorach i funkcjach fizycznych czy też matematycznych (np. liczba Pi, stała G, czy też liczba miesięcy w roku). Korzystanie ze stałych nie tylko zwiększa czytelność i stopień zrozumienia kodu, ale również zmniejsza zużycie pamięci przez aplikację oraz pozwala na szybką zmianę parametrów obliczeń w obrębie całej aplikacji. Aby zadeklarować stałą należy skorzystać z podobnej składni jak w wypadku deklaracji zmiennej. Jedyną różnicą jest zastąpienie słowa Dim słowem Const oraz konieczność inicjalizacji wartości stałej w momencie jej deklaracji: Const Nazwatałej As Typ Danych = Wartość Przykład użycia stałej w obliczeniach demonstruje poniższy kod: Const LiczbaMiesiecyWRoku as ingle = 20 Dim OkresWLatach as ingle = 20 Dim LiczbaMiesiecyWOkresie as ingle LiczbaMiesiecyWOkresie= OkresWLatach * LiczbaMiesiecyWRoku Zasięg zmiennych Zasięg zmiennej to obszar kodu, dla jakiego dana zmienna jest dostępna. Użycie zmiennej poza jej zasięgiem spowoduje w zależności od ustawienia opcji Option Explicit bądź błąd kompilatora bądź też powołanie do życia nowej zmiennej typu object o takiej samej nazwie. Należy pamiętać, że zasięg zmiennej powinien być jak najmniejszy (oszczęda to pamięć oraz minimalizuje ryzyko odnoszenia się w kodzie do niewłaściwej zmiennej). Zmienna może mieć jeden z następujących czterech zasięgów (zakresów): Blok zmienna dostępna jest tylko dla kodu wewnątrz funkcji lub procedury. Blok kodu rozpoczyna się od słów kluczowych języka określających warunek lub pętlę Procedura zmienna dostępna jest dla całego bloku kodu procedury Moduł zmienna dostępna jest dla całego kodu modułu, klasy lub struktury zawierającej deklarację Przestrzeń nazw (Namespace) zmienna dostępna jest dla kodu w tej samej przestrzeni nazw (dla całego kodu projektu) O tym, jaki będzie zakres danej zmiennej, decydują trzy elementy: miejsce deklaracji zmiennej blok, procedura, moduł, klasa, struktura modyfikator dostępu (access modifier) - Public, Friend, Private lub Protected użyta do deklaracji składnia Aby zadeklarować zmienną lokalną o zasięgu bloku należy wewnątrz bloku użyć składni deklarującej zmienną zgodnie ze strukturą przedstawioną w początkowej części artykułu. Przykład: If jestznizka Then Dim znizka as ingle Znizka=15 End If Deklaracja zmiennej o zasięgu procedury jest identyczna jak deklaracja zmiennej o zasięgu bloku, różni się natomiast ulokowaniem w kodzie. Przykładową deklarację zmiennej o zasięgu procedury demonstruje następujący kod:
ub PokazIleDoZaplaty() Dim naleznosc as ingle 'ta zmienna ma zasięg procedury Dim dozaplaty as ingle 'ta zmienna ma zasięg procedury Dim znizka as ingle 'ta zmienna ma zasięg procedury naleznosc=1500 znizka=15 dozaplaty=((100-znizka)/100)*naleznosc MessageBox.how(dozaplaty) End ub Po zakończeniu działania kodu procedury wszystkie zmienne lokalne o zasięgu zawartych bloków kodu oraz o zasięgu procedury są usuwane z pamięci. Aby przechowywana pomiędzy kolejnymi wywołaniami procedurami należy zadeklarować ją jako lokalną zmienną statyczną. Wartość zmiennej będzie wtedy przechowywana w pamięci, aż do zakończenia działania aplikacji. Umożliwia to następująca deklaracja: tatic NazwaZmiennej As TypDanych Lokalne zmienne statyczne najczęściej wykorzystywane są jako liczniki wywołań procedury co prezentuje poniższy kod procedury: ub PokazIleRazyWywolano() tatic ile as ingle 'ta zmienna ma zasięg procedury ile=ile+1 MessageBox.how(ile) End ub Do deklaracji zmiennej o zasięgu modułu, klasy lub struktury należy skorzystać z poniższej składni: ModyfikatorDostępu NazwaZmiennej As TypDanych Należy pamiętać, że deklaracja ta nie może mieć miejsca wewnątrz dowolnej procedury lub funkcji. Modyfikator dostępu jest jednym z trzech słów kluczowych: Private, Friend lub Public. Zmienna o modyfikatorze Private jest dostępna dla dowolnego kodu w obrębie modułu, struktury lub klasy zawierającej deklarację. Zmienna o modyfikatorze Friend dostępna będzie dla całego kodu projektu (solution), ale nie dla kodu spoza projektu. Zmienna o modyfikatorze Public dostępna będzie dla każdego z projektów wchodzących w skład tworzonego rozwiązania (solution), w którego skład może wchodzić więcej niż jeden projekt. Na zasięg zmiennej wpływa nie tylko użyty w czasie deklaracji modyfikator dostępu, ale zasięg danego modułu, klasy czy też struktury zawierającej deklarację. Zasięg danej zmiennej nigdy nie może być jednak większy niż zasięg zawierającej deklarację jednostki kodu. Uważny czytelnik z pewnością zwróci uwagę na teoretyczne podobieństwo zmiennych prywatnych o zakresie modułu oraz statycznych zmiennych lokalnych. Zasadniczą różnicą pomiędzy oboma typami zmiennych jest możliwość lub brak możliwości modyfikowania wartości zmiennej przez kod spoza procedury zawierającej deklarację lokalnej zmiennej statycznej. Konwersja typu danych Kod każdej z aplikacji składa się z wielu struktur, procedur i funkcji korzystających z wielu zmiennych i argumentów. Każda ze zmiennych ma określony typ danych, a każda z funkcji i procedur może korzystać z argumentów określonego typu. Co zrobić, jeśli typ danych zmiennej jest niedpowiedni do przeprowadzenia danej operacji? Należy go zmienić. Konwersja wartości z jednego typu danych do innego typu danych nazywany jest konwersją. Konwersja może być jawna przeprowadzona przez kod aplikacji z użyciem jednej z funkcji konwersji, lub niejawna przeprowadzona w razie potrzeby automatycznie przez kompilator. Zaleca się jak najczęstsze
korzystanie z konwersji jawnej, gdyż owocuje ona szybszym działaniem kodu oraz minimalizuje możliwość pojawienia się nieoczekiwanych błędnych wyników obliczeń. Do przeprowadzenia jawnej konwersji należy użyć jednej z prezentowanych przez poniższą tabelę przykładowych funkcji. Należy pamiętać, że konwersja pomiędzy typami danych nie zawsze może być możliwa, gdyż zależy od konwertowanej wartości i typu docelowego. Funkcja konwersji Docelowy typ danych Dopuszczalne wartości do skonwertowania Ctr tring Dowolna wartość numeryczna, Boolean, Char, Date, Object CInt Integer Dowolna wartość numeryczna, Boolean, tring, Object CDbl Double Dowolna wartość numeryczna, Boolean, tring, Object CDate Date tring, Object posób użycia niektórych z prezentowanych funkcji prezentuje poniższy kod: Dim liczbainteger As Integer Dim liczbadouble As Double liczbainteger = 321 liczbadouble = 3.1415 MessageBox.how(liczbaInteger) MessageBox.how(Ctr(liczbaInteger) & "0") MessageBox.how(CInt(liczbaDouble)) Wszystkie funkcje konwersji mają tę samą budowę. Ich nazwa rozpoczyna się od litery C, a następnie zawiera skrót od nazwy docelowego typu danych. Należy zwrócić jeszcze uwagę na kolejny aspekt związany z konwersją. Rozpatrzmy przykład konwersji liczby typu Integer do typu Long. Typ danych Long jest dokładniejszy niż Integer, dlatego po konwersji wartość zwiększy swą precyzję. Konwersję, w której typ docelowy pozwala na przechowanie dowolnej wartości typu źródłowego nazywa się konwersją poszerzającą (widening conversion). Konwersja zawężająca (narrowing conversion) zachodzi natomiast w momencie, gdy konwertowana wartość musi zostać zmniejszona (np. konwersja wartości typu Long do Integer). Konwersja niejawna Konwersja niejawna jest przeprowadzana przez kompilator, w sytuacji niedopasowania typu danych i braku konwersji jawnej. Poniższy przykład prezentuje konieczność przeprowadzenia konwersji niejawnej przez kompilator: Dim liczba As Integer Dim napis As tring napis = "13" liczba = 15 liczba = liczba + napis W powyższym przykładzie, aby poprawnie wykonać operację dodawania kompilator dokona niejawnej konwersji zmiennej typu tring na typ danych Integer. Należy pamiętać, że konwersja niejawna wprowadza do kodu ryzyko pojawienia się błędów powstałych wskutek utraty precyzji danych, nieoczekiwanych błędnych wyników operacji oraz spowolnienia działania aplikacji. Pracę z konwersją niejawną ułatwia opcja Option trict. Domyślne ustawienie Option trict Off pozwala na korzystanie zarówno z niejawnej konwersji poszerzającej jak i zawężającej. Aby kompilator traktował niejawną konwersję zawężającą jako błąd należy skorzystać z opcji Option trict On. truktury, czyli typy danych użytkownika Informacje mogą często być złożone z szeregu danych. Przykładem takiej informacji mogą być dane samochodu w skład których wchodzi model, marka, data produkcji oraz typ nadwozia. Jak widać przykładowa struktura opisująca samochód złożona jest z trzech danych typu tring (model, marka i typ nadwozia) oraz jednej danej typu Date. Kombinacja prostych typów danych pozwala więc
na zdefiniowanie jednej struktury danych, a następnie na deklarowanie zmiennej tego typu oraz wykorzystywanie jej w kodzie. truktury są typami wartości (value type). Oznacza to, że zmienna tego typu bezpośrednio przechowuje dane w pamięci (w przeciwieństwie do typów referencyjnych przechowujących wskaźnik do miejsca w pamięci). W odróżnieniu do Visual Basic 6 w Visual Basic.NET struktury coraz bardziej przypominają klasy, gdyż mogą zawierać nie tylko dane, ale również mogą posiadać własności, metody, procedury. Mogą również wywoływać i obsługiwać zdarzenia. Zanim zaczniesz korzystać ze struktury musisz ją zadeklarować w osobnym pliku projektu lub wewnątrz modułu lub klasy (zapamiętaj, że deklaracji struktury nie powinno umieszczać się wewnątrz procedury). Deklaracja struktury rozpoczyna się od modyfikatora dostępu (Public, Protected, Friend lub Private) oraz wyrażenia tructure i kończy się odpowiadającym wyrażeniem End tructure. Następnie ciało deklaracji struktury należy uzupełnić o conajmniej jedną deklarację składowych struktury. kładowe struktury mogą być dowolnego typu, należy również określić zasięg każdej z nich (poprzez jeden z modyfikatorów dostępu: Dim, Friend, Private oraz Public). Domyślnie modyfikator dostępu Dim równoznaczny jest modyfikatorowi Dim, a brak określenie typu danych składowej spowoduje, że będzie ona typu Object. Następujący przykład demonstruje jak zadeklarować strukturę amochod: Public tructure amochod Public Marka As tring Public Model As tring Public Nadwozie As tring Public RokProdukcji As Date End tructure Kiedy deklaracja struktury jest już gotowa możemy zadeklarować zmienną samochod1 typu amochod: Dim samochod1 as amochod Następnie możemy w kodzie aplikacji korzystać ze struktury odczytując lub modyfikując odpowiednio składowe struktury: samochod1.marka = "Ford" samochod1.model = "Focus" samochod1.nadwozie = "Combi" samochod1.rokprodukcji = #5/20/2003# If Year(samochod1.RokProdukcji) = 2003 And samochod1.marka = "Ford" Then MessageBox.how("To jest Ford rocznik 2003") End If Na tym zakończymy ten odcinek Akademii PC Kuriera. Kolejny odcinek zawierał będzie informacje na temat tablic. Poruszona zostanie także tematyka tworzenia i korzystania procedur oraz funkcji użytkownika.