Kod aplikacji cz. 1 | Część II | Część III
Program MapInfo Professional znajduje zastosowanie w bardzo wielu branżach, często dość od siebie odległych. Poza wykorzystywaniem danych przestrzennych nie mają one ze sobą wiele wspólnego, co jest dowodem na to, że MapInfo to program naprawdę uniwersalny. Mimo tego istnieją czynności, charakterystyczne dla danego typu użytkownika, do których wykonania lub uproszczenia niezbędne jest napisanie dodatkowej aplikacji. Służy do tego specjalnie stworzony dla MapInfo język MapBasic.
Dla kogo jest ten kurs
Niniejszy kurs nie jest przeznaczony dla informatyków i nie jest przez informatyka pisany! Podstawowym założeniem jest przedstawienie MapBasic'a jako narzędzia bardzo użytecznego i możliwego do opanowania dla osób nie będących programistami (wystarczy dobrze znać MapInfo Professional).
Oczywiście istnieją bardzo rozbudowane aplikacje, których napisanie wymaga wiedzy informatycznej. Są one skomplikowane i najczęściej dodają zupełnie nową funkcjonalność do MapInfo. Niemniej jednak tworzenie prostych, lecz bardzo przydatnych aplikacji nie jest trudne i może zostać opanowane przez każdego zaawansowanego użytkownika MapInfo. Właśnie dla tego MapBasic może stać się narzędziem codziennej pracy biznesmenów, urzędników i inżynierów.
Pierwsza część opisuje czym jest MapBasic i jak można z niego korzystać oraz daje pewne podstawowe informacje pozwalające na pisanie aplikacji. Przedstawiony jest bardzo prosty przykład, który prowadzi od okna MapBasic do pełnej aplikacji. W następnych numerach Imagis Forum pojawiać się będą opisy kolejnych, przydatnych elementów języka oraz przykłady bardziej złożonych aplikacji.
Mam nadzieję, że cały cykl zachęci Czytelników do pisania własnych programów i MapBasic przestanie być traktowany jako narzędzie jedynie dla programistów.
Po co MapBasic
MapBasic jest językiem programowania do tworzenia aplikacji działających w środowisku MapInfo Professional. Pozwala na rozszerzanie funkcjonalności MapInfo, automatyzację powtarzalnych czynności lub integrację MapInfo z innymi aplikacjami.
Rozszerzenie funkcjonalności jest konieczne, kiedy system ma być zastosowany w sposób nietypowy. Pewne zadania nie mogą być wykonane wprost w MapInfo. Wyobraźmy sobie, że chcemy na planie miasta wykreślić strefę obejmującą miejsca, z których odległość dojazdu do danego punktu nie jest większa niż 5 kilometrów. Standardowo w MapInfo możliwe jest stworzenie bufora o promieniu 5 kilometrów wokół tego punktu. Jednakże tworząc naszą strefę dojazdu będziemy brać pod uwagę odległość mierzoną po odcinkach ulic. Zatem kształt tej strefy będzie inny niż okrąg (bufor wokół punktu).
Tak więc do wykonania tego zadania niezbędne jest dodanie odpowiedniej funkcjonalności do MapInfo, słowem - napisanie aplikacji. Innym przykładem rozszerzania funkcjonalności systemu jest aplikacja optymalizująca transport, która powstała w firmie IMAGIS.
Często bywa tak, że aby uzyskać pożądany efekt musimy powtarzać pewne czynności wielokrotnie. W tym przypadku napisanie aplikacji, dzięki której możemy wykonywać je automatycznie, pozwala zaoszczędzić czas. Stworzenie aplikacji w MapBasic'u jest także uzasadnione jeżeli wykonujemy pewne zadanie wielokrotnie i wiemy, że będziemy je wykonywać w przyszłości.
Taka aplikacja może jednocześnie upraszczać obsługę programu. Przykładowo, w pewnej firmie świadczącej usługi assistance, zainstalowano kilkanaście kopii MapInfo. Pracownicy mają za zadanie poinformować każdego dzwoniącego klienta, który poda swoją lokalizację, o najbliższych zakładach mechaniki samochodowej, hotelach, restauracjach, aptekach, itp. Operator musi znaleźć to miejsce, wyświetlić odpowiednią warstwę z żądanymi obiektami i znaleźć najbliższy. Aby uzyskać gotową do podania informację należy wykonać wiele czynności, powiększać lub pomniejszać mapę, a przede wszystkim: dobrze znać MapInfo. W takiej sytuacji uzasadnione jest napisanie aplikacji w MapBasic'u, która po wypełnieniu odpowiednio zaprojektowanego okna dialogowego od razu wyświetli najbliższe żądane obiekty, ich cechy oraz odpowiedni widok mapy. Firma oszczędzi na szkoleniach, operator pozbędzie się stresu, a czekający po drugiej stronie słuchawki niecierpliwy klient otrzyma natychmiast pełną informację.
Możliwa jest też integracja MapInfo z istniejącymi już w firmach gotowymi programami, które doskonale sprawdzają się w praktyce. Zastosowanie pewnych funkcji mapowych, na przykład pokazanie rozkładu danych w przestrzeni geograficznej może znacznie je wzbogacić. MapBasic umożliwia napisanie programu łączącego owe aplikacje z MapInfo w jeden, zintegrowany system.
Standardowe narzędzia MapInfo to aplikacje MapBasic.
Wraz z każdym programem MapInfo dostarczany jest zestaw aplikacji napisanych w MapBasic'u i nazywanych narzędziami. Każdy użytkownik ma do nich dostęp z menu Narzędzia > Menedżer narzędzi. Aby zobaczyć, gdzie znajdują się te aplikacje należy w oknie dialogowym Menedżer narzędzi, po podświetleniu narzędzia np. "Autoetykiety", kliknąć przycisk Edytuj narzędzie. Pojawi się kolejne okno dialogowe, gdzie w polu Położenie wpisana jest ścieżka dostępu do katalogu Tools. W tym właśnie katalogu znajdują się pliki, z których większość ma rozszerzenie .MBX . Są to gotowe aplikacje. Mając do dyspozycji MapBasic możemy samodzielnie tworzyć takie właśnie pliki .MBX i uruchamiać je w MapInfo, dodając jako nowe narzędzie do Menedżera narzędzi, bądź poprzez komendę Aplikacja MapBasic w menu Plik.
Stworzona przez nas aplikacja będzie mogła wykonywać konkretne polecenia MapInfo i zaprogramowane przez nas funkcje, manipulować tabelami i obiektami graficznymi w oknie mapy oraz będziemy mogli zaprojektować własny interfejs użytkownika z odpowiednimi oknami dialogowymi.
Środowisko programowania MapBasic
Środowisko programowania jakim jest MapBasic, składa się przede wszystkim z edytora, w którym pisze się tak zwany kod programu (można go pisać także w innym edytorze tekstu). Kod programu jest po prostu tekstem zawierającym poszczególne instrukcje i zmienne (więcej o elementach języka w dalszej części kursu). Kolejnym elementem jest tak zwany kompilator. Kompilacja to zamiana kodu źródłowego napisanego w języku programowania na gotową do uruchomienia aplikację. Dużym ułatwieniem jest to, że podczas kompilacji znajdowane są błędy w kodzie i podawane miejsca gdzie one występują.
Można tworzyć rozbudowane aplikacje korzystające z innych, gotowych już kodów źródłowych. Umożliwia to opcja łączenia oddzielnie napisanych modułów programu.
Środowisko MapBasic zawiera wbudowaną pomoc opisującą składnię i użycie poszczególnych funkcji języka. Wraz z produktem dostarczana jest dokumentacja: przewodnik użytkownika oraz spis wszystkich poleceń języka.
Okno MapBasic - tylko jeden krok do programowania...
Aby zorientować się czym jest okno MapBasic wystarczy wykonać poniższe czynności: uruchom MapInfo i z menu Opcje wybierz Wyświetl okno MapBasic. Pojawi się puste okno. Następnie otwórz dowolny zbiór zawierający mapę i tabelę (np. zbiór Woj_16.TAB zawierający mapę podziału administracyjnego Polski), zaznaczając opcję Preferowany widok: Bez okien. Zauważ, że w oknie MapBasic pojawił się tekst podobny do poniższego:
Open Table "D:\mapy\Woj_16.TAB" Interactive
Jest to po prostu komenda w języku MapBasic otwierająca zbiór Woj_16.TAB znajdujący się na dysku D w katalogu "mapy". Nie zajmujmy się na razie tym, co oznaczają poszczególne elementy komendy oraz jaka jest jej składnia. Zmodyfikujmy strukturę zbioru dodając dowolną kolumnę o nazwie "kolumna1" do tabeli (Dane > Zbiory > Struktura zbioru). Z menu Okno wybierzmy Nowe okno mapy, oraz Nowe okno tabeli. Zauważmy, że każda z powyższych czynności spowodowała pojawienie się odpowiedniej komendy w oknie MapBasic:
Open Table "D:\mapy\Woj_16.TAB" Interactive
Alter Table "Woj_16" ( add kolumna1 Char(2) ) Interactive
Map From Woj_16
Browse * From Woj_16
Aby ponownie wykonać daną czynność, korzystając z obecnej już w oknie komendy MapBasic, wystarczy ustawić kursor na komendzie i wcisnąć enter (można też napisać je w oknie MapBasic od nowa). Przykładowo: aby dodać kolejne pola do tabeli można skorzystać z komendy MapBasic, która pojawiła się w oknie: Alter Table "Woj_16" ( add kolumna1 Char(30) ) Interactive. Należy jednak zamienić nazwę pola "kolumna1", na inną.
Jak widać, okno MapBasic może być przydatne w pracy z MapInfo i to nie tylko jeżeli znamy komendy języka z dokumentacji MapBasic'a. Możemy się także nauczyć wielu komend "podglądając" w oknie MapBasic, co robi MapInfo. Trzeba jednak wiedzieć, że nie można tam wpisywać wszystkich komend języka. W oknie MapBasic można wpisywać komendy jedna po drugiej i wykonywać je kolejno, lecz nie można tworzyć pętli oraz korzystać z wielu bardziej złożonych funkcji.
Ponieważ wszystkie komendy pojawiające się w oknie MapBasic są rozumiane przez kompilator języka MapBasic, można skopiować zawartość okna, wkleić do edytora MapBasic i poprzez kompilację stworzyć plik .MBX, który wykona wszystkie czynności na raz.
Możemy zatem napisać w ten sposób pierwszą aplikację w MapBasic'u. W tym celu należy zapisać ten tekst (MapBasic > Zapisz...) jako plik aplikacja1.TXT. Edytor w środowisku programowania MapBasic czyta i tworzy pliki z rozszerzeniem .MB. Konieczna zatem jest zmiana rozszerzenia pliku z .TXT na .MB.
Następnie po otwarciu środowiska programowania MapBasic wystarczy otworzyć plik aplikacja.MB (File > Open...), a następnie dokonać jego kompilacji (Project > Compile Current File...). W wyniku tych dwóch prostych czynności powstaje plik aplikacja1.MBX. zapisany w tym samym katalogu co ten z rozszerzeniem .MB.
Aby sprawdzić jak zadziała nasza pierwsza aplikacja należy usunąć dokonane zmiany w naszym zbiorze (poprzez usunięcie dwóch dodanych kolumn), zamknąć go i uruchomić aplikację (Plik > Aplikacja MapBasic...), która sama wykona wszystkie uprzednio opisane czynności.
Użytkownik MapInfo ma do czynienia z kodem MapBasic nie tylko w opisywanym oknie. Jeżeli otworzymy pliki pola pracy w edytorze tekstu zobaczymy również podobne komendy. Można zatem korzystać również z pól pracy, tworząc swoją aplikację.
Trochę więcej o pisaniu aplikacji
W opisanym powyżej przykładzie program zawiera tylko sekwencję kolejno wykonywanych poleceń, skopiowanych z okna MapBasic w programie MapInfo. Niemniej jednak, kiedy piszemy bardziej rozbudowaną aplikację musi ona mieć odpowiednią strukturę i zawierać pewne niezbędne elementy.
Cały program składa się procedury głównej (noszącej nazwę "Main") oraz wielu podprocedur (które można nazywać dowolnie). Każda procedura zawiera grupę wyrażeń wykonującą pewne zadanie. Rozpoczyna się komendą: Sub nazwa_procedury, kończy zaś komendą: End Sub. Wszystkie procedury muszą zostać zadeklarowane na początku programu wyrażeniem Declare Sub. Ilustruje to poniższy przykład:
Declare Sub Main
Sub Main
Sub powitanie
Sub informacja
Declare Sub powitanie
Declare Sub informacja
Call powitanie
Call informacja
End Sub
Note "Dzień dobry!"
End Sub
Note "To jest MapBasic!"
End Sub
Na początku powyższego programu zadeklarowana jest procedura główna i dwie podprocedury wykonujące poszczególne zadania, którym nadano unikatowe nazwy. Program wykonując procedurę główną najpierw przywołuje podprocedurę "powitanie", a następnie - gdy ją wykona - wraca do procedury głównej i wykonuje kolejną instrukcję przywołującą drugą z kolei podprocedurę - "informacja". W rezultacie, po kompilacji i uruchomieniu, program najpierw wyświetli pierwsze okno komunikatu z napisem "Dzień dobry!", a potem, po naciśnięciu OK kolejne z informacją "To jest MapBasic!".
Jeszcze kilka słów o tym co powinno znaleźć się na początku programu i poprzedzać procedurę główną. Oprócz deklaracji procedur można również zadeklarować funkcje (o których będzie mowa w dalszej części cyklu), zadeklarować zmienne globalne, zdefiniować identyfikatory oraz wstawić pliki tekstowe, które zostaną skompilowane razem z programem jako jego część.
Zmienne są komórkami pamięci identyfikowanymi przez ciąg znaków, pod które można podstawiać dowolną wartość. Zmienne globalne, w odróżnieniu od zmiennych lokalnych, obowiązują w całym programie. Deklaruje się je komendą: Global nazwa_zmiennej As typ_zmiennej (typ zmiennej: tekstowa, logiczna , liczby całkowite, liczby zmiennopozycyjne itd.). Zmienne lokalne deklaruje się komendą: Dim nazwa_zmiennej As typ_zmiennej w poszczególnych podprocedurach i obowiązują one tylko w ich obrębie.
Identyfikatory wykorzystuje się, gdy chcemy jakąś stałą wartość zastąpić innym ciągiem znaków. Klasycznym przykładem może być zdefiniowanie liczby ś: jeżeli na początku programu pojawi się wyrażenie: Define PI 3.141593, to w całym programie można używać dwóch liter "PI" zamiast całego ciągu cyfr liczby ś.
Pliki tekstowe zawierające cześć kodu mogą być wstawiane do programu dzięki znajdującej się na początku komendzie Include. Najczęściej jest to plik mapbasic.def, który dostarcza standardowe identyfikatory i powinien znaleźć się na początku każdej wykorzystującej je aplikacji.
Bardzo istotnym elementem każdego języka programowania jest możliwość konstruowania warunków. Dzięki nim możemy, w zależności od tego jaki zajdzie warunek, wykonać pewne polecenie albo inne, gdy warunek nie będzie spełniony. W MapBasic'u składnia jest następująca: If warunek Then polecenie Else polecenie Enf If.
Komunikacja z użytkownikiem aplikacji następuje dzięki oknom dialogowym. Konstruowanie okien dialogowych jest szerokim tematem i będzie omawiane sukcesywnie, w miarę wykorzystywania ich w przykładowych aplikacjach. Definiowanie okna dialogowego rozpoczyna się komendą: Dialog. Następnie deklaruje się tytuł okna: Title "nazwa_okna", a następnie poszczególne jego elementy zwane kontrolkami: Control typ_kontrolki (typy kontrolki: dowolny napis, okno tekstowe, przycisk, rozwijalna lista itd.) z odpowiednimi parametrami.
Pierwsza aplikacja
Przystąpmy zatem do pisania aplikacji zawierającej wszystkie wyżej opisane elementy. Należy ją zaprojektować na trzech poziomach. Po pierwsze zastanowić się jaki jest cel jej stworzenia i jakie zadania powinna wykonywać. Następnie zaprojektować poszczególne zadania, kolejność ich wykonywania oraz komunikację z użytkownikiem czyli okna dialogowe. Ostatnim poziomem jest pisanie kodu.
Pierwsza aplikacja, którą stworzyliśmy poprzez skopiowanie i skompilowanie zawartości okna MapBasic, otwierała konkretny zbiór i dodawała do niego kolumnę o konkretnej nazwie, a następnie wyświetlała okno tabeli i okno mapy. Naszym celem będzie zatem dokonanie modyfikacji stworzonego już kodu poprzez dodanie elementów, które pozwolą:
W przykładzie tym zwykły prosty kod wygenerowany w oknie MapBasic, został wzbogacony o instrukcje oraz standardowe funkcje MapBasic (PathToTableName(), Ask(), itd.) tworzące odpowiednią strukturę aplikacji oraz nadające programowi pewną uniwersalność. Teraz wystarczy skompilować program i uruchomić w MapInfo powstały plik .MBX.
Być może aplikacja ta nie jest bardzo wyrafinowanym narzędziem przydatnym w praktyce korzystania z MapInfo, ale zawiera wszystkie typowe elementy i może być wzorcem do stworzenia innej, bardziej przydatnej w konkretnych zastosowaniach.
Podsumowanie
MapBasic nie jest trudny. Znając opisane w niniejszym kursie podstawy programowania oraz korzystając z przystępnie napisanego przewodnika użytkownika i opisu funkcji, Użutkownik jest w stanie pisać własne aplikacje. Na początku będą one zapewne proste i zbudowane na skopiowanym z okna MapBasic "szkielecie", lecz z czasem mogą stać się bardziej zaawansowane i wykonywać konkretne zadania.