Professional Documents
Culture Documents
SPIS TREŚCI........................................................................................................................................................ 1
CZĘŚĆ I PROJEKTOWANIE BAZY DANYCH .......................................................................................... 21
ROZDZIAŁ 1. CO NOWEGO W ACCESSIE 2000.................................................................................. 22
Nowy interfejs użytkownika .......................................................................................................................... 22
Zmiany w VBE .............................................................................................................................................. 23
Strony dostępu do danych............................................................................................................................. 24
Podarkusze danych....................................................................................................................................... 24
Autokorekta nazw ......................................................................................................................................... 25
ADO jako domyślny system dostępu do danych .......................................................................................... 25
Współpraca online........................................................................................................................................ 25
Access jako interfejs użytkownika dla SQL Server....................................................................................... 26
ROZDZIAŁ 2. PLANOWANIE PROCESU ROZWOJU ......................................................................... 27
Określenie wymagań .................................................................................................................................... 28
Dlaczego faza wymagań jest tak ważna? ................................................................................................. 28
Odnalezienie rzeczywistego problemu..................................................................................................... 28
Śledztwo ................................................................................................................................................... 28
Diagramy procesu..................................................................................................................................... 29
Identyfikacja zakresu projektu ................................................................................................................. 30
Spisywanie wymagań ............................................................................................................................... 30
Architektura.................................................................................................................................................. 31
Planowanie rozwoju ..................................................................................................................................... 31
Strategia dostarczania............................................................................................................................... 32
Styl............................................................................................................................................................ 33
Standardy.................................................................................................................................................. 33
Standardy nazewnictwa ........................................................................................................................ 34
Standardy kodowania ........................................................................................................................... 34
Konstrukcja .................................................................................................................................................. 34
Dziel i rządź: działania w fazie Konstrukcja............................................................................................ 34
Edycje i kompilacje .................................................................................................................................. 35
Szczegółowy projekt ................................................................................................................................ 38
Kontrola projektu ..................................................................................................................................... 39
Tworzenie aplikacji .................................................................................................................................. 39
Kontrola aplikacji ..................................................................................................................................... 39
Testowanie................................................................................................................................................ 39
Testowanie modułu .............................................................................................................................. 39
Testowanie aplikacji............................................................................................................................. 40
Testowanie instalacji i konfiguracji...................................................................................................... 40
Odnajdywanie usterek .............................................................................................................................. 41
Kontrola wersji ......................................................................................................................................... 43
ROZDZIAŁ 3. PROJEKT BAZY DANYCH I NORMALIZACJA ....................................................... 45
Spis treści 2
Optymalizowanie kwerend............................................................................................................................ 76
ROZDZIAŁ 5. JET 4.0 – SILNIK BAZ DANYCH MICROSOFT .......................................................... 77
Historia Microsoft Jet .................................................................................................................................. 77
Jet 1.0........................................................................................................................................................ 77
Jet 1.1........................................................................................................................................................ 77
Jet 2.0........................................................................................................................................................ 77
Jet 2.5........................................................................................................................................................ 78
Jet 3.0........................................................................................................................................................ 78
Jet 3.5........................................................................................................................................................ 78
Jet 3.51...................................................................................................................................................... 78
Jet 4.0........................................................................................................................................................ 78
Przyszłe wersje Microsoft Jet................................................................................................................... 79
Praktyczne zastosowanie nowych opcji silnika Jet 4.0 ............................................................................... 79
Wbudowany dostawca baz danych OLE.................................................................................................. 79
Blokowanie na poziomie rekordu............................................................................................................. 79
Pełna obsługa Unicode ............................................................................................................................. 79
Czym jest Unicode?.............................................................................................................................. 79
Obsługa Unicode 1.1 w silniku Jet 4.0 ..................................................................................................... 80
Sortowanie kompatybilne z NT............................................................................................................ 81
Typy danych Jet........................................................................................................................................ 81
Ulepszenia opcji Autonumerowanie......................................................................................................... 82
Przeszukiwalne pola Memo...................................................................................................................... 83
Kontrola połączeń i zamknięcie bierne .................................................................................................... 83
Nowa składnia SQL.................................................................................................................................. 84
Zabezpieczenia ..................................................................................................................................... 84
Definiowanie widoków i procedur ....................................................................................................... 85
Wywoływanie parametrów................................................................................................................... 85
Transakcje............................................................................................................................................. 85
Tworzenie tabel DDL ........................................................................................................................... 86
CZĘŚĆ II DOSTĘP DO DANYCH .................................................................................................................. 88
ROZDZIAŁ 6. WPROWADZENIE DO OBIEKTÓW DANYCH ACTIVEX ...................................... 89
Historia dostępu do danych.......................................................................................................................... 89
Firmowe interfejsy API ............................................................................................................................ 89
Open Database Connectivity (ODBC) ..................................................................................................... 89
Microsoft Jet/Obiekty Data Access (DAO).............................................................................................. 90
Zdalne obiekty danych (RDO) i ODBCDirect ......................................................................................... 90
Universal Data Access ................................................................................................................................. 90
Obiekty ActiveX Data (ADO) ....................................................................................................................... 91
ADO 1.0 ................................................................................................................................................... 91
ADO 1.5 ................................................................................................................................................... 91
ADO 2.0 ................................................................................................................................................... 91
ADO 2.1 ................................................................................................................................................... 91
Model obiektowy ADO ................................................................................................................................. 92
Obiekt Connection.................................................................................................................................... 93
Otwarcie połączenia w Accessie 2000 ................................................................................................. 93
Wykonywanie wyrażeń SQL w obiekcie Connection.............................................................................. 94
Obiekty ADO: Recordset .............................................................................................................................. 94
Użycie Recordset z obiektami Command i Parameter ............................................................................. 96
Wykonywanie kwerendy funkcjonalnej poprzez obiekt Command........................................................ 98
Obiekty Field i Property ........................................................................................................................... 99
Obiekty ADO: Error ................................................................................................................................... 100
Spis treści 4
Substr.................................................................................................................................................. 304
Decode................................................................................................................................................ 305
Obliczenia w Oracle'u ............................................................................................................................ 305
Ceil()................................................................................................................................................... 305
Floor()................................................................................................................................................. 305
Nvl() ................................................................................................................................................... 306
Round()............................................................................................................................................... 306
Sign() .................................................................................................................................................. 306
Trunc()................................................................................................................................................ 306
Greatest/Least ..................................................................................................................................... 306
Obliczenia na datach............................................................................................................................... 307
Arytmetyka ......................................................................................................................................... 307
Sysdate................................................................................................................................................ 307
Add_Months ....................................................................................................................................... 307
Months_Between................................................................................................................................ 307
Next_Day() ......................................................................................................................................... 308
To_Date() ........................................................................................................................................... 308
Problem roku 2000 ............................................................................................................................. 308
Poznajemy widoki i procedury przechowywane........................................................................................ 309
Tworzenie widoków ............................................................................................................................... 309
Połączenie z Oracle'em poprzez ADO ................................................................................................... 310
Parametry............................................................................................................................................ 311
Tworzenie procedur przechowywanych................................................................................................. 312
Uruchamianie procedury ........................................................................................................................ 313
Tworzenie niezwiązanego interfejsu do Oracle'a....................................................................................... 313
Tworzenie niezwiązanego interfejsu ...................................................................................................... 314
Tworzenie zmiennych globalnych...................................................................................................... 314
Ładowanie danych i inicjalizacja formularza..................................................................................... 315
Programowanie przycisków sterujących ............................................................................................ 315
Zmiana danych Oracle'a przy użyciu formularza............................................................................... 317
Wstawienie danych do Oracle'a przy użyciu formularza ................................................................... 318
Zapisywanie danych do Oracle'a przy użyciu formularza.................................................................. 318
Usuwanie danych przy użyciu formularza ......................................................................................... 319
Zamykanie połączenia z Oracle'em.................................................................................................... 319
CZĘŚĆ VI WSPÓŁOPERATYWNOŚĆ ....................................................................................................... 321
ROZDZIAŁ 18. UŻYCIE AUTOMATYZACJI ACTIVEX ................................................................... 322
Co to jest automatyzacja ActiveX ............................................................................................................... 322
Dlaczego używamy automatyzacji.............................................................................................................. 322
Różnice między serwerem automatyzacji a klientem automatyzacji ......................................................... 323
Określanie zasobów wymaganych przez automatyzację ........................................................................... 323
Wielka trójka .............................................................................................................................................. 323
Tworzenie i ustanowienie odwołania do innej aplikacji ............................................................................ 323
Ustanawianie odwołania do innej aplikacji............................................................................................ 323
Przegląd obiektów, właściwości i metod................................................................................................ 324
Poznajemy strukturę obiektów ............................................................................................................... 324
Użycie narzędzia Object Browser .......................................................................................................... 324
Tworzenie zmiennej obiektowej............................................................................................................. 326
Odwołanie do pracującej aplikacji ......................................................................................................... 326
Przypisywanie zmiennej obiektowej do aplikacji ...................................................................................... 326
Tworzenie egzemplarza aplikacji ............................................................................................................... 327
Jednoczesne użycie funkcji GetObject i New ........................................................................................ 327
Użycie wczesnego i późnego łączenia typów ........................................................................................ 327
Spis treści 14
Autopodsumowanie............................................................................................................................ 346
Widoki dokumentu ............................................................................................................................. 347
Spis treści ........................................................................................................................................... 347
Przypisy .............................................................................................................................................. 347
Nagłówki ............................................................................................................................................ 347
Stopki.................................................................................................................................................. 347
Hiperłącza........................................................................................................................................... 347
Tworzenie tabel .................................................................................................................................. 348
Ustawienia strony ............................................................................................................................... 348
Podgląd wydruku................................................................................................................................ 348
Drukowanie dokumentów, kopert i etykiet ........................................................................................ 348
Pola ..................................................................................................................................................... 348
Informacje o dokumencie ................................................................................................................... 349
Inne możliwości Worda...................................................................................................................... 350
Automatyzacja Excela ................................................................................................................................ 350
Model obiektów Excela.......................................................................................................................... 350
Przykłady automatyzacji Excela............................................................................................................. 351
Formatowanie dokumentów Excela ................................................................................................... 351
Tworzenie wykresów.......................................................................................................................... 351
Użycie właściwości Parent ................................................................................................................. 352
Automatyzacja PowerPoint ........................................................................................................................ 352
Model obiektów PowerPoint .................................................................................................................. 353
Przykłady automatyzacji PowerPoint..................................................................................................... 353
Dodanie slajdu .................................................................................................................................... 353
Dodanie efektu przejścia .................................................................................................................... 354
Wstawianie danych i formatowanie slajdów...................................................................................... 354
Wstawienie rysunku do slajdu............................................................................................................ 354
Uruchamianie prezentacji................................................................................................................... 354
Automatyzacja Outlook .............................................................................................................................. 354
Model obiektów Outlook........................................................................................................................ 355
Przykłady automatyzacji Outlook .......................................................................................................... 355
Dodawanie i wyświetlanie folderów .................................................................................................. 355
Dodawanie nowego zadania i wyświetlenie zadań ............................................................................ 356
Tworzenie wiadomości e-mail z załącznikiem................................................................................... 356
Tworzenie elementów Outlooka......................................................................................................... 357
Wyświetlanie domyślnych folderów .................................................................................................. 357
Wyświetlenie foldera publicznego ..................................................................................................... 357
Szukanie elementu w Outlooku.......................................................................................................... 357
Filtrowanie elementów w Outlooku ................................................................................................... 357
Automatyzacja Graph................................................................................................................................. 358
Model obiektów Graph........................................................................................................................... 358
Tworzenie wykresu ................................................................................................................................ 358
Przykłady automatyzacji Graph ............................................................................................................. 359
Automatyzacja MapPoint ........................................................................................................................... 359
Model obiektów MapPoint ..................................................................................................................... 359
Przykłady automatyzacji MapPoint........................................................................................................ 360
Automatyzacja FrontPage .......................................................................................................................... 360
Model obiektów FrontPage .................................................................................................................... 360
Przykłady automatyzacji FrontPage ....................................................................................................... 361
Automatyzacja Bindera .............................................................................................................................. 362
Model obiektów Bindera ........................................................................................................................ 362
Przykłady automatyzacji Bindera........................................................................................................... 362
Zabezpieczanie dokumentów, szablonów i kodu programu ....................................................................... 363
Spis treści 16
Gdy na rynku pojawiła się pierwsza wersja programu Access, trudno było przypuszczać, że kiedyś stanie się on tak
potężnym narzędziem jakim jest Access 2000. Ci, którzy korzystali z Accessa 1.0, pamiętają z pewnością aplikację o
następujących cechach: maksymalnej wielkości pliku ograniczonej do 128 MB, braku zdolności transakcyjnych, braku
narzędzi programistycznych z prawdziwego zdarzenia, statycznych paskach narzędzi, braku integralności referencyjnej
oraz bardzo niskiej wydajności. Pomimo wyżej wymienionych wad w owym czasie program ten nie miał sobie równych.
Zawdzięczał to łatwym w obsłudze narzędziom konstrukcyjnym, dynasetom oraz konstruktorowi kwerend. Z każdym
uaktualnieniem Access stawał się coraz potężniejszym i bardziej użytecznym narzędziem oraz systemem rozwoju.
Użytkownicy oraz programiści pracujący z Accessem z zadowoleniem przyjmowali kolejne ulepszenia silnika bazy danych
aż do wersji 4.0. Wówczas to, Access posiadał już przetwarzanie transakcyjne, integralność referencyjną, zdolności
replikacyjne, ulepszone zarządzanie współbieżnością, a ponadto działał szybciej i dużo stabilniej. Ponadto program
początkowo posiadający proste makra języka Access VB został wyposażony w pełną obsługę VBA wraz ze środowiskiem
rozwoju prawie identycznym z Visual Studio w wersji 6.0. Poprawiono także interfejs narzędzi. Obsługa narzędzi innych pro-
ducentów oraz formantów ActiveX znacznie poszerzyły dostępne programistom możliwości projektowania. Wraz z
pojawieniem się na rynku Accessa 95 i 97 programiści uzyskali możliwość tworzenia wielu kopii formularzy. Wersja 97
umożliwiła im również korzystanie z Active Server Pages, rozszerzając tym samym zasięg Accessa na Internet.
Na przestrzeni lat, usprawnienia Accessa można liczyć w setkach. Dziś ulepszenia, jakie wprowadzono w Accessie 2000,
są naprawdę zadziwiające. Różnice między Accessem 2000 a jego poprzednią wersją są prawie tak duże jak różnice
między jego pierwszą wersją i Accessem 97. Nie ulega wątpliwości, iż miliony docelowych użytkowników i programistów
Accessa uznają jego nową wersję za elastyczne i niezwykle użyteczne narzędzie. Z pewnością również kolejne miliony
przekonają się o jego zaletach i zaczną z niego korzystać w nadchodzących miesiącach i latach.
Rysunek 1.1.
Wszystko,
co jest związane
z zamówieniami
i sprzedażą, znajduje
się w jednym miejscu
Mniej widoczną, lecz równie ważną zmianą, jest wyświetlanie w menu Accessa 2000 jedynie najczęściej używanych
poleceń. Dwukrotne kliknięcie menu lub kliknięcie znaku rozwijającego spowoduje wyświetlenie pozostałych poleceń.
Czynność tę przedstawiliśmy na rysunku 1.2
Rysunek 1.2.
Rozwijane menu
pomagają
zapobiegać
bałaganowi
Kreatory służące tworzeniu i edycji obiektów również mają odpowiednie, przyporządkowane im miejsca, dzięki czemu
zawsze wiesz, gdzie się znajdują. Ta kontekstowa dostępność pozwoli programistom zaoszczędzić czas.
Zwiększono również zestaw dostępnych funkcji obecnej już od dawna w systemie Windows opcji – schowka. Teraz możesz
skopiować do schowka kilka elementów, a następnie zgodnie z potrzebą wklejać je do dokumentu. Dzięki temu znacznie
łatwiej jest zmieniać układ funkcji lub ustawiać właściwości obiektu.
Zmiany w VBE
Kolejną kosmetyczną zmianą jest wygląd środowiska Visual Basic (VBE – ang. Visual Basic Environment). Teraz, zamiast
otwierać moduł, jakby to był zwykły plik tekstowy, Access posiada osobną przestrzeń roboczą służącą do pisania,
usuwania błędów oraz uruchamiania projektów Accessa 2000. Tym samym środowisko programistyczne Accessa
osiągnęło poziom pozostałych programów pakietu Office i zawiera teraz zintegrowane środowisko programowania (IDE –
ang. Integrated Development Environment). Jeśli kiedykolwiek pracowałeś z VBA w Office 97 lub z Visual Basic, nowe,
przedstawione na rysunku 1.3, VBE Accessa 2000 nie będzie Ci obce.
Dzięki możliwości umieszczania pasków narzędzi i okien w dowolnym miejscu będziesz mógł dostosować miejsce pracy
do swoich potrzeb. Jedno z okien może zawierać kod programu, który piszesz, natomiast w innym możesz przeglądać
właściwości dowolnego obiektu. W trzecim oknie mogą być wyświetlone formularze, raporty, moduły i klasy w bazie
danych. W jeszcze innym oknie, takie narzędzia jak okienko bezpośrednie lub okienko zmiennych lokalnych (które w tej
wersji są osobnymi oknami) pomogą Ci usuwać błędy w kodzie programu.
Rysunek 1.3.
Środowisko VBE
jest teraz
w dużym stopniu
konfigurowalne
Elementy sterujące stron dostępu do danych przedstawionych na rysunku 1.4 korzystają z wewnętrznych elementów
HTML oraz formantów COM. Posiadają one także bogaty zasób obiektów i współpracują z Visual Basic Scripting Edition,
skryptami Java oraz komponentami Office Web Components. Oznacza to, iż nabyte uprzednio umiejętności projektowania
stron sieci Web mogą być z łatwością przeniesione do Accessa 2000.
Podarkusze danych
Kolejną z cech interfejsu użytkownika Accessa 2000, która z pewnością będzie bardzo użyteczna, są podarkusze danych.
Dzięki nim możesz praktycznie bez wysiłku tworzyć edytowalne, hierarchiczne grupy danych, rozszerzane przez kliknięcie
małego znaku plus.
Rysunek 1.4.
Dane i zestaw
funkcji mogą być
przeglądane
z poziomu aplikacji
lub przeglądarki
25 Rozdział 1. ♦ Co nowego w Accessie 2000
Rysunek 1.5.
Kliknięcie znaku plus
powoduje
wyświetlenie
powiązanych danych
Grupy te możesz umieścić w dowolnym miejscu w widoku arkusza danych. Uzyskane dzięki temu trójwymiarowe
spojrzenie na dane z pewnością znajdzie wiele zastosowań i może stać się szybką i prostą alternatywą dla formantu Tree.
Autokorekta nazw
Kolejną bardzo przydatną cechą Accessa 2000 jest autokorekta nazw. W poprzednich wersjach Accessa musiałeś bardzo
uważać podczas zmiany nazwy obiektu, gdyż Access nie rozpoznawał nowej nazwy dopóty, dopóki nie uaktualniłeś
wszystkich obiektów z nią powiązanych. Access 2000 automatycznie wykona to męczące zadanie za Ciebie, więc gdy
uznasz, że dane pole powinno nazywać się inaczej, możesz zmienić jego nazwę w dowolnym momencie, a aplikacja będzie
wciąż działać poprawnie.
Oprócz ADO, również dostawcy OLEDB dostarczają podobnych interfejsów dla szerokiej gamy źródeł danych w
standardzie Microsoft’s Universal Data Access. Ustawienia dla dostawców OLEDB mogą być również zapisane w pliku
typu Universal Data Link (UDL), co znacznie ułatwia kontrolowanie (i zmianę) źródeł danych.
Współpraca online
Współpraca online jest szczególnie wartościowa dla programistów, którzy współpracują ze sobą mimo dzielącej ich
odległości. Po rozpoczęciu spotkania programiści mogą wymieniać uwagi o projektach za pomocą serwera listy, a także
korzystać z takich opcji jak wspólna tablica, aby efektywnie wyrażać swoje pomysły.
Część I ♦ Projektowanie bazy danych 26
danych, z którą jego silnik Jet mógł sobie poradzić, oraz ilości użytkowników, których mógł obsłużyć. Microsoft Access
Project nie posiada takich ograniczeń, gdyż jest prawdziwym interfejsem użytkownika dla SQL Server i Microsoft Data
Engine.
Dzięki obsłudze OLEDB, Access 2000 może całkowicie pominąć Jet i współpracować bezpośrednio z innymi silnikami
baz danych. Podczas tworzenia bazy danych w Accessie 2000 użytkownik może utworzyć Project, a następnie wybrać
między dołączonym do pakietu Office 2000 Microsoft Data Engine (MSDE) a SQL Server 6.0 i 7.0. Każdy z nich jest w
stanie obsługiwać tysiące użytkowników i terabajty danych. Access jest środowiskiem rozwoju i administrowania dla SQL
Servera, a utworzona aplikacja staje się prawdziwym klientem w relacji klient-serwer.
Access Project nie zawiera żadnych danych, tabel czy kwerend. Jest bezpośrednio połączony z zapleczem i umożliwia
tworzenie, przeglądanie i modyfikowanie tabel w bazie, przechowywanych procedur, widoków i diagramów bazy danych. W
porównaniu do poprzednich wersji Accessa możemy mówić o radykalnej zmianie. Mimo iż wielu programistów dołączało
tabele z SQL Server i Oracle, kwerendy na nich oparte były wykonywane lokalnie (uruchomienie kwerendy opartej na
dołączonej tabeli powoduje przeniesienie danych na komputer klienta). Niektórzy programiści tworzyli kwerendy
przekazujące, dzięki czemu serwer wykonywał większość obliczeń, ale to dość specyficzny przypadek. Dołączona tabela
nie mogła być modyfikowana, a stworzenie i obsługa widoków i przechowywanych procedur, pobranych za pomocą
kwerendy przekazującej, mogły wymagać osobnych narzędzi administracyjnych. Ograniczenia te powodowały opóźnienia w
realizacji projektu i wymagały zaangażowania dodatkowych pracowników wówczas, gdy nie było to pożądane. Access
Projects umożliwiły programistom tworzenie całego projektu aplikacji klient-serwer samemu i bez użycia dodatkowych
narzędzi.
Przedstawiciele Microsoftu są przekonani o tym, iż ta opcja zyska sobie aprobatę użytkowników i przyczyni się do sukcesu
tego programu. Aby było to możliwe, typy danych Accessa dostosowano do SQL Server, uaktualniono składnię SQL, by
była zgodna ze standardami ANSI, a także uaktualniono kreatory i narzędzia wspomagające nową architekturę klient-serwer.
Stworzono także nowe narzędzia służące do tworzenia i zarządzania obiektami po stronie serwera w widoku Projekt klienta.
Także inne zwykłe czynności administracyjne, jak zabezpieczenia, sporządzanie kopii zapasowych i replikacja, mogą być
zarządzane przez Access 2000.
Rozdział 2.
Planowanie procesu rozwoju
W tym rozdziale:
u Określenie wymagań.
u Architektura.
u Planowanie rozwoju.
u Konstrukcja.
W pozostałych rozdziałach tej książki opisane są wszystkie potężne narzędzia i opcje, jakie oferuje Access 2000. Jednakże,
nawet po opanowaniu tego materiału, gdy będziesz już świetnym programistą, sukces Twoich projektów wciąż będzie
niepewny, jeśli nie zrozumiesz, jak ważny dla ich powodzenia jest proces rozwoju. Nawet, jeśli świetnie programujesz, to
efektem braku dobrze zaplanowanego procesu lub zgranej grupy współpracowników może być niezadowalający wynik
projektu.
W tym rozdziale zawarliśmy kilka kluczowych informacji oraz czynności dotyczących zespołu i procesu rozwoju.
Chcielibyśmy pomóc Ci w budowaniu udanych projektów, poprzez stworzenie Twojego własnego, efektywnego i opartego
na sprawdzonych metodach procesu rozwoju. Opisanie tych zagadnień w pełni zajęłoby nam całą książkę.
Udany proces rozwoju skupia się na czterech kluczowych etapach projektu: Wymaganiach, Architekturze, Planowaniu
Rozwoju oraz właściwej fazie Konstrukcji. W fazie Wymagania, będziesz zbierał i analizował rzeczywiste potrzeby
użytkowników. W fazie Architektura wybierzesz układ, technologie i narzędzia rozwoju, które w najlepszy sposób te
potrzeby zaspokoją. Podczas fazy Planowanie rozwoju sporządzisz plan rozwoju, który będzie opisywał sposób, w jaki
projekt będzie wdrożony, ustalisz niezbędną liczbę programistów oraz koszty całego przedsięwzięcia. Ostatnia faza
rozwoju to tworzenie aplikacji.
Rysunek 2.1 przedstawia cztery fazy procesu rozwoju, począwszy od określenia wymagań, aż do tworzenia aplikacji. Zawiera
on również niektóre z edycji programu, wypuszczane podczas tej fazy. W tym rozdziale szczegółowo scharakteryzujemy
każdą z faz.
Rysunek 2.1.
Proces rozwoju
Część I ♦ Projektowanie bazy danych 28
Określenie wymagań
Określenie i analiza wymagań jest najważniejszą czynnością wpływającą na jakość aplikacji. Wielokrotnie byliśmy
świadkami projektów, które upadały na skutek nieprecyzyjnie bądź błędnie zdefiniowanych wymagań.
Dlaczego aż tak dużo? Po pierwsze, wymagania powinny być uaktualniane. Projekt i kod programu muszą być
analizowane, aby ocenić czy zmiany są konieczne. Wówczas zmiany te muszą być wprowadzone, a różne moduły,
kwerendy, formularze i raporty przetestowane. Sama aplikacja musi być osobno przetestowana, aby mieć pewność, że
zmiany odniosły przewidywany skutek i nie spowodowały wystąpienia kolejnych błędów. Wreszcie, poprawiona aplikacja
musi być ponownie dostarczona do każdego z użytkowników.
Oczywiście, podane tu mnożniki to średnie wartości dla tej gałęzi przemysłu, a nie wartości absolutne. W zależności od
rozmiaru zmian, koszty mogą być od nich niższe bądź wyższe. Jeśli błąd odbił się negatywnie na działalności klienta,
koszty mogą być astronomiczne.
Aby zilustrować proces rozwoju, przez cały ten rozdział będziemy używać
przykładu „Sprawozdanie o kosztach pracowników”.
Przykładowo, klient może zamówić dla swoich pracowników system, który będzie służył do wprowadzania i drukowania
raportów o poniesionych kosztach. Po przeprowadzeniu analizy możesz stwierdzić, że rzeczywistą potrzebą klienta jest
automatyzacja wprowadzania, podziału, zatwierdzania i przetwarzania całego procesu związanego z raportami o kosztach.
Odnajdywanie takich różnic należy do twoich zadań. Czasami klient myśli o rozwiązaniu, które jest zbyt małe, aby
rozwiązać jego problem. Równie często zdarza się, że klient myśli o rozwiązaniu, które jest zbyt obszerne i złożone. Aby
zrozumieć jak aplikacja współdziała z pozostałymi częściami działalności klienta, powinieneś koniecznie poszerzyć zasięg
procesu określania wymagań ponad oczekiwany zysk z jej funkcjonowania.
Śledztwo
Aby określić, jaki problem rzeczywiście wymaga rozwiązania i właściwie ustalić wymagania, musisz na chwilę stać się
detektywem.
Pierwszym etapem śledztwa jest określenie wszystkich uczestników procesu. Przez uczestnika rozumiemy osobę, grupę lub
dział, który jest zainteresowany procesem lub aplikacją. Uczestnikami są menedżerowie, osoby nadzorujące oraz
pracownicy bezpośrednio odpowiedzialni za każdy z zaangażowanych w proces działów. Uczestnikami są także ci
użytkownicy aktualnego procesu, którzy staną się użytkownikami tworzonej przez Ciebie aplikacji. Niektóre z grup
uczestników będą tak duże, że będziesz je musiał ograniczyć tylko do kilku przedstawicieli. W trakcie trwania śledztwa
możesz odkryć nowych uczestników, których będziesz musiał dołączyć. Dodatkowym zyskiem z uwzględnienia
uczestników w procesie określania wymagań jest uzyskany dzięki temu wzrost ich poczucia przynależności do nowego
systemu. Zauważysz większą chęć do współpracy i pomoc przy dostarczaniu i uruchamianiu aplikacji u klienta.
Kontynuujmy nasz przykład sprawozdania o kosztach. Zechcesz przeprowadzić wywiady z kilkoma reprezentatywnymi
użytkownikami, z których część rzadko ponosi jakiekolwiek wydatki, część często podróżuje, a także z kilkoma
przeciętnymi użytkownikami. Później porozmawiasz z kilkoma osobami z działu płac, które co miesiąc zajmują się prze-
twarzaniem tych sprawozdań oraz przedstawionych rachunków.
Teraz rozpoczyna się prawdziwe śledztwo. Porozmawiaj z każdym uczestnikiem. Zadawaj wiele pytań, słuchaj uważnie i
sporządzaj notatki. Pytaj, jak działa aktualny system oraz co im się w nim podoba lub nie. Zapytaj także, co chcieliby
zmienić.
Z tych notatek możesz ułożyć prawdziwy obraz aktualnego procesu i sposobu działania firmy. Przeanalizuj aktualny proces
i zanotuj wszystkie potencjalne gniazda zapalne i wąskie gardła. Pamiętaj także o zebraniu wszystkich wad, zalet, życzeń i
marzeń, o których dowiedziałeś się podczas wywiadów.
Diagramy procesu
Diagramy procesu są doskonałym sposobem na opisanie sposobu działania procesu handlowego. Przedstawiony na rysunku
2.2 diagram ilustruje przykład sprawozdania o kosztach. Diagramy te przedstawiają interakcje zachodzące między głównymi
osobami, grupami i działami zaangażowanymi w proces. Poszczególne kroki lub czynności w procesie następują od lewej
do prawej i przedstawione są za pomocą prostokątów. Kroki te pochłaniają wpływy z lewej strony i powodują powstawanie
wyników z prawej. Pionowe strzałki oznaczają wszystkie wewnętrzne zasady handlowe bądź zewnętrzne uregulowania i
ograniczenia. Romby przedstawiają podejmowane w trakcie trwania procesu decyzje.
Jako że pozioma oś przedstawia czas, wszelkie opóźnienia i czasochłonne czynności są łatwe do zidentyfikowania. Po
przeanalizowaniu przedstawionego na diagramie aktualnego procesu oraz potrzeb uczestników można narysować drugi
diagram, który będzie ilustrował proces po wprowadzeniu zmian.
Rysunek 2.2.
Przykład diagramu
procesu rozliczania
kosztów podróży
Diagramy procesu, takie jak ten na rysunku 2.2, są bardzo proste w tworzeniu i zrozumiałe dla wszystkich uczestników. Po
zobaczeniu diagramu wielu z uczestników będzie zaskoczonych stopniem skomplikowania i złożonością aktualnego
procesu. Jeśli sporządzanie diagramu procesu rozpoczniesz odpowiednio wcześnie, będziesz mógł go modyfikować
podczas rozmów z uczestnikami. Diagramy procesu mogą znacznie ułatwić Ci stworzenie scenariusza i prowadzenie
wywiadów. Każdy uczestnik będzie mógł teraz wyjaśnić i pokazać szczegóły całego procesu.
Możesz uznać za przydatne stworzenie hierarchii diagramów procesu. Na najwyższym poziomie znajdzie się diagram
opisujący cały proces, a poniżej będą diagramy ilustrujące w powiększeniu poszczególne jego etapy. Podprocesy mogą być
przedstawione ze szczegółami na osobnych diagramach procesu. Podejście hierarchiczne często ułatwia zrozumienie
skomplikowanych diagramów.
do uwzględnienia rachunków za podróż w dziale księgowości. Zdecydowano również pominąć systemy księgowe i sam
proces rezerwowania biletów. Te elementy nie zostały uwzględnione w zakresie aplikacji.
Spisywanie wymagań
Przedstawienie wymagań na piśmie jest najlepszym sposobem komunikacji pomiędzy programistą a klientem. Praktyka ta
umożliwia wyeliminowanie nieporozumień. Forma pisemna nie oznacza, iż musi to być koniecznie dokument oficjalny.
Istnieje wiele skutecznych sposobów na przekazywanie wymagań: przykładowe raporty, formularze, diagramy procesu lub
rysunki. Spisywanie wymagań nie jest wcale trudne. Wystarczy zadbać o to, by klient mógł bez trudu je przeczytać i
zrozumieć.
Oto jakie pytania możesz zadać, aby sprawdzić, czy właściwie zidentyfikowałeś wymagania:
u Czy opisuje potrzebę, czy raczej sposób jej realizacji?
u Czy może być zweryfikowane po jego wprowadzeniu?
u Czy jest jednoznaczne?
u Czy w pełni opisuje potrzebę?
u Czy razem z pozostałymi wymaganiami stanowi jednolitą całość?
W tabeli 2.1 umieściliśmy przykłady wielu rodzajów wymagań, których użycie powinieneś rozważyć. Wymagania te
posłużą jako część umowy. Wydrukuj tę wersję dokumentacji wymagań i poproś klienta o jej podpisanie. Ten dokument
stanie się podstawą dalszego rozwoju aplikacji. Od tego momentu musisz zacząć zastanawiać się nad wpływem zmian w
wymaganiach na planowany budżet i harmonogram. Pamiętaj, aby po dokonaniu zmian zweryfikować budżet,
harmonogram i wszystkie pozostałe powiązane wymagania oraz dokumentację projektu.
Tabela 2.1.
Typy wymagań
Tabela 2.1.
Typy wymagań (ciąg dalszy)
31 Rozdział 2. ♦ Planowanie procesu rozwoju
Architektura
Po przeanalizowaniu zapisanych wymagań klienta możesz wybrać odpowiednią architekturę, technologie i narzędzia
rozwoju. Czy aplikacja klienta powinna być oparta na Excelu, Accesie czy VB? A może, za pomocą ASP i XML, powinna
korzystać z sieci Web? Czy można zastosować konstrukcję dwuwarstwową, czy może n-warstwowa byłaby lepsza? Czy
motorem bazy danych będzie Jet-MDB, SQL-MSDE, SQL Server czy Oracle? Oto kilka ważnych pytań, z których każde
będzie miało duży wpływ na produkt końcowy. Dopiero, gdy na nie odpowiesz, będziesz mógł właściwie określić budżet
i harmonogram prac.
Planowanie rozwoju
Po podjęciu decyzji dotyczących wymagań i architektury powinieneś zastanowić się nad najlepszym sposobem
skonstruowania aplikacji. Czy wszystkie opcje i zestawy funkcji powinny być umieszczone w wersji 1.0, czy może
Część I ♦ Projektowanie bazy danych 32
powinieneś część z nich umieścić dopiero w następnych wersjach? Niezależnie od tego, którą z metod wybierzesz, nim
przejdziesz dalej, powinieneś zastanowić się nad budżetem i harmonogramem.
Być może już sporządziłeś wstępny plan projektu, który został zaakceptowany i dzięki temu dotarłeś do tej fazy projektu.
Ta wstępna wersja opierała się na przewidywanych wymaganiach i zakresie aplikacji, a także sporządzonym z dużym
przybliżeniem budżecie i harmonogramie. Jeśli posiadasz taki wstępny plan, teraz nadeszła chwila, by go skorygować. Jeśli
taki plan jeszcze nie istnieje, teraz powinieneś go napisać. Po zakończeniu fazy Wymagania masz już wystarczająco dużo
informacji, by sporządzić listę zadań, listę zasobów, harmonogram i budżet.
Strategia dostarczania
Staraj się unikać umieszczania każdego pomysłu i przydatnych opcji w jednej, olbrzymiej edycji. Prawie zawsze lepiej jest
zaplanować kilka dodatkowych wersji.
Wróćmy do przykładu ze sprawozdaniem o kosztach. Podczas spotkań programistów z decydentami dyskutowano na temat
możliwego zakresu aplikacji, harmonogramu prac i budżetu. Zgodzono się, iż wersja 1.0 powinna skoncentrować się na
automatyzacji tworzenia, zatwierdzania, podziału i kontroli raportów o kosztach. Kolejna wersja, z numerem 2.0,
zautomatyzuje tworzenie, zatwierdzanie, podział i kontrolę procesu rozliczania zaliczek na poczet delegacji. Rysunek 2.3
przedstawia kolejne etapy rozwoju aplikacji oraz przykłady możliwych edycji. Na rysunku 2.4 znajduje się poprawiony
diagram procesu, pokazujący, która z planowanych w obecnej strategii dostarczania dwóch wersji obejmuje poszczególne
etapy procesu.
Rysunek 2.3.
Przykład strategii
dostarczania
33 Rozdział 2. ♦ Planowanie procesu rozwoju
Rysunek 2.4.
Przykład diagramu
procesu dotyczącego
sprawozdania
o kosztach
i delegacjach,
uwzględniający
strategię dostarczania
Styl
Profesjonalne aplikacje zawsze charakteryzują się jednolitym wyglądem i sposobem działania. Jeśli do zamykania
niektórych formularzy używamy przycisku Anuluj, a innych Zamknij, użytkownicy szybko się pogubią, co spowoduje wzrost
kosztów szkolenia i pomocy. Jeśli jeden z programistów lubi, gdy każde pole w formularzu umieszczone jest w osobnym,
wklęsłym okienku, a wyświetlane dane są zawsze pogrubione, podczas gdy inny projektuje formularze z pogrubionymi
etykietami i płaskimi polami tekstowymi, aplikacja będzie sprawiała wrażenie niespójnej. Decyzje co do tych cech podejmij
na początku procesu rozwoju i spraw, by wszyscy programiści się z nimi zapoznali, zanim przejmą własne rozwiązania.
Oto kilka typów elementów stylu, które powinieneś określić w swoim standardzie:
u Układ formularza (na przykład: rozmieszczenie formantów, rozmiar i proporcje formularza).
u Grupowanie pól (na przykład: wklęsłe ramki czy proste linie)
u Określenie dla pól i etykiet rodzaju, koloru, rozmiaru i stylu czcionki (pogrubienie/kursywa)
u Nazwy oraz sposoby reagowania przycisków (na przykład: Anuluj, Zamknij czy Zakończ?)
u Wskazanie użytkownikowi, czy formularze są przeznaczone tylko do odczytu, czy też można je edytować.
u Sposób komunikacji z użytkownikiem (na przykład: zwięzły bądź rozwlekły).
Standardy
Bez standaryzacji pracy programistów aplikacje staną się bardzo kłopotliwe w obsłudze i użytkowaniu.
Zasada 1: Standardy dużo ulepszają.
Zasada 2: Standardy same w sobie nic nie ulepszają.
Podstawowym celem standaryzacji jest ujednolicenie efektów pracy członków zespołu programistów. To, że wszyscy piszą
w „dobrym” stylu, jest sprawą drugorzędną.
Najbardziej powszechne typy standardów to nazewnictwo i kodowanie. Standardy te znacznie ułatwiają czytanie i
przeglądanie kodu programu, a także upraszczają późniejsze czynności serwisowe.
Standardy nazewnictwa
Poniższy przykład korzysta z przyrostkowego standardu nazewnictwa i czynności wykonywane przez programistę są
oczywiste.
DblLodgingTotal = Double(intNights) * dblRate
Standardy kodowania
Oto przykłady elementów, które możesz chcieć określić w standardach kodowania:
u komentarze nagłówków;
u komentarze w kodzie;
u wcięcia;
u rozmiar podprocedur i funkcji (na przykład: maksymalnie 60 wierszy);
u użycie instrukcji Option Explicit.
Konstrukcja
Aby podnieść wydajność zespołu w fazie Konstrukcja możesz stosować kilka technik. W tej części omówimy zagadnienia
związane z podziałem zadań między programistami oraz kontrolować projekt i proces jego wdrażania. Przekonamy Cię
także do dokładnego przetestowania aplikacji i znalezienia wszystkich dotychczas popełnionych błędów.
Ważne jest, aby podczas tworzenia podstaw aplikacji zespół programistów ściśle ze sobą współpracował. Wówczas to
zapadają najważniejsze decyzje, a także definiowane są interfejsy. Po stworzeniu tych podstaw dużo łatwiej jest
programistom pracować osobno lub podzielić się na mniejsze grupy.
Istnieją dwa wydajne sposoby dzielenia procesu wdrożenia między grupy: według obiektów Accessa lub według obiektów
aplikacji. Gdy dzielimy zadania według obiektów Accessa, jeden z zespołów koncentruje się na formularzach, inny na
raportach, a może zaistnieć potrzeba utworzenia trzeciego zespołu, który zajmie się kodowaniem reguł handlowych i
dostarczeniu procedur wspomagających. Jeśli używasz architektury zorientowanej na obiekty, możesz rozdzielić zadania
według obiektów aplikacji. Przykładowo, jeden z zespołów zająłby się tworzeniem obiektów Sprawozdania o kosztach
(moduły, tabele, formularze, raporty), a inny tworzeniem obiektów związanych z Zatwierdzaniem (moduły, tabele,
formularze, raporty).
Rysunek 2.5 przedstawia pięć etapów postępowania wszystkich zespołów w fazie Konstrukcja.
Rysunek 2.5.
Etapy fazy Konstrukcja
Ten sam sposób postępowania wykorzystywany jest na różnych poziomach procesu rozwoju. Na najwyższym z nich diagram ten
opisuje powstawanie całej aplikacji na przestrzeni kilku miesięcy, począwszy od sporządzenia szczegółowego projektu, aż do
ostatecznych testów aplikacji. Na dużo niższym poziomie ten sam diagram mógłby opisywać, jak jeden programista spędza
popołudnie na opracowywaniu jednej z zamówionych opcji.
Podczas trwania fazy Konstrukcja wypuszcza się zazwyczaj kilka wersji programu. Najczęściej są to: prototyp sprawdzający
funkcjonalność graficznego interfejsu użytkownika (GUI); kilka wersji alfa, dzięki którym otrzymujemy wstępne uwagi od
użytkowników; jedna lub dwie wersje beta, umożliwiające użytkownikom przetestowanie aplikacji w rzeczywistych
warunkach; i wreszcie oficjalna wersja 1.0, dostarczana wszystkim użytkownikom.
Edycje i kompilacje
Wraz ze wzrostem złożoności aplikacji i projektu ważności nabiera śledzenie wszystkich wypuszczanych wersji aplikacji.
Co pewien czas twórz (patrz następna wskazówka) edycję aplikacji zawierającą ostatnie poprawki i zmiany dokonane przez
wszystkich programistów. Robiąc to codziennie lub co dwa dni, każdy z programistów ma dostęp do najnowszych
poprawek. W tabeli 2.2 znajdziesz przykłady edycji, które mogą powstać podczas rozwoju aplikacji.
Kompilacja
Kompilacja jest nową wersją aplikacji. Najczęściej zawiera ona umieszczoną
w systemie klienta bazę danych wraz ze wszystkimi powiązanymi z nią plikami
typu DLL i EXE oraz znajdujące się na serwerze pliki danych. Dla
wewnętrznych potrzeb zespołu programistów podczas rozwoju aplikacji
powstanie wiele kompilacji. W rzeczywistości tylko kilka z nich trafia do
użytkowników. Przykład w tabeli 2.2 przedstawia projekt, podczas którego
powstało 178 kompilacji, ale tylko szesnaście edycji (definicja edycji
znajduje się poniżej).
Część I ♦ Projektowanie bazy danych 36
Edycja
Edycja to kompilacja, która zostaje wypuszczona poza zespół programistów.
Zazwyczaj jest ono przekazywane jednemu lub więcej użytkownikom
końcowym.
Nie przejmuj się za bardzo ilością kompilacji. Ich duża ilość nie jest oznaką
słabości procesu rozwoju, lecz ostrożności, z jaką go przeprowadzasz.
Tabela 2.2.
Przykłady edycji
Edycja Kompilacja
Prototyp 1
Prototyp 2
V1.0 Alfa 1 12
V1.0 Alfa 2 27
V1.0 Beta 1 42
V1.0 Beta 2 56
Wersja 1.0 EK1 88
Wersja 1.0 EK2 89
Wersja 1.0 89
Wersja 1.1 EK1 93
Wersja 1.1 93
Wersja 1.2 EK1 97
Wersja 1.2 EK2 98
Wersja 1.2 98
Wersja 2.0 135
Wersja 3.0 178
Tworzenie nowej kompilacji (rysunek 2.6) należy rozpocząć od zebrania w jedną całość zmian i dodatków od wszystkich
programistów. Czasami ich integracja jest równie prosta jak import nowego raportu do interfejsu bazy danych. Częściej
jednak dodanie nowego formularza lub modułu pociąga za sobą konieczność dokonania zmian w jednym lub więcej
formularzach, aby uwzględnić w nich nowy zestaw funkcji. Może się okazać, że dwóch programistów będzie musiało
połączyć swe siły i zintegrować te zmiany. Po wkomponowaniu w kompilację wszystkich dodatków i zmian możesz zaktu-
alizować nazwę edycji/kompilacji wyświetlaną przez aplikację.
Rysunek 2.6.
Tworzenie kompilacji
To także idealny moment na wykonanie kopii zapasowej całej kompilacji. Kopia ta powinna zawierać zarówno bazę
danych, jak i wszystkie pliki, które uległy modyfikacji przy przejściu z jednej kompilacji do drugiej. Ponieważ w projekt
włożono już znaczące zasoby i czas, warto sporządzić tę kopię na osobnym nośniku.
Aby upewnić się, że poszczególne części właściwie ze sobą współpracują, po stworzeniu nowej kompilacji każdorazowo
powinieneś przeprowadzać testy integralności. Po stwierdzeniu, iż nowa kompilacja działa bez zarzutu, powinieneś
dostarczyć je każdemu członkowi zespołu. Umieść kopię aplikacji w ogólnodostępnym katalogu, by każdy z programistów
i testerów miał do niego dostęp. Jeśli to możliwe, skorzystaj z funkcji narzędzia służącego do kontroli wersji, takiego jak
Microsoft Visual SourceSafe. Dzięki temu będziesz mógł budować i śledzić tworzone kompilacje, a także ograniczyć
problemy powstające na skutek zmian dokonywanych przez kilku programistów.
Niektóre kompilacje powstają na różnych etapach procesu rozwoju (patrz przykłady w tabeli 2.2 i na rysunku 2.8). Podczas
fazy koncepcyjnej lub zbierania wymagań dobrze jest stworzyć jeden lub kilka prototypów, które pozwolą użytkownikom
ocenić wygląd proponowanego GUI. Później, gdy kilka z podstawowych opcji już działa, bardzo przydatnym może okazać
się przekazanie jednemu lub dwa użytkownikom edycji alfa. Dzięki temu będziesz znał ich opinię, co może pozwolić Ci
znacznie zmniejszyć ryzyko niepowodzenia. Gdy aplikacja jest już prawie gotowa, dostarczenie użytkownikom do testów
wersji beta znacznie podwyższy jakość produktu końcowego. Większość z tych edycji powstaje dla każdej z głównych
wersji (duże zmiany) i mniejszych poprawek (małe zmiany). Przed wypuszczeniem ostatecznej wersji warto też oddać
użytkownikom do testów jedną lub kilka edycji-kandydatek (EK1, EK2 i tak dalej).
Aby utworzyć edycję, weź prawidłowo działającą kompilację i przygotuj pakiet instalacyjny. Czynność ta może być tak
prosta jak spakowanie interfejsu bazy danych albo tak skomplikowana jak stworzenie profesjonalnego skryptu
instalacyjnego przy użyciu zawartego w Office 2000 Developer’s Edition narzędzia instalacyjnego. W obu przypadkach,
edycja powinna być przetestowana na kilku komputerach, aby upewnić się, że działa bez zarzutu (rysunek 2.7).
Gdy produkt z pozytywnym wynikiem przejdzie fazę testów, przekaż go do zainstalowania użytkownikom. Do każdej wersji
dołącz „Informacje o edycji”. Wylicz w nich nowe opcje, zmiany i znane problemy. Nawet jeśli użytkownik nigdy ich nie
przeczyta, przydają się one programistom, gdyż czytając je, wiedzą, co w danej edycji zostało zmienione. Nie zapomnij o
aktualizacji dokumentacji użytkownika, za każdym razem, gdy dokonujesz zmian w aplikacji. Nieaktualna dokumentacja jest
gorsza niż całkowity jej brak.
Rysunek 2.7.
Tworzenie edycji
W czasie trwania projektu utworzonych zostanie wiele edycji i kompilacji. Na rysunku 2.8 przedstawiono przykład cyklu,
w którym tworzone są edycje i kompilacje. Każda kompilacja daje programistom, testerom, a czasami nawet
użytkownikom okazję do przetestowania aplikacji i podzielenia się z resztą zespołu swoimi uwagami i spostrzeżeniami.
Nazywane są one często usterkami lub problemami. W zależności od ich ważności w stosunku do kontynuacji rozwoju
aplikacji poprawienie ich następuje już w następnej kompilacji lub też odkładane jest na później.
Część I ♦ Projektowanie bazy danych 38
Rysunek 2.8.
Przykład cyklu
kompilacji i edycji
Szczegółowy projekt
Mimo iż w większości opcji i zadań sposób ich implementacji w aplikacji jest oczywisty, zdarza się (w pięciu do dwudziestu
procent przypadków), że wymaga to chwili zastanowienia. Do typowych przykładów należą moduły, formularze nawigacyjne,
skomplikowane algorytmy i rzadkie techniki automatyzacyjne. Projekt takich opcji lub zadań powinien być w jakiś sposób
udokumentowany. Pozostaw po swoich decyzjach i sposobie ich uwzględnienia w projekcie jakiś ślad. Może on przydać
się tobie lub komuś innemu, gdy nadejdzie potrzeba dokonania pewnych zmian. Zachowaj dokumentację dotyczącą pro-
jektu do czasu, gdy wyjaśnione zostaną wszelkie wątpliwości.
Kontrola projektu
Kontrola projektu polega na skonsultowaniu problemów wynikłych podczas tworzenia projektu oraz sposobów ich
rozwiązania z osobami trzecimi. Konsultacja ta może być całkiem nieformalna, ale równie dobrze może przybrać formę
oficjalnej prezentacji podczas zebrania członków zespołu. Często zdarza się, że podczas opisywania projektu innym
osobom zauważasz nowe problemy lub lepsze rozwiązania. Inny programista często znajduje to, co Ty przeoczyłeś. To
doskonały moment, by wykryć błędy w aplikacji, zanim rozpoczniesz czasochłonne kodowanie i testowanie.
Tworzenie aplikacji
Tworzenie aplikacji jest tym etapem procesu rozwoju, który klientom, użytkownikom i niedoświadczonym programistom
kojarzy się z procesem pisania programu. Podczas tej fazy powstają formularze i raporty oraz pisany jest kod programu.
Większość rozdziałów tej książki obejmuje zagadnienia związane z tą fazą procesu rozwoju.
Kontrola aplikacji
Kontrola aplikacji (lub kodu programu) przypomina kontrolę projektu, z tą różnicą, że dotyczy efektów jego wdrożenia.
Zazwyczaj kontrola tworzonych formularzy, raportów, kwerend, a także kodu programu niesie ze sobą wiele korzyści.
Podobnie jak to miało miejsce w przypadku kontroli projektu, przez samo opisywanie tego, co zrobiłeś i jak to działa,
zauważasz elementy, które wcześniej przeoczyłeś. Osoba trzecia, patrząc na Twoją pracę, może zauważyć coś, co
pominąłeś. Ty lub osoba, z którą konsultujesz aplikację, możecie odnaleźć błędy powstałe w trakcie jej tworzenia, w jej
projekcie, architekturze lub wymaganiach klienta. Pamiętaj, że im wcześniej błąd jest odnaleziony, tym mniej kosztuje jego
naprawienie.
Kontrole kodu programu przynoszą dodatkową korzyść w postaci podnoszenia umiejętności programistów. Aby to osiągnąć,
poproś doświadczonych programistów, by kontrolę kodu programu zlecali nowym lub mniej doświadczonym członkom
zespołu. Inną korzyścią jest poznanie przez programistów części aplikacji pisanych przez ich kolegów.
Jeśli jesteś samotnym programistą (chodzi nam oczywiście o to, że nie pra-
cujesz w zespole), znajdź innego programistę i dokonujcie wzajemnej
kontroli kodu. Poświęcony temu czas szybko się wam zwróci. Bardzo
pomocne mogą być tu grupy użytkowników.
Testowanie
Testowanie w procesie rozwoju odbywa się na kilku poziomach: jednostki, aplikacji, konfiguracji i instalacji.
Testowanie modułu
Przed rozpoczęciem tworzenia opcji lub obiektu zastanów się, jak zamierzasz je testować. Po utworzeniu danego elementu
przeprowadź zaplanowane testy, aby sprawdzić, czy jego działanie jest zgodne z Twoimi intencjami oraz czy można ten
element dołączyć do reszty aplikacji. Z doświadczenia wiemy, iż 20% czasu tworzenia aplikacji powinno się poświęcić na
testowanie wszystkich opcji i obiektów. Przykładowo, jeśli poświęciłeś siedem godzin na opracowanie algorytmu i trzy
godziny na napisanie go i usunięcie błędów, to można założyć, że testowanie go powinno zabrać Ci około dwóch godzin.
Jeśli testujesz podprogram, funkcję lub moduł, przetestuj wszystkie możliwe parametry wejściowe, poprzez wprowadzenie
zarówno oczekiwanych, jak i nieoczekiwanych wartości. Podczas testowania nowego formularza upewnij się, że sprawdziłeś,
czy wszystkie
formanty działają poprawnie. Przede wszystkim sprawdź, czy prawidłowo funkcjonują: kontrola poprawności
wprowadzanych danych, zablokowane pola, kolejność klawisza Tab, wstawianie nowych rekordów, jednolitość stylów i
poruszanie się po formularzu.
Część I ♦ Projektowanie bazy danych 40
Testowanie aplikacji
Testowania aplikacji (lub systemu) dokonuje się na całej aplikacji po umieszczeniu w niej wszystkich opcji. Istnieje kilka
przyczyn uzasadniających wykonywanie tego typu testów. Najważniejszą z nich jest stwierdzenie, czy aplikacja
uwzględnia wszystkie wymagania zgłoszone przez klienta. Drugą z przyczyn jest określenie, w jakim stopniu aplikacja jest
gotowa do wypuszczenia jej na rynek.
Odnajdywanie usterek
Przez usterkę rozumiemy każdy błąd, niedociągnięcie bądź problem związany z funkcjonowaniem aplikacji. Może to być
błąd w dokumencie, narzędziu bądź we wdrożeniu aplikacji. Usterki mogą być odnajdywane na każdym etapie procesu
rozwoju i wszystkie powinny być zgłaszane.
Niezależnie od tego, z jakiego źródła pochodzi informacja o błędzie oraz kto ją zgłasza, musi ona być udokumentowana.
Wszystkie informacje o błędach przechowuj w jednym miejscu. Informacje umieszczone na różnych kartkach czy w e-
mailach możesz zgubić lub zwyczajnie o nich zapomnieć. Możesz używać dostępnego w sprzedaży narzędzia służącego do
śledzenia błędów, stworzyć osobną bazę danych w Accessie lub zapisywać usterki na komputerze przenośnym.
Jakkolwiek przechowujesz informacje o błędach, będziesz potrzebował procesu zapewniającego, że każda usterka jest
analizowana. Zauważ, że „analizowana” nie musi koniecznie oznaczać „naprawiana”. Może się zdarzyć, że w zależności od
tego jak poważny jest błąd i jak często występuje, zdecydujesz się go nie naprawiać.
Każda usterka powinna przejść ten sam proces, począwszy od jej stwierdzenia aż do rozwiązania.
1. Zaraz po odkryciu błędu informacje o nim wprowadź do systemu kontroli błędów. Tabela 2.3 zawiera listę
informacji, które według nas powinieneś zbierać. W tabelach od 2.4 do 2.8 znajdziesz dalszy opis informacji o
usterkach.
2. Zespół programistów powinien co pewien czas przejrzeć nierozpatrzone usterki i określić ważność każdej z nich.
Decyzja ta powinna być oparta na wadze, częstości występowania i powtarzalności każdej usterki. Następnym
krokiem jest przydzielenie zadania rozwiązania problemu jednemu z programistów.
3. Programista naprawia usterkę lub stwierdza, że nie zaszła taka konieczność. Do niego należy także uaktualnienie
opisu i statusu rozwiązania problemu. Jeśli usterka została zlikwidowana, status rozwiązania problemu zostanie
zmieniony na „poprawiono”.
4. Jeśli to możliwe, inny członek zespołu sprawdza wszystkie poprawione błędy. Wówczas status rozwiązania
problemu zmieniany jest na „sprawdzono”.
Tabela 2.3.
Informacje o usterkach
Tabela 2.3.
Informacje o usterkach (ciąg dalszy)
Część I ♦ Projektowanie bazy danych 42
Tabela 2.4.
Waga usterki
Waga Kryteria
Krytyczna Niepełny zestaw funkcji bądź utrata danych
Poważna Opcja nie działa tak jak zaplanowano; zmniejszenie użyteczności.
Przeciętna Powoduje, iż aplikacja zawiesza się, lecz nie w sposób krytyczny; nie
następuje utrata danych
Niska Kosmetyczny problem lub prośba o ulepszenie danej opcji
Tabela 2.5.
Częstotliwość występowania
Częstotliwość Kryteria
Powszechna Użytkownik podczas normalnego korzystania z aplikacji z łatwością
zauważy usterkę, co najmniej raz za każdym użyciem. (Na przykład:
zamykając główny formularz)
Tabela 2.5.
Częstotliwość występowania (ciąg dalszy)
Częstotliwość Kryteria
Okazjonalna Jest mało prawdopodobne, by użytkownik trafiał na usterkę za każdym
razem, gdy używa produktu, lecz prawdopodobnie kiedyś ją zauważy.
(Na przykład: usterka występuje tylko podczas drukowania
dwustronicowej faktury)
Rzadka Bardzo mała część użytkowników zauważy tę usterkę. (Na przykład:
usterka dotyczy tylko określonych kart graficznych)
Tabela 2.6.
Powtarzalność usterki
Powtarzalność Kryteria
Zawsze Usterka powtarza się zawsze.
43 Rozdział 2. ♦ Planowanie procesu rozwoju
Tabela 2.7.
Ważność naprawienia usterki
Ważność Opis
Krytyczna Musi zostać naprawiona
Wysoka Powinna zostać naprawiona, jeśli to tylko możliwe
Przeciętna Naprawić, jeśli starczy czasu
Przełożyć na później Nie trzeba naprawiać w tym momencie
Tabela 2.8.
Rozwiązanie problemu
Rozwiązanie Opis
Nie rozwiązano Problem nowy i jeszcze nie analizowany
Zignorowano Element działa tak, jak zaplanowano
Odłożono na później Problem nie zostanie rozwiązany w tym momencie
Poprawiono Problem został rozwiązany i czeka na sprawdzenie
Sprawdzono Naprawiony element został przetestowany i usterka jest usunięta
Kontrola wersji
Istnieje wiele przyczyn, dla których powinieneś w jakiś sposób kontrolować wersje aplikacji w procesie rozwoju. Za
każdym razem, gdy zespół składa się z więcej niż jednego programisty, pojawia się kilka przeszkód. Początkowo
sprawowanie kontroli nad wersjami wydaje się całkiem proste. Wystarczy przechowywać „główną” bazę danych na
serwerze i uważnie przydzielać tworzenie i obsługę obiektów różnym programistom.
Łatwe, prawda? Niestety, jak bardzo byś się nie starał temu zapobiec, pewnym jest, że dwóch programistów dokona
jednoczesnych zmian w tym samym obiekcie. Być może otworzą dany formularz w tym samym momencie i jeden z nich
doda pole, podczas gdy drugi naprawia funkcję. Obydwaj zapiszą zmiany w „głównej” bazie danych. Ten, który to zrobi
jako drugi, wygrywa – nadpisze zmiany zapisane przez pierwszego programistę. Przy odrobinie szczęścia, pierwszy
programista przetestuje swoją pracę i zauważy, że dokonane przez niego zmiany zniknęły. W innym przypadku, problem
zostanie zauważony później. Nie ma nic gorszego niż ponowne wykonywanie tych samych czynności. Jednakże problem
ten może zostać rozwiązany przez monitorowanie i kontrolowanie uprawnień do dokonywania zmian obiektów.
Inną przyczyną, dla której warto wdrożyć kontrolę wersji, jest możliwość identyfikacji i odtworzenia poprzedniej,
działającej wersji aplikacji. Może się zdarzyć, że będziesz chciał sprawdzić, czy dany problem występował we
wcześniejszych wersjach. Odtworzenie poprzedniej wersji przydaje się również, gdy zaplanowane zmiany nie odniosły za-
mierzonych efektów i chcesz je cofnąć. Takie sytuacje zdarzają się niezależnie od rozmiaru zespołu programistów.
Istnieje kilka technik i narzędzi, za pomocą których można rozwiązać problemy związane z kontrolą wersji.
Prawdopodobnie najlepszym rozwiązaniem jest zakup specjalnie do tego przeznaczonego narzędzia. Najpopularniejszym z
nich jest Microsoft Visual SourceSafe, ponieważ program ten jest mocno zintegrowany z Accessem 2000. Możesz także
wdrażać różne metody, aby sprostać wyzwaniom związanym z kontrolą wersji aplikacji.
Część I ♦ Projektowanie bazy danych 44
Aby rozwiązać kwestię współpracy wielu programistów, możesz sporządzić listę współdzielonych obiektów „głównej”
bazy danych. Może to być plik tekstowy lub tabela w Accessie, z której programiści będą mogli sprawdzić, czy dany obiekt
jest w danej chwili dostępny oraz wpisać czas pobrania i zwrotu danego obiektu. Jednak, by metoda ta była skuteczna,
ustalona procedura musi być bez wyjątków przestrzegana.
Innym wyjściem z tej sytuacji jest okresowe sporządzanie kopii zapasowej wszystkich plików powiązanych z aplikacją w
postaci nowego podkatalogu lub pliku typu ZIP. Pamiętaj jednak o tym, by podkatalogom i plikom typu ZIP nadawać
zrozumiałe nazwy, zawierające kompilację, wersję i datę. Proces ten możesz zautomatyzować z poziomu Accessa 2000.
W trakcie tworzenia aplikacji w Accessie 2000 powinieneś przez cały czas pamiętać, że każda z tworzonych przez Ciebie
aplikacji jest bazą danych. Aby tworzyć szybsze i bardziej wydajne aplikacje, musisz poznać i zrozumieć pojęcie
normalizacji baz danych
– temat tego rozdziału. Mimo iż być może miałeś już okazję zapoznać się z normalizacją baz danych na różnych szkoleniach,
powinieneś przyjrzeć się teorii relacyjnej w odniesieniu do Accessa.
spełnia on tych wymagań, jednakże ja się z tym nie zgadzam i uważam, że nie jest błędem zaliczenie Accessa do grupy
projektów RDBMS. Oto 13 zasad relacyjnych i ich zastosowanie w Accessie.
Tabela 3.1.
Zasady relacyjne dr Codda
Zasada
Nazwa zasady Opis Komentarz dotyczący Accessa
dr Codda
Zasada 0. Zasada tworzenia Każdy program typu RDBMS musi Access był pierwszą na rynku,
być w stanie zarządzać bazami danych działającą w systemie Windows
jedynie za pomocą swoich zdolności bazą danych, która przestrzegała
relacyjnych. Jeśli system działa na tej zasady. Access,
zasadach operowania danymi rekord- w przeciwieństwie do niektórych
po-rekordzie, nie możemy go nazywać systemów, nie stosuje numeracji
Część I ♦ Projektowanie bazy danych 46
Tabela 3.1.
Zasady relacyjne dr Codda (ciąg dalszy)
Zasada
Nazwa zasady Opis Komentarz dotyczący Accessa
dr Codda
Zasada 5. Kompletny język Program typu RDBMS musi Access (Jet) w pełni obsługuje
obsługiwać jasno określony język SQL dla operowania danymi,
do operowania danymi (SQL), który określania widoków (kwerendy
w pełni obsługuje definiowanie wybierające) i ograniczeń
i operowanie danymi, określanie integralności (Okno Relacje
widoku, ograniczenia integralności, i komenda UTWÓRZ
ograniczenia transakcyjne OGRANICZENIE)
i autoryzację
Zasada 6. Uaktualnianie Wszystkie widoki mogą być Access był pierwszą bazą
widoków systemowo uaktualnione. danych, umożliwiającą użycie
W prawdziwym programie typu kwerend aktualizujących
RDBMS, większość (ale nie
wszystkie) widoków może być
uaktualniana
Zasada 7. Ustawianie Program typu RDBMS musi nie tylko Access spełnia to wymaganie
poziomu potrafić pobierać zestawy danych. poprzez użycie kwerend
uaktualnień Musi także potrafić wstawiać, funkcjonalnych
aktualizować i usuwać dane jako
zestaw relacyjny
Zasada 8. Fizyczna Dane i aplikacja muszą być od siebie Access umożliwia Ci
niezależność fizycznie niezależne. Odpowiedni modyfikowanie obiektów bazy
danych program typu RDBMS lub danych, bez konieczności
„optymalizator” powinny móc śledzić dokonywania zmian w reszcie
fizyczne zmiany w danych. aplikacji. Jet zawiera także
Przykładowo, aplikacje RDBMS nie logiczny aparat przechowywania
powinny ulegać modyfikacji na skutek
dodania bądź usunięcia z tabeli
indeksu
Zasada 9. Logiczna Gdy to tylko możliwe, aplikacja Gdy tworzysz w Accessie
niezależność powinna być niezależna od zmian kwerendę, możesz ją z łatwością
danych dokonywanych w tabelach połączyć z formularzem lub
podstawowych. Przykładowo, raportem, jakby to była tabela
d t b l ł id k
47 Rozdział 3. ♦ Projekt bazy danych i normalizacja
Tabela 3.1.
Zasady relacyjne dr Codda (ciąg dalszy)
Zasada
Nazwa zasady Opis Komentarz dotyczący Accessa
dr Codda
Zasada 11. Niezależność Zdolności programu typu RDBMS nie Ponieważ silnik Jet przechowuje
podziału będą ograniczone dzięki umieszczeniu swoje zasady integralności
jego komponentów w osobnych danych na poziomie aparatu,
bazach danych. pozostałe jego komponenty nie
mają wpływu na zasady
integralności.
Zasada 12. Brak podwersji Jeśli program RDBMS posiada język Access umożliwia Ci użycie
typu „jeden rekord jednocześnie”, obiektów DAO i ADO, aby
język ten nie może być używany do operować jednym rekordem
omijania zasad integralności lub jednocześnie poprzez
ograniczeń języka relacyjnego. aktualizowalne zestawy
Dlatego też nie wystarczy, by zasady rekordów. Dzięki tym
relacyjne zarządzały programem typu narzędziom do operowania
RDBMS, ale muszą być prawami danymi nie możesz naruszyć
nadrzędnymi. zasad integralności.
Relacyjne systemy zarządzania bazami danych przeważają w kilku punktach nad innymi systemami, w szczególności w
procesie projektowania. Programy typu RDBMS korzystają z teorii projektowania relacyjnego, aby tworzyć własne modele
projektowe baz danych. Na tym skupimy się w następnej części tego rozdziału.
Tabele i niepowtarzalność
Kiedy tworzysz aplikacje bazy danych, każda tabela przedstawia odrębną jednostkę lub proces występujący w
rzeczywistym świecie. Będziesz tworzył tabele kontrolujące ludzi, wydarzenia, transakcje finansowe i przedmioty (np.
produkty). Zgodnie z teorią relacyjną, musisz przechowywać wszystkie dane w tabelach (zasada 1.) oraz, że tabela składa
się z unikatowych wierszy i kolumn (zasada 2.). Sposobem na zapewnienie unikalności każdej z zasad jest ustawienie
klucza głównego dla każdego wiersza.
Klucz główny to pole lub grupa pól (mówimy wtedy o wielopolowym kluczu głównym), które jest unikatowym
identyfikatorem tego wiersza. Klucz główny musi być unikatowy. W przeciwnym bowiem wypadku dochodziłoby do
naruszenia zasady 2. Access pozwala Ci uczynić pole kluczem głównym, poprzez nadanie mu wartości Klucz w widoku
Projekt tabeli. Access sprawdzi wówczas, czy dane w tym polu są unikatowe i nie występują w nim duplikaty. Czasami,
gdy przestrzegamy reguł handlowych, podanie unikatowej wartości dla każdego wiersza może być trudne. Przykładowo,
możesz utworzyć przedstawiony na rysunku 3.1 system zarządzający kontaktami.
Rysunek 3.1.
Przykładowa,
nieznormalizowana
tabela
Podczas projektowania systemu zarządzającego kontaktami, jako klucz możesz wybrać Nazwisko, Telefon lub e-mail (pola takie
powszechnie nazywane są „polami-kandydatami”). Ogólna zasada projektowania baz danych głosi, że klucz powinien być jak
najprostszy, unikatowy i jak najrzadziej zmieniany. Nazwisko może się zmieniać na skutek zawarcia małżeństwa, rozwodu itp.
Numery telefonów i adresy e-mail zmieniają się ciągle. Dobrym kluczem byłby numer PESEL, ale co, gdy dana osoba nie jest
obywatelem polskim? W tej sytuacji Access umożliwia Ci utworzenie pola Autonumerowanie, które stanie się polem klucza
podstawowego. Autonumerowanie jest samogenerującą się wartością liczbową, która będzie wzrastać z każdym nowym
rekordem. Istnieją dwa typy Autonumerowania:
u Wartości całkowite;
u Id replikacji lub GUID (używany w replikacji). Więcej informacji na ten temat znajdziesz w rozdziale 22.
„Replikacja i JRO”.
Istnieje kilka sposobów na manipulowanie Autonumerowaniem w aparacie
Jet, co nie było możliwe we wcześniejszych wersjach Accessa. Możesz teraz
ustawić wartość, o jaką Autonumerowanie będzie przyrastać, a także sprawić,
by było odliczane wstecz. Więcej szczegółów na ten temat znajdziesz w
rozdziale 5. Mimo iż wartość, o jaką Autonumerowanie przyrasta, może być
kontrolowana, pamiętaj, że Autonumerowanie nie oznacza numeru rekordu.
Rysunek 3.2.
Tabela z dwoma
kluczami obcymi
Jak widać na rysunku 3.2, można przechowywać wartość klucza głównego jednej tabeli, aby przedstawiać rekordy w innej
tabeli. Wówczas mówimy o kluczu obcym, który będzie podstawą opisanych w następnej części relacji. Przedstawiona na
rysunku 3.2 tabela trelContactInfo przechowuje dwa obce klucze: ContactID i ContactTypeID. ContactID to klucz główny
tabeli tblContact, a ContactTypeID to klucz główny tabeli tlkpContactType.
49 Rozdział 3. ♦ Projekt bazy danych i normalizacja
Gdy używasz kluczy obcych, będą się one zawsze znajdować w tej samej domenie. Domeny są to zbiory wartości, z
których pobierane są kolumny. Dobrym przykładem jest StudentID. Jego domeną są wszystkie dostępne w systemie
numery PESEL.
Relacje
Gdy definiujesz klucze główne i klucze obce, masz do czynienia z relacjami. Przez relacje rozumiemy zasady obsługiwane
na poziomie silnika bazy danych (patrz: Zasada 4. dr Codda). Access wyróżnia trzy różne typy relacji:
u relacja jeden-do-jednego;
u relacja jeden-do-wielu;
u relacja wiele-do-wielu.
Aby tworzyć relacje w Accessie, naciśnij znajdujący się w na pasku narzędzi przycisk Relacje lub wybierz
Narzędzia⇒Relacje, aby otworzyć okno Relacje.
Relacja jeden-do-jednego
Dwie tabele łączy relacja jeden-do-jednego, gdy każdemu wierszowi z jednej tabeli przyporządkowany jest co najwyżej
jeden wiersz z drugiej tabeli.
Na rysunku 3.3 znajduje się przykład relacji jeden-do-jednego. Ten typ relacji jest najrzadziej spotykany, ponieważ w
większości przypadków możesz powiązane informacje umieszczać w jednej tabeli. Jednakże, ze względów
bezpieczeństwa, możesz zdecydować, iż należy informacje rozdzielić na dwie tabele. Również skomplikowane transakcje
finansowe zawierają wiele relacji jeden-do-jednego.
Rysunek 3.3.
Relacja
jeden-do-jednego
Relacja jeden-do-wielu
Najpopularniejszy typ relacji, relacja jeden-do-wielu, występuje wtedy, gdy tabela ma wiele (lub nie ma w ogóle)
powiązanych rekordów w drugiej tabeli. Przykładem może być relacja Customer do Order lub przedstawiona na rysunku
3.4 relacja Contact do ContactInfo. Czasami tabela po stronie „jeden” nazywana jest tabelą odnośnika. Zazwyczaj, tabele
odnośnika zawierają informacje, które będą przekazywane do innych tabel (na przykład, nazwy województw lub kody
pocztowe). Podczas adaptowania konwencji nazewnictwa dobrze jest dla tabeli odnośnika użyć przedrostka tlkp.
Rysunek 3.4.
Relacja
jeden-do-wielu
Część I ♦ Projektowanie bazy danych 50
Relacja wiele-do-wielu
O relacji wiele-do-wielu mówimy wówczas, gdy każdemu wierszowi z jednej tabeli odpowiada wiele wierszy w drugiej
tabeli, a każdemu wierszowi z drugiej tabeli odpowiada wiele wierszy w pierwszej. Jedynym sposobem na przedstawienie w
Accessie relacji wiele-do-wielu jest użycie tabeli „łączącej”, w której jako klucze obce znajdują się klucze główne obu
tabel.
Rysunek 3.5 przedstawia relację wiele-do-wielu między tabelami tblContact i tlkpContactType, utworzoną za pomocą tabeli
łączącej trelContactInfo. Tabela tblContact zawiera wszystkie kontakty w bazie danych. Tabela tlkpContactType zawiera
sposoby porozumiewania się: Faks, Email, Telefon i Pager. Tabela łącząca zawiera odnośnik do pól Faks i Telefon oraz
Kontaktu, tak więc gdy za pomocą pola Kontakt dodaje się do listy nowy sposób porozumiewania się (jak na przykład adres
sieci Web), możesz w tabeli odnośnika (tlkpContactType) dodać pozycję „Adres sieci Web” i dodać łączący rekord do
tabeli trelContactInfo. To najbardziej elastyczny sposób budowania systemu zarządzania kontaktami, gdyż nie będą
występować puste pola, dajmy na to „Telefon2”. Nie będziesz również musiał dodawać nowych pól, gdy będziesz dodawał
do listy następny sposób porozumiewania się. Gdy korzystasz z tabeli łączącej, najlepiej jest użyć konwencji nazewnictwa
„trel”.
Rysunek 3.5.
Relacja
wiele-do-wielu
Podarkusze danych
Jedną z nowych opcji Accessa 2000 są podarkusze danych – nowy sposób przeglądania powiązanych danych w widoku
arkusza danych. Podarkusze danych, jak ten na rysunku 3.6, są „poszerzonym” widokiem powiązanych danych.
Podarkusze danych automatycznie odczytują relacje w bazie i wyświetlają powiązane tabele. Nie zawsze jest to najlepszy
sposób na przeglądanie powiązanych danych, tak jak to ma miejsce w przypadku przedstawionej na rysunku 3.6 relacji
wiele-do-wielu.
Aby zoptymalizować widok podarkuszy danych, możesz utworzyć kwerendę, która połączy dane z powiązanych tabel tak,
by wyświetlone były opisy, a nie klucze obce. Następnie otwórz tabelę w widoku Projekt i spójrz na właściwości tabeli
(rysunek 3.7). W polu Nazwa podarkusza danych wybierz nazwę utworzonej kwerendy. Być może będziesz również
musiał ustawić właściwości podrzędnego i nadrzędnego pola łączącego, jeśli Access nie rozpozna ich automatycznie.
Rysunek 3.6.
Podarkusz danych
Accessa 2000
51 Rozdział 3. ♦ Projekt bazy danych i normalizacja
Rysunek 3.7.
Właściwości
podarkusza danych
Tabela 3.2.
Właściwości podarkusza danych
Normalizacja danych
Zgodnie z zestawem zasad dr Codda proces projektowania bazy danych nazywany jest normalizacją danych. Dr Codd wyróżnia
sześć poziomów normalizacji. Skoncentrujemy się tutaj na trzech z nich, gdyż mają one największy wpływ na decyzje dotyczące
projektu bazy:
u Pierwsza postać normalna.
u Druga postać normalna.
u Trzecia postać normalna.
Rysunek 3.8 przedstawia przykład tabeli, która nie jest w pierwszej postaci normalnej, ponieważ w kolumnie ContactInfo
przechowywana jest tablica wartości. Rysunek 3.9 jest przykładem tabeli w pierwszej postaci normalnej, gdyż w żadnej z
kolumn nie występują powtarzające się informacje.
Rysunek 3.8.
Tabela jest nie
będąca w pierwszej
postaci normalnej
Część I ♦ Projektowanie bazy danych 52
Rysunek 3.9.
Tabela w pierwszej
postaci normalnej,
ale nie w drugiej
postaci normalnej
Dobrym przykładem zależności jest pole obliczeniowe (korzystniej jest nie przechowywać pól obliczeniowych, tylko
wyświetlać wyniki obliczeń jako część kwerendy). Na rysunku 3.10 druga tabela przechowuje pola ContactInfoID i
ContactType (opis). Jeśli wartość pola ContactType poznajesz dzięki polu ContactInfoID, tabela nie jest w trzeciej postaci
normalnej.
Aby otrzymać trzecią postać normalną, wyodrębnij z ContactInfo trzecią tabelę i utwórz między tabelami ContactInfo i
ContactDetails relację jeden-do-wielu, tak jak na rysunku 3.11.
53 Rozdział 3. ♦ Projekt bazy danych i normalizacja
Rysunek 3.11.
Tabele w trzeciej
postaci normalnej
Korzyści z normalizacji
W poprzednim przykładzie, zyskałeś wiele, normalizując początkową, przedstawioną na rysunku 3.8 tabelę. Tabela
początkowa zawierała sposoby porozumiewania się w tablicy wartości, co prawie całkowicie uniemożliwiało przeszukiwanie
zawartości pola Faks. Dodatkowo, gdy zmieniał się numer telefonu kontaktu lub zachodziła potrzeba dodania nowego
sposobu porozumiewania się, jak na przykład adres e-mail, edycja danych była utrudniona i łatwo było o błędy. Pierwsza
postać normalna znacznie poprawiła sytuację i zwiększyła elastyczność w kontrolowaniu numerów telefonów, faksów i
adresów
e-mail naszych kontaktów.
W przedstawionej na rysunku 3.9 tabeli, która jest w pierwszej, lecz nie jest w drugiej postaci normalnej, zarządzanie
danymi dotyczącymi kontaktów jest utrudnione, gdyż informacje wielokrotnie się powtarzają. Jeśli masz w bazie 10
numerów telefonów i przechowujesz to samo nazwisko 10 razy, to jest to nie tylko strata przestrzeni dyskowej, ale również
problem, gdy zachodzi potrzeba uaktualnienia wszystkich 10 wpisów, gdy dana osoba zmieniła nazwisko. Utrzymanie
spójności w tym przypadku może Cię kosztować dużo wysiłku.
Tabele na rysunku 3.10, mimo iż są w pierwszej i drugiej postaci normalnej (wszystkie kolumny zależą od całego klucza),
nie są w trzeciej postaci normalnej. Przenosząc dane i uzyskując trzecią postać normalną, uzyskujesz większą elastyczność
modelu danych, gdyż teraz możesz zarządzać typami kontaktów w osobnej tabeli.
Ustawienie aktualizowania kaskadowego rekordów daje Ci pewność, że gdy aktualizujesz wartość klucza podstawowego
tabeli „jeden”, zmiana ta odniesie skutek w tabelach „wielu”. Przykładowo, powiedzmy, że masz tabelę odnośnika dla
Stanów Zjednoczonych. W tabeli tej znajduje się miasto Nowy Jork, z kluczem podstawowym NY i opisem Nowego Jorku.
Wyobraź sobie, że miasto to odłączyło się i stworzyło swój własny stan (to nie jest fikcja, prawie do tego doszło w roku
1789!). Gdy zmienisz wartości NY na NY1 (lub coś bardziej opisowego), wartości NY we wszystkich podrzędnych tabelach
zostaną zmienione na NY1. Jeśli aktualizowanie kaskadowe nie było włączone, musiałbyś dodać rekord NY1 do tabeli
odnośnika, zaktualizować wszystkie rekordy w podrzędnej tabeli, a następnie usunąć z tabeli odnośnika rekord NY.
Włączenie usuwania kaskadowego daje Ci pewność, że gdy usuwasz rekord z tabeli „jeden”, usuniesz również wszystkie
rekordy z tabeli „wielu”. Ma to swoje dobre i złe strony. Jeśli usuwasz jednego z klientów, a usuwanie kaskadowe było
włączone, usunięte zostaną wszystkie faktury po stronie „wielu”. W przeciwnym wypadku, usunięcie rekordu z tabeli
„jeden” nie będzie wykonane, dopóki nie usuniesz wszystkich rekordów z tabeli „wielu”.
Rozdział 4.
Zaawansowane kwerendy
W tym rozdziale:
u Kwerendy w Accesie 2000.
u Tworzenie zaawansowanych kwerend.
u Użycie kwerend.
u Właściwości kwerendy.
u Siatka QBE.
u Panel tabel.
u Siatka kwerendy.
u Kwerendy podsumowujące.
u Użycie kwerend krzyżowych.
u Użycie kwerend parametrycznych.
u Kwerendy przekazujące.
u Kwerendy definiujące dane.
u Optymalizowanie kwerend.
Kwerendy są elementami napędowymi baz danych Accessa. Występują w kilku formach i rodzajach. Mogą być zapisywane
w bazie (jak tabele) lub działać tylko w pamięci komputera. Do ich tworzenia można używać poleceń SQL lub graficznego
interfejsu użytkownika nazywanego tabelą QBE. Kwerenda może zarówno przedstawiać dane w takiej postaci, w jakiej
występują w bazie, jak również przed wyświetleniem grupować je i przeliczać. Kwerenda Accessa może już przed
uruchomieniem wiedzieć, co powinna wykonać lub zadawać użytkownikowi dodatkowe pytania. Kwerendy potrafią także
aktualizować dane, tworzyć i usuwać rekordy, a nawet zmieniać strukturę bazy. Kwerendy w Accessie mogą pracować z
danymi przechowywanymi w plikach typu MDB, innych, przyłączonych do Accessa źródłach danych, a nawet bazach
danych typu klient-serwer (np. Oracle i Microsoft SQL Server). Są one najszybszym i najpewniejszym sposobem
efektywnej interakcji z danymi w relacyjnej bazie danych.
Weźmy za przykład rachunek telefoniczny. Raz w miesiącu operator sieci telefonicznej przysyła Ci rachunek za swoje
usługi, a jeśli sobie tego zażyczysz – szczegółowy wykaz rozmów. Wykaz ten zawiera wszystkie informacje o
przeprowadzonych w poprzednim miesiącu rozmowach telefonicznych: datę, godzinę, numer telefonu osoby, do której
dzwoniłeś, czas trwania rozmowy, ilość naliczonych impulsów oraz całkowity koszt rozmowy. To bardzo dużo informacji,
55 Rozdział 4. ♦ Zaawansowane kwerendy
jednakże na podstawie samego wykazu trudno jest odpowiedzieć na najbardziej nawet podstawowe pytania. Dużo
wygodniej byłoby móc połączyć go z książką adresową. Gdyby to było możliwe, mógłbyś dokładnie stwierdzić, do kogo
dzwoniłeś, kiedy to było i ile Cię ta rozmowa kosztowała. Mógłbyś wówczas obliczyć, ile pieniędzy wydałeś na rozmowy
z pracownikami danego klienta i na jaką kwotę należy poszczególnych klientów obciążyć.
Mogłoby się wydawać, że takiej obróbki danych można dokonać przy użyciu innych narzędzi niż relacyjna baza danych.
Jednakże z prawidłowo zaprojektowaną bazą danych obróbka ta będzie banalnie łatwa, wiarygodna i szybka.
Tworzenie kwerend wymaga ustalenia różnych właściwości, które nadzorują sposób, w jaki kwerend, się zachowuje
podczas jej uruchamiania. Możesz zacząć od samej kwerendy.
Wszystkie zapisane kwerendy możesz przeglądać, klikając obiekt Kwerendy znajdujący się w oknie Grupy głównego okna
bazy danych. Kliknięcie prawym przyciskiem myszy którejś z pojedynczych kwerend powoduje wyświetlenie
odpowiadającego jej okna dialogowego Właściwości (rysunek 4.1).
Rysunek 4.1.
Okno dialogowe
Właściwości
wybranej kwerendy
Użycie kwerendy
Podobnie jak w przypadku wszystkich innych obiektów baz danych Accessa możesz stosować nazwy o długości nie
przekraczającej 255 znaków. Również wszystkie konwencje nazewnictwa używane w przypadku pozostałych obiektów
mają zastosowanie do kwerend. Okno Właściwości zawiera także informacje o typie danej kwerendy. Możesz tam również
znaleźć jej opis. Jest to bardzo ważna właściwość. Staranny projektant baz danych powinien z niej korzystać tak często, jak
tylko to możliwe. Porządny opis umożliwi Ci stwierdzenie, jaką czynność dana kwerenda miała wykonać. Również inni
programiści docenią wagę opisu, gdy przyjdzie im pracować z utworzoną przez Ciebie kwerendą. Okno Właściwości
zawiera także datę utworzenia kwerendy oraz datę ostatniej modyfikacji, automatycznie aktualizowaną przez Access.
Zgodnie z domyślnym ustawieniem właścicielem kwerendy jest osoba, która ją utworzyła. Ma to znaczenie dla za-
bezpieczeń bazy (temat ten został szczegółowo omówiony w rozdziale 23., „Bezpieczeństwo”). Na dole okna znajdują się
dwa pola wyboru. Zaznaczenie pola Ukryty spowoduje, iż obiekt ten nie będzie widoczny dla użytkowników w głównym
oknie bazy danych. Dzięki temu będziesz mógł zapobiec przypadkowym zmianom tego obiektu.
Pole wyboru Replikowalny informuje, czy dany obiekt jest elementem schematu replikacji, który przygotowałeś dla bazy
danych. Mówimy, że obiekt jest replikowalny, gdy poprzez operację replikacji jest modyfikowany przez inny obiekt,
najczęściej bardziej aktualną wersję samego siebie. Więcej informacji o replikacji znajdziesz w rozdziale 22. „Replikacja i
JRO”.
Właściwości kwerendy
Ponieważ zachowanie kwerendy zależy bezpośrednio od ustawień właściwości, ważnym jest zrozumienie, czym te właściwości
są i jak funkcjonują. Tak więc, zanim przejdziemy do zaawansowanych opcji kwerend, przyjrzyjmy się podstawowym
kwerendom i określeniom, jakich będziemy używać podczas projektowania bardziej zaawansowanych kwerend.
Siatka QBE
Access ułatwia Ci tworzenie kwerend, umożliwiając graficzne ich ułożenie w siatce QBE (rysunek 4.2). Wszystkie źródła
danych, niezależnie od tego czy są to wbudowane czy dołączane tabele, albo nawet inne kwerendy wybierające, mogą być
w taki sam sposób rozmieszczane w siatki QBE. W interfejsie siatki QBE znajdują się relacje między tabelami (tabele i
kwerendy wyglądają w niej tak samo), polecenia sortowania i grupowania oraz kryteria.
Rysunek 4.2.
Siatka QBE
podzielona jest na
dwie podstawowe
części: panel
z tabelami u góry
i siatkę kwerendy
u dołu
Kliknij prawym przyciskiem myszy w dowolnym miejscu okna panelu tabel. Z kontekstowego menu wybierz Właściwości,
aby wyświetlić właściwości kwerendy. Oto lista wszystkich właściwości kwerendy:
u Opis – taka sama właściwość dostępna jest z poziomu obiektu.
u Wyprowadź wszystkie pola – ustawienie tej właściwości na Tak powoduje ten sam skutek co zaznaczenie opcji
Pokaż w każdym polu kwerendy. Dzięki temu również wszystkie pola danej kwerendy są dostępne dla innych
kwerend, formularzy i raportów.
u Najwyższe wartości – jeśli chcesz zobaczyć tylko 5 najdroższych produktów, ustaw tę właściwość. Możesz
używać również wielkości procentowych. Właściwość ta umożliwia wybranie górnych 5, 10, 25 lub 100 rekordów
(albo 5% bądź 25%), lecz możesz ustawić tę opcję w dowolny sposób. Właściwość ta jest stosowana do pola,
które w siatce QBE znajduje się najbardziej z lewej strony. Jeśli w kwerendzie, od lewej do prawej znajdują się
trzy pola ([nazwa produktu], [koszt jednostkowy] i [cena hurtowa]) i chcesz zobaczyć pięć najdroższych produktów,
według [ceny hurtowej], musisz pole [cena hurtowa] posortować malejąco. Jeśli pole [cena jednostkowa] również
posortujesz, pięć górnych elementów będzie wyświetlonych na bazie pola [cena jednostkowa]. Jeśli żadne z pól
nie jest posortowane, pięć pierwszych rekordów będzie przedstawionych bez sortowania.
u Wartości unikatowe – właściwość ta umożliwia otrzymanie reprezentatywnej listy wartości danego pola. Jeśli
podczas pracy z tabelą Zamówienia chcesz zobaczyć, które produkty zostały zamówione, możesz użyć tej
właściwości, aby z setek zamówień wyodrębnić kilkadziesiąt produktów.
u Rekordy unikatowe – właściwość ta jest podobna do właściwości Wartości unikatowe, z tą jednak różnicą, że działa
na wielu polach. Wynik kombinacji tych pól musi być unikatowy.
u Uaktywnij uprawnienia – podczas zabezpieczania bazy danych musisz mieć możliwość zablokowania tabel w taki
sposób, aby użytkownicy nie mogli ich edytować bez Twojej kontroli. Jednocześnie, użytkownicy będą musieli
mieć możliwość pracować z tymi tabelami i zawartymi w nich danymi. Poprzez ustawienie tej właściwości możesz
pozwolić użytkownikowi uruchamiać kwerendę tak, jakby miał uprawnienia właściciela tabeli. W ten sposób, w
zabezpieczonej bazie, użytkownicy mogą w kontrolowany sposób usuwać i aktualizować dane nawet, jeśli
57 Rozdział 4. ♦ Zaawansowane kwerendy
ustawione uprawnienia normalnie by im na to nie pozwalały. Bez tej właściwości trudno jest zabezpieczać dane w
bazie i jednocześnie umożliwiać użytkownikom wykonywanie na nich operacji.
u Źródłowa baza danych – domyślnie ustawiona jest bieżąca baza danych. To domyślne ustawienie dotyczy również
danych dołączanych do innej bazy Accessa. Gdyby dane były umieszczone w innej bazie, z którą nie istniałoby
połączenie, właściwość ta zawierałaby ścieżkę dostępu i nazwę pliku.
u Źródłowy ciąg połączenia – właściwość ta zawiera nazwę aplikacji, której użyto do tworzenia zewnętrznego źródła
bazy danych. Obie właściwości, Źródłowa baza danych i Źródłowy ciąg połączenia, umożliwiają Accessowi użycie
zewnętrznych, niepołączonych danych.
u Blokowanie rekordów – właściwość ta umożliwia określenie, w jaki sposób kwerenda będzie w systemie
wieloużytkownikowym rozwiązywać kwestie wielodostępu. Problem taki pojawia się, gdy dwóch lub więcej
użytkowników spróbuje dokonać zmian w tym samym rekordzie. Istnieją trzy opcje dla tej właściwości – Bez
blokowania, Wszystkie rekordy i Edytowany rekord. Opcje te dotyczą jedynie rekordów związanych z działaniem
kwerendy, a nie wszystkich rekordów źródłowej tabeli. Jeśli wybrana została opcja Bez blokowania, możliwe jest
dokonywanie zmian w rekordzie przez jednego użytkownika, podczas gdy pracują z nim inni użytkownicy.
Pierwszy z nich, który zapisze zmiany na dysku – wygrywa. Access ostrzega użytkowników, że pracują z rekor-
dem, który został zmieniony przez innego użytkownika. Każdy z nich musi zdecydować, jak rozwiązać tę kwestię.
Istnieją następujące możliwości – zrezygnować z własnych zmian, nadpisać zmiany innego użytkownika lub też
skopiować zmiany do Schowka i później zdecydować, co robić dalej. Po wybraniu opcji Wszystkie rekordy inni
użytkownicy nie będą mogli edytować rekordów kontrolowanych przez tę kwerendę, dopóki pierwszy użytkownik
nie zakończy pracy. Opcja Edytowany rekord dotyczy jedynie rekordu w danym momencie edytowanego przez
użytkownika.
u Typ zestawu rekordów – właściwość ta pozwala na określenie, czy używany przez formularz bądź raport zestaw
rekordów to Dynamiczny, Dynamiczny (Niespójny) czy Migawka. Opcja Dynamiczny umożliwia aktualizowanie w
relacji strony Wiele. Ustawienie Dynamiczny (Niespójny) umożliwia aktualizowanie obu stron relacji. Ważnym
jest zapamiętanie, że użycie opcji Dynamiczny (Niespójny) może mieć poważny wpływ na integralność danych.
Najlepiej korzystać z tego ustawienia w momencie, gdy relacja ma włączone wymuszanie więzów integralności i
kaskadowe aktualizowanie rekordów i to dopiero po przeprowadzeniu dokładnych testów. Ustawienie Migawka
uniemożliwia użytkownikom edytowanie danych, jednakże kwerenda działa wówczas szybciej niż w przypadku
dynamicznego zestawu rekordów. Każdy z powyższych wyborów ma wpływ na wydajność i możliwości
edytowania danych.
u Czas oczekiwania ODBC – jeśli kwerenda ma korzystać z sieci, właściwość ta określa, jak długo kwerenda ma
czekać na rezultaty. Jednostką miary jest sekunda, a domyślne ustawienie to 60 sekund. Mimo iż możesz zmieniać
tę liczbę, inne zmienne będą miały wpływ na wydajność. Obciążenie sieci i sposób buforowania plików na
serwerze mogą powodować ciągłe zmiany czasu odpowiedzi. Tak więc ustawienie tej wartości musi się odbyć
metodą prób i błędów. Ważne, by nie ustawić zbyt długiego oczekiwania, gdyż może się zdarzyć, że użytkownik
oczekuje na rezultaty, podczas gdy serwer faktycznie nie działa.
u Filtr – doskonałe narzędzie programistyczne dla początkujących. Coś jak automatyczny konstruktor kwerend. Jeśli
użytkownik uruchamia kwerendę, a następnie musi ograniczyć rezultaty, może wybrać wartość w zestawie
rezultatów i użyć przycisków filtra, aby wypełnić tę właściwość tak, by przypominała kryteria. Tego wszystkiego
może dokonać, nie znając składni sekcji kryteria tabeli QBE.
u Uporządkuj według – ta przypominająca Filtr właściwość umożliwia początkującym użytkownikom uruchomić
kwerendę, a następnie zmienić sposób sortowania jej rezultatów poprzez wybranie wartości w zestawie rezultatów.
Polecenie dla tego sortowania zawarte jest w tej właściwości.
u Maksymalna liczba rekordów – wpisanie wartości liczbowej w tym polu ogranicza liczbę zwracanych przez
kwerendę rekordów, niezależnie od tego ile rekordów w rzeczywistości spełnia kryteria kwerendy. Jeśli kwerenda
normalnie zwraca 500 rekordów, a właściwość ta ustawiona jest na 17, to kwerenda zwróci jedynie pierwszych 17
rekordów. Nie ma możliwości otrzymania dodatkowych rekordów bez zmiany tej właściwości.
u Nazwa podarkusza danych (NOWOŚĆ) – to jedna z nowych właściwości w Accessie 2000. Możesz dzięki niej
tworzyć kwerendy, które umożliwią Ci dogłębną analizę danych. Gdy utworzyłeś kwerendę wyświetlającą
wielkość sprzedaży według produktów, możesz ustawić tę właściwość na tabelę lub kwerendę zawierającą opisy
zamówień. Po uruchomieniu kwerendy zobaczysz podsumowanie wielkości sprzedaży według produktów oraz
przycisk, po kliknięciu którego zobaczysz szczegóły składające się na tę sumę.
u Podrzędne pole łączące (NOWOŚĆ) – jest to pole podarkusza danych, najczęściej pole klucza, które odpowiada
polu w głównej kwerendzie.
u Nadrzędne pole łączące (NOWOŚĆ) – jest to pole głównej kwerendy, najczęściej pole klucza, które odpowiada
polu w podarkuszu danych. Aby podarkusz danych działał, pole to musi być widoczne w rezultatach kwerendy.
Część I ♦ Projektowanie bazy danych 58
u Wysokość podarkusza danych (NOWOŚĆ) – wartość w calach, określająca wysokość wyświetlanego podarkusza
danych.
u Rozwinięty podarkusz danych (NOWOŚĆ) – jeśli właściwość ta ustawiona jest na Tak, szczegóły podarkusza
danych będą wyświetlane po otwarciu kwerendy. Jeśli ustawiona jest na Nie, użytkownik będzie musiał nacisnąć
przycisk, aby przejść do szczegółów podarkusza.
Panel tabel
Wszystkie tabele i kwerendy użyte w danej kwerendzie znajdują się w górnym panelu okna – panelu tabel. Wyświetlane są
jako niewielkie, zawierające listę pól okna. Jeśli w panelu tym umieścisz kwerendę, wyświetlone zostaną jedynie pola,
które mają być umieszczone w rezultatach tej kwerendy. Linia między tabelami przedstawia istniejącą między nimi relację.
Relacje ustawione w oknie dialogowym Relacje są tu wyświetlane automatycznie. Funkcja ta nazywa się Autosprzęganie i
pozwala Accessowi zakładać istnienie powiązań między polami o tej samej nazwie i tym samym lub kompatybilnym typie
danych. Autosprzęganie niespodziewanie tworzy między nimi kwerendę. Może się zdarzyć, że dwa pola o tej samej nazwie
nie pozostają ze sobą w relacji, więc sprawdź
wszystkie relacje w kwerendzie przed jej użyciem. Możesz wyłączyć Autosprzęganie, otwierając z poziomu menu
Narzędzia okno dialogowe Opcje. Opcja Włącz autosprzęganie znajduje się na zakładce Tabele/Kwerendy.
Górna część okna kwerendy jest dość duża, więc możesz rozszerzać tabele, klikając i przeciągając ich krawędzie. Jeśli
kwerenda korzysta z wielu tabel, możliwe jest przesuwanie zawartości okna, dzięki czemu tabele są dobrze widoczne.
Możesz również skorzystać z tej przestrzeni i umieścić w niej mniej ważne tabele (np. tabele odnośników), co pozwoli Ci
zlikwidować bałagan w tym oknie.
Do linii sprzężenia mogą być również dołączone takie znaki jak symbol nieskończoności czy cyfra 1. Znaki te informują Cię
o charakterze relacji między polami i wyświetlane są, gdy relacja została utworzona na poziomie bazy danych. Jeśli
tworzysz relację na poziomie bazy danych, masz do dyspozycji trzy typy relacji: jeden do jednego, jeden do wielu i wiele
do wielu. Linia sprzężenia przedstawia charakter relacji poprzez umieszczenie cyfry 1 po stronie jednej relacji i symbolu
nieskończoności po stronie wielu. Każdy znak może się znajdować po obu stronach relacji. Istnienie tych znaków nie musi
oznaczać, iż faktycznie po stronie jeden występuje jeden rekord, a po stronie wielu jest ich kilka. Określają one jedynie
potencjał relacji danych. Ich zadaniem jest pomóc w zdecydowaniu, co z daną kwerendą można zrobić.
Jak wszystkie obiekty linia sprzężenia również ma swoje właściwości. W przypadku większości z nich po kliknięciu
obiektu prawym klawiszem myszy wyświetlone zostaje menu kontekstowe, z którego można wybrać opcję Właściwości.
Właściwości linii sprzężenia wyświetlane są po dwukrotnym kliknięciu linii lewym przyciskiem myszy. Jeśli relacja
została utworzona na poziomie bazy danych, możesz z menu Widok wybrać pozycję Właściwości sprzężenia. Czynność tę
przedstawia rysunek 4.3.
Rysunek 4.3.
Możesz otworzyć
okno Właściwości
sprzężenia, klikając
dwukrotnie jego linię
Okno właściwości sprzężenia różni się od okien właściwości innych obiektów. Zawiera ono cztery rozwijane listy (dwie z
nazwami tabel i dwie z nazwami pól) oraz trzy, wzajemnie wykluczające się pola wyboru. Określają one typ tworzonej
relacji. Są to następujące opcje:
u Sprzężenie wewnętrzne – jest to ustawienie domyślne. Ten typ relacji przedstawia prosta linia między dwoma
polami. Rezultatem kwerendy z relacją ustaloną na bazie sprzężenia wewnętrznego będą wszystkie rekordy, w
których dwa, objęte relacją pola są takie same. Innymi słowy, jeśli kwerenda zawierała klientów i zamówienia,
połączone poprzez pola IDklienta, w rezultatach kwerendy znaleźliby się jedynie klienci, którzy złożyli
zamówienia i zamówienia powiązane z klientami w tabeli Klienci.
u Lewe sprzężenie zewnętrzne (ang. outer join) – linia przedstawiająca to sprzężenie będzie z jednej strony
zakończona strzałką. Ten typ sprzężenia pozwala dominować jednej ze stron. Dominująca strona relacji wskazuje
na stronę podporządkowaną. Oznacza to, że kwerenda z Klientami i Zamówieniami, gdzie występowałoby lewe
sprzężenie zewnętrzne (linia sprzężenia skierowana w stronę tabeli Zamówienia), wyświetliłaby wszystkich
klientów, niezależnie od tego, czy składali jakiekolwiek zamówienia. Jednakże nie wyświetliłaby zamówień
nieprzyporządkowanych do żadnego z klientów.
u Prawe sprzężenie zewnętrzne – linia przedstawiająca to sprzężenie również będzie zakończona strzałką z jednej
strony. Ten typ relacji również pozwala jednej ze stron dominować. Dominująca strona relacji wskazuje na stronę
podporządkowaną. Kwerenda z Klientami i Zamówieniami, gdzie występowałoby prawe sprzężenie zewnętrzne
(linia sprzężenia skierowana w stronę tabeli Klienci), wyświetlałaby wszystkie złożone zamówienia, niezależnie od
tego, czy były składane przez określonych klientów. Jednakże nie wyświetliłaby klientów, którzy nie składali
zamówień.
Rozwijane listy w tym oknie dialogowym umożliwiają określenie, których tabel i pól po odpowiedniej stronie sprzężenie
ma dotyczyć. Jest to nowe rozwiązanie. Wcześniej, lewa i prawa strona relacji były przedmiotem zmian w zależności od
sposobu zbudowania kwerendy. W większości przypadków, integralność referencyjna wymusza użycie prawego bądź
lewego sprzężenia zewnętrznego. To tak, jakbyś mógł otrzymać klientów, którzy nie składali zamówień, ale nie mógł
jednocześnie otrzymywać zamówień, do których nie ma przyporządkowanych klientów. Jeśli uda Ci się otrzymać nie-
przyporządkowane rekordy w wyniku zarówno prawego jak i lewego sprzężenia zewnętrznego tej samej relacji, to znaczy,
że coś jest nie w porządku z integralnością danych. Rekordy znajdujące się po podporządkowanej stronie relacji i nie
posiadające pary po stronie dominującej nazywamy rekordami osieroconymi. Rekordy zagubione są zazwyczaj niewidocz-
ne podczas zwykłych operacji dokonywanych na bazie danych, jednakże wywołują statystyczne niezgodności w sytuacji,
gdy kwerenda oparta jest na podporządkowanej tabeli, bez użycia tabeli dominującej. Innymi słowy, raporty o
zamówieniach poszczególnych produktów mogą nie zgadzać się z raportami o zamówieniach według klientów.
Ważne, by nie myliły Ci się pojęcia lewe sprzężenie i prawe sprzężenie. Może się zdarzyć, że w tabeli QBE lewe sprzężenie
będzie wskazywać w prawo, a prawe w lewo. Jest to mylące zwłaszcza wtedy, gdy już kontrolujesz to, co jest po prawej i to
co po lewej stronie. Najważniejsze, byś pamiętał, że dominująca strona wyświetla wszystkie rekordy, nawet jeśli nie
odpowiadają one żadnym rekordom ze strony podporządkowanej.
Część I ♦ Projektowanie bazy danych 60
Inna z opcji w tym oknie dialogowym umożliwia tworzenie za jego pomocą kolejnej relacji. Kliknięcie przycisku Nowe
spowoduje wyświetlenie okna dialogowego, z poziomu którego możesz niespodziewanie ustanowić relację między
istniejącymi tabelami.
Poniższe rysunki przedstawiają różne rezultaty kwerendy opartej na tabelach Klienci i Zamówienia. Rezultaty sprzężenia
wewnętrznego znajdują się na rysunku 4.4, a odpowiadające mu wyrażenie SQL na wydruku 4.1.
Rysunek 4.4.
Dziesięciu klientów
z najmniejszą ilością
zamówień
w sprzężeniu
wewnętrznym
Kwerenda ta przedstawia ilość zamówień każdego z klientów i używa sprzężenia wewnętrznego, więc wyświetlane są
jedynie rekordy mające swoje odpowiedniki po obu stronach relacji.
Rysunek 4.5.
Dwunastu klientów
z najmniejszą ilością
zamówień
w sprzężeniu
zewnętrznym
Rysunek 4.4 wygląda zwyczajnie; wszystko wydaje się być w porządku, ale rezultaty kwerendy nie są prawdziwe.
Sprzężenie wewnętrzne na rysunku 4.5 wskazuje, iż istnieją dwaj klienci, którzy nie składali żadnych zamówień i nie zostali
uwzględnieni w rezultatach kwerendy ze sprzężeniem wewnętrznym. Ponieważ pole wyświetlane po stronie Zamówienia
jest sumowane, pokazywany rezultat to zero. Normalnie, brakujący rekord po stronie podporządkowanej byłby
przedstawiony jako Null.
Kwerenda pokazująca rekordy nie posiadające swoich odpowiedników to po prostu sprzężenie zewnętrzne z kryterium
klucza obcego ustawionym na Null. Bez takiego ustawienia kryterium mógłbyś pośród wszystkich rekordów przeoczyć
tych kilka pustych pól. Przykład takiej sytuacji przedstawia rysunek 4.6 i wydruk 4.3.
Rysunek 4.6.
Klienci, którzy nie
składali zamówień
Kwerenda wyświetla dwa rekordy zamiast dziesięciu lub dwunastu, jak to miało miejsce w przypadku braku ustawienia
kryterium Null na kluczu obcym.
Podsumowując, nie wystarczy, że właściwe pola w odpowiednich tabelach połączone są relacją. Typ tej relacji musi być
odpowiedni, by zapewnić zgodny z prawdą zestaw rezultatów kwerendy. Dwie kwerendy oparte na tych samych
tabelach i polach mogą dawać zupełnie różne rezultaty, jeśli typ relacji między polami jest różny. Wyrażenia SQL kwe-
rend na rysunkach 4.4 i 4.5 różnią się tylko jednym słowem (spójrz na rysunki 4.7 i 4.8). Jeśli w przykładzie Northwind
występowałby rekord zagubiony, inne wyrażenie SQL mogłoby spowodować jego wyświetlenie, po zmianie słowa Left
(lewe) na Inner (wewnętrzne) (równie dobrze słowo Inner można zamienić na Right (prawe)). Po raz kolejny
otrzymujemy zupełnie inny zestaw rezultatów, zmieniając w relacji zaledwie jedno słowo.
Rysunek 4.7.
SQL dla sprzężenia
wewnętrznego
Rysunek 4.8.
Dziesięciu\ klientów
z najmniejszą ilością
zamówień
w sprzężeniu
wewnętrznym
Ponieważ istnieją rekordy z takimi samymi wartościami, kwerenda wyświetla 12 rekordów, mimo iż żądano 10
najwyższych.
Łatwiej jest zaznaczyć przekątną linię sprzężenia niż pionową czy poziomą.
Przemieszczanie tabel lub przesuwanie ich pól może ułatwić Ci wybieranie
linii sprzężenia.
Siatka kwerendy
W dolnej połowie okna znajduje się tabela kwerendy. Tutaj możesz wybrać pola, które mają być widoczne w rezultatach
kwerendy, kolejność sortowania, informacje o grupowaniu, obliczenia, informacje o aktualizacji i dołączaniu oraz
kryteriach, według których kwerenda będzie wybierać rekordy. Tutaj odbywa się największa część pracy związanej z
tworzeniem kwerendy.
Część I ♦ Projektowanie bazy danych 62
Użycie drugiego wiersza siatki QBE jest opcjonalne, jednakże w Accessie 2000 jest on stale wyświetlany. Wiersz Tabela
wskazuje projektantowi kwerendy, z której tabeli dane pole pochodzi. Ułatwia to pracę, gdy w więcej niż jednej tabeli
występują pola o podobnych nazwach. Możesz użyć tego wiersza, aby szybko zmienić tabelę źródłową dla dowolnego z
pól w siatce QBE.
Czwarty wiersz określa, czy pole jest wyświetlane w rezultatach kwerendy. Nawet, jeśli pole nie jest wyświetlane, wciąż
może wpływać na rezultaty kwerendy. Aby kwerenda była wykonywana, co najmniej jedno pole musi być wyświetlane w
jej rezultatach.
Piąty i wszystkie pozostałe wiersze przeznaczone są dla warunków. Wiersze dotyczące warunków zawierają wartości
służące do wybierania wierszy do zestawu rekordów. Mogą również zawierać procedury SQL, jednakże technika ta nie jest
zalecana, gdyż procedury SQL muszą być wykonywane dla każdego rekordu w możliwym zestawie rezultatów kwerendy,
zanim zostanie wyświetlony rezultat końcowy. Zazwyczaj ten sam efekt można uzyskać przez użycie podkwerend.
Jeśli zajdzie taka potrzeba, do tabeli QBE możesz dodać kolejny wiersz: Podsumowanie. Aby uzyskać dostęp do tego
wiersza kliknij znajdujący się na pasku narzędzi przycisk Sumy lub wybierz tę opcję z menu Widok. Włączenie opcji Sumy
zmienia nieco charakter kwerendy. Te zagregowane kwerendy pozwalają Ci na twórcze kształtowanie zestawu rezultatów.
Szczegóły użycia wiersza Podsumowanie omówione zostaną w następnej części tego rozdziału.
Kwerendy podsumowujące
Zazwyczaj zestaw rezultatów kwerendy zawiera tak wiele informacji, że jest dla użytkownika bezużyteczny. Aby to
zmienić, Access umożliwia Ci tworzenie podsumowania danych za pomocą kwerend podsumowujących.
63 Rozdział 4. ♦ Zaawansowane kwerendy
Aby utworzyć podsumowanie klientów i ich zakupów, możesz w dołączonej do Accessa 2000 bazie Northwind utworzyć
nową kwerendę. Gdy skończysz, kwerenda będzie wyświetlać listę klientów i zakupionych przez nich produktów jako listę
unikatowych kombinacji.
Aby rozpocząć pracę z tą kwerendą, umieść w panelu tabel następujące tabele: Klienci, Zamówienia, Opisy zamówień i
Produkty.
Z tabeli Klienci przenieś do siatki kwerendy pole NazwaFirmy, a z tabeli Produkty – pole NazwaProduktu. Posortuj
kwerendę według NazwaFirmy i NazwaProduktu. Uruchom kwerendę, klikając znajdujący się na pasku narzędzi symbol
czerwonego wykrzyknika lub wybierając Kwerenda⇒Uruchom. Jeśli dokładnie przyjrzysz się rysunkowi 4.9, zauważysz,
że niektórzy z klientów występują w zestawie rezultatów więcej niż raz. Wyrażenie SQL dla rysunku 4.9 znajduje się na
wydruku 4.6.
Rysunek 4.9.
Niektórzy klienci
pojawiają się
kilkakrotnie dla tego
samego produktu,
gdyż zamówili go
więcej niż raz
Powróć do widoku Projekt kwerendy i kliknij znajdujący się na pasku narzędzi przycisk Sumy lub wybierz tę opcję z menu
Widok. Wiersz podsumowania pojawi się w siatce kwerendy z wybraną dla obu pól opcją Grupuj według. Oznacza to, że
kwerenda zmniejszy rozmiar zestawu rekordów tak, by wyświetlał tylko jeden raz każdą kombinację wartości NazwaFirmy
i NazwaProduktu. Uruchom kwerendę ponownie, a zobaczysz, że nazwy firm i produktów się nie powtarzają.
Spowodowało to usunięcie z zestawu setek rekordów.
Możesz korzystać z opcji Grupuj według nawet dla dziesięciu pól, pamiętaj jednak, że użycie tej opcji dla każdego
zbędnego pola spowalnia pracę kwerendy i powoduje wyświetlenie dodatkowych wierszy w zestawie rezultatów. Używaj
opcji Grupuj według tylko dla pól, które są niezbędne dla uzyskania pożądanych rezultatów. W polu z zaznaczoną opcją
Grupuj według nie możesz wprowadzać wartości [nazwatabeli].*.
Opcja Sumy jest rozbudowana i posiada wiele innych możliwości. Wprowadzając do kwerendy wiersz Podsumowanie,
masz do dyspozycji dwanaście opcji. Dziewięć z nich to funkcje agregujące, co oznacza, że wykonują one na danych różne
obliczenia. Teraz przyjrzymy się każdej z nich.
Gdy uruchamiasz kwerendę agregującą ważne jest, by nie znajdowało się w niej nic zbędnego. Prawie wszystko co
znajduje się w siatce QBE może mieć wpływ na działanie funkcji agregującej. Jeśli nie usuniesz tych tabel (mimo iż nie
Część I ♦ Projektowanie bazy danych 64
używasz ich w siatce QBE), spowodują one, że kwerenda będzie zliczać wszystkie zamówione produkty, a nie zamówienia
(rysunek 4.10 i wydruk 4.7).
Rysunek 4.10.
Zliczanie zamówień
klientów
Zauważ, że na rysunku 4.10 nie zachodzi potrzeba określenia kolejności sortowania. Prosta kwerenda agregująca sama
sortuje rezultaty według pola grupowania. Jeśli nie określisz kolejności sortowania, określana jest ona przez położenie od
lewej do prawej strony pól z opcją Grupuj według.
Rysunek 4.11.
Siatka QBE
kwerendy
obliczającej średnią
Funkcja agregująca Średnia działa zarówno na polach typu Liczba, Data/Godzina, Walutowy i Autonumerowanie i
wyświetla średnią wartość danej grupy pól.
sposób tabeli da subiektywne wyniki. Stanie się tak dlatego, że dla funkcji Pierwszy i Ostatni najważniejsza jest kolejność
przedstawienia pól, a powiązania danych z innymi polami są nieważne.
Funkcji tych użyjesz, aby uzyskać listę najdroższych produktów w każdej kategorii. Lista ta będzie zawierać pola
NazwaKategorii, NazwaProduktu i CenaJednostkowa. Utwórz nową kwerendę, opartą na tabelach Kategorie i Produkty. W
siatce QBE umieść pole NazwaKategorii z tabeli Kategorie oraz pola NazwaProduktu i CenaJednostkowa z tabeli Produkty.
Ustaw kolejność sortowania pola NazwaKategorii na Rosnąco i CenaJednostkowa na Malejąco.
Z menu Kwerenda wybierz Kwerenda tworząca tabele i nazwij nową tabelę Kategorie i Produkty Sortowane według Ceny.
Uruchom kwerendę. W nowej tabeli powinno znaleźć się ponad 70 nowych rekordów. Teraz możesz utworzyć kwerendę
korzystającą z funkcji Pierwszy i Ostatni.
Utwórz nową kwerendę i wyświetl w panelu tabelę Kategorie i Produkty sortowane według ceny. Wszystkie jej pola umieść
w siatce kwerendy. Dodaj wiersz Podsumowanie i ustaw funkcję agregującą w polu NazwaProduktu na Pierwszy, a
następnie w polu CenaJednostkowa również na Pierwszy. Uruchom kwerendę, a zobaczysz najdroższy produkt w każdej
kategorii. Jeśli funkcje Pierwszy zamienisz na Ostatni, zobaczysz najtańszy produkt w każdej kategorii. Ustawienie jednego
z pól na Pierwszy, a drugiego na Ostatni pokaże, jak funkcje te pobierają dane z różnych wierszy w zestawie rekordów, ale
przedstawia je tak, jakby były częścią tego samego rekordu. Spróbuj użyć takiej samej kwerendy na początkowej tabeli, a
zobaczysz jak bardzo funkcje Pierwszy i Ostatni zależą od uprzedniego sortowania. Aby funkcje Pierwszy i Ostatni działały
efektywnie, sortowanie rekordów musi być wykonane świadomie (tak jak zrobiliśmy to w tymczasowej tabeli) lub poprzez
indeksy tabel. W tym konkretnym przykładzie, funkcje Pierwszy i Ostatni mogłyby być zastąpione przez Minimum i
Maksimum, jednakże w przypadku pola NazwaProduktu możliwe byłoby jedynie użycie tych pierwszych.
Funkcja Wyrażenie
Wyrażenie umożliwia przedstawienie obliczeń w rezultatach kwerendy, jednakże obliczenia te muszą zawierać funkcję
agregującą. Używaj tej opcji, gdy chcesz w kwerendzie przedstawić wynik wielu funkcji. Przykładowe wyrażenie znajduje
się na rysunku 4.12 (wyrażenie SQL na wydruku 4.9).
Rysunek 4.12.
Zestaw rezultatów
z wyrażeniem
W tym przykładzie zliczasz produkty, a następnie podnosisz średnią cenę każdej kategorii o 5%. Aby tego dokonać,
ustawiasz wartość wiersza Podsumowanie danego pola na Wyrażenie, a następnie zapisujesz wzór używający funkcji
agregującej. Jeśli w zapisanym wyrażeniu brak będzie funkcji agregującej, Access wyświetli komunikat o błędzie, a
kwerenda nie zostanie wykonana.
Warunek Gdzie
Zastosowanie kryteriów w kwerendzie agregującej odbywa się przez użycie polecenia Gdzie lub przez wprowadzenie
kryteriów do siatki QBE, jak to ma miejsce w przypadku zwykłej kwerendy wybierającej. Istnieją jednak różnice między
tymi sposobami i wybór ich może mieć wpływ na zachowanie kwerendy. Podczas użycia polecenia Gdzie kwerenda
najpierw stosuje kryteria, dołączając lub wyłączając rekordy, zanim zostaną one pogrupowane.
Jeśli wprowadzisz kryteria w innym polu bez użycia polecenia Gdzie, kryteria będą stosowane dopiero po zakończeniu
grupowania. Przed kryteriami wyrażonymi bez użycia polecenia Gdzie, w SQL występować będzie polecenie Having.
Różnice są proste, lecz bardzo ważne. Jeśli z kwerendy agregującej chcesz usunąć sprzedaż zagraniczną, użyj polecenia
Gdzie. Jeśli chcesz jednocześnie zobaczyć jedynie rezultaty, których wynik zliczania jest wyższy niż 1000, wyraź to w polu
wykonującym polecenie Policz. Kryterium wykluczające sprzedaż zagraniczną powinno być wpisane w siatce kwerendy
dla pola KrajOdbiorcy i wyrażone w SQL za pomocą wyrażenia Having. Polecenie Having przydaje się przy stosowaniu
kryteriów na dokonanych obliczeniach. Przykłady użycia tego polecenia znajdują się na rysunku 4.13 i wydruku 4.10.
Rysunek 4.13.
Kwerenda używająca
pleceń Where
i Having
w siatce QBE
Prosta kwerenda krzyżowa składa się przynajmniej z trzech elementów: Nagłówka wiersza, Nagłówka kolumny i Wartości.
Kwerenda ta może korzystać z zestawu rezultatów dowolnej kwerendy wybierającej.
Aby utworzyć kwerendę krzyżową, w wyniku której podzielimy klientów według kategorii zamawianych produktów, będziemy
potrzebować następujących tabel: Klienci, Kategorie, Produkty, Zamówienia i Opisy zamówień. Z tabeli Klienci wybierz pole
NazwaFirmy, z tabeli Kategorie pole NazwaKategorii, a z tabeli Opisy zamówień pole Ilość.
Aby kwerendę wybierającą przekształcić w krzyżową, wybierz z menu Kwerenda opcję Kwerenda krzyżowa. Po
przekształceniu w siatce kwerendy pojawi się nowy wiersz (rysunek 4.14 i wydruk 4.11). Wiersz ten umożliwi Ci
przyporządkowanie pola do odpowiednich elementów kwerendy krzyżowej. Pole NazwaFirmy ustaw jako Nagłówek wier-
sza, pole NazwaKategorii jako Nagłówek kolumny (ta część będzie wyświetlana u góry zestawu rezultatów), pole Ilość jako
Wartość, a w wierszu Podsumowanie tego pola wybierz Suma. Po uruchomieniu kwerendy Access automatycznie utworzy
sumę na każdym przecięciu klienta i produktu.
Rysunek 4.14.
Kwerenda krzyżowa
w siatce QBE
Możliwe jest ustawienie w kwerendzie krzyżowej więcej niż jednego pola jako Nagłówka wiersza, jednakże może być tylko
jeden Nagłówek kolumny i jedna Wartość. To dałoby hierarchiczny widok danych, ze wzrastającym stopniem
szczegółowości wraz z przesuwaniem się od lewej do prawej. Aby zobaczyć jak to działa, możesz jako Nagłówki wiersza
dodać pola Kraj i Region.
W polu Wartość możesz wprowadzić również własne obliczenia. Zamień w siatce Ilość na następujące wyrażenie:
Expr1: IIF(Sum([Ilość])>=50, "High", "Low")
Ten fragment kodu korzysta z funkcji agregującej, aby wyświetlić wartość w kwerendzie krzyżowej.
Część I ♦ Projektowanie bazy danych 68
W wierszu Podsumowanie dla tego pola ustaw wartość Wyrażenie. Po uruchomieniu kwerendy w tabeli zobaczysz wynik
IIf(). Wyrażenia, które tworzysz w kwerendzie krzyżowej, muszą być kompatybilne z wyrażeniami, które napisałbyś dla
innej kwerendy agregującej.
W podobny sposób kwerenda może zawierać wynik wyrażenia w nagłówku wiersza bądź kolumny. Poniższa kwerenda
(przedstawiona na rysunkach 4.15 i 4.16 oraz wydruku 4.12) korzysta z wyrażenia, aby podzielić dane w nagłówkach
kolumn na ćwiartki. Wyrażenie przestawne wygląda w następujący sposób:
"Q" & CStr(DatePart("Q", [OrderDate]))
Aby kwerenda krzyżowa uwzględniła dokonane zmiany, musisz ją zamknąć i na nowo otworzyć.
Rysunek 4.15.
Zmodyfikowana
kwerenda krzyżowa
w siatce QBE
Rysunek 4.16.
Zestaw rezultatów
zmodyfikowanej
kwerendy krzyżowej
69 Rozdział 4. ♦ Zaawansowane kwerendy
Rysunek 4.17.
Podstawa dla prostej
kwerendy
parametrycznej
Gdy uruchomisz tę kwerendę, otrzymasz listę wszystkich klientów, ich przedstawicieli oraz wszystkich numerów
telefonów. Można jednak wprowadzić wartość kryterium w taki sposób, aby uzyskać informacje o przedstawicielu
konkretnego klienta. Ilustruje to rysunek 4.18 i wydruk 4.14.
Działa całkiem nieźle, jednakże dość męczące jest każdorazowe modyfikowanie kryteriów i uruchamianie kwerendy.
Rozwiązanie to jest także mało praktyczne, jeśli z tej aplikacji mają korzystać osoby nie zaznajomione z siatką QBE
Accessa. Zamiast tego możesz utworzyć parametr dla tej kwerendy i pozwolić mu funkcjonować jako prymitywny interfejs
dla użytkowników. Dzięki użyciu kwerendy parametrycznej kryteria są zmieniane, a użytkownicy nie muszą borykać się z
projektowaniem kwerendy.
Część I ♦ Projektowanie bazy danych 70
Rysunek 4.18.
Kwerenda z prostym
kryterium
w siatce QBE
W kwerendzie opartej na tabelach Klienci, Zamówienia, Opisy zamówień i Produkty umieść pola IDklienta, NazwaFirmy,
DataZamówienia, NazwaProduktu, CenaJednostkowa, Ilość i Rabat. Posortuj kwerendę malejąco według DataZamówienia i
rosnąco według NazwaProduktu. Z menu Kwerenda wybierz opcję Parametry. Wprowadź pierwszy parametr jako ID klienta
z typem danych tekst. W pierwszej linii sekcji kryteria pola IDklienta wprowadź [ID klienta]. Jest to informacja dla
kwerendy, że ma akceptować parametr tekstowy nazwany ID klienta i użyć go w kwerendzie jako kryterium pola IDklienta.
Ta kwerenda parametryczna przedstawiona jest na rysunku 4.19, a odpowiadające jej wyrażenie SQL na wydruku 4.15.
Uruchom kwerendę i w odpowiedzi na pytanie o parametr wpisz Quick. W zestawie rezultatów znajdą się wszystkie
rekordy, w których IDklienta to Quick.
Parametrem może być zdanie o maksymalnej długości 255 znaków. Umożliwia to zadawanie użytkownikom pytań o
kryteria w bardziej zrozumiały lub po prostu bardziej grzeczny sposób. Zmień parametr i sposób jego przedstawienia na
Proszę wprowadzić kod klienta.
End Function
Kwerendy przekazujące
Access posiada umiejętność łączenia tabel z innych źródeł danych i tworzenia opartych na nich kwerend tak, jakby były
utworzone w Accessie. Oprócz tego, Access może również przesyłać kwerendy do innych baz danych. W takiej sytuacji,
obca baza sama przetwarza swoje dane i zwraca jedynie zestaw rezultatów.
Głównymi przyczynami, dla których warto używać kwerend przekazujących, są: wydajność i przepustowość sieci. Gdy
dołączasz tabelę z bazy typu klient-serwer (np. SQL Server lub Oracle) i uruchamiasz kwerendę opartą na tej tabeli, serwer
nie jest w stanie stwierdzić, czego od niego oczekujesz. Nawet, gdyby serwer mógł zobaczyć procedurę SQL Accessa, nie
mógłby jej zinterpretować, gdyż jest napisana w innym dialekcie SQL niż ten używany przez serwery. Wówczas serwer
może tylko przesłać olbrzymie ilości informacji na komputer klienta i pozostawić wszystkie obliczenia silnikowi Jet. W
przypadku dużych baz operacja taka może spowolnić działanie sieci i w żadnym wypadku nie można jej nazwać
efektywnym korzystaniem z serwera. Zamiast tego, możesz, korzystając z kwerendy przekazującej, „spotkać” serwer w pół
drogi.
Kwerenda przekazująca jest jedną z kwerend charakterystycznych dla języka SQL, co oznacza, że będziesz musiał ją
napisać w SQL. A tak właściwie, to w dialekcie SQL serwera. Wiele opcji, z których możesz korzystać w Accessie, nie jest
dostępnych w kwerendach przekazujących. Jednakże wzrost prędkości i zmniejszenie obciążenia sieci zrekompensują to z
nawiązką.
73 Rozdział 4. ♦ Zaawansowane kwerendy
ODBC (Open Database Connectivity) to przedrostek ciągu połączenia. Poprzedza on zawsze ciągi połączenia do baz danych
SQL Server, Oracle, Informix i Sybase. Każde źródło danych ODBC używa sterownika, aby tłumaczyć polecenia ODBC.
Nazwa zazwyczaj przypomina nazwę oprogramowania serwera. Server to właściwy adres, pod którym znajduje się baza
danych. UID (User ID) informuje serwer, kim jesteś. W ciągu połączenia może być również przechowywane hasło,
jednakże nie jest to zalecane. Na jednym serwerze może znajdować się wiele baz danych. Warunek Database wskazuje
kwerendzie odpowiednią bazę. Trusted Connection umożliwia dostanie się do serwera, jeśli masz na nim utworzony
profil, któremu serwer „ufa”.
Jeśli nie jesteś pewien, jak ciąg połączenia powinien wyglądać, skontaktuj się z administratorem bazy danych lub skopiuj
ciąg połączenia z dołączonej tabeli. Następnie wklej go do właściwości ciągu połączenia kwerendy i zmodyfikuj opisane
wcześniej właściwości.
Po ustawieniu właściwości możesz wprowadzić wyrażenie SQL o składni właściwej dla serwera, do którego adresowana
będzie kwerenda. Oto przykład prostego wyrażenia SQL dla bazy SQL Server. Rezultat przedstawiony jest na rysunku
4.20.
Select * from klienci Where Kraj = 'USA'
Rysunek 4.20.
Wynik kwerendy
przekazującej SQL
Teraz siecią przesyłany jest jedynie zestaw rezultatów, ponieważ całą pracę wykonał serwer. Następnym krokiem jest
stworzenie widoków i procedur przechowywanych na serwerze. Procedury przechowywane na serwerze mogą być
uruchamiane z poziomu kwerendy przekazującej, poprzez podanie ich nazw i wszystkich wymaganych parametrów.
Dodatkową zaletą tego sposobu jest to, iż serwer może polegać na własnych zdolnościach optymalizacyjnych i profilach
wykonania, aby uzyskać jeszcze większą wydajność.
Kwerendy definiujące dane mogą działać na tabelach Jet, lecz nie tylko. Jeśli zajdzie potrzeba definiowania danych w tabelach
nie utworzonych przez mechanizm Jet, zadziałać mogą obiekty DAO. Jeśli musisz definiować dane w tabelach baz SQL
Server lub Oracle, możesz skorzystać z podobnych opcji w ich językach SQL. Wykonuj ich definiujące dane procedury
SQL poprzez kwerendy przekazujące Accessa.
Kwerendy definiujące dane posiadają podstawowy schemat, którego zrozumienie znacznie ułatwia korzystanie z nich.
Zaczynają się słowem kluczowym Create Table, Alter Table lub Drop Table, po którym występuje nazwa tabeli.
Kolejnym elementem jest umieszczona w nawiasie sekcja definiująca pole. Po niej występuje nazwa pola, jego typ danych, a
następnie rozmiar pola (w nawiasie). Sekcja definiująca dane może być dowolnej długości. Po każdej definicji pola może
występować warunek ograniczający, ustawiający indeksy, klucze i klucze: obcy lub nadający polu wartość NOT NULL. Wa-
runek ograniczający jest opcjonalny.
Korzystając z procedur definiujących dane w kwerendzie charakterystycznej dla języka SQL, możesz tworzyć lub
modyfikować tabele w taki sam sposób, jak dokonujesz zmian w tabeli w widoku Projekt.
Aby utworzyć tabelę zawierającą dwa pola o długości 15 znaków, możesz użyć następującej procedury:
CREATE TABLE TestTable (FirstName TEXT (15), LastName TEXT (15));
Po uruchomieniu tej kwerendy i odświeżeniu zawartości bazy zauważysz nową tabelę. Będąc w widoku Projekt zauważysz
również, że długość obu pól ustawiona jest na 15 znaków. Gdybyś użył tradycyjnej kwerendy tworzącej tabele, pola
miałyby długość 255 znaków. Rozmiar pola jest opcjonalną częścią procedury. Gdyby go w niej nie umieścić, pola miałyby
długość 255 znaków. Dobrze jest korzystać z tego polecenia, kiedy to tylko możliwe.
Modyfikowanie tabeli
Po utworzeniu tabeli możliwe jest modyfikowanie jej zawartości przy użyciu kwerend definiujących dane. Polecenie
Alter Table powoduje dodanie pola do tabeli. Podstawowe polecenie Alter Table ma następującą składnię:
ALTER TABLE nazwatabeli ADD
nazwapola1 typdanych (rozmiar),
nazwapola2 typdanych (rozmiar);
Aby zmodyfikować tabelę, dodając do niej dwa nowe pola, możesz użyć następującego polecenia:
Alter Table TestTable Add
Phone Text (10),
Fax Text (10),
Cellular Text (10);
Utworzone w ten sposób pola mogą być dalej określane za pomocą warunków ograniczających. Warunki te omówimy
jednak osobno. Nowością w Accessie 2000 jest możliwość dodawania więcej niż jednego pola jednocześnie. Jednakże
wciąż konieczne jest korzystanie z osobnych poleceń Drop do usuwania pól z tabeli.
75 Rozdział 4. ♦ Zaawansowane kwerendy
I
Alter Table TestTable drop Fax;
I
Alter Table TestTable drop Cellular;
Tworzenie indeksów
Po utworzeniu, zaimportowaniu bądź dołączeniu tabeli może zaistnieć konieczność utworzenia indeksu. Umożliwia to
polecenie Create Index.
Jeśli indeks ma zawierać tylko wartości unikatowe, użyj słowa kluczowego UNIQUE. Warunek opcjonalny WITH umożliwia
wymuszenie zasad poprawności. Indeks może zakazać użycia wartości Null poprzez użycie Disallow Null. Opcja
Ignore Null dopuszcza rekordy z wartością Null w indeksowanym polu, jednakże usuwa je z indeksu. Gdy używane
jest słowo kluczowe PRIMARY, może zastępować słowo UNIQUE.
Zauważ, że dla polecenia CREATE INDEX składnia jest nieco inna. W tym przypadku nazwa pola poprzedza nazwę tabeli.
Sprawdź w projekcie tabeli, aby potwierdzić utworzenie klucza podstawowego w polu Nazwisko.
Usuwanie tabeli
Aby usunąć tabelę z bazy danych lub usunąć indeks z tabeli, użyj polecenia DROP TABLE lub DROP INDEX.
DROP TABLE nazwatabeli/[nazwaindeksu ON nazwatabeli]
Gdy określamy relacje dla tabeli lub pola, składnia warunku ograniczającego jest nieco inna:
Część I ♦ Projektowanie bazy danych 76
Gdy tworzysz relacje między dwoma polami, za pomocą warunku CONSTRAINT, pamiętaj, że typy danych tych pól muszą
być takie same lub kompatybilne.
Znajdujące się na wydruku 4.18 wyrażenie definiujące dane tworzy tabelę z polem IDpracownika, o typie danych Long.
Pole to jest kluczem głównym tabeli. Tworzy ona również relację między tym polem i polem Idpracownika w tabeli
Pracownicy. Wyrażenie to tworzy jednocześnie pola Imię, Nazwisko i Telefon.
Po uruchomieniu tej kwerendy otwórz okno Relacje i dodaj do niego tabelę TabelaTestowa. Access automatycznie rozpozna
relację między tabelami Pracownicy i TabelaTestowa.
Optymalizowanie kwerend
Oto kilka czynności, które może wykonać programista, aby zapewnić odpowiednią wydajność kwerendy:
u Indeksuj sprzężone pola po obu stronach relacji. Dotyczy to również tabel nie tworzonych przez mechanizm Jet.
u Gdy pomiędzy dwoma tabelami istnieje więcej niż jedno pole sprzężone, ustaw pola w siatce kwerendy w taki
sposób, w jaki występują w swoich tabelach.
u Utwórz indeks dla pól, których będziesz używał do sortowania. Nieindeksowane pola sortuj tylko w ostateczności.
u Upewnij się, że dla wszystkich pól wybrałeś właściwy typ danych i rozmiar. Rozmiar pól powinien być możliwie
najmniejszy.
u Nie przeciążaj siatki QBE. Używaj tylko pól niezbędnych dla zestawu rezultatów.
u Nie umieszczaj pól obliczanych w zagnieżdżonej kwerendzie. Zamiast tego, obliczenia wykonuj na końcu
sekwencji kwerend lub, jeśli to tylko możliwe, na formularzu i raporcie.
u Staraj się unikać korzystania z pól Grupuj według. Pola te zabierają dużo miejsca i mogą niekorzystnie wpływać na
wydajność. Jeśli pogrupowane pola mają indeksy, spróbuj używać ich w takiej samej kolejności, w jakiej
występują w tabeli.
u Kwerenda podsumowująca ze sprzężeniami może być bardziej wydajna po podzieleniu jej na dwie osobne
kwerendy. Pierwsza z nich wykonuje sprzężenie, a kwerenda grupująca korzysta z zestawu rezultatów pierwszej.
u Umieszczenie kryteriów po jednej zamiast po drugiej stronie relacji może mieć również wpływ na wydajność.
Zazwyczaj kwerenda z kryterium po stronie Jeden relacji jest szybsza, lecz eksperymentowanie może dać inne
wyniki.
u Formularze i Raporty zawsze działają szybciej, gdy są oparte na tabeli. Gdy to tylko możliwe, z zestawu
rezultatów twórz tabelę, na której będziesz opierał formularze i raporty.
u Kwerendy krzyżowe działają szybciej, gdy w nagłówku kolumny nie umieszczono żadnych obliczeń. Mimo iż
obliczenia te są czasami konieczne dla podsumowań, unikaj umieszczania ich jedynie ze względów
kosmetycznych.
u Używaj kwerend parametrycznych poprzez kod zamiast ciągów SQL w kodzie. Ponieważ kwerendy
parametryczne są obiektami kompilowanymi i mają profil wykonania, zazwyczaj będą działać szybciej niż
odpowiadający im ciąg SQL.
Access 2000 jest zaawansowanym interfejsem użytkownika dla silnika baz danych Microsoft Jet 4.0. Niezależnie od tego,
czy jesteś tego świadom, Jet zarządza bazą danych zawartą w pliku MDB. Gdy uruchamiasz plik typu MDB poprzez
obiekty DAO lub ADO, również używasz do tego silnika Microsoft Jet. Przechowuje on tabele, indeksy i kwerendy, które
uruchamia poprzez wbudowany mechanizm zapytań. Jet jest rozbudowaną, wyposażoną w kompletny zestaw funkcji,
wielowątkową, relacyjną bazą danych.
Jet 1.0
Historia Microsoft Jet rozpoczyna się ponad dziesięć lat temu, kiedy to w firmie Microsoft rozpoczęto wdrażanie projektu
Access. Gdy w 1992 roku Access 1.0 trafił na półki sklepowe, razem z nim na rynek domowych baz danych wszedł Jet 1.0.
Zawierał on wiele bardzo potrzebnych opcji domowych baz danych, jak definiowanie danych, kwe-
rendy, zabezpieczenia i indeksowanie. Jet był jednocześnie produktem pionierskim, gdyż zawierał wiele nowych opcji, jak
na przykład: kwerendy aktualizujące, heterogeniczne sprzężenia danych i możliwość tworzenia kwerendy w oparciu o inną
kwerendę. Opcje te umożliwiły programowi Microsoft Access osiągnąć pozycję najpopularniejszej domowej bazy danych.
Jet 1.1
Sukces Accessa był zaskoczeniem dla wszystkich, łącznie z firmą Microsoft. W maju 1993 roku wydano Access 1.1 oraz
Visual Basic 3.0, a razem z nimi Jet 1.1. Ta edycja umożliwiała programistom korzystanie z wielu nowych opcji:
poprawionej, zgodnej ze standardem ODBC komunikacji i nowych sterowników ODBC. Od tej pory zaprzestano tworzenia
kodu programu poprzez interfejs API ODBC, a dostęp do danych ODBC stał się możliwy dla każdego. Jet 1.1 umożliwił
również swoim użytkownikom łatwe dołączanie zewnętrznych danych, zwłaszcza w nowym formacie Microsoft FoxPro.
Poprawiono biblioteki obiektów DAO, a maksymalny rozmiar bazy Jet wzrósł ze 128 MB do 1,1 GB.
Jet 2.0
Jet 2.0 został wprowadzony na rynek w kwietniu 1994 roku wraz z bardzo popularnym Accessem 2.0. Dzięki takim opcjom
jak wymuszanie reguł poprawności na poziomie silnika bazy, czy integralności referencyjnej Jet 2.0 stał się nowoczesnym
Część I ♦ Projektowanie bazy danych 78
aparatem baz danych. Aby zwiększyć jego wydajność, dodano również zapożyczoną z FOX-a technologię Rushmore oraz
poprawiono funkcjonowanie SQL i obiektów DAO. Jet 2.0 był również, bardziej niż poprzednie wersje, zgodny z ANSI.
Jet 2.5
W październiku 1994 roku firma Microsoft wypuściła na rynek pakiet Service Pack do Accessa 2.0 oraz pakiet
sterowników ODBC Desktop Drivers Pack 2.0. Były to również narodziny Jet 2.5. W tej wersji do konstruowania wyrażeń
Jet używał już VBA, a wsparcie dla źródeł danych ODBC uległo znacznej poprawie. Ulepszono także obsługę aplikacji
przeznaczonych dla wielu użytkowników.
Jet 3.0
Gdy pod koniec 1995 roku Microsoft wypuścił na rynek Access 95, silnik Jet został wprowadzony w 32-bitowe
środowisko. Jet stał się zatem 32-bitowym silnikiem baz danych, posiadającym zdolność replikacji danych, a także
ulepszone opcje ODBC i DAO. Jet 3.0 był bardzo szybkim silnikiem baz danych.
Jet 3.5
Wraz z wprowadzeniem na rynek w styczniu 1997 roku pakietu Office 97 oddano do rąk użytkowników Jet 3.5. Był on już
w pełni 32-bitowym silnikiem baz danych, którego największym ulepszeniem był znaczny wzrost wydajności. Jet 3.5
zawierał także nowe zdolności buforowania danych, poprawione blokowanie stron, ulepszenia w pracy kwerend,
ODBCDirect oraz programowe anulowanie poleceń zapisu na dysk. Replikacja została rozszerzona o repliki częściowe, a
wsparcie danych zewnętrznych o obsługę danych HTML i Exchange.
Jet 3.51
Wypuszczenie na rynek w połowie 1997 roku Jet 3.51, będącego kontynuacją Jet 3.5, prawie nie zostało zauważone. Nowy
Jet zawierał ulepszoną metodę defragmentowania i naprawiania plików typu MDB. Opcja naprawiania została włączona w
znacznie poprawiony proces defragmentowania. W Jet 3.51 poprawiono błędy dotyczące niskopoziomowej obsługi wielu
użytkowników, jednakże najważniejsze w nim było narzędzie do defragmentowania i naprawy JetCOMP.exe,
korzystające z nowej opcji defragmentującej.
Jet 4.0
W czerwcu 1999 roku, wraz z pakietem Office 2000, Microsoft wypuścił na rynek Jet 4.0. Edycja ta była tym, na co czekali
wszyscy programiści. Jet 4.0 zawiera więcej funkcji niż wszystkie poprzednie wersje razem wzięte. Większość z nich
została dodana dzięki uwzględnieniu zgromadzonych przez lata próśb i uwag programistów. Wersja 4.0 to bardzo
rozbudowany program, zawierający tak zaawansowane opcje, jak:
u nowy wbudowany dostawca baz danych OLE;
u blokowanie na poziomie rekordów;
u pełna obsługa Unicode;
u ulepszone typy danych;
u poprawione funkcje Autonumerowania;
u przeszukiwalne pola typu Memo;
u poprawki trybu przeznaczonego dla wielu użytkowników;
u ulepszenia w replikacji;
u nowa składnia SQL (bardziej zgodna z ANSI 92).
Gdy poznasz te opcje i będziesz przy ich użyciu budował aplikacje, z trudem będziesz mógł sobie wyobrazić, jak
wyglądała Twoja praca, gdy tych opcji nie było.
79 Rozdział 5. ♦ Jet 4.0 – silnik baz danych Microsoft
Praktyczne zastosowanie
nowych opcji silnika Jet 4.0
W rozdziale tym omówimy zaawansowane opcje silnika baz danych Microsoft Jet 4.0. Wszystkie przykłady kodu działają
w Accessie 2000, a po dokonaniu drobnych modyfikacji w Visual Basic 5 lub 6.
ADO 1.0 zawierało losowego dostawcę dla ODBC, tak więc gdybyś używał Jet i ADO, byłbyś zmuszony do korzystania z
warstwy ODBC. Jet 4.0 posiada wbudowanego dostawcę baz danych OLE o nazwie kodowej JOLT 4.0. Umożliwia Ci to
wykorzystywanie ADO jako metodologii dostępu do danych w aparacie Jet. Poprzez JOLT masz dostęp do zestawu funkcji
Jet, a ponadto do kilku opcji charakterystycznych dla JOLT. Temat ten będzie poruszany jeszcze kilkakrotnie w dalszej
części tej książki.
Na początku lat dziewięćdziesiątych International Standards Organisation (ISO), w połączeniu z konsorcjum Unicode,
rozpoczęła prace nad podobnym standardem. Dzięki tej współpracy wydane w 1993 roku Unicode 1.1 i ISO 10646 są
identyczne.
Do przedstawiania znaków tekstowych ze wszystkich języków poza chińskim kod Unicode korzysta z 16-bitowego
schematu kodowania znaków o stałej szerokości. Kod Unicode rozwiązuje problem dużej liczby języków stron kodowych i
umożliwia wymianę i współdzielenie danych między wieloma językami bez ryzyka uszkodzenia.
Aby przy użyciu SQL określić kolumnę, która będzie używać kompresji, podczas tworzenia tabeli z DDL użyj nowego
znacznika WITH COMPRESSION:
CREATE TABLE MyTable (MyCompressedField CHARACTER (255) WITH COMPRESSION)
Ta klauzula SQL dostępna jest jedynie poprzez kod VBA i ADO. Powyższe wyrażenie SQL możesz wykonać poprzez
aktualne połączenie ADO projektu VBA (wydruk 5.1).
CurrentProject.Connection.Execute strSQL
'Sukces
MsgBox "Tabela Utworzona OK", vbInformation
Proc_Exit:
Exit Sub
Proc_Err:
'Określ, czy tabela istnieje
If Err.Number = -2147217900 Then
MsgBox "Obiekt już istnieje. Usuń go i spróbuj jeszcze raz",_
vbCritical
Else
MsgBox Err.Description, vbCritical
End If
Resume Proc_Exit
End Sub
Sortowanie kompatybilne z NT
Umieszczenie kodu Unicode w silniku Jet 4.0 umożliwiło mu korzystanie z mechanizmu sortowania opartego na zestawie
funkcji Microsoft Windows NT. Ten nowy mechanizm sortujący używany jest przez Jet również w systemach Windows 95 i
98. W systemach tych możliwe jest również właściwe sortowanie wszystkich dostępnych w Windows NT języków, zamiast
jedynie domyślnego języka systemu, który Windows 95 obsługuje w swoim sortowaniu ANSI. Pozwala to szybciej i łatwiej
tworzyć międzynarodowe aplikacje, ponieważ teraz działa jednolite sortowanie we wszystkich systemach operacyjnych.
Microsoft SQL Server 7.0 i Visual Basic 6 używają do sortowania tego sa-
mego zestawu funkcji, czego rezultatem jest jednolitość między pro-
duktami.
Tabela 5.1.
Przegląd typów danych Jet 4.0
Tabela 5.1.
Przegląd typów danych Jet 4.0 (ciąg dalszy)
LongBinary Obiekt OLE Maksymalna długość wynosi teraz około 2,14 GB.
DateTime Data/Godzina Synonim Timestamp nie jest już akceptowany, a słowo
Timestamp w SQL Server nie odpowiada dokładnie
znaczeniu typu danych Data/Godzina.
Single Pojedyncza precyzja Dopuszczalne synonimy: Real, Float4 oraz IEEESingle.
Double Podwójna precyzja Dopuszczalne synonimy to Float, Double Precision,
Float8 i IEEEDouble.
Synonim Numeric nie jest już akceptowany dla tego typu
danych. Słowo Numeric używane jest do zdefiniowania
kolumny jako określonego typu danych, odpowiadającego
typom danych Decimal bądź Numeric w SQL Server.
Byte Bajt Jedyny dopuszczalny synonim to Tinyint.
Integer Liczba całkowita Dopuszczalne synonimy: Smallint, Integer2 oraz Short.
LongInteger Liczba całkowita długa Dopuszczalne synonimy: Int, Integer oraz Counter.
Nie jest już akceptowane słowo AutoIncrement. Więcej
informacji na ten temat znajdziesz w części
o autoinkrementacji kolumn.
Tabela 5.1.
Przegląd typów danych Jet 4.0 (ciąg dalszy)
nad sekwencjami klucza podstawowego. Aby utworzyć tabelę o nazwie MyCoolCounter z Autonumerowaniem
rozpoczynającym się od 1000 i przyrastającym o 100 w polu CoolCounter użyj następującej składni SQL:
CREATE TABLE MyCoolCounter (CoolCounter IDENTITY (1000,100), myTextField CHAR)
Aby w dowolnym momencie modyfikować wartość początkową i przyrost, użyj polecenia ALTER TABLE. Przykładowo, by
zmienić punkt początkowy na 5000, a przyrost na 10, składnia jest następująca:
ALTER TABLE MyCoolCounter ALTER COLUMN CoolCounter IDENTITY (5000,10)
Możesz zawsze odnaleźć ostatnią wstawioną wartość, korzystając z polecenia SELECT @@IDENTITY. Inaczej będzie
zachowywać się baza w przypadku użycia wartości przyrostowych innych niż jeden. Jeśli wartość przyrostu jest inna niż
jeden, Jet nie zresetuje następnej wartości do maksymalnej dopuszczalnej wartości w tabeli.
Podobnie jak w poprzednich wersjach Jet domyślne ustawienie uniemożliwia użytkownikom edycję danych typu Licznik.
Jednakże administratorzy będą mieli możliwość nadania użytkownikom praw, umożliwiających im aktualizowanie danych
typu Licznik.
With conn
.Provider = "Microsoft.Jet.OLEDB.4.0"
.ConnectionString = "data source=" & strPath
.Open
End With
Do Until rst.EOF
Debug.Print rst!COMPUTER_NAME
Debug.Print rst!LOGIN_NAME
Debug.Print rst!CONNECTED
Debug.Print rst!SUSPECTED_STATE
rst.MoveNext
Loop
End Sub
Otwieramy połączenie ADO do bazy danych, a następnie ustawiamy właściwość obiektu Jet OLEDB.Connection na 1. Tak
długo, jak obiekt połączenia ma wyznaczony zakres, żaden nowy użytkownik nie zostanie podłączony do bazy. Program
znajdujący się na wydruku 5.2 otwiera jednocześnie listę użytkowników jako zestaw rekordów ADO. Aby otworzyć listę
użytkowników, używamy metody połączenia z obiektem OpenSchema. Wymaga to przekazanie dość długiego identyfikatora
GUID dla obiektu ADO w celu wskazania Listy użytkowników. W ten sposób otrzymamy zestaw rekordów z nazwą kom-
putera, użytkownika (poprzez Jet Security lub Admin (przy braku zabezpieczeń), polem Connected, wskazującym czy dany
użytkownik jest połączony z bazą, oraz polem Suspected_State, stwierdzającym, czy istnieje podejrzenie uszkodzenia
bazy.
Część I ♦ Projektowanie bazy danych 84
Zabezpieczenia
Dzięki nowej składni, SQL obsługuje definiowanie zabezpieczeń bazy danych. Bezpośrednią z tego korzyścią jest
ułatwienie programowej obsługi zabezpieczeń. Możesz teraz zrezygnować z ADO i DAO na korzyść SQL, aby zaspokajać
swoje potrzeby w zakresie bezpieczeństwa. Poniższe wydruki zawierają rozszerzenia SQL obsługujące zabezpieczenia w
Jet 4.0:
CREATE/ADD/ALTER/DROP USER/GROUP
GRANT/REVOKE
Zabezpieczenia mogą być stosowane na poziomie następujących obiektów: CONTAINER (kontener), INDEX (indeks), QUERY
(kwerenda) i TABLE (tabela). Procedura na wydruku 5.3 przedstawia jak utworzyć na tabeli tblCustomers posiadającej
pełne uprawnienia grupę o nazwie SuperGroup. Następnie kod spowoduje odebranie tej grupie pozwolenia usuwania
danych z tabeli tblCustomers, po czym utworzy użytkownika o imieniu Steve i haśle Batman, aby na końcu dodać go do
grupy SuperGroup.
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description, vbCritical
Resume Proc_Exit
End Sub
Funkcje zabezpieczeń SQL w Jet 4.0 zostały również wyposażone w możliwość tworzenia bądź nadawania hasła w
następujący sposób:
85 Rozdział 5. ♦ Jet 4.0 – silnik baz danych Microsoft
Wywoływanie parametrów
Poprzez ADO Jet 4.0 obsługuje teraz podawanie parametrów poprzez listę, co przypomina w działaniu wykonywanie
zapisanej parametrycznej procedury SQL Server. Zapisana kwerenda qryParameterQuery posiada dwa parametry –
EmployeeID i DepID:
PARAMETERS [EmployeeID] Long, [DepID] Long;
SELECT Employees.EmployeeID, Employees.[First Name],
Employees.[Last Name], Employees.Phone, Employees.[Dept ID]
FROM Employees
WHERE (((Employees.EmployeeID)=[EmployeeID])
AND ((Employees.[Dept ID])=[DepID]));
Podawanie parametrów i wykonywanie kwerendy parametrycznej jest teraz bardzo łatwe dzięki składni EXEC:
EXEC qryParameterQuery 1, 4179
Ten kod SQL podaje następujące wartości parametrów: EmployeeID=1 i DepID=4179. Parametry musisz podawać w
takiej kolejności, w jakiej znajdują się w kodzie SQL. Kod na wydruku 5.4 przedstawia, jak otwierać zestaw rekordów
ADO oparty na kwerendzie qryParameterQuery.
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description, vbCritical
Resume Proc_Exit
End Sub
Transakcje
SQL Jet 4.0 obsługuje teraz transakcje. Transakcja musi obowiązkowo rozpoczynać się w następujący sposób:
BEGIN TRANSACTION
Kod na wydruku 5.5 przedstawia, w jaki sposób można edytować i usuwać rekordy w jednej transakcji. Zauważ, że
transakcja musi rozpoczynać się w innej linii niż linia wyrażenia SQL.
With conn
.Provider = "Microsoft.Jet.OLEDB.4.0"
.ConnectionString= "data source=" & Application.CurrentProject.Path & "employee_2k.mdb"
.Open
End With
End Sub
Kod na wydruku 5.6 przedstawia, jak utworzyć tabelę CreditLimit, wprowadzić wartość, utworzyć tabelę Customers wraz z
ograniczeniem, a następnie jak spróbować wstawiać wiersze. Pierwszy rekord zostanie zaakceptowany, a drugi będzie
odrzucony ze względu na przekroczony limit kredytu.
'Dokonaj wprowadzenia
conn.Execute "INSERT INTO Customers_Con (CLstNm, CFrstNm, CustomerLimit)" & _
"VALUES ('Collins', 'Kevin', 100);"
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description, vbCritical
Resume Proc_Exit
End Sub
Gdy nakładasz ograniczenie na pole, Jet uniemożliwi Ci wprowadzenie w tym polu wartości niezgodnej z tą zasadą.
Rysunek 5.2 przedstawia komunikat o błędzie wywołany przez ostatni wiersz kodu na wydruku 5.6.
Rysunek 5.2.
Komunikat o błędzie
wyświetlany
w momencie
naruszenia
ograniczenia
Część II
Dostęp do danych
Rozdział 6.
Wprowadzenie
do obiektów danych ActiveX
W tym rozdziale:
u Historia dostępu do danych.
u Universal Data Access.
u Obiekty ActiveX Data (ADO).
u Model obiektowy ActiveX Data.
u Obiekty ADO: Recordset.
u Obiekty ADO: Error.
u Przejście z obiektów DAO do ADO.
u Porównanie modelu obiektowego ADO i DAO.
Wraz z wypuszczeniem na rynek pakietu Office 2000 do rąk użytkowników trafiły też obiekty ActiveX Data. Zastąpiły one
obiekty DAO oraz standard ODBCDirect i stały się jedyną metodą dostępu do danych zarówno dla Jet, jak i dla
architektury klient-serwer. Od tego momentu wystarczy nauczyć się jednej metody oraz jednego modelu obiektu.
Rysunek 6.1 przedstawia aktualny wygląd technologii Universal Data Access. Głównymi obiektami dostępu do danych baz
OLE są obiekty ActiveX Data (ADO). Jak widzisz, zarówno bezpośrednio, jak i poprzez obiekty ADO, bazy danych OLE
mogą komunikować się z innymi bazami (relacyjnymi lub nie) oraz danymi na komputerze głównym za pomocą jednego
interfejsu.
Rysunek 6.1
Schemat dostępu do
danych – stan na
dzień dzisiejszy
91 Rozdział 6. ♦ Wprowadzenie do obiektów danych Active X
ADO 1.0
Po wprowadzeniu na rynek w końcu roku 1996 obiekty ADO używane były głównie jako metoda dostępu do danych poprzez
skrypt w opartych na Active Server Pages aplikacjach internetowych. Posiadały one jedynie podstawowy zestaw funkcji
służący jako dostęp do danych w architekturze typu klient-serwer. W tym czasie obiekty ADO służyły jako podzestaw dla
popularnych modeli obiektów DAO i RDO. Programiści używali jedynego dostępnego dostawcy OLEDB – ogólnego
dostawcy dla wszystkich źródeł danych ODBC.
ADO 1.5
Jesienią 1997 roku Microsoft wprowadził na rynek ADO 1.5 oraz Microsoft Data Access Components 1.0 (MDAC) i IIS
4.0. Obiekty ADO w wersji 1.5 zawierały między innymi: Remote Data Services (RDS) i obsługę zestawów rekordów
odłączonych od bazy. Pierwszym dostawcą baz danych OLE, który ujrzał światło dzienne, był dostawca dla aparatu Jet o
nazwie JOLT.
ADO 2.0
Latem 1998 roku, wraz z wypuszczeniem wersji 2.0 MDAC, powstała trzecia wersja obiektów ADO – ADO 2.0. Był to
prawie nadzestaw RDO 2.0 i DAO 3.5, zawierający dodatkowo kilka interesujących opcji. Do ADO 2.0 dołączono również
dostawców baz danych OLE dla Jet, SQL Server i Oracle. Wiele z nowych opcji było już wcześniej wykorzystanych w
obiektach RDO i DAO, włączając w to operacje asynchroniczne i powtórną synchronizację poprzez kursory klienta. Obiekty
ADO zawierały też zupełnie nowe technologie, jak:
u Microsoft Data Links.
u Stałe zestawy rekordów.
u Zestawy rekordów tworzone przez użytkownika.
u Zestawy rekordów OLAP.
ADO 2.1
Wydane wraz z SQL Serverem 7.0, pakietem Office 2000 i Internet Explorerem 5.0 obiekty ADO w wersji 2.1 zawierają
wszystkie opcje umieszczone w wersji 2.0 oraz dwa nowe modele obiektu:
u ADO – dla operacji DDL i zabezpieczeń (ADOX);
u JRO (Jet Replication Objects) – dla opcji replikacji oraz funkcji zmniejszania i naprawiania baz danych w silniku
Jet.
Do operacji związanych z Accessem i silnikiem Jet nie należy używać wer-
sji ADO dostarczanej wraz z SQL Serverem 7.0. Zawiera ona błędy i nie
wszystkie opcje opisane w tym i pozostałych rozdziałach będą w niej
funkcjonować. Upewnij się, że używasz wersji ADO dostarczanej wraz z
pakietem Office 2000 lub systemem NT 2000.
ADOX najlepiej współpracuje z JOLT, jednakże działa również z SQL Server i innymi dostawcami. JRO jest
rozszerzeniem przeznaczonym dla Jet, używanym głównie podczas replikacji. Model ADOX omówiony zostanie w
następnym rozdziale, a JRO w rozdziale 22., „Replikacja i JRO”.
Jak wszystko w tej branży obiekty ADO i bazy danych OLE są przez cały
czas udoskonalane. Trudno jest czasami nadążyć za zmianami. Jako że
Mi ft d j j bi któ ADO i l ż i d ki t Offi
Część II ♦ Dostęp do danych 92
Rysunek 6.2.
Strona WWW
dotycząca obiektów
ADO i baz OLE
Ponieważ obiekty ADO oparte są na wspólnym modelu obiektowym (COM), tworzenie ich powinno być Ci już znane.
Przykładowo, możesz utworzyć obiekt połączenia ADO w taki sposób:
Dim conn As ADODB.Connection
Set conn= New ADODB.Connection
93 Rozdział 6. ♦ Wprowadzenie do obiektów danych Active X
Po utworzeniu obiektu możesz ustawić jego właściwości lub uruchomić go, na czym skupimy się w pozostałej części tego
rozdziału.
Obiekt Connection
Obiekt Connection przedstawia fizyczne połączenie do bazy lub dostawcy danych. Możesz otworzyć połączenie,
wskazując obiektowi Connection, którego dostawcy ma użyć, oraz określając ciąg połączeniowy. Kod ten przedstawiony
jest na wydruku 6.1 i znajdziesz go w pliku Rozdz06.mdb na dołączonej do książki płycie CD-ROM.
Wydruk 6.1. Łączenie z bazą danych Accessa poprzez ADO i obiekt Connection
Sub ConnectToDatabase()
'Procedura ta spowoduje utworzenie połączenia z bazą
'danych Accessa przy użyciu dostawcy OLE DB dla Jeta
'Z książki "Access 2000 Księga eksperta" (Helion)
'Autorzy: Forte, Howe, Ralston
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description, vbCritical
Resume Proc_Exit
End Sub
u ConnectionString.
u Mode.
Provider jest ciągiem przedstawiającym unikatowy ProgID wybranego dostawcy OLEDB. My wybraliśmy
„Microsoft.Jet.4.0”, który jest dostawcą OLEDB dla Jet 4.0. Ciąg połączeniowy (ConnectionString) to określenie
ścieżki dostępu do bazy oraz innych informacji dotyczących połączenia, jak na przykład lokalizacja pliku grupy roboczej,
czy zabezpieczenia (więcej informacji o zabezpieczeniach w rozdziale 23.). Później ustawiliśmy właściwość Mode na stałą
ADO adModeReadWrite. Umożliwia nam to uruchomienie bazy danych w trybie Odczyt/Zapis. W tym miejscu możesz
również nakazać otwieranie bazy danych jedynie w trybie tylko do odczytu.
With conn
'Ustaw właściwość dostarczyciela
'W ten sposób nakazujemy Ado użycie JOLT'a
.Provider = "Microsoft.Jet.OLEDB.4.0"
'W ciągu połączenia określ ścieżkę
.ConnectionString = "data source=C:\northwind.mdb"
.Mode = adModeReadWrite
.Open
End With
'SQL Statement
strSQL = "UPDATE Customers SET Customers.Region = " & _
Chr(39) & "YK" & Chr(39) & vbNewLine & _
"WHERE (((Customers.Region)=" & _
Chr(39) & "BC" & Chr(39) & "));"
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description, vbCritical
Resume Proc_Exit
End Sub
Nasze wyrażenie zmieni wszystkie wiersze tabeli Customers, w których wartość pola Region="BC", w taki sposób, by
wartość tego pola była równa "YK". Zauważ, że możesz dowiedzieć się, ile rekordów zostało zmienionych, dodając
zmienną do metody Execute, a następnie sprawdzając wartość tej zmiennej.
Wydruk 6.3 przedstawia, jak otworzyć zestaw rekordów oparty na tabeli Customers. Utworzyliśmy połączenie oparte na
aktualnej bazie danych, a następnie otwarliśmy zestaw rekordów z kursorem tylko do przekazania, tylko do odczytu.
Użyliśmy także parametru adCmdTableDirect, który „każe” Accessowi otworzyć tabelę bezpośrednio.
'Utwórz połączenie
Set conn = CurrentProject.Connection
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description, vbCritical
Resume Proc_Exit
End Sub
Tabela 6.1.
Parametry otwarcia obiektu Recordset
Accessa
adCmdTable – wykonanie na tabeli
polecenia Select * From
adCmdTableDirect – Bezpośrednie
otwarcie tabeli (jak db OpenTable w DAO)
adCmdText – Procedura SQL
adCmdUnknown – Wartość nieznana,
Access określi ją za ciebie
Możesz także dodać informacje o połączeniu – ciąg oraz polecenie dynamicznego otwarcia połączenia bez obiektu
Connection:
'Otwórz zestaw rekordów
rst.Open "Customers", "provider=Microsoft.Jet.OLEDB.4.0; " & _
"data source c:\northwind.mdb", _
adOpenForwardOnly, adLockReadOnly, adCmdTableDirect
Dodatkowo, oprócz otwarcia tabeli, możesz również otworzyć zestaw rekordów oparty na wyrażeniu SQL:
Rst.Open "Select * From Customers Where CustomerID= ALFKI", _
CurrentProject.Connection, _
adOpenForwardOnly, adLockReadOnly, adCmdTableDirect
Jak wiadomo, jedną z najważniejszych opcji silnika Jet jest wydajna praca z zewnętrznymi danymi. Aby otworzyć
zewnętrzne źródło danych, będziesz musiał zmodyfikować ciąg połączenia. Źródło danych musi wskazywać na zewnętrzny
plik, do którego chcesz uzyskać dostęp (tekstowy, DBF, Excela lub inny), a także musi być ustawiona właściwość
„Zaawansowane właściwości” indeksowego dostępu sekwencyjnego do plików. Kolejny przykład fragmentu kodu
przedstawia, w jaki sposób Jet może poprzez ADO uzyskać dostęp do arkusza kalkulacyjnego Excel 8.0. W poniższym
przykładzie otworzymy zestaw rekordów oparty na danych w arkuszu „Sheet1” pliku Customers.xls:
Dim conn As ADODB.Connection
Dim rst As ADODB.Recordset
With conn
.Provider = "Provider=Microsoft.Jet.OLEDB.4.0."
.ConnectionString = "Data Source=C:\excel\Customers.xls;" &_
"Extended Properties=Excel 8.0;"
.Open
End With
Dim rst As ADODB.Recordset
Set rst = New ADODB.Recordset
rst.Open "Sheet1$", conn, _
adOpenDynamic, adLockOptimistic, adCmdTableDirect
W siatce QBE Accessa zdefiniowaliśmy naszą kwerendę i utworzyliśmy dla niej parametr, korzystając ze znajdującej się w
menu Kwerenda opcji Parametry. Parametry zdefiniowaliśmy w sposób przedstawiony na rysunku 6.4.
Rysunek 6.4.
Okno dialogowe
Parametry
kwerendy
Teraz tworzymy obiekt Command i określamy, którego obiektu Connection będziemy używać i jaki to typ polecenia.
Każemy mu użyć utworzonego przed chwilą obiektu Connection, a następnie wskazujemy na znajdującą się w bazie
kwerendę qryCustOrders_Prm. Możesz użyć tych samych opcji dla zestawu rekordów w przypadku obiektu Command.
Dim cmd as ADODB.Command
Set cmd = New ADODB.Command
With cmd
.ActiveConnection = conn
.CommandText = “qryCustOrders_Prm"
.CommandType = adCmdStoredProc
End With
Ustawiliśmy właściwość CommandType na adCmdStoredProc, ponieważ ADO/Jolt traktuje zapisane kwerendy jak
procedury. Następnym rodzajem CommandType jest adCmdTable, używane w starszych wersjach Jet.
Gdy konwertujesz aplikacje z Jet 3.51 do 4.0 w Accessie 2000 lub VB6,
pamiętaj o różnicy w działaniu tych dwóch metod. W przypadku Jet 3.51
musisz określić CommandType jako adCmdTable, natomiast w aparacie Jet
4.0 powinieneś użyć adCmdStoredProc.
Aby ustawić informacje o parametrze, wystarczy określić cztery właściwości: Name, Type, Value i Direction. Nazwę
(Name) i typ danych (Type) wpisz takie same jak w zapisanej kwerendzie Jet. Będziesz musiał również określić właściwość
Direction, która informuje ADO, czy parametr jest wartością wejściową, wyjściową czy zwracaną. Teraz ustaw wartość
parametru, opierając się na tym, co użytkownik określił w aplikacji, a następnie dodaj parametr do zbioru parametrów
obiektu Command.
With prm
.Name = "OrderID"
.Value = 10248
.Type = adInteger
.Direction = adParamInput
End With
cmd.Parameters.Append prm
Teraz korzystamy z metody Execute obiektu Command, aby utworzyć obiekt Recordset. Możesz użyć danych z zestawu
rekordów, aby wypełnić pola tekstowe w formularzu VB lub wykonać obliczenia. Aby otrzymać dane z wykonanego pole-
cenia, musisz ustawić Recordset na wykonane polecenie w następujący sposób:
Set rst = cmd.Execute
Wydruk 6.4 łączy te wszystkie przykłady i otwiera zestaw rekordów oparty na wykonanym poleceniu.
'Utwórz połączenie
Set conn = CurrentProject.Connection
With cmd
.ActiveConnection = conn
.CommandText = "qryCustOrders_Prm"
.CommandType = adCmdTable
End With
With prm
.Name = "OrderID"
.Value = 10248
.Type = adInteger
.Direction = adParamInput
End With
cmd.Parameters.Append prm
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description, vbCritical
Resume Proc_Exit
End Sub
Aby uruchomić tę kwerendę programowo poprzez ADO, musisz utworzyć obiekt Command, skojarzyć go z obiektem
Connection i wykonać. Wydruk 6.5 przedstawia, jak tę czynność wykonać.
With cmd
'Połącz z aktualną bazą danych
.ActiveConnection = CurrentProject.Connection
'Nazwa kwerendy w Accessie
.CommandText = "qryUpdateTitle"
'Ustaw tę własciwość jako adCmdStoredProc, Jet zaklasyfikuje
'Zapisane Kwerendy jako procedury dla obiektu Command
.CommandType = adCmdStoredProc
'Uruchom kwerendę
.Execute, lngRecordsAffected
End With
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
rst.Close
Set rst = Nothing
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Część II ♦ Dostęp do danych 100
Tabela 6.2.
Główne właściwości obiektu Error
Właściwość Komentarz
Description Opis błędu
Number Numer błędu ADO
Native Error Numer błędu dostawcy
SQL State Kod błędu charakterystyczny dla dostawcy. W silniku Jet oznacza on dawny numer
błędu DAO
Source Źródło błędu. W naszym przypadku będzie to Jet
Ponieważ dowolny błąd w kodzie może powodować wiele błędów ADO, możesz przeglądać zbiór błędów obiektu
Connection, a następnie sprawdzać poszczególne właściwości. Jeśli użyłeś w aplikacji kodu opartego na dawnej
numeracji błędów DAO, aby uzyskać kompatybilność wstecz będziesz zmuszony użyć właściwości SQLState. Dzięki niej
uzyskasz dawny kod błędu DAO. Możesz przeglądać zbiór błędów, korzystając z obiektu Error (wydruk 6.7). Wynik
działania programu z wydruku 6.7 znajduje się na rysunku 6.5.
'Wymuś błąd
rst.Open "badTable", conn
Proc_Exit:
Exit Sub
Proc_Err:
Dim adoErr As ADODB.Error
'Przejdź przez każdy z błędów
'w zbiorze błędów połączenia
For Each adoErr In conn.Errors
101 Rozdział 6. ♦ Wprowadzenie do obiektów danych Active X
Resume Proc_Exit
End Sub
Access 2000 przyjmie, że zmienna rst będzie rekordem ADO, a nie DAO, ponieważ ADO domyślnie znajduje się wyżej w
odwołaniach VBA. Przed dokonaniem konwersji baz danych z Accessa 97, 95 lub innych powinieneś przed nazwami
obiektów DAO umieścić przedrostek DAO. Powyższy kod powinien wyglądać następująco:
Dim db As DAO.Database
Dim rst as DAO.Recordset
Książka ta oraz znajdująca się na stronie WWW Microsoftu dokumentacja dotycząca obiektów ADO
(http://www.microsoft.com.data) powinny przygotować Cię do nauki obsługiwania tej technologii. W następnej części
znajduje się opis przygotowania typowego planu konwersji.
Poznanie technologii ADO i proces konwersji kodu aplikacji z DAO do ADO powinny być częścią budżetu
przeznaczonego na konwersję. Proces konwersji do Accessa 2000 wymaga więcej czasu niż typowa konwersja. Postępując
według poniższych wskazówek, będziesz mógł zaoszczędzić dużo czasu, pieniędzy i wysiłku.
Schemat konwersji
W tej części pokażemy, jak powinieneś podejść do procesu konwersji aplikacji z DAO do ADO. Pamiętaj, zawsze
sporządzaj kopie zapasowe swojej pracy!
5. Uruchom Accessa 97. Jeśli aplikacja jest w starszej wersji niż Access 97, najpierw musisz ją skonwertować do
Accessa 97.
6. Przeanalizuj koszty. Dokonaj analizy bazy danych, aby określić, jak wiele procedur używa DAO. Następnie
sporządź w Excelu listę wszystkich procedur i oceń, ile czasu zajmie konwersja każdej z nich.
Część II ♦ Dostęp do danych 102
W trakcie czytania tej książki natrafisz na operacje, które DAO wykonuje lepiej niż ADO (niektóre operacje dotyczące
DDL oraz zabezpieczeń). Jeśli aplikacja w znacznej części opiera się na tych technikach, lepiej będzie jej nie konwertować
lub zdecydować się na połączenie obu technologii.
w obu tych technologiach. Temat ten został omówiony w rozdziałach 22. „Replikacja i JRO” i 7. „Zaawansowane ADO”.
103 Rozdział 6. ♦ Wprowadzenie do obiektów danych Active X
W tabeli 6.3 znajdziesz najbardziej powszechne obiekty związane z dostępem do danych w DAO i ich odpowiedniki w
technologii ADO.
Tabela 6.3.
Porównanie obiektów DAO i ADO
Teraz, kiedy już umiesz używać obiektów ADO i porównałeś je z DAO, przyjrzyj się tym cechom ADO, które pomogą Ci
tworzyć aplikacje w Accessie 2000.
With conn
.Provider = "Microsoft.Jet.OLE.DB.4.0"
.ConnectionString = "data source= C:\databases\sample.mdb"
.Open
End With
Jeśli zachodzi konieczność określenia innych informacji dotyczących połączenia (np. hasło bazy danych czy plik grupy
roboczej), dołącz je do ciągu połączeniowego, poprzedzając średnikiem. W tabeli 7.1 znajdziesz charakterystyczne dla
dostawcy właściwości połączenia, których możesz użyć w ciągu połączeniowym. Inne charakterystyczne dla dostarczyciela
właściwości, które znajdują się w zbiorze właściwości połączenia, zostaną zignorowane.
Tabela 7.1.
Właściwości ciągów połączenia charakterystyczne dla dostawcy OLE DB dla Microsoft Jet
Nazwa Opis
Jet OLEDB:Registry Path Ścieżka dostępu do klucza rejestru dla Jet. Nie zawiera
znacznika HKEY_LOCAL_MACHINE. Wartość ta może
zostać zamieniona na drugorzędną lokalizację w celu
przechowywania wartości rejestru aplikacji, które nie są
współdzielone z innymi aplikacjami korzystającymi z Jet
na tym komputerze.
Przykładowo, ustawienie dla Accessa 2000 to:
SOFTWARE\Microsoft\Office\9.0\Access\Jet\4.0\Engines
Jet OLEDB:System database Lokalizacja systemowej bazy Jet, która ma być używana
przez określonych użytkowników. Powoduje to
105 Rozdział 7. ♦ Zaawansowane ADO
Oprócz właściwości umieszczonych w tabeli 7.1 silnik bazy danych Microsoft Jet posiada kilka opcji, których ustawienie określa
zachowanie silnika. Opcje te często mają bezpośredni wpływ na jego wydajność. Domyślnie, po uruchomieniu Jet używane są
wartości znajdujące się w rejestrze, w kluczu \HKEY_LOCAL_MACHINES\Software\Microsoft\Jet. Istnieje jednak
możliwość tymczasowego unieważnienia tych ustawień. W przypadku ADO wartości te stanowią część ciągu połączenia.
Stałe ciągu połączenia znajdują się w tabeli 7.2.
Tabela 7.2.
Opcje ciągu połączenia ADO
DAO ADO
dbPageTimeout Jet OLEDB:Page Timeout
dbSharedAsyncDelay Jet OLEDB:Shared Async Delay
dbExclusiveAsyncDelay Jet OLEDB:Exclusive Async Delay
dbLockRetry Jet OLEDB:Lock Retry
dbUserCommitSync Jet OLEDB:User Commit Sync
dbImplicitCommitSync Jet OLEDB:Implicit Commit Sync
dbMaxBufferSize Jet OLEDB:Max Buffer Size
dbMaxLocksPerFile Jet OLEDB:Max Locks Per File
dbLockDelay Jet OLEDB:Lock Delay
dbRecycleLVs Jet OLEDB:Recycle Long-Valued Pages
dbFlushTransactionTimeout Jet OLEDB:Flush transaction Timeout
Poniższy fragment kodu powoduje otwarcie zabezpieczonej bazy, określając jej hasło i plik grupy roboczej:
Dim conn As ADODB.Connection
Set conn = New ADODB.Connection
With conn
.Provider = "Microsoft.Jet.OLE.DB.4.0"
.ConnectionString = "data source= C:\databases\sample.mdb"&_
";Jet OLEDB:Database Password=supersecret " & _
"; OLEDB:System database=" & _
"c:\windows\system\system.mdw"
.Open
End With
Część II ♦ Dostęp do danych 106
CurrentProject.Connection
Gdy chcesz uzyskać dostęp do aktualnej bazy poprzez kod ADO, Access umożliwia Ci pójście na skróty. Oddaje do Twojej
dyspozycji odnośnik do obiektu Connection
– CurrentProject.Connection. Używając tej składni, możesz z łatwością przydzielić aktualnej bazie obiekt
Connection. Polecenie CurrentProject.Connection dostępne jest jedynie w kodzie VBA Accessa 2000. Użycie tej
składni przedstawia poniższy fragment kodu:
Dim conn As ADODB.Connection
Set conn = CurrentProject.Connection
CurrentProject.Connection pozwala zaoszczędzić czas, jeśli chcesz otworzyć zestaw rekordów. Możesz wykorzystać
zdolność ADO do dynamicznego tworzenia połączenia poprzez polecenie Open:
Dim rst As ADODB.Recordset
Set rst = New ADODB.Recordset
rst.Open "Customers", CurrentProject.Connection
Zanim zaczniesz używać UDL w aplikacjach VB lub VBA, musisz najpierw je utworzyć. Tworzenie UDL nie jest
skomplikowane. Uruchom Eksploratora Windows, z menu Plik wybierz Nowy, a następnie Microsoft Data Link (rysunek 7.1).
Po utworzeniu pliku UDL kliknij go dwukrotnie, aby rozpocząć edycję. Przedstawiony na rysunku 7.2 pierwszy ekran
zawiera listę wszystkich zainstalowanych na Twoim komputerze dostawców OLE DB. Wybierz jednego z nich i kliknij
Dalej, aby przejść do zakładki Połączenie. Teraz możesz określić wszystkie, charakterystyczne dla dostawcy informacje
dotyczące połączenia (rysunek 7.3). W naszym przykładzie użyliśmy dostawcy OLE DB dla Jet, więc musieliśmy określić
ścieżkę dostępu, identyfikator użytkownika i hasło (gdybyśmy wybrali SQL Server, musielibyśmy podać nazwę serwera
i bazy danych). Następna zakładka, Zaawansowane, służy do określenia właściwości dostawcy, które zazwyczaj ustalane
są przez takie polecenia jak CommandTimeout. Ostatnia zakładka, Wszystkie, jest podsumowaniem wszystkich wybranych
właściwości.
107 Rozdział 7. ♦ Zaawansowane ADO
Rysunek 7.1.
Tworzenie nowego
pliku UDL
Rysunek 7.2.
Wybór dostawcy
OLE DB
Rysunek 7.3.
Wprowadzanie
informacji
o połączeniu
Teraz, gdy utworzyłeś już plik UDL, możesz umieścić go w kodzie VBA, aby utworzyć w ADO obiekt Connection.
Składnia jest prosta. Utwórz obiekt Connection, tak jak to zwykle robisz, i użyj obiektu Open. Następnie wskaż plik UDL
za pomocą identyfikatora File Name:
Dim conn As ADODB.Connection
Set conn = New ADODB.Connection
Conn.Open "File Name=c:\chapter7.udl;"
' Porządki
rst.Close
conn.Close
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Rysunek 7.4.
Zarządzanie
plikami UDL
Rysunek 7.5.
Ustawianie
odnośnika na
Microsoft OLE DB
Service Component
1.0 Type Library
Po ustawienie odwołania możesz rozpocząć zarządzanie plikami UDL. Dodatkowo możesz poprosić użytkownika o
podanie informacji o połączeniu OLE DB poprzez okna dialogowe UDL. Możliwość ta jest przydatna w prototypowych
aplikacjach lub wersjach demonstracyjnych produktów przeznaczonych dla użytkowników zaznajomionych z
funkcjonowaniem Microsoft Data Links. Możesz tego dokonać, wykorzystując metodę PromptNew obiektu DataLinks.
Kod na wydruku 7.2 prosi użytkownika o podanie informacji o połączeniu OLE DB poprzez okno dialogowe UDL, a
następnie łączy się z bazą danych i otwiera zestaw rekordów.
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Część II ♦ Dostęp do danych 110
rst.MoveNext
Loop
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
procedur pobierających dane z nierelacyjnych źródeł (np. folder z plikami) i zwracających zestaw rekordów. Dzięki ADO
aplikacja może przez cały czas współpracować z zestawami rekordów, a kod aplikacji jest dużo prostszy. Poniższy
przykład przedstawia sposób utworzenia zestawu rekordów zawierającego nazwy plików znajdujących się w określonym
folderze. Jeśli umieścisz ten kod w module, będziesz go mógł użyć w wielu aplikacjach. Przykładowo, my
wykorzystaliśmy go do sporządzenia listy wszystkich plików typu ZIP w katalogu serwera FTP, a następnie przejrzenia ich
i utworzenia strony, z której można te pliki pobrać. Przewagą tej techniki nad dostawcą NT Active OLE DB jest fakt, iż
działa ona w systemie Windows 95. Wydruk 7.4 przedstawia w jaki sposób można otworzyć zestaw rekordów oparty na
liście nazw plików w folderze.
With rst
'Wykonaj operacje lokalne
.CursorLocation = adUseClient
'Otwórz rst
.Open , , adOpenStatic, adLockBatchOptimistic
strPath = Dir
Loop
.MoveFirst
'Wydrukuj pliki
Do Until .EOF
Debug.Print !FileName
rst.MoveNext
Loop
End With
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Kształtowanie danych
Umożliwienie przeglądania danych w zhierarchizowany sposób w obiektach ADO jest bardzo proste. Możesz użyć nowej
zdolności ADO, o nazwie Data Shaping (ang. kształtowanie danych), aby przeglądać nadrzędne i podrzędne rekordy w
jednym zestawie. Możesz użyć dostawcy MSDataShape OLE DB do tworzenia hierarchii opartych na relacjach i hierarchii
grupowania. Tworzenie tego typu hierarchicznych zestawów rekordów może ułatwić dość pracochłonną obróbkę
hierarchicznych danych. Przykładowo, na rysunku 7.6 znajduje się grupowa hierarchia wszystkich zamówień klientów z bazy
Northwind, przeglądana w nowej siatce o nazwie Microsoft Hierarchical FlexGrid (wersja OLAP popularnej FlexGrid).
Formant ten dołączony jest do pakietu Office 2000 w wersji Developer Edition oraz do Visual Basic 6 (nasze wartości i listingi
napisane zostały w VB 6 i używają bazy danych Accessa jako źródła danych). Zwróć uwagę na znak plus znajdujący się przy
każdym z rekordów. Umożliwia on rozszerzanie każdego z rekordów i przeglądanie jego szczegółów, co przedstawia rysunek
7.7. Zanim powstał dostawca MSDataShape OLE DB, utworzenie takiej siatki wymagało napisania wielu linijek kodu.
Część II ♦ Dostęp do danych 112
Rysunek 7.6.
Zestaw rekordów
uzyskany poprzez
dostawcę
MSDataShape OLE
DB w Visual Basic
Rysunek 7.7.
Zestaw rekordów
GrupujWedług
w Visual Basic
'Pokaż RST
Set frmADO.MSHFlexGrid1.Recordset = rst
End Sub
Jak widać w tym fragmencie kodu, musisz użyć specjalnej, powiązanej z Data Shaping składni SQL. Kompletną listę
zastosowań tej składni znajdziesz w dostarczanym wraz z Visual Basic 6 i pakietem Office Developer 2000 dokumentacji
MSDN oraz na stronie WWW pod adresem http://www.microsoft.com/data. Możesz również użyć tego kodu do operacji
Data Shaping i przeniesienia danych do programu Microsoft Excel. Kod na wydruku 7.6 przedstawia sposób, jak za
pomocą poprzedniego przykładu przenieść dane do arkusza programu Excel.
rst.ActiveConnection = strConnect
'Pokaż RST
ShowRSTinExcel rst
End Sub
intCurrentRow = intCurrentRow + 1
Next
rst.MoveNext
Loop
Cells(1, 1).Select
End Sub
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Dodawanie rekordu
Dodawanie rekordu przebiega w prawie identyczny sposób jak edycja. Musisz otworzyć zestaw rekordów i użyć metody
AddNew. Tak samo jak w przypadku Edit tak i w przypadku Update zastosowanie mają te same zasady. Po dodaniu
rekordu będziesz się znajdował w aktualnym rekordzie. Wydruk 7.8 zawiera przykład dodawania rekordu do tabeli.
With rst
' Otwarcie tabeli
.Open "Authors", CurrentProject.Connection, _
adOpenDynamic, adLockOptimistic, adCmdTableDirect
' Teraz należy użyć AddNew
.AddNew
!AuthorFirstName = "Mike"
!AuthorLastName = "Smith"
.Update
' Po dodaniu rekordem bieżącym jest nowy rekord
MsgBox "ID nowego autora: " & !AuthorID
End With
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
115 Rozdział 7. ♦ Zaawansowane ADO
Być może zauważyłeś, że otwarłeś tabelę ze stałą adCmdTableDirect. Jeśli użyjesz tej stałej z typem kursora
adOpenDynaset i blokowaniem optymistycznym, osiągniesz taki sam efekt jak przy użyciu polecenia dbOpenTable w
DAO. Tabela 7.3 zawiera wszystkie opcje kursorów i blokowania ADO oraz ich odpowiedniki w DAO.
Tabela 7.3.
Kombinacje obiektów ADO dla Accessa
Tabela 7.3.
Kombinacje obiektów ADO dla Accessa (ciąg dalszy)
u adPersistXML.
Jeśli wybierzesz format adPersistADTG lub adPersistXML, będziesz mógł później z łatwością otworzyć ten plik w
ADO. Wydruk 7.9 przedstawia, jak otworzyć zestaw rekordów, zmienić rekord, zapisać zmiany do pliku, otworzyć go
ponownie i włączyć z powrotem do bazy.
Wydruk 7.9. Zapisywanie zestawu rekordów na dysku, jego ponowne otwarcie i ponowne włączenie do bazy danych
Sub RstPersistence Save()
' Przykład pobrania wyniku, odłączenia od bazy danych
' zapisu na dysk a następnie synchronizacji z bazą
' Synchronizacja zachodzi w RstPersistence_Open
' Z książki "Access 2000 Księga eksperta" (Helion)
' Autorzy: Forte, Howe, Ralston
rst.Close
Set rst = Nothing
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
117 Rozdział 7. ♦ Zaawansowane ADO
Rysunek 7.8.
Microsoft ADO Ext.
2.1 For DDL and
Security
Obiekt Catalog
Gdy korzystasz z ADOX, wszystko co robisz związane jest z obiektem Catalog. Catalog oznacza bazę danych. Pracując
w Accessie, musisz jedynie ustawić właściwość tego obiektu, ActiveConnection, na prawidłowy obiekt Command.
Dim cat As ADOX.Catalog
Set cat = New ADOx.Catalog
'Wskaż obiektowi Catalog
'aktualną bazę danych
cat.ActiveConnection = CurrentProject.Connection
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Część II ♦ Dostęp do danych 118
cat.Tables.Append tbl
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Jako Link Datasource podaj ścieżkę dostępu do bazy danych, do której chcesz się dołączyć. Jako Remote Table
Name ustaw nazwę tej bazy. Cały przykład znajduje się na wydruku 7.12.
tbl.Name = "Customers_Połączona"
' Skrót dla tworzenia tabel
Set tbl.ParentCatalog = cat
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Istnieją inne właściwości, które możesz ustawić dla obiektu Column. Umieściliśmy je w tabeli 7.4 wraz z ich
odpowiednikami w DAO.
Tabela 7.4.
Właściwości obiektu Field
Tworzenie indeksu
Tworząc indeks w ADOX, będziesz musiał użyć klucza obiektu. Po jego utworzeniu musisz dołączyć do niego pole, a
następnie określić, czy ma to być klucz podstawowy czy unikatowy i jaka ma być kolejność sortowania:
Set idx = New Adox.Index
'Teraz ustalamy, że będzie to klucz podstawowy,
'sortowany w kolejności malejącej
With idx
.Name = 'Primary Key'
.Columns.Append "CustomerID"
.Columns("CustomerID").SortOrder = adSortDescending
.IndexNulls = adIndexNullsDisallow
.PrimaryKey = True
End With
'Dołączenie indeksu do tabeli
tbl.Indexes.Append idx
Właściwość IndexNulls ustawiona jest domyślnie na adIndexNullsDisallow, co oznacza, że wartości Null nie są w
indeksie dopuszczalne i w przypadku, gdy pole w indeksie będzie taką wartość zawierać, żaden wpis do indeksu nie
zostanie dokonany. W tabeli 7.5 znajdują się wartości akceptowane przez właściwość IndexNulls, wraz z ich
odpowiednikami w DAO.
Tabela 7.5.
Wartości dla właściwości IndexNulls
Kod na wydruku 7.13 łączy te wszystkie przykłady, tworząc tabelę pola Autonumerowanie i indeks klucza głównego w tej
tabeli.
'Obiekty ADOX
Dim cat As ADOX.Catalog
Dim tbl As New ADOX.Table
Dim idx As ADOX.Index
'Sprzątamy
Set cat = Nothing
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Gdy odnosisz się do kwerendy w Accessie, musisz pamiętać, że Microsoft Jet 4.0 zarządza wszystkimi tabelami, kwerendami,
polami i indeksami za Ciebie. Microsoft Jet definiuje kwerendy Accessa na dwa sposoby:
u widoki;
u procedury.
Przez widok rozumiemy zwracającą wiersze, nieparametryczną kwerendę, podczas gdy procedura oznacza wszystkie inne
kwerendy.
Tworzenie widoku
Microsoft Jet zajmie się za Ciebie definiowaniem kwerendy. By utworzyć widok, należy utworzyć kwerendę poprzez
obiekt Command (wydruk 7.15).
Tworzenie procedury
Tworzenie procedury jest równie proste jak tworzenie widoku. Wystarczy zdefiniować właściwość Commandtext i
dołączyć go do obiektu catalog (wydruk 7.16).
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Zauważysz, że w kodzie ADO znajdującym się na wydruku 7.17 ustawienie właściwości Command obiektu Procedure na
zmodyfikowany obiekt Command powoduje zapisanie zmian. Gdybyśmy nie umieścili tego ostatniego kroku, zmiany nie
zostałyby umieszczone na stałe w bazie danych. Różnica ta wynika z faktu, iż obiekty Command zostały zaprojektowane jako
tymczasowe. Fakt ten ma duże znaczenie, gdyż w DAO obiekty Querydefs uważane były za trwałe. Może Ci się wydawać,
że poniższe fragmenty kodu ADO są równoznaczne:
Set cmd = cat.Procedures("qryEmployeesRegion").Command
cmd.CommandText = "Parameters [@Region] Text;" & _
"Select * from Employees where Region = [@Region]"
Set cat.Procedures("qryEmployeesRegion").Command = cmd
oraz
cat.Procedures("qryEmployeesRegion").CommandText = _
"Parameters [@Region] text;" & _
"Select * from Employees where Region = [@Region] "
Mimo iż pozornie wygląda na to, że działają podobnie, drugi fragment kodu nie spowoduje rzeczywistej aktualizacji
kwerendy w bazie. W drugim przykładzie możesz użyć obiektu Command z jego nowym SQL w kodzie VBA. Jednakże
kiedy zakończysz pracę, zmiany w SQL nie zostaną zapisane w bazie. W pierwszym przypadku, ponieważ nakazujesz
zapisanie cmd, zmiany zostaną uwzględnione w bazie danych.
Część III
Interfejs użytkownika
W tej części:
u Projektowanie formularza.
u Rozbudowa formularzy przy użyciu formantów ActiveX.
u Raporty.
Rozdział 8.
Projektowanie formularza
W tym rozdziale:
u Właściwości formularza.
u Formanty formularza w Accessie.
Formularze decydują o powodzeniu tworzonej aplikacji. Nie dlatego, że są one sercem aplikacji Accessa, lecz dlatego, że
to na pracy z nimi użytkownicy spędzają najwięcej czasu. Dlatego też Twórcy programu dołożyli wszelkich starań, by
formularze w Accessie były jednocześnie proste i potężne.
W rozdziale tym nie zamierzamy wyjaśnić wszystkich szczegółów dotyczących tworzenia formularzy w Accessie (temat ten
jest bardzo obszerny i istnieje wiele dobrych książek, zarówno dla początkujących jak i doświadczonych użytkowników). Aby
przekazać Ci jak najwięcej szczegółów zanadto się nie rozpisując, skupimy się na niektórych ustawieniach i właściwościach
formularza, które mogą ułatwić proces tworzenia oraz pomóc w uzyskaniu rozbudowanego zestawu funkcji. Następnie
przyjrzymy się zastosowaniu niektórych formantów Accessa i pokażemy, jak możesz wykorzystać je w tworzeniu for-
mularzy będących czymś więcej niż tylko narzędziem do wprowadzania danych. Po przeczytaniu tego rozdziału będziesz w
stanie projektować formularze, które nie tylko będą dostarczać użytkownikom szerokiego zestawu funkcji, ale jednocześnie
będą łatwe w obsłudze i estetyczne.
Na początku tego rozdziału przyjrzymy się właściwościom i ustawieniom w Accessie 2000. Następnie przejdziemy do
bardziej zaawansowanych formantów w Przyborniku Accessa, a zwłaszcza pól listy i pól wyboru. Później przyjrzymy się
użyciu przycisków polecenia i przycisków opcji, a następnie pokażemy, jak zwiększyć funkcjonalność formularza i
ograniczyć ilość stron i niepotrzebnych formantów, wykorzystując do tego celu podformularze.
Na koniec przyjrzymy się dołączonym do pakietu Office 2000 w wersji Developer Edition formantom ActiveX oraz
sposobom ich wykorzystania w celu powiększenia zestawu funkcji aplikacji.
Właściwości formularza
Określając właściwości formularza w Accessie 2000, możesz wybierać spośród 81 zdefiniowanych właściwości,
znajdujących się na zakładce Właściwości (rysunek 8.1). Dokładne ich omówienie zajęłoby całą książkę. My skupiliśmy się
na tych właściwościach, które będą miały wpływ na Twoją pracę jako programisty.
Rysunek 8.1.
Okno dialogowe
Właściwości
formularza
Część III ♦ Interfejs użytkownika 126
Zakładka Dane
Formularze w Accessie 2000 są ściśle powiązane z ukrywającymi się za nimi danymi. Możesz bez trudu utworzyć
formularz i rozpocząć wprowadzanie danych bez pisania ani jednej linii kodu. Możesz to zrobić dzięki właściwościom
znajdującym się na zakładce Dane, które jak sama nazwa wskazuje opisują sposób, w jaki formularz powinien przed-
stawiać i współpracować z danymi.
Źródło rekordów
To chyba najczęściej wykorzystywana właściwość formularza. Dzięki niej możesz powiązać formularz z dowolną tabelą,
kwerendą, wyrażeniem SQL lub czymkolwiek innym. Właściwość ta, zależnie od potrzeb, może być określana podczas
projektowania lub też uruchamiania formularza.
Edycja dozwolona
Po ustawieniu tej właściwości na Tak użytkownicy będą mogli modyfikować dane na formularzu. Inaczej będzie w
przypadku ustawienia Nie. Dzięki temu można w prosty sposób utworzyć formularz tylko do odczytu.
Usuwanie dozwolone
Po ustawieniu tej właściwości na Tak użytkownicy będą mogli usuwać rekordy z formularza. Dzięki tej właściwości masz
kontrolę nad tym, którzy z użytkowników mogą usuwać rekordy z bazy danych.
Dodawanie dozwolone
Po ustawieniu tej właściwości na Nie użytkownicy nie będą mogli dodawać do bazy nowych rekordów. Rozwiązanie to jest
wygodne w sytuacji, gdy wyświetlasz rezultaty kwerendy w widoku arkusza danych, ale nie chcesz, by użytkownicy
dodawali na końcu zestawu rezultatów nowe rekordy.
Wprowadzanie danych
Ustawienie tej właściwości na Tak spowoduje, iż użytkownicy będą mieli możliwość dodawania nowych rekordów,
jednakże bez możliwości przeglądania już istniejących.
Generalnie, użycie tych właściwości może okazać się nieprzydatne. Używając kwerendy we właściwości Źródło rekordów,
możesz za jednym razem określić parametry i kolejność sortowania. Co więcej, we właściwości Źródło rekordów możesz
skorzystać z optymalizowanych kwerend, co jeszcze bardziej przyśpiesza pracę.
Zakładka Format
Formularze są tymi obiektami, które użytkownik ogląda. Może nie są najważniejszą częścią aplikacji, jednak użytkownicy
o tym nie wiedzą. Wyrabiają sobie opinię na temat aplikacji właśnie na podstawie formularzy. Sposób, w jaki wyglądają,
zachowują się i ułatwiają (bądź utrudniają) codzienne zadania użytkownikom jest bardzo ważny zarówno dla tych
ostatnich, jak i dla Ciebie. Ustawienie właściwości związanych z formatem umożliwi kontrolowanie wyglądu tworzonych
formularzy.
Widok domyślny
Ustawienie tej właściwości nakazuje Accessowi otwarcie formularza w określony sposób. Masz do wyboru następujące
możliwości:
127 Rozdział 8. ♦ Projektowanie formularza
Dostępne widoki
Ustawiając tę właściwość, możesz ograniczyć ilość sposobów, na jakie użytkownicy będą przeglądać dane. Opcja ta jest
bardzo przydatna, gdy chcesz, aby użytkownicy widzieli tylko jeden rekord jednocześnie lub jedynie dane w arkuszu
danych. Masz do wyboru następujące ustawienia:
u Formularz.
u Arkusz danych.
u Oba.
Paski przewijania
Właściwość ta umożliwia Ci wyłączenie lub włączenie pionowego i poziomego paska przewijania w formularzu.
Selektory rekordów
Właściwość ta włącza lub wyłącza znajdujące się po lewej stronie formularza selektory rekordów. W przypadku
pojedynczych formularzy właściwość ta jest zazwyczaj wyłączona. Dobrze jest jednak ją włączyć w formularzach ciągłych
i arkuszu danych.
Przyciski nawigacyjne
Jeśli chcesz, by Access zajął się przemieszczaniem się po rekordach, ustaw tę właściwość na Tak. Jeśli chcesz tę operację
wykonywać własnoręcznie, wybierz Nie. Pasek nawigacyjny nie będzie wówczas wyświetlany.
Styl obramowania
Formularze w Accessie, w zależności od ich przeznaczenia, mogą być wyświetlane w różnych rodzajach obramowań:
u Zmienny – umożliwia użytkownikom zmianę rozmiaru formularza. Na oknie umieszczone są przyciski Minimalizuj
i Maksymalizuj.
u Dialog – powoduje określenie stałego rozmiaru formularza. Przyciski Minimalizuj i Maksymalizuj są wyłączone.
Ustawienie to doskonale nadaje się do okien komunikatu i rozwijanych formularzy.
u Cienki – powoduje określenie stałego rozmiaru formularza. Przyciski Minimalizuj i Maksymalizuj są włączone.
u Brak – brak jakiegokolwiek obramowania. Ustawienie to sprawdza się w przypadku ekranów tytułowych.
Przycisk Zamknij
Gdy ustawisz tę właściwość na Tak, użytkownicy będą mogli używać menu kontrolnego do zamykania formularza.
Zakładka Inne
Właściwości znajdujące się w tej kategorii są równie ważne jak te opisane powyżej. Opisują kilka bardzo ważnych
aspektów zachowania się formularza i pełnią rolę zestawu zaawansowanych właściwości, służących do wykańczania
formularza. Nowością w tej wersji Accessa jest opisana poniżej właściwość Zezwolenie na zmiany projektu.
Modalny
Gdy właściwość ta ustawiona jest na Tak, po otwarciu formularza żaden inny formularz nie będzie dostępny przed
zamknięciem formularza modalnego. Opcja ta sprawdza się jako komunikat o błędzie lub nakaz wykonania przez
użytkownika określonych czynności przed przejściem dalej.
Podręczny
Formularze podręczne są formularzami podrzędnymi w stosunku do okna Accessa. Odróżnia to je od pozostałych
formularzy, które są podrzędne w stosunku do formularza, w którym zostały otwarte. Oznacza to, że formularze podręczne
mogą być umieszczone w dowolnym miejscu na pulpicie Accessa.
Menu podręczne
Gdy ustawisz tę właściwość na Tak, za każdym razem, gdy użytkownik użyje na formularzu prawego klawisza myszy,
zostanie wyświetlone menu, które wybrałeś we właściwości Pasek menu podręcznego.
Metka
Właściwość ta może przechowywać dowolną, wybraną przez Ciebie wartość. Możesz pobrać ją z dowolnego miejsca w
aplikacji i zostanie ona zapisana wraz z formularzem.
Ma moduł
Po ustawieniu tej właściwości na Nie Access usunie cały kod, na którym oparty jest formularz. W ten sposób
„odchudzony” formularz bardzo szybko się ładuje.
Jeśli formularz nie zawiera kodu, koniecznie ustaw tę właściwość na Tak. W ten sposób Access nie będzie próbował
kompilować formularza za każdym jego ładowaniem. Nie pisząc kodu, możesz dodatkowo poprawić funkcjonalność
formularza, wstawiając do niego hiperłącze (opisane w dalszej części tego rozdziału) i łącząc go z obiektem w bazie
danych (rysunek 8.2).
129 Rozdział 8. ♦ Projektowanie formularza
Rysunek 8.2.
Okno dialogowe
Wstaw hiperłącze
Użyteczne właściwości
nie znajdujące się na arkuszu właściwości
Jak zawsze, rzeczy ukryte są dla nas bardziej interesujące niż te ogólnodostępne. Zasada ta ma zastosowanie do ukrytych
właściwości formularza. W tym przypadku ukryte właściwości ułatwiają tworzenie w Accessie wykorzystujących
formularze, złożonych aplikacji.
Właściwość ArgumentyOtwarcia przydaje się, gdy do zbierania żądanych informacji używasz formularzy modalnych. Jeśli
chcesz sformatować formularz w inny, zgodny z logiką aplikacji sposób, możesz użyć ArgumentyOtwarcia do wysłania
„wiadomości” do formularza i pobrania jej podczas zdarzenia Form_Open. W trakcie trwania zdarzenia możesz zmienić
wygląd formularza lub zablokować możliwość poruszania się między rekordami, by skoncentrować się na tym rekordzie,
który musisz edytować. Po otwarciu formularza jako okna dialogowego nie będziesz mógł go programowo modyfikować,
więc jedynym sposobem na zapewnienie zgodności z logiką aplikacji będzie użycie właściwości ArgumentyOtwarcia.
Właściwości użytkownika
W sekcji ogólnych deklaracji formularza zadeklarowanie zmiennej jako jawnej lub niejawnej spowoduje utworzenie
właściwości użytkownika. Aby właściwość ta była dostępna również dla innych modułów, musisz zadeklarować zmienną
właściwości jako jawną. Jeśli istnieje potrzeba udostępnienia tej właściwości innym formularzom lub jeśli będziesz chciał
dodać walidację przy pobieraniu bądź ustawianiu tej właściwości, możesz do walidacji wykorzystać metody Property
Get i Property Let.
Załóżmy, że tworzysz aplikację przetwarzającą prawa jazdy i jednym z wymagań jest to, że wiek kierowcy musi być
większy niż 16 lat. Do rozwiązania problemu odczytu i zapisu tej właściwości mógłbyś napisać poniższą regułę
poprawności.
W deklaracjach ogólnych:
' Utwórz w pamięci zmienną intMyAge.
Dim intMyAge as Integer
' Użyj tego kodu, by odczytać wartość wejściową i sprawdzić, czy
Część III ♦ Interfejs użytkownika 130
Użyj tego kodu, aby dodać metodę Property Get. Dzięki temu kod będzie dostępny na zewnątrz formularza.
Public Property Get MyAge() as Integer
MyAge = intMyAge
End Property
Gdy chcesz zobaczyć utworzoną właściwość w oknie rozwijanej listy IntelliSense (tak jak ją kodujesz), musisz
zadeklarować zmienną formularza typu Form_nazwa_twojego_formularza.
Zdarzenia
Access posiada ponad 30 zdarzeń, które pomagają kontrolować działanie programu. Bardzo ważnym jest, byś wiedział, w
jakiej kolejności zdarzenia te następują. Poniżej znajdziesz informacje na temat kolejności występowania zdarzeń w
różnych okolicznościach. Niektóre z tych zdarzeń pomijają parametr Cancel (Anuluj), który może być ustawiony na
True, jeśli chcesz zatrzymać otwieranie lub zamykanie formularza. Gdy ustawisz parametr Cancel na True, Access po
zatrzymaniu zdarzenia kontynuuje działanie, wyświetlając komunikat o błędzie 2501. Musisz naprawić ten błąd, w prze-
ciwnym wypadku narażasz się na ryzyko kolejnego błędu Accessa (rysunek 8.3).
Rysunek 8.3.
Błąd Accessa 2501,
wyświetlany po
ustawieniu
parametru Cancel
na True
Działanie systemu operacyjnego Windows oparte jest na zdarzeniach. Oznacza to, iż poza wewnętrznym zegarem
komputera jedynym źródłem działania jest użytkownik. System operacyjny w przeciągu kilku nanosekund odpowiada na
uruchamiane zdarzenia i przekazuje je do aktywnej aplikacji. Na następnej stronie umieściliśmy listę zdarzeń uru-
chamianych podczas pracy użytkownika z formularzem w Accessie.
Otwarcie formularza
Podczas otwierania formularza określone zdarzenia uruchamiane są w przedstawionej poniżej kolejności. Po ustawieniu
parametru Cancel na True, wykonywanie zdarzeń jest zatrzymywane.
15. Otwórz (z opcją Anuluj).
16. Załaduj.
17. Zmień rozmiar.
18. Aktywuj.
19. Aktualny.
20. Wejście do pierwszego formantu.
21. Uzyskanie fokusu przez pierwszy formant.
Jeśli w formularzu umieszczony jest podformularz, następujące zdarzenia wykonywane są PRZED zdarzeniem otwarcia
głównego formularza:
1. Otwórz (z opcją Anuluj).
2. Załaduj.
3. Zmień rozmiar.
131 Rozdział 8. ♦ Projektowanie formularza
4. Aktualny.
5. Wejście do pierwszego formantu.
6. Uzyskanie fokusu przez pierwszy formant.
Umożliwia to uzyskanie dostępu do pól podformularza z poziomu zdarzenia Otwórz głównego formularza i w razie
potrzeby daje możliwość anulowania.
Zamknięcie formularza
Podczas zamykania formularza określone zdarzenia uruchamiane są w przedstawionej poniżej kolejności. Po ustawieniu
parametru Cancel na True wykonywanie zdarzeń jest zatrzymywane.
7. Wyładuj (z opcją anuluj).
8. Dezaktywuj.
9. Zamknij.
Maksymalizowanie formularza
Gdy formularz jest maksymalizowany, określone zdarzenia uruchamiane są w przedstawionej poniżej kolejności.
12. Zmień rozmiar.
Przykładowo, przyjmijmy, że utworzyłeś listę rozwijaną z klientami i wprowadzono klienta, którego jeszcze nie było na
liście. Korzystając z poniższego kodu, mógłbyś wyłapać ten błąd i zapytać użytkownika, czy chce utworzyć nowego
klienta:
Dim MyResponse AS Variant
Dim Msg As String
Część III ♦ Interfejs użytkownika 132
Else
End If
To wszystko!
Oto fragment kodu, znajdujący się w bazie danych Solutions.mdb, który przedstawia sposób, jak dodać u góry listy
rozwijanej wartość specjalną Wszystkie.
Function AddAllToList(ctl As Control, lngID As Long, _
lngRow As Long, lngCol As Long, intCode As Integer) As Variant
intDisplayCol = 1.
strDisplayText = "(Wszystkie)"
If Not IsNull(ctl.Tag) Then
intSemiColon = InStr(ctl.Tag, ";")
If intSemiColon = 0 Then
intDisplayCol = Val(ctl.Tag)
133 Rozdział 8. ♦ Projektowanie formularza
Else
intDisplayCol = Val(Left(ctl.Tag, intSemiColon - 1))
strDisplayText = Mid(ctl.Tag, intSemiColon + 1)
End If
End If
Bye_AddAllToList:
Exit Function
Err_AddAllToList:
MsgBox Err.Description, vbOKOnly + vbCritical, "AddAllToList"
AddAllToList = False
Resume Bye_AddAllToList
End Function
Pole listy
Pole listy przypomina opisaną powyżej listę rozwijaną. Różnica tkwi w możliwości przeglądania wszystkich możliwych
wartości bez konieczności rozwijania listy. Również w przeciwieństwie do listy rozwijanej, pole listy umożliwia wybranie
kilku wartości jednocześnie. Opcja ta przydaje się w sytuacji, gdy chcesz umożliwić użytkownikowi w tworzonym przez
Ciebie systemie przeglądanie informacji o 5 ze 100 wpisów (faktury, ludzie, płyty CD czy ciężarówki). Ponieważ większość
właściwości pola listy została już opisana, skoncentrujemy się na różnicach.
Ustawienia właściwości
Aby używać pola listy wielokrotnego wyboru, musisz najpierw utworzyć zwykłe pole listy i później przekształcić je w pole
wielokrotnego wyboru. Możesz tego dokonać, zmieniając znajdującą się na arkuszu właściwości obiektu właściwość Wybór
wielokrotny. W tabeli 8.1 znajdują się możliwe ustawienia.
Tabela 8.1.
Ustawienia właściwości Wybór wielokrotny
Wartość Znaczenie
Brak Wybór wielokrotny nie jest możliwy.
Prosty Elementy wielokrotne wybierane są przez kliknięcie myszką lub naciśnięcie
klawisza spacji.
Rozszerzony Elementy wielokrotne wybierane są przez przytrzymanie klawisza Shift i kliknięcie ich
myszką lub przez przytrzymanie klawisza Shift i naciśnięcie klawisza strzałki (powoduje to
rozszerzenie zaznaczenia od poprzednio wybranego do aktualnego elementu). Możesz
również zaznaczać elementy, przeciągając je myszką. Przytrzymanie klawisza Ctrl
i klinięcie go myszką powoduje jego zaznaczenie lub zniesienie zaznaczenia.
Aby pobrać wartości, będziesz musiał posłużyć się kodem. Przykładowo, by odczytać wartości z listy pracowników,
mógłbyś napisać następujący fragment kodu:
Dim strMsg As String
Dim strName As String
Dim i As Integer
For i = 1 To Me.lstMulti.ListCount
Kod ten nie tylko odczytuje wartości z pola listy, ale również wykorzystuje właściwość column w celu pobrania wartości z
więcej niż tylko jednej, związanej kolumny.
Podformularze
Podformularze zawsze były świetnym sposobem na prezentowanie danych w relacji jeden-do-wielu. Korzystając z
nadrzędnego i podrzędnego pola łączącego, programiści mogą z łatwością powiązać ze sobą dane w relacji.
Podformularze posiadają jeszcze jedną bardzo przydatną cechę. Zmieniając właściwość Obiekt źródłowy, programiści mogą
wstawiać do jednego, głównego formularza nieograniczoną ilość podformularzy. Dzięki temu, programiści mogą tworzyć
własne zbiory obiektów, czyli coś, czego nie można było zrobić w Visual Basicu. Zbiory te umożliwiają grupowanie
obiektów i odnoszenie się do nich jako całości.
Dodatkowo, podformularze są doskonałym sposobem na obejście dwudziesto-dwu calowego limitu długości formularzy w
Accessie. Podformularze umożliwiają również szybsze ładowanie formularzy, gdyż nie muszą ładować każdego formularza,
pola listy czy pola memo, którego mógłby potrzebować użytkownik. Programiści mogą kontrolować sposób przedstawiania
danych i ograniczać ilość elementów graficznych lub innych zasobochłonnych obiektów.
Dodawanie podformularzy
Istnieją trzy sposoby dodawania do formularza podformularzy:
135 Rozdział 8. ♦ Projektowanie formularza
u Po otwarciu formularza w widoku Projekt wybierz z przybornika obiekt Podformularz i przeciągnij go na główny
formularz. Utworzony zostanie pusty podformularz. Następnie dodaj obiekt źródłowy oraz nadrzędne i podrzędne
pole łączące.
u Drugi sposób jest jeszcze prostszy. Otwórz główny formularz w widoku Projekt i przejdź do okna bazy danych.
Przeciągnij formularz, którego chcesz użyć jako podformularza z okna bazy danych na główny formularz. Access
spróbuje połączyć nadrzędne i podrzędne pola i ustawić za Ciebie obiekt źródłowy. Access ustawi również
rozmiar podformularza tak, by dobrze pasował do okna głównego formularza. Ręczne wykonywanie tej czynności
może czasami przysporzyć wielu trudności.
u Użyj dołączonego do Accessa kreatora podformularzy.
Metoda ta uległa znacznemu poprawieniu w Accessie 2000, ponieważ zbiór formantów jest domyślnym zbiorem dla
formularza. Teraz możesz stworzyć odniesienie dla tego samego obiektu w następujący sposób:
Forms!MyForm!SubFormControlName!ControlName
lub
Me!MyForm!SubFormControlName!ControlName
Rysunek. 8.4.
Przybornik
z wciśniętym
przyciskiem Kreatora
formantów
Grupa opcji
Programiści Visual Basica mieli do swojej dyspozycji tablice obiektów (czyli możliwość tworzenia odniesień do grupy
formantów za pomocą tej samej nazwy, lecz innego indeksu). Dzięki temu możliwe było znaczne uproszczenie procesu
ustawiania właściwości lub zmiany wartości. Niestety, poza formantem Grupa opcji, w Accessie 2000 nie ma takiej
możliwości.
Dzięki temu formantowi, możesz wewnątrz ramki umieścić pola wyboru, przyciski opcji lub przyciski przełącznika, a
następnie tworzyć odniesienia do każdego obiektu według wartości jego indeksu. Możesz jednym poleceniem (zamiast
pięciu czy sześciu) włączać lub wyłączać właściwość Widoczny obiektów wewnątrz ramki. Możesz także używać
konstrukcji For Each, aby przejść przez wszystkie wartości wewnątrz grupy opcji, zamiast testować każdą z nich osobno.
Część III ♦ Interfejs użytkownika 136
Podręczne menu
Podręczne menu pojawiły się wraz z systemem Windows 95. Większość z tych użytkowników, którzy z Windows 95
powrócili do Windows 3x, przeklina niemożność korzystania z prawego przycisku myszy. Podręczne menu to doskonały
sposób na skrócenie wykonywania najpopularniejszych czynności lub umożliwienie korzystania z charakterystycznych dla
danego obiektu opcji. Formularze, a nawet pojedyncze formanty, mogą posiadać swoje własne menu podręczne, a odrobina
kodu pomoże Ci na bieżąco modyfikować wygląd pasków poleceń.
Aby utworzyć podręczne menu, kliknij dowolny pasek narzędzi lub pasek menu i wybierz Dostosuj. Możesz również wybrać z
menu Widok pozycję Paski narzędzi⇒Dostosuj.
15. Na zakładce Paski narzędzi kliknij Nowy...
16. W polu Nazwa paska narzędzi wpisz dowolną nazwę i kliknij OK.
17. Na zakładce Paski narzędzi kliknij Właściwości.
18. Z listy Typ wybierz Podręczny.
19. Ustaw właściwość Zezwalaj na dostosowanie w żądany sposób i kliknij Zamknij. Nie martw się, nie stracisz tego
paska.
20. W oknie Paski narzędzi kliknij Menu podręczne.
21. Na pasku narzędzi Menu podręczne kliknij kategorię Niestandardowe. Tam znajdziesz swoje nowe menu
podręczne.
22. Aby wykończyć menu, postępuj w następujący sposób:
Dodaj polecenia z okna dialogowego Dostosuj.
Przenoś lub kopiuj polecenia z innych menu.
Hiperłącza
Hiperłącza to niezmiernie przydatne formanty, umożliwiające użytkownikowi przechodzenie za jednym kliknięciem do
formularzy, raportów, arkuszy Excela, dokumentów Worda czy nawet stron WWW. Ponieważ nie kryją one za sobą kodu,
idealnie nadają się do formularzy nawigacyjnych. Można ich używać na „odchudzonych” formularzach (tych z
właściwością Ma moduł ustawioną na Nie). Hiperłącze jest niepołączoną etykietą (etykieta bez obiektu nadrzędnego) z
właściwościami Adres hiperłącza i Podadres hiperłącza ustawionymi na Null.
Rozdział 9.
Rozbudowa formularzy przy użyciu
formantów ActiveX
W tym rozdziale:
u Jak korzystać z formantów ActiveX.
u Użycie formantów ActiveX.
u 21 formantów ActiveX.
u Rozpowszechnianie formantów ActiveX.
Formanty ActiveX umożliwiają zwiększenie zestawu funkcji aplikacji pisanych w Accessie, ułatwiając ich tworzenie i
obsługę. Możliwości, jakie dają programistom, są nieograniczone.
Z tego rozdziału dowiesz się, jakie formanty ActiveX masz do swojej dyspozycji i nauczysz się dodawać je do formularzy
Accessa. Najpierw jednak powiemy, czym są i skąd wzięły się formanty ActiveX.
Formanty ActiveX pozwalają na wzbogacenie tworzonych aplikacji o funkcje, których nie udostępniał Access. Mógłby to
być, na przykład, kalendarz lub formant siatki. Formanty ActiveX są zazwyczaj przechowywane w folderze systemowym i
są plikami o rozszerzeniu OCX lub DLL.
Formanty ActiveX nie są częścią Accessa, jednakże mogą być używane w jego aplikacjach. Działają dokładnie w ten sam
sposób, co pozwala na uzyskanie wysokiej wydajności.
W tym rozdziale pokażemy, jak używać formantów ActiveX w formularzach Accessa, jednakże te same formanty mogą
być użyte w aplikacjach Visual Basic, Office, a nawet w aplikacjach działających w sieci WWW.
Formanty związane z procesem projektowania umieszczane są na formularzach Accessa, lecz nie są nigdy widoczne dla
ostatecznego użytkownika. Formanty te zawierają kod, który powiększa zestaw funkcji dostępnych dla programisty.
Widoczne są one w procesie projektowania, a nie podczas używania aplikacji, tak więc ostateczny użytkownik ich nie
widzi. Przykładem formantów związanych z procesem projektowania są formanty Image oraz Common Dialog.
Formanty wykorzystywane podczas użytkowania aplikacji zawierają interfejs użytkownika, który jest dla ostatecznego
użytkownika widoczny. Omówione w dalszej części tego rozdziału przykłady tego typu formantów to: Toolbar,
MonthView, ListView, a także wiele innych. Formanty tego typu widoczne są zarówno podczas fazy projektowania, jak i
podczas użytkowania aplikacji. W tej drugiej fazie użytkownicy mają możliwość manipulowania formantami w określony
sposób.
Ważnym jest, by dokładnie przeczytać dotyczącą formantu umowę licencyjną. Przykładowo, mogłeś otrzymać formanty
dokonując zakupu narzędzi programistycznych od firmy Microsoft. Przeczytaj umowę licencyjną, aby sprawdzić, czy
możesz korzystać z tych formantów i rozpowszechniać je bez dodatkowych opłat. Powinieneś postępować w ten sam
sposób, kupując formanty od innych firm.
Formanty, których nie kupowałeś, mogą pochodzić z Internetu. Najprawdopodobniej nie będziesz miał prawa do
umieszczania ich w swoich aplikacjach. Często, gdy próbujesz użyć formantu ActiveX w swojej aplikacji, wyświetlane jest
ostrzeżenie, że nie masz praw do używania i rozpowszechniania tego formantu.
Przestrzeganie umów licencyjnych jest zapewnione z mocy prawa. Niewłaściwe użycie bądź bezprawne
rozpowszechnianie formantu ActiveX jest tym samym co nielegalne kopiowanie oprogramowania. Może być ścigane jak
przestępstwo kryminalne albo pociągnąć za sobą roszczenia odszkodowawcze ze strony poszkodowanego.
139 Rozdział 9. ♦ Rozbudowa formularzy przy użyciu formantów ActiveX
Niektóre formanty ActiveX rejestrowane są automatycznie po ich zainstalowaniu. Aby zrobić to ręcznie, gdy formularz
otwarty jest w widoku Projekt, z menu Narzędzia wybierz pozycję Formanty ActiveX. Wyświetlone zostanie okno dialogowe
Formanty ActiveX. Wybierz formant, który chcesz zarejestrować i kliknij przycisk Zarejestruj. Wyświetlone zostanie okno
dialogowe Dodaj formant ActiveX. Wybierz odpowiadający wybranemu formantowi plik (.OCX) i kliknij OK. (rysunek 9.1).
Rysunek 9.1.
Okno dialogowe
Dodaj formant
ActiveX
Rysunek 9.2.
Znajdujący się
w Przyborniku
przycisk Więcej
formantów
Wyświetlone zostanie okno dialogowe Wstawianie formantu ActiveX. Wybierz formant, który chcesz dodać do formularza, i
kliknij przycisk OK. (rysunek 9.3). Okno dialogowe zostanie zamknięte. Na formularzu kliknij miejsce, w którym chcesz
umieścić formant.
Rysunek 9.3.
Wybierz formant
ActiveX, który chcesz
dodać do formularza
Po wstawieniu formantu Access zachowuje odniesienie do właściwej dla niego biblioteki. Aby wyświetlić wszystkie
odniesienia w aplikacji, otwórz edytor Visual Basic i z menu Tools wybierz pozycję References (rysunek 9.4).
Rysunek 9.4.
Formanty ActiveX
wyświetlone
w oknie
dialogowym
References
Rysunek 9.5.
Strona
z właściwościami
formantu
ImageList
141 Rozdział 9. ♦ Rozbudowa formularzy przy użyciu formantów ActiveX
Aby uzyskać informacje o właściwościach, metodach i zdarzeniach związanych z formantem, skorzystaj z narzędzia Object
Browser (rysunek 9.6).
Rysunek 9.6.
Korzystaj z narzędzia
Object Browser,
by uzyskać
informacje
o właściwościach,
metodach
i zdarzeniach
związanych
z formantem
21 formantów ActiveX
Teraz omówimy 21 formantów ActiveX. Można by oczywiście wiele napisać o wszystkich formantach ActiveX (których są
setki), ale niektóre z nich dostarczane są przez firmę Microsoft.
Tabela 9.1.
Przegląd formantów ActiveX
Tabela 9.1.
Przegląd formantów ActiveX (ciąg dalszy)
ImageList MSCOMCTL.OCX Zawiera bitmapy i obrazki, które mogą być używane przez
inne formanty
ListView MSCOMCTL.OCX Przedstawia dane na liście na cztery różne sposoby
MAPIMessages MSMAPI32.OCX Wysyła i odbiera wiadomości, wyświetla książki adresowe
i inne opcje związane z pocztą
MAPISession MSMAPI32.OCX Umożliwia rozpoczęcie i zamknięcie sesji MAPI
MonthViev MSCOMCT2.OCX Interfejs w formie kalendarza, umożliwiający przeglądanie
i wybieranie informacji o datach
ProgressBar MSCOMCTL.OCX Wyświetla informacje o stanie zaawansowania
danego procesu
RichText RICHTX32.OCX Umożliwia formatowanie tekstu w polach tekstowych
(zmianę rodzaju czcionki, jej koloru, rozmiaru i inne)
Slider MSCOMCTL.OCX Poziomy i pionowy suwak
StatusBar MSCOMCTL.OCX Umieszcza na formularzu pasek stanu
SysInfo SYSINFO.OCX Odbiera i wysyła informacje o systemie
TabStrip MSCOMCTL.OCX Rozmieszcza zakładki w rzędach i wyświetla na nich
rysunki
ToolBar MSCOMCTL.OCX Umieszcza na formularzu pasek narzędzi
TreeView MSCOMCTL.OCX Wyświetla dane w formacie hierarchicznym
UpDown MSCOMTC2.OCX Umożliwia użytkownikom zwiększanie i zmniejszanie
wartości innego formantu
WebBrowser SHDOCVW.DLL Wyświetla na formularzu przeglądarkę WWW
Formant Animation
Formant ten umożliwia odtwarzanie na formularzu Accessa plików wideo (.AVI) (rysunek 9.7).
Tabela 9.2 zawiera najczęściej używane właściwości i metody dla formantu Animation.
Rysunek 9.7.
Przykład formantu
Animation
Tabela 9.2.
Właściwości i metody dla formantu Animation
Obiekt Opis
143 Rozdział 9. ♦ Rozbudowa formularzy przy użyciu formantów ActiveX
Właściwość AutoPlay Jeśli właściwość ta jest ustawiona na True, plik AVI odtwarzany jest w pętli od
momentu jego załadowania do formantu. Przy ustawieniu False plik nie jest
odtwarzany aż do wywołania metody Play
Metoda Close Zamyka otwarty plik AVI
Metoda Open Otwiera plik AVI
Metoda Play Odtwarza załadowany do formantu plik AVI
Metoda Stop Zatrzymuje rozpoczęte za pomocą metody Play odtwarzanie pliku AVI
Formant Calendar
Formant Calendar wyświetla w formularzu Accessa kalendarz (rysunek 9.8).
Formant Calendar przydaje się do ustawiania i pobierania wartości daty. W zależności od ustawienia, może on zawierać
dzień, miesiąc i rok. Tabela 9.3 zawiera najczęściej używane właściwości, metody i zdarzenia dla formantu Calendar.
Tabela 9.3.
Właściwości, metody i zdarzenia dla formantu Calendar
Obiekt Opis
Właściwość Day Ustawia dzień miesiąca (1–31)
Właściwość Month Ustawia miesiąc
Właściwość ShowDateSelectors Wyświetla rozwijane pole listy selektora daty
Właściwość Value Ustawia lub pobiera wybraną datę
Właściwość Year Ustawia rok
Metoda NextDay Wyświetla następny dzień
Metoda PreviousDay Wyświetla poprzedni dzień
Metoda Today Wyświetla dzisiejszą datę
Zdarzenie Click Występuje, gdy użytkownik kliknie datę
Część III ♦ Interfejs użytkownika 144
Rysunek 9.9.
Przykład formantu
Common Dialog
Formant ten związany jest z procesem projektowania. Wystarczy wstawić formant do formularza i przywołać metodę
wyświetlającą żądane okno dialogowe. Poniższy kod powoduje wyświetlenie okna dialogowego Kolor:
Me.ActiveXCommonDialogControl.ShowColor
Tabela 9.4 zawiera najczęściej używane właściwości i metody dla formantu Common Dialog.
Tabela 9.4.
Właściwości i metody dla formantu Common Dialog
Obiekt Opis
Właściwość Color Pobiera kolor wybrany w oknach dialogowych Kolor i Czcionka
Właściwość Copies Ilość kopii do wydrukowania z okna dialogowego Drukuj
Właściwość Filter Określa typ lub nazwę pliku dla okien dialogowych Otwórz i Zapisz jako
Właściwość FontName Czcionka wybrana w oknie dialogowym Czcionka
Właściwość FontSize Rozmiar czcionki wybrany w oknie dialogowym Czcionka
Właściwość Orientation Orientacja strony (pionowa lub pozioma) z okna dialogowego Drukuj
Metoda ShowColor Wyświetla okno dialogowe Kolor
Metoda ShowFont Wyświetla okno dialogowe Czcionka
Metoda ShowHelp Wyświetla Pomoc
Metoda ShowOpen Wyświetla okno dialogowe Otwórz
Metoda ShowPrinter Wyświetla okno dialogowe Drukuj
Metoda ShowSave Wyświetla okno dialogowe Zapisz jako
Formant DateTimePicker
Formant DateTimePicker umożliwia wyświetlenie rozwijanego kalendarza, który ułatwia użytkownikom wprowadzanie
dat w formularzu (rysunek 9.10). Przypomina on formant daty programu Outlook, używany do planowania zajęć.
Rysunek 9.10.
Przykład formantu
DateTimePicker
Powyższy przykład przedstawia rozwijany kalendarz służący do wybierania daty. Użytkownik ma również możliwość
zmiany wprowadzonej w tym formancie daty przy użyciu klawiszy strzałek (góra – dół). Przykładowo, gdy wprowadzono
datę 7/15/99, gdzie 7 oznacza miesiąc, 15 – dzień, a 99 – rok, za pomocą klawiszy strzałek można te wartości
zmodyfikować.
145 Rozdział 9. ♦ Rozbudowa formularzy przy użyciu formantów ActiveX
Tabela 9.5.
Właściwości formantu DateTimePicker
Obiekt Opis
Właściwość CalendarBackColor Ustawia bądź pobiera kolor tła rozwijanego kalendarza
Właściwość CalendarForeColor Ustawia bądź pobiera kolor pierwszego planu kalendarza
rozwijanego
Właściwość CalendarTitleBackColor Ustawia bądź pobiera kolor tła tytułu rozwijanego
kalendarza
Właściwość CalendarTitleForeColor Ustawia bądź pobiera kolor pierwszego planu tytułu
rozwijanego kalendarza
Właściwość CalendartrailingForeColor Ustawia bądź pobiera kolor pierwszego planu dat
w rozwijanym kalendarzu
Właściwość Checkbox Umieszcza w formancie pola wyboru
Właściwości Day, Month i Year Zwraca wybraną wartość
Właściwość DayOfWeek Zwraca dzień tygodnia
Właściwość Format Wyświetla datę długą, datę krótką, czas i inne formanty
Właściwości MinDate i MaxDate Określa zakres daty
Właściwości Second, Minute i Hour Zwraca wybrane właściwości
Właściwość Value Ustawia bądź pobiera wybraną datę/godzinę
Formant FlatScrollBar
Oto nowa wersja suwaka o płaskim wyglądzie (rysunek 9.11). Poprzez zmianę właściwości Orientation możesz wybrać
suwak poziomy lub pionowy.
Rysunek 9.11.
Przykład formantu
FlatScrollBar
Tabela 9.6.
Właściwości formantu FlatScrollBar
Obiekt Opis
Właściwość Appearance Ustawia bądź pobiera wygląd suwaka. Suwak może być dwu- lub
trójwymiarowy
Właściwość Orientation Ustawia bądź pobiera położenie (poziome lub pionowe) suwaka
Formant ImageCombo
Formant ImageCombo przypomina zwykłe pole listy rozwijalnej, z tą różnicą, że pozycjom na liście można
przyporządkować rysunki (rysunek 9.12). To ułatwia użytkownikom korzystanie z listy.
Część III ♦ Interfejs użytkownika 146
Rysunek 9.12.
Przykład formantu
ImageCombo
Do umieszczenia rysunków w formancie ImageCombo używany jest formant ImageList. Rysunek może być umieszczony
obok tekstu na liście lub w części edycyjnej pola listy. Aby programowo dodawać obiekty do formantu ImageCombo, użyj
metody Add w następujący sposób:
With ctlImageCombo.ComboItems
' Add Index, ItemNames, ListBox Display Name, Image Key Name.
.Add 1, "Cloudy", "Cloudy", "Cloudy"
.Add 2, "Rainy", "Rainy", "Rainy"
.Add 3, "Snowing", "Snowing", "Snowing"
.Add 4, "Sunny", "Sunny", "Sunny"
.Add 5, "Lightning", "Lightning", "Lightning"
End With
Tabela 9.7 zawiera najczęściej używane właściwości, metody i zdarzenia dla formantu ImageCombo.
Tabela 9.7.
Właściwości, metody i zdarzenia dla formantu ImageCombo
Obiekt Opis
Obiekt Collection Zbiór ComboItems (obiektów listy rozwijalnej)
Obiekt Individual Obiekt ComboItem jest obiektem na liście
Właściwość ComboItems Pobiera odnośnik do zbioru ComboItems
Tabela 9.7.
Właściwości, metody i zdarzenia dla formantu ImageCombo (ciąg dalszy)
Obiekt Opis
Właściwość ImageList Przyporządkowuje formant ImageList do ImageCombo
Właściwość Indentation Ustawia bądź pobiera szerokość wcięć (każde wcięcie wynosi
10 pikseli)
Właściwość SelectedItem Wybrany obiekt z listy
Metoda Add Programowe dodawanie obiektów do ImageCombo
Zdarzenie DropDown Występuje po rozwinięciu listy formantu
Formant ImageList
Formant ImageList należy do grupy formantów związanych z procesem projektowania. Jest on niewidoczny dla
ostatecznego użytkownika.
Formant ten służy do przechowywania plików rysunków. Możesz przechowywać wiele typów rysunków: bitmapy (.BMP),
ikony (.ICO), pliki typu .GIF, .DIB, .CUR i .JPG. Z rysunków przechowywanych w formancie ImageList mogą później
korzystać inne formanty. W ten sposób działają omówione w tym rozdziale formanty ActiveX ImageCombo, ListView i
Toolbar.
Dzięki stronie z właściwościami formantu ImageList (rysunek 9.13) dodawanie rysunków jest dość proste. Pamiętaj, że
rysunki dodawane do formantu ImageList muszą być tego samego rozmiaru. Jeśli chcesz korzystać z rysunków o różnych
rozmiarach, musisz użyć kilku formantów ImageList.
147 Rozdział 9. ♦ Rozbudowa formularzy przy użyciu formantów ActiveX
Rysunek 9.13.
Strona
z właściwościami
formantu ImageList
Rysunkom dodawanym do formantu ImageList zawsze przyznawane są numery indeksu. Nie powinieneś się na nich
opierać. Zamiast tego, zawsze wprowadzaj wartość Key (wartość klucza) dla każdego rysunku.
Tabela 9.8 zawiera najczęściej używane właściwości, metody i zdarzenia dla formantu ImageList.
Tabela 9.8.
Właściwości, metody i zdarzenia dla formantu ImageList
Obiekt Opis
Obiekt Collection Zbiór ListImages
Obiekt Individual Obiekt ListImage jest rysunkiem w formancie
Właściwość Index Unikatowa wartość indeksu dla każdego rysunku
Właściwość Key Wartość tekstowa przyporządkowana rysunkowi
Właściwość ImageCount Aktualna liczba rysunków w formancie ImageList
Metoda Overlay Nadpisywanie jednego rysunku na drugim
Add (dodaj) rysunki Używana w kodzie metoda Add dla zbioru ListImages
Przykład wykorzystania rysunków w formularzu przy użyciu formantu ImageList przedstawiony jest na rysunku 9.14.
Formant ListView może korzystać z rysunków tylko dzięki formantowi ImageList.
Formant ListView
Formant ListView wyświetla listę obiektów na cztery różne sposoby. Jako przykład może posłużyć prawe okno
Eksploratora Windows, w którym użytkownicy mogą przeglądać pliki w formatach Duże ikony, Małe ikony, Lista i
Szczegóły.
Część III ♦ Interfejs użytkownika 148
W formularzach Accessa listy z danymi mogą być wyświetlane w podobny sposób dzięki formantowi ListView (rysunek
9.14). Obiekty na liście mogą być umieszczone z nagłówkami kolumn lub bez nich. Formant ten jest bardzo elastyczny i
umożliwia przeglądanie danych na wiele różnych sposobów.
Rysunek 9.14.
Przykład formantu
ListView
Tabela 9.9.
Obiekty i właściwości formantu ListView
Obiekt Opis
Obiekt Collection Zbiór ListItems
Obiekt Individual Obiekt ListItem jest obiektem na liście
Obiekt Collection Zbiór ColumnHeaders
Obiekt Individual Obiekt ColumnHeader, tekst nagłówka kolumny
Właściwość AllowColumnReorder Zmienia układ kolumn
Właściwość Arrange Rozmieszcza ikony w formancie
Właściwość ColumnHeaders Tworzy odniesienie zbioru do obiektów ColumnHeader
Właściwość FullRowSelect Wybór całego wiersza
Właściwość GridLines Wyświetla linie siatki w widoku Szczegóły
Właściwość HideColumnHeaders Ukrywa i odkrywa nagłówki kolumn w widoku Szczegóły
Właściwość LabelEdit Umożliwia użytkownikom edytowanie etykiet
Właściwość LabelWrap Zawija etykiety obiektów ListItems
Właściwość MultiSelect Umożliwia użytkownikom zaznaczanie kilku obiektów
Właściwość SelectedItem Określa wybrany ListItem
Tabela 9.9.
Obiekty i właściwości formantu ListView (ciąg dalszy)
Obiekt Opis
Właściwość Sorted Określa, czy obiekty w zbiorze mają być sortowane
Właściwość SortKey Określa, czy obiekty mają być sortowane według właściwości
ListItem Text, czy według indeksu zbioru SubItems
Formant MAPISession
Interfejs MAPI (ang. Messaging Application Programming Interface) nadzoruje korzystające z poczty aplikacje Accessa.
Formant MAPISession umożliwia rozpoczęcie i zamknięcie sesji MAPI (rysunek 9.15).
Rysunek 9.15.
Przykład formantu
MAPISession
Formant MAPISession związany używany jest w procesie projektowania i nie są z nim związane żadne zdarzenia.
Tabela 9.10 zawiera najczęściej używane właściwości i metody dla formantu MAPISession.
Tabela 9.10.
Właściwości i metody dla formantu MAPISession
Obiekt Opis
Właściwość DownloadMail Pobiera nowe wiadomości
Właściwość LogonUI Wyświetla okno dialogowe logowania
Właściwość NewSession Tworzy nową sesję pocztową
Właściwość Password Hasło związane z właściwością UserName
Właściwość SessionID Identyfikator aktualnej sesji pocztowej
Właściwość UserName Profil używany do tworzenia nowej sesji pocztowej
Metoda SignOff Wylogowanie użytkownika i zakończenie sesji pocztowej
Metoda SignOn Zalogowanie użytkownika do sesji pocztowej
Formant MAPIMessages
Po otwarciu sesji przez użytkownika za pomocą formantu MAPISession w celu tworzenia nowych wiadomości i
przeglądania starych, wysyłania z załącznikami lub bez, odpowiadania na wiadomości, wyświetlania książek adresowych i
innych czynności można korzystać z formantu MAPIMessages. Przykład wykorzystania tego formantu znajduje się na
rysunku 9.15.
Tabela 9.11 zawiera najczęściej używane właściwości i metody dla formantu MAPIMessages.
Tabela 9.11.
Właściwości i metody dla formantu MAPIMessages
Obiekt Opis
Właściwość AttachmentName Nazwa pliku załącznika
Właściwość MsgCount Ilość wiadomości w zbiorze
Część III ♦ Interfejs użytkownika 150
Tabela 9.11.
Właściwości i metody dla formantu MAPIMessages (ciąg dalszy)
Obiekt Opis
Metoda Delete Usuwanie wiadomości
Metoda Fetch Tworzenie zbioru z wybranych wiadomości
Metoda Forward Przesyłanie wiadomości dalej
Metoda Reply Odpowiadanie na wiadomość
Metoda Save Zapisywanie wiadomości
Metoda Send Wysyłanie wiadomości
Formant MonthView
Formant ten daje użytkownikom możliwość przeglądania i wybierania dat za pomocą kalendarzowego interfejsu (rysunek
9.16). Ilość wyświetlanych miesięcy i kolorystyka formantu mogą być dowolnie modyfikowane.
Rysunek 9.16.
Przykład formantu
MonthView
Użytkownicy mają możliwość wybierania pojedynczych dat lub zaznaczania ich blokowo przy użyciu właściwości
MultiSelect.
Tabela 9.12 zawiera najczęściej używane właściwości i zdarzenia dla formantu MonthView.
Tabela 9.12.
Właściwości i zdarzenia dla formantu MonthView
Obiekt Opis
Właściwość DayOfWeek Określa dzień tygodnia
Właściwość MinDate/MaxDate Zakres dat wyświetlanych w formancie
Tabela 9.12.
151 Rozdział 9. ♦ Rozbudowa formularzy przy użyciu formantów ActiveX
Obiekt Opis
Właściwość MaxSelCount Maksymalna możliwa ilość dat do zaznaczenia
Właściwość MonthBackColor Określa kolor tła miesiąca
Właściwość MonthColumns Ilość wyświetlanych kolumn miesięcznych
Właściwość MonthRows Ilość wyświetlanych wierszy miesięcznych
Właściwość MultiSelect Umożliwia zaznaczanie kilku dat jednocześnie
Właściwość SelStart/SelEnd Dolna i górna granica zaznaczenia
Właściwość ShowToday Umożliwia użytkownikowi powrót do dzisiejszej daty
Właściwość StartOfWeek W skrajnej lewej kolumnie wyświetla dzień tygodnia
Właściwość Value Aktualnie wybrana data
Zdarzenie DateClick Kliknięcie daty w formancie
Zdarzenie DateDblClick Dwukrotne kliknięcie daty w formancie
Zdarzenie SelChange Występuje przy nowym wybraniu daty
Formant ProgressBar
Ważne jest, by w przypadku dłuższych procesów informować użytkownika o jego przebiegu. W przeciwnym razie
użytkownik może uznać, że komputer się zawiesił, i zamknąć aplikację. Może to doprowadzić do błędów w programie,
utraty danych i tym podobnych problemów.
Formant ProgressBar dostarcza użytkownikowi informacji o tym, że komputer jest zajęty i określa w przybliżeniu czas,
w jakim proces zostanie zakończony (rysunek 9.17). Możesz dostosowywać wygląd tego formantu, zmieniając jego
położenie oraz minimalne i maksymalne wartości. Umożliwia to zmianę długości paska stanu w zależności od czasu
trwania procesu.
Rysunek 9.17.
Przykład formantu
ProgressBar
Tabela 9.13.
Właściwości formantu ProgressBar
Obiekt Opis
Właściwość Min/Max Minimalne i maksymalne wartości formantu
Właściwość Orientation Położenie (poziome i pionowe) formantu
Właściwość Scrolling Określa, czy postęp jest wyświetlany skokowo, czy w sposób łagodny
Zdarzenie Value Wartość formantu. Gdy wartość jest zwiększana, postęp wyświetlany
f i t
Część III ♦ Interfejs użytkownika 152
w formancie wzrasta
Formant RichText
Formant RichText dostarcza użytkownikowi zaawansowanych możliwości formatowania tekstu. W przeciwieństwie do
standardowych pól tekstowych formant ten umożliwia stosowanie różnych czcionek i kolorów (rysunek 9.18).
Rysunek 9.18.
Przykład formantu
RichText
Tabela 9.14 zawiera najczęściej używane właściwości, metody i zdarzenia dla formantu RichText.
Tabela 9.14.
Właściwości, metody i zdarzenia dla formantu RichText
Obiekt Opis
Właściwość BulletIndent Ustawia bądź pobiera wielkość akapitu
Właściwość FileName Nazwa pliku załadowanego do formantu
Właściwość MaxLength Maksymalna ilość znaków w formancie
Właściwość MultiLine Umożliwia pisanie tekstu w więcej niż jednej linii
Właściwość RightMargin Określa prawy margines
Właściwość ScrollBars Wyświetla poziomy i pionowy pasek przewijania
Właściwość SelAlignment Określa wyrównanie zaznaczonych paragrafów
Właściwości SelBold, SelItalics, Formatuje zaznaczony tekst
SelStrikeThru, SelUnderline
Formant Slider
Formant Slider może być wykorzystany do wprowadzania lub wyświetlania danych na skali ciągłej (rysunek 9.19).
Modyfikować można przedział zmiany, właściwości ruchu i położenie (poziome i pionowe).
153 Rozdział 9. ♦ Rozbudowa formularzy przy użyciu formantów ActiveX
Rysunek 9.19.
Przykład formantu
Slider
Tabela 9.15 zawiera najczęściej używane właściwości, metody i zdarzenia dla formantu Slider.
Tabela 9.15.
Właściwości, metody i zdarzenia dla formantu Slider
Obiekt Opis
Właściwość LargeChange Określa skok suwaka po naciśnięciu klawiszy Page Up i Page Down
oraz kliknięciu jednego z końców suwaka
Właściwośc SmallChange Określa skok suwaka po naciśnięciu klawiszy strzałek (lewo–prawo)
Właściwość Min/Max Minimalna i maksymalna wartość formantu
Właściwość Orientation Położenie formantu (poziome i pionowe)
Właściwość SelectRange Określenie wielkości zaznaczenia
Właściwość Value Aktualna wartość formantu
Metoda ClearSel Usuwa aktualne zaznaczenie formantu
Metoda GetNumTicks Pobiera ilość skoków suwaka pomiędzy wartościami Min i Max
Zdarzenie Scroll Występuje przy ruchu suwaka
Formant StatusBar
Formant ten (pasek stanu) jest wykorzystywany w wielu aplikacjach (np. Word i Excel). Dostarcza on użytkownikowi
wielu informacji (rysunek 9.20).
Rysunek 9.20.
Przykład formantu
StatusBar
Formant StatusBar zawiera obiekty Panel i zbiór Panels, które mogą być użyte do programowego wykonywania
czynności. Przykładowo, jeśli użytkownik kliknie określony panel, wykonana zostanie dana czynność.
Tabela 9.16 zawiera najczęściej używane obiekty, metody i zdarzenia dla formantu StatusBar.
Tabela 9.16.
Obiekty, metody i zdarzenia dla formantu StatusBar
Obiekt Opis
Obiekt Collection Zbiór Panels
Obiekt Individual Obiekt Panel jest obiektem na liście
Część III ♦ Interfejs użytkownika 154
Właściwość Align Określa położenie formantu na formularzu (u góry, u dołu, z lewej lub
prawej strony)
Właściwość SimpleText Ustawia bądź pobiera tekst z formantu, gdy właściwość Style ustawiona
jest na Simple
Właściwość Style Ustawia właściwość stylu, by wyświetlać jedne lub wszystkie panele
Zdarzenie PanelClick Występuje, gdy użytkownik kliknie panel
Zdarzenie PanelDblClick Występuje, gdy użytkownik dwukrotnie kliknie panel
Formant SysInfo
Formant ten umożliwia otrzymywanie informacji o systemie i reagowanie na nie (rysunek 9.21). Może on służyć od
kontrolowania następujących informacji systemowych:
u System operacyjny, jego wersja i numer edycji.
u Zdarzenia na pulpicie, wielkość monitora i zmiany rozdzielczości.
u Zdarzenia związane z Plug and Play.
u Właściwości i zdarzenia związane z zarządzaniem energią.
Rysunek 9.21.
Przykład formantu
SysInfo
Tabela 9.17 zawiera najczęściej używane obiekty, metody i zdarzenia dla formantu SysInfo.
Tabela 9.17.
Obiekty, metody i zdarzenia dla formantu SysInfo
Obiekt Opis
Właściwość ACStatus Wykrywa użycie zasilania prądem zmiennym
Właściwość BatteryFullTime Gdy bateria jest w pełni naładowana, określa jej żywotność
w sekundach
Tabela 9.17.
Obiekty, metody i zdarzenia dla formantu SysInfo (ciąg dalszy)
Obiekt Opis
Właściwość BatteryLifePercent Żywotność baterii w procentach
Właściwość BatteryLifeTime Zwraca ilość sekund pozostałej żywotności baterii
Właściwość BatteryStatus Stan baterii (niski, średni, wysoki, ładowanie)
Właściwość OSBuild Numer wersji systemu operacyjnego
Właściwość OSPlatform System operacyjny (Windows 95, Windows NT)
Właściwość OSVersion Numer edycji systemu operacyjnego
Zdarzenie ConfigChange Występuje w przypadku zmiany profilu sprzętowego
Zdarzenie DeviceArrival Występuje w przypadku dodania do systemu nowego sprzętu
Zdarzenie PowerStatusChanged Występuje w przypadku zmiany stanu zasilania
Zdarzenie PowerSuspend Występuje przed wstrzymaniem pracy komputera
Zdarzenie TimeChanged Występuje w przypadku zmiany ustawienia zegara systemowego
155 Rozdział 9. ♦ Rozbudowa formularzy przy użyciu formantów ActiveX
Formant TabStrip
Formant TabStrip przydaje się w sytuacji, gdy pojawia się konieczność umieszczenia wielu formantów na jednym
formularzu (rysunek 9.22). Przy jego użyciu formanty mogą być rozmieszczone na różnych zakładkach. Wygląd i położenie
formantów na zakładkach może być modyfikowane.
Rysunek 9.22.
Przykład formantu
TabStrip
Tabela 9.18 zawiera najczęściej używane obiekty, właściwości, metody i zdarzenia dla formantu TabStrip.
Tabela 9.18.
Obiekty, właściwości, metody i zdarzenia dla formantu TabStrip
Obiekt Opis
Obiekt Collection Zbiór Tabs
Obiekt Individual Obiekt Tab – pojedyncza zakładka
Właściwości ClientHeight, Zwraca współrzędne obszaru wyświetlania formantu
ClientWidth, ClientLeft,
ClientRight
Formant Toolbar
Dzięki temu formantowi możesz utworzyć pasek narzędzi dla aplikacji Accessa. Oddaje on do rąk użytkowników graficzny
interfejs, zawierający najczęściej używane obiekty menu (rysunek 9.23).
Rysunek 9.23.
Przykład formantu
Toolbar
Formant Toolbar zawiera obiekty Button (przycisk) i zbiór Buttons. Przyciski mogą być programowo dodawane i
usuwane z formularza. Istnieje również możliwość napisania kodu, który będzie reagował na zdarzenia (najczęściej na
zdarzenie ButtonClick).
Tabela 9.19 zawiera najczęściej używane obiekty, właściwości, metody i zdarzenia dla formantu Toolbar.
Część III ♦ Interfejs użytkownika 156
Tabela 9.19.
Obiekty, właściwości, metody i zdarzenia dla formantu Toolbar
Obiekt Opis
Obiekt Collection Zbiór Buttons
Tabela 9.19.
Obiekty, właściwości, metody i zdarzenia dla formantu Toolbar (ciąg dalszy)
Obiekt Opis
Obiekt Individual Obiekt Button – pojedynczy przycisk
Obiekt Collection Zbiór ButtonMenus
Obiekt Individual Obiekt ButtonMenu – rozwijana lista obiektu Button
Właściwość Align Wyświetla formant u góry, u dołu, po lewej lub po prawej stronie
formularza
Właściwość AllowCustomize Umożliwia użytkownikowi dostosowywanie formantu
Właściwość BorderStyle Określa wygląd ramki formantu
Właściwości ButtonHeight, Wysokość i szerokość znajdujących się na pasku narzędzi
ButtonWidth przycisków
Właściwość ImageList Przyporządkowuje formant ImageControl
Właściwość Style Określa styl formularza (zwykły, transparentny lub tekst na prawo
od rysunku)
Metoda Customize Umożliwia użytkownikowi dostosowywanie paska narzędzi
Metoda RestoreToolbar Przywraca początkowy stan paska narzędzi
Obiekt ButtonClick Występuje po naciśnięciu przycisku
Obiekt ButtonMenuClick Występuje po naciśnięciu przycisku w menu
Formant TreeView
Formant TreeView wyświetla hierarchiczną listę – taką, jaka znajduje się w lewym ok.nie Eksploratora Windows. W
Eksploratorze hierarchiczna lista folderów może być przeglądana na różne sposoby. Na rysunku 9.24 znajduje się przykład
użycia formantu TreeView w formularzu Accessa.
Rysunek 9.24.
Przykład formantu
TreeView
Formant TreeView zawiera obiekty Node (węzeł). Każdy obiekt Node zawiera tekst i rysunki. Po hierarchii formantu
można poruszać programowo, a także rozwijać i zwijać węzły.
Tabela 9.20 zawiera najczęściej używane obiekty, właściwości i zdarzenia dla formantu TreeView.
Tabela 9.20.
Obiekty, właściwości i zdarzenia dla formantu TreeView
157 Rozdział 9. ♦ Rozbudowa formularzy przy użyciu formantów ActiveX
Obiekt Opis
Obiekt Collection Zbiór Nodes
Obiekt Individual Obiekt Node – obiekt w formancie TreeView
Właściwość Checkboxes Włącza pola wyboru w formancie
Właściwość Indentation Określa szerokość wcięcia
Właściwość LabelEdit Umożliwia użytkownikom edycję etykiet węzłów
Właściwość LineStyle Określa sposób wyświetlania linii między węzłami
Właściwość SelectedItem Zaznaczony węzeł
Właściwość Sorted Określa sposób sortowania węzła głównego i węzłów podrzędnych
Właściwość Style Określa wygląd każdego z węzłów (tekst, rysunki, plus – minus i linie)
Zdarzenie AfterLabelEdit Występuje, gdy użytkownik dokona edycji etykiety węzła
Zdarzenie Collapse Występuje, gdy węzeł zostanie zwinięty
Zdarzenie Expand Występuje, gdy węzeł zostanie rozwinięty
Zdarzenie NodeClick Występuje po kliknięciu węzła
Formant UpDown
Formant UpDown ułatwia użytkownikom zmianę wartości liczbowych za pomocą myszy. Składa się on z pary strzałek,
które użytkownik może klikać, by żądana wartość wzrosła bądź zmalała (rysunek 9.25).
Formant UpDown można bez trudu połączyć z innym formantem (np. polem tekstowym), za pomocą właściwości
BuddyControl. Nie ma konieczności pisania dodatkowego kodu. Dzięki użyciu właściwości BuddyControl dwa
formanty będą ze sobą współpracować. Gdy użytkownik kliknie jedną ze strzałek formantu UpDown, wartość w polu
tekstowym automatycznie się zmieni.
Rysunek 9.25.
Przykład formantu
UpDown
Tabela 9.21 zawiera najczęściej używane właściwości i zdarzenia dla formantu UpDown.
Tabela 9.21.
Właściwości i zdarzenia dla formantu UpDown
Obiekt Opis
Właściwość Alignment Umieszcza formant UpDown po lewej lub prawej stronie formantu
związanego
Właściwość AutoBuddy Określa, czy użyto właściwości BuddyControl do ustawienia
formantu związanego
Właściwość BuddyControl Określa nazwę formantu, który ma być formantem związanym
Właściwość BuddyProperty Określa właściwości, dzięki którym można zsynchronizować formant
UpDown z formantem związanym
Formant WebBrowser
Formant ten służy do umieszczania przeglądarki Microsoft Internet Explorer wewnątrz formularzy Accessa (rysunek 9.26).
Jaki jest tego cel, skoro większość użytkowników już posiada przeglądarkę na swoim komputerze?
u Przeglądarka ta jest udostępniana użytkownikom bez konieczności opuszczania Accessa.
u Ogranicza dostęp użytkownika do wybranych stron WWW. Kierownictwo niektórych firm zauważyło znaczną
utratę produktywności swoich pracowników, spowodowaną przeglądaniem stron WWW, niezwiązanych z ich
obowiązkami.
Rysunek 9.26.
Przykład formantu
WebBrowser
Dzięki formantowi WebBrowser można użytkownikom nadać dostęp do określonych stron lub uniemożliwić
dostęp do niektórych z nich.
Tabela 9.22 zawiera najczęściej używane właściwości, metody i zdarzenia dla formantu WebBrowser.
Tabela 9.22.
Właściwości, metody i zdarzenia dla formantu WebBrowser
Obiekt Opis
Właściwość AdressBar Pokazuje pasek z adresem strony
Właściwość FullScreen Maksymalizuje okno
Właściwość LocationName Pobiera nazwę strony/pliku
Właściwość LocationURL Pobiera pełną ścieżkę dostępu do strony/pliku
Właściwość MenuBar Pokazuje pasek menu
Właściwość Type Pobiera typ dokumentu w formancie
Metoda GoBack Powrót do poprzedniej strony
Metoda GoForward Przejście do następnej strony
Metoda GoHome Przejście do strony początkowej
Metoda GoSearch Przejście do strony z wyszukiwarką
Metoda Navigate Odświeża aktualną stronę
Metoda Refresh Zatrzymuje otwieranie strony
159 Rozdział 9. ♦ Rozbudowa formularzy przy użyciu formantów ActiveX
Tabela 9.22.
Właściwości, metody i zdarzenia dla formantu WebBrowser (ciąg dalszy)
Obiekt Opis
Zdarzenie DownloadComplete Występuje po zakończeniu otwierania strony
Zdarzenie StatusChangeText Występuje po zmianie tekstu na pasku stanu
Zdarzenie TitleChange Występuje po zmianie tytułu dokumentu
Aby tego dokonać, z menu Add-Ins Edytora Visual Basic wybierz pozycję Add-In Manager. Zaznacz VBA Package and
Deployment Wizard. U dołu formularza zaznacz sposób, w jaki narzędzie ma zostać uruchomione, a następnie kliknij OK.
Kreator przeprowadzi Cię przez wszystkie kroki i pomoże utworzyć program instalacyjny dla Twojej aplikacji. Kreator ten
dołączy wszystkie wymagane formanty ActiveX i inne niezbędne pliki.
Po uruchomieniu tego programu przez ostatecznego użytkownika i zainstalowaniu na jego komputerze aplikacji wraz z
powiązanymi z nią plikami aplikacja będzie działać poprawnie. VBA Package and Deployment Wizard dokonuje również
odpowiednich zapisów w rejestrze systemowym komputera użytkownika.
Rozdział 10.
Tworzenie raportów
W tym rozdziale:
u Czym są raporty?
u Struktura raportów w Accessie.
u Tworzenie prostych raportów przy użyciu kreatora.
u Dostosowywanie raportów.
u Praca z podraportami.
u Tworzenie prostych etykiet adresowych.
u Publikowanie raportu.
u Modyfikowanie raportu podczas jego działania.
u Programowe tworzenie raportów.
u Wskazówki.
Po zakończeniu projektowania struktury danych w aplikacji i po stworzeniu formularzy, które ułatwią użytkownikom pracę
z danymi, nadszedł czas na stworzenie raportów. Raporty to najbardziej widoczna część aplikacji. Ludzie, którzy nigdy nie
zobaczą żadnego formularza i nie mają pojęcia, jak poradziłeś sobie z bezpieczeństwem i układem danych, będą oglądać
stworzone przez Ciebie raporty. Tak się składa, że dowiesz się, czy Twoja aplikacja jest dobra, jeśli będziesz często
proszony o nowe raporty lub modyfikacje już istniejących. Praca ta jest równie przyjemna co męcząca, jako że pośród
wszystkich obiektów w Accessie raporty stawiają przed programistami największe wyzwanie.
Czym są raporty?
W tym rozdziale podzielimy raporty na części składowe i omówimy działanie każdej z nich. Przyjrzymy się również kilku
sztuczkom, które sprawią, że nasze raporty z łatwością będą wykonywały z pozoru trudne zadania. W przypadku zadań,
których nie
można wykonać w prosty sposób, pokażemy, jak można modyfikować raport przy użyciu kodu VBA tak, by raport
wykonywał prawie każde Twoje polecenie. Zajmiemy się również raportami związanymi oraz niezwiązanymi, formantami
i podraportami.
Raporty powstały jako narzędzie do tworzenia wydruków. Dlatego też ich możliwości są do pewnego stopnia ograniczone.
W przeciwieństwie do formularzy raporty nie są interaktywne, tak więc po ich wydrukowaniu bądź przejściu do widoku
podgląd wydruku użytkownik nie ma możliwości zmiany wartości lub źródeł danych. Ostateczny wygląd raportu zależy od
sterownika drukarki, ponieważ to, co widzimy, musi być zgodne z parametrami drukarki i rodzajem użytego papieru.
Pomimo tych ograniczeń, raporty Accessa to bardzo elastyczne narzędzia do prezentacji danych. Kluczem do ujarzmienia
ich zdolności jest poznanie obiektu raport i wszystkich jego elementów. Najlepszym sposobem, by to osiągnąć, jest
przyjrzenie się im wszystkim z osobna.
161 Rozdział 10. ♦ Tworzenie raportów
Najprostszym sposobem prezentowania danych w raporcie jest umieszczenie w poszczególnych sekcjach związanych
formantów. Jednakże jest możliwe umieszczenie w dowolnej sekcji innego raportu tak, by pełnił funkcję podraportu. W
tym rozdziale poznasz nowe opcje oraz kwestie związane z użyciem podraportów w Accessie 2000.
Wreszcie obiekt Raport, który jak wszystkie obiekty Accessa 2000 jest pełen właściwości i zdarzeń, które umożliwią
dostosowanie i automatyzację działania raportów. Od czasu Accessa 97 w raportach nie zmieniło się zbyt wiele, jednak
przyjrzymy się zaletom tych właściwości i zdarzeń, by móc tworzyć doskonałe raporty w Accessie 2000.
Rysunek 10.1.
Widok Projekt
raportu Kategorie
i Produkty
Aby utworzyć raport przy użyciu Kreatora raportów wystarczy z okna dialogowego Nowy raport wybrać pozycję Kreator
raportów (rysunek 10.2).
28. Wybierz źródło danych (w naszym przykładzie używamy tabeli Kategorie) i kliknij przycisk OK.
29. Kreator poprosi o podanie pól, które chcesz umieścić w raporcie. Możesz je wybierać pojedynczo lub umieścić w
raporcie wszystkie pola jednocześnie. Kolejność, w jakiej wybierasz pola, ma wpływ na sortowanie i umieszczenie
formantów w raporcie.
Część III ♦ Interfejs użytkownika 162
30. W kolejnym, przedstawionym na rysunku 10.3, oknie dialogowym możesz określić rodzaj grupowania w raporcie.
Ponieważ nasz przykład jest oparty o jedną tabelę, grupowanie nie jest zbyt użyteczne. Możesz przejść do kolejnego
okna.
Rysunek 10.2.
Okno dialogowe
Nowy raport
z wybranymi
Kreatorem raportów
i tabelą Kategorie
Rysunek 10.3.
Ustawienia
właściwości
Sortowanie
i Grupowanie
W oknie tym mamy możliwość ustawienia sposobu sortowania raportu. Pola mogą być sortowane maksymalnie po
czterech polach w kolejności rosnącej bądź malejącej. Wybierz pola do sortowania: IDkategorii oraz
NazwaProduktu.
31. Po wybraniu kolejności sortowania możesz zdecydować o układzie raportu: kolumnowy, tabelaryczny i
wyjustowany. Możesz także wybrać orientację drukowanego raportu (poziomą bądź pionową). Kolejna opcja umożliwia
dostosowanie szerokości pól tak, by były widoczne na stronie. Nie chodzi tu o przekształcenie czcionki do
odpowiedniego rozmiaru, jak to ma miejsce w przypadku podobnej opcji programu Microsoft Excel. W przypadku
Accessa wybranie tej opcji powoduje zmianę szerokości formantów, by mieściły się na stronie. W rezultacie dane
mogą stać się nieczytelne, bo zostaną obcięte, jeśli szerokość formantu będzie zbyt mała.
W następnym oknie masz do wyboru kilka stylów. Zmieniają one nagłówki, etykiety oraz sekcje raportu i mogą
przy niewielkim wysiłku z Twojej strony nadać raportowi elegancki i estetyczny wygląd.
32. W ostatnim oknie dialogowym powinieneś podać nazwę dla raportu i wybrać, czy chcesz zobaczyć raport, czy
modyfikować go w widoku Projekt.
Mimo iż Kreator utworzył raport, możesz modyfikować go w dowolny sposób, kiedy tylko zechcesz.
Kreator ten może również tworzyć raporty oparte na więcej niż jednym źródle danych. Jeśli utworzyłeś relację między
tabelami w bazie danych, Kreator raportów utworzy dla raportu odpowiednie wyrażenie SQL.
33. Korzystając z kreatora, utwórz ponownie nowy raport. Przejdź do okna dialogowego, gdzie wybierałeś pola, i
dodaj pole NazwaKategorii z tabeli Kategorie (rysunek 10.4).
163 Rozdział 10. ♦ Tworzenie raportów
Rysunek 10.4.
Wybieranie pól
w Kreatorze
raportów
34. Z rozwijanej listy Tabele/Kwerendy wybierz tabelę Produkty, a następnie wybierz pole NazwaProduktu (rysunek
10.5).
Rysunek 10.5.
Oba pola zostały
dodane
W widoku Projekt raportu zauważysz, że Kreator raportów utworzył wyrażenie SQL, korzystając z relacji powstałych w
fazie projektowania bazy danych Northwind.
Dostosowywanie raportów
Nie często się zdarza, by raport utworzony przy użyciu kreatora idealnie odpowiadał Twoim potrzebom. By zaoszczędzić
czas, powinieneś w każdej sytuacji korzystać z Kreatora raportów, jednak wiedzy o dostosowywaniu raportów nie da się
niczym zastąpić.
W kilku krokach i dokonując kilku obliczeń możesz zmienić raport Kategorie i Produkty w raport pokazujący zamówienia
produktów według kategorii. Będzie on posiadał źródło rekordów oparte na kilku tabelach, sortowanie, grupowanie,
obliczenia oraz nagłówki i stopki. To elementy, których będziesz używał w 75% raportów Accessa.
Rysunek 10.6.
Właściwość Źródło
rekordów w oknie
właściwości raportu
W oknie właściwości raportu wybierz właściwość Źródło rekordów i kliknij przycisk z wielokropkiem (...), aby uruchomić
Konstruktora kwerend ( rysunek 10.7). Do kwerendy dodaj tabelę Opisy zamówień. Z tabeli Produkty dodaj również pola
Ilośćjednostkowa i IDproduktu. Zamknij Konstruktora kwerend.
Teraz, gdy źródło rekordów zostało zmienione, możesz zmodyfikować raport tak, by przedstawiał dane w użyteczny
sposób.
Rysunek 10.7.
Konstruktor kwerend
Tabela 10.1.
Wartości przedziału grupowania i ograniczenia w ich stosowaniu
165 Rozdział 10. ♦ Tworzenie raportów
Tabela 10.1.
Wartości przedziału grupowania i ograniczenia w ich stosowaniu (ciąg dalszy)
u Trzymaj razem – właściwość ta dotyczy drukowanego raportu i sposobu, w jaki Access będzie próbował zmieścić
dane na tej samej stronie. Wartości dla tej właściwości i efekt ich działania zawiera tabela 10.2.
Tabela 10.2.
Wyjaśnienie ustawień właściwości Trzymaj razem
W raporcie sumującym sprzedane jednostki produktu w poszczególnych kategoriach grupowanie musi się odbywać według
produktów. Najlepiej do tego celu wykorzystać unikatowy identyfikator. Mimo iż poniższy przykład funkcjonowałby
równie dobrze
z Nazwą Produktu, w rzeczywistości produkty mogą występować w różnych rozmiarach, wagach i konfiguracjach, lecz pod
tą sama nazwą. Użycie pola ID Produktu umożliwi raportowi odróżnienie takich produktów.
37. Z menu Widok wybierz Sortowanie i Grupowanie. Zmień właściwość sortowania NazwaProduktu na IDproduktu i
ustaw właściwość Nagłówek grupy na Tak. Utwórz także Stopkę grupy dla pola kategoria. Elementy te wystarczą
do stworzenia pogrupowanego raportu o kategoriach i produktach.
38. Z listy pól wybierz IDproduktu i umieść w Nagłówku IDproduktu, na prawo od formantu IDkategorii w Nagłówku
Kategorii. Możesz wyciąć i wkleić etykietę formantu IDproduktu do Nagłówka strony.
Część III ♦ Interfejs użytkownika 166
39. Przesuń formant NazwaProduktu z sekcji Szczegóły do Nagłówka IDproduktu. Będziesz musiał połączyć go z jego
etykietą.
Otrzymujemy raport, który zbiera wszystkie kategorie, wielkości ich sprzedaży i tworzy z nich listę. W tej formie raport
przedstawia jedynie listę sprzedanych produktów w każdej kategorii, bez podania wielkości sprzedaży. Do tego celu należy
stworzyć wyrażenie.
umieszczone w nagłówku IDproduktu zwróci wartość sprzedaży każdego z produktów. Jeśli umieścimy to wyrażenie w
stopce Kategorii, otrzymamy wartość sprzedaży w danej kategorii.
Aby zobaczyć jak to wygląda w praktyce, utwórz pole tekstowe w nagłówku IDproduktu i wpisz wyrażenie
Suma ([IlośćJednostkowa])
Mimo iż raport nie zawiera formantu o nazwie „IlośćJednostkowa”, pole takie znajduje się w źródle danych i może być
użyte w wyrażeniu. Skopiuj formant do stopki Kategorii.
Przejdź do widoku Podgląd wydruku, powinieneś wtedy zobaczyć taki sam rezultat jak na rysunku 10.8.
Rysunek 10.8.
W zależności od
położenia wyrażenia,
jego wynik zmienia się
„Poniżej” lub brak reakcji). Istnieje możliwość zagnieżdżenia funkcji IIF w innej funkcji, tak więc gdy jeden warunek
jest spełniony, przeprowadzany jest kolejny test i tak dalej. Funkcje IIF powinny być używane dość rzadko, gdyż mogą
spowalniać pracę raportu.
Raport może wykorzystywać procedurę IIF do zaznaczania tych produktów, w przypadku których sprzedaż była równa
lub przekroczyła 500 jednostek. Aby to uczynić, z prawej strony nagłówka IDproduktu umieść pole tekstowe i w jego
źródle danych wpisz następującą formułę:
=IIF ([Suma of Ilośćjednostkowa]>=500, "Powyżej", "")
Będąc w widoku Projekt raportu, z menu Widok wybierz Kod programu. Spowoduje to otwarcie modułu raportu, w którym
możesz tworzyć procedury i funkcje wykorzystywane w tym raporcie.
Dzięki temu będziesz w stanie lepiej kontrolować to, co dzieje się w danym momencie w formancie, gdyż możesz nadawać
funkcjom znaczące nazwy. Umieszczenie funkcji w formancie zapewnia jednocześnie zachowanie ciągłości, jeśli
wykorzystujesz te same obliczenia w różnych miejscach raportu.
Użyjemy tu nowej funkcji VBA Accessa – Split(). Funkcja ta, w oparciu o wybrany ogranicznik (domyślnie jest nim
znak spacji), podzieli ciąg na elementy tablicy. Funkcja ta może mieć wiele zastosowań w Accessie 2000. W tym
przypadku posłuży do zamiany w nazwach produktów małych liter na duże.
Funkcja ta jest bardzo prosta. Traktuje ciąg jako argument i dzieli go na elementy tablicy (varArray). Następnie, przy
użyciu funkcji UCase(), zamienia pierwszą literę każdego słowa na dużą. Aby zwrócić słowa z zamienionymi literami,
funkcja korzysta z funkcji Left i Right, które umożliwiają oddzielenie pierwszej litery z lewej strony słowa. Później te
grupy liter są ponownie łączone w taki sposób, by znów tworzyły całe słowa.
W ten sam sposób łączone są elementy tablicy, by znów tworzyły jeden ciąg, lecz już z poprawną pisownią. Wydruk 10.2
przedstawia, jak to się dzieje.
Wydruk 10.2. Zmiana małych liter na duże i użycie nowej funkcji Split
Function MakeProper(str As String) As String
If Len(str) = 0 Then
Resume MakeProper_Exit
End If
str = LCase(str)
For i = 0 To Ubound(vararray)
strTemp = strTemp & UCase(Left(vararray(i), 1)) & _
Right(vararray(i), Len(vararray(i)) - 1) & " "
Next
' Usuń zbędne spacje
MakeProper = Trim(strTemp)
MakeProper_Exit:
On Error Resume Next
Exit Function
MakeProper_Err:
MakeProper = ""
Resume MakeProper_Exit
End Function
Użycie konkatenacji
Konkatenacja (łączenie) jest niezwykle często wykorzystywana w zaawansowanych raportach. Umożliwia ona łączenie nazwisk i
adresów tak, by można je było łatwo drukować i prezentować. Gdy łączysz dwa elementy danych, nie mogą one już być
przetwarzane osobno. Innymi słowy, formularz pokazujący połączone imię i nazwisko klienta nie może być wykorzystywany
(bez pisania dużej ilości kodu) do wprowadzania nowych nazwisk.
Konkatenacja wykonywana jest przy użyciu operatora konkatenacji, znaku [&]. Można również używać znaku [+], lecz formuły
łączące numery klientów z numerami kont mogą być wówczas mylące dla programisty. Więcej zastosowań konkatenacji
opiszemy w przedstawionym w dalszej części tego rozdziału przykładzie dotyczącym etykiet adresowych.
Przykład:
="Access" & Space (1) & "2000" & Space (1) & _
"Księga" & Space (1) & "Eksperta"
zwraca
"Access 2000 Księga Eksperta"
Możesz sprawdzić działanie tej funkcji w oknie Immediate. Z menu Widok modułu wybierz Immediate Window lub naciśnij
klawisze Ctrl+G.
W oknie wpisz
?MakeProper ("access 2000 księga eksperta")
I naciśnij Enter. Jeśli wszystko zostało poprawnie wprowadzone, powinieneś otrzymać „Access 2000 Księga Eksperta”.
Podczas dokonywania konkatenacji musisz zwrócić uwagę na składnię w następujących przypadkach:
u Jeśli w nazwach pól występują spacje, nazwy te muszą być umieszczone w kwadratowych nawiasach (na przykład [ID
Zamówienia]). Jednakże dla zachowania przejrzystości dobrze jest używać kwadratowych nawiasów w każdym
przypadku.
u Ciągi tekstów muszą być umieszczone w cudzysłowie ("Uwaga"). Rozważ także użycie Chr(34), gdy masz do
czynienia z cudzysłowem w kodzie.
u Daty muszą być umieszczone między znakami krzyżyka (#7/27/20000#).
Następnym krokiem jest wykorzystanie tej funkcji w raporcie. Spowoduje ona zmianę pisowni nazw produktów z małych
liter na duże. W widoku Projekt raportu zmień właściwość źródła formantu NazwaProduktu na:
=MakeProper ([NazwaProduktu])
W niektórych przypadkach to wystarczy. Jednakże w tym przypadku, sprawa nie jest taka prosta. Ponieważ formant ten nosi
taką samą nazwę jak pole w źródle rekordów raportu, rezultatem funkcji będzie błąd. Oto jeden z powodów, dla których
warto przestrzegać przyjętej konwencji nazewnictwa podczas tworzenia formantów w formularzach i raportach. Ponieważ
do tworzenia raportu korzystałeś z kreatora, nie miałeś wiele do powiedzenia przy nazywaniu jego formantów. Teraz masz
możliwość zmiany nazwy tego formantu. Ponieważ NazwaProduktu jest polem tekstowym, powinieneś zmienić jego nazwę
na txtNazwaProduktu.
169 Rozdział 10. ♦ Tworzenie raportów
Gdy będziesz teraz przeglądał raport w widoku Podgląd wydruku (jak na rysunku 10.9), zauważysz, że w niektórych
przypadkach nazwa produktów została zmieniona.
Jak dotąd nauczyłeś się tworzyć prosty raport oraz trochę bardziej skomplikowany przy użyciu kreatora. Wiesz już, jak
modyfikować raport po jego utworzeniu. Dowiedziałeś się, co to grupowanie, obliczenia i konkatenacja oraz jak
wykorzystywać funkcje w raportach. Tematy te obejmują 90% tworzenia raportów w bazie danych Accessa.
Praca z podraportami
Tak jak w formularzach można było umieszczać podformularze, tak w raportach można umieszczać podraporty. Podraport
jest to raport umieszczony wewnątrz innego raportu, najczęściej służący do pokazywania powiązanych rekordów. Może on
być również wykorzystywany do pokazywania tego samego podzestawu danych w różnych raportach. Używając
podraportu, możesz korzystać z elastyczności, jaką dają Ci dwa raporty.
Rysunek 10.9.
Pierwsze litery nazw
produktów zostały
zmienione
Gdy między rekordami w raporcie głównym a rekordami w podraporcie istnieje relacja jeden-do-wielu, główny raport
nazywany jest raportem nadrzędnym, a podraport podrzędnym. Mimo iż podobny efekt można często osiągnąć dzięki
grupowaniu raportu, podraporty przydają się w sytuacji, gdy chcesz wydrukować rekordy z kilku różnych tabel. Rysunek
10.10 przedstawia kategorię (Napoje) z bazy Northwind i jej podraport o poszczególnych produktach.
Rysunek 10.10.
Czwarta strona
raportu Katalog
w bazie Northwind
przedstawia
elastyczność, jaką
dają podraporty
Część III ♦ Interfejs użytkownika 170
Jeśli raport główny i podraport są ze sobą powiązane, to, aby raport działał,
właściwości Nadrzędne pole łączące i Podrzędne pole łączące muszą być
ustawione poprawnie. Istnieje możliwość utworzenia konstrukcji raport
główny – podraport bez tworzenia między nimi relacji. W takich
przypadkach można używać wykorzystywanych w wielu raportach
odnośników lub bloków adresowych, lecz wyświetlanych jako podraport w
celu zapewnienia spójności i przejrzystości. Można nawet utworzyć raport
główny, który nie będzie zawierał żadnych rekordów.
Sposób wyświetlania podraportów został w Accessie 2000 znacznie poprawiony. We wcześniejszych wersjach podraport
przedstawiany był jako puste pole w widoku Projekt głównego raportu. Teraz wyświetla on wiele przydatnych informacji o
używanych w podraporcie polach.
Co więcej, istnieje możliwość edycji podraportu w widoku Projekt raportu głównego ( rysunek 10.11). Możliwości
modyfikowania właściwości i formantów podraportu są dużo większe niż kiedyś. Pozwala to zaoszczędzić dużo czasu i
wysiłku. We wcześniejszych wersjach, aby modyfikować podraport, programista musiał otwierać go w osobnym oknie, z
poziomu głównego okna bazy danych.
Rysunek 10.11.
Modyfikowanie
formantów
podraportu
171 Rozdział 10. ♦ Tworzenie raportów
Istnieje jeszcze jeden rodzaj raportu, który różni się nieco od innych, a jest dość często używany: etykiety adresowe. W
następnej części tego rozdziału omówimy ten typ raportów i jego cechy charakterystyczne.
Aby utworzyć etykiety, utwórz nowy raport i wybierz Kreator etykiet z okna Nowy raport. Jako źródło danych wybierz
tabelę Customers. Kliknięcie OK uruchamia kreator etykiet.
45. Wybieranie formatu etykiet nie jest trudne. Przedstawione na rysunku 10.12 okno dialogowe zawiera dokładne
wymiary najczęściej spotykanych etykiet i według nich automatycznie formatuje raport. Musisz wybrać jednostki
miary (angielskie lub metryczne) oraz typ etykiety (najczęściej spotykany Podawany arkuszami albo Ciągły).
Każdy z dokonywanych przez Ciebie wyborów zmienia liczbę dostępnych produktów. Możesz filtrować etykiety
według ich producentów. Domyślnym ustawieniem jest Avery, gdyż etykiety tego producenta są najczęściej
używane i wielu innych producentów dostosowuje się do ich rozmiarów oraz używa na swoich produktach tych
samych numerów produktów.
Rysunek 10.12.
Wybierz typ etykiety
odpowiadający
etykietom, na których
będziesz drukował
46. Gdy znalazłeś etykietę odpowiadającą tym, których używasz, przejdź do następnego okna kreatora, aby wybrać
rodzaj i wielkość czcionki. Ponieważ Windows umożliwia wybór dowolnego rodzaju i wielkości czcionki, może się
zdarzyć, że wybierzesz czcionkę zbyt dużą dla etykiety. W oknie dialogowym zobaczysz jak etykieta będzie
wyglądać w przypadku wybrania danego rodzaju i wielkości czcionki. Dzięki temu unikniesz przykrych
niespodzianek przy drukowaniu etykiet.
47. Naciśnięcie przycisku Dalej spowoduje przejście do kolejnego okna dialogowego (rysunek 10.13), w którym będziesz
mógł określić wygląd etykiety. Duży, pusty obszar po prawej stronie zawiera pola prototypu etykiety. Możesz
przenosić do niego pola ze źródła danych, klikając dwukrotnie lub korzystając z przycisku >. Aby zacząć od nowej
linii, musisz na końcu poprzedniej wcisnąć klawisz Enter. Po utworzeniu linii możesz umieścić jej elementy w
osobnych liniach. Aby usunąć określony element z prototypu, zaznacz go wskaźnikiem myszy i naciśnij klawisz
Delete. Wprowadzanie tekstu odbywa się w sposób standardowy: po prostu kliknij odpowiednie miejsce i pisz.
Każda z czynności, którą wykonujesz na prototypie etykiety, ma wpływ na wszystkie etykiety.
Rysunek 10.13.
Wypełniony prototyp
etykiety
Część III ♦ Interfejs użytkownika 172
Przedstawiony na rysunku 10.13 prototyp etykiety umożliwi tworzenie etykiet zawierających u góry nazwę firmy,
poniżej adres i nazwisko osoby, do której list będzie przeznaczony. Zwróć uwagę na przecinek i spację po
{Miasto}. Znaki te umieszczone zostaną na każdej z etykiet. To samo dotyczy znajdującego się u dołu etykiety
zwrotu „Do wiadomości”.
48. Przejście do następnego okna Kreatora etykiet umożliwia nam zmianę kolejności sortowania etykiet. Możesz je
sortować według kilku pól (na przykład nazwisko, a potem imię) lub według jednego. Jeśli nie określisz kolejności
sortowania, etykiety zostaną ułożone w takiej kolejności, w jakiej znajdują się w źródle rekordów. Podczas
tworzenia dużej ilości etykiet adresowych możesz je posortować według kodu pocztowego (rysunek 10.14).
Rysunek 10.14.
Wybór sortowania po
kodzie pocztowym
49. W ostatnim oknie dialogowym podajmy nazwę raportu. Ponieważ są to etykiety adresowe klientów, wpisujemy
„Korespondencja z klientami”. Możesz również zdecydować, czy otworzyć raport w widoku Projekt, czy też
Podgląd wydruku. Wybór opcji Chcę zmienić projekt etykiety pozwoli zobaczyć, że etykieta to zwykły raport, z
odpowiednio ustawionymi właściwościami.
Wynikiem działania kreatora jest mały raport, zawierający pola odpowiadające każdej z widocznych w prototypie linii.
Zauważ, że kreator połączył oddzielne pola Miasto, Region oraz Kod pocztowy i utworzył z nich jedną linię. Zauważ
również, że kreator otoczył pola funkcją Trim(). Dzięki temu przed i za polami nie występują spacje, które mogłyby
wpłynąć na wyrównanie etykiet. Gdybyś tworzył te etykiety ręcznie, musiałbyś sam utworzyć konkatenację i odwoływać się
do funkcji Trim w każdym formancie. Raport swoimi rozmiarami idealnie odpowiada wybranemu typowi etykiety.
Wysokość i szerokość raportu sprawiają, że dane będą drukowane kolumna po kolumnie i strona po stronie.
Właściwość Trzymaj grupę razem jest ustawiona na Na kolumnę. To, w połączeniu z innymi ustawieniami właściwości,
sprawia, że raport jest szeroki na dwie kolumny i w każdej z nich mieści cztery etykiety.
Jeśli już wcześniej miałeś do czynienia z etykietami, prawdopodobnie nasuwa Ci się kilka pytań. Co jeśli adres zajmuje
więcej niż jedną linię? Jak przesunąć region i kod pocztowy, gdy nazwa miasta jest bardzo długa lub bardzo krótka?
Właściwości Można powiększać i Można zmniejszać dla tych formantów ustawione są na Tak, więc będą one
automatycznie dostosowywać się do zmiany warunków. Dzięki temu nie zachodzi potrzeba tworzenia osobnych
procedur warunkowych, aby brać takie możliwości pod uwagę.
Publikowanie raportu
Access jest doskonałym, lecz nie jedynym narzędziem do zarządzania danymi i tworzenia raportów. Często zdarza się, że
bardzo niewygodnym jest instalowanie u każdego z użytkowników Accessa, by mogli przeglądać i drukować dane z raportów,
a dostarczenie wydrukowanego raportu do więcej niż kilku użytkowników to męczące i czasochłonne zadanie. Co więcej,
niektórzy użytkownicy mogą chcieć obrabiać dane w raporcie po jego otrzymaniu. Raport może zawierać dokładnie to, czego
życzą sobie użytkownicy, jednakże forma i układ, w jakim są prezentowane, mogą sprawić, że dane te będą dla nich prawie
bezużyteczne. Czasami dane z raportu Accessa muszą być opublikowane w inny, bardziej twórczy i dostosowany do potrzeb
użytkowników sposób niż zwykły raport.
Pierwszą z decyzji, jakie musisz podjąć przed opublikowaniem danych jest to, czy użytkownicy wymagają sformatowanej,
zawierającej podsumowania wersji danych, czy może zależy im na nieprzetworzonych danych. Jeśli mamy do czynienia z
drugim przypadkiem i użytkowników nie interesuje wygląd, obliczenia, grupowania itp., najlepiej będzie przekazać im dane,
eksportując kwerendę lub tabelę, niż wysyłać raport. Sposób postępowania przy eksportowaniu kwerendy lub tabeli jest
bardzo podobny do eksportowania raportu, jednak w przypadku zestawów rekordów istnieje kilka innych opcji do wyboru.
Najważniejszymi rzeczami, o których należy pamiętać przy publikowaniu raportu, jest to, że opublikowany raport nie
będzie uwzględniał zmian dokonanych w źródle rekordów oraz to, że użytkownicy nie będą mieli możliwości
modyfikowania informacji podsumowujących w celu poznania szczegółów. Jeśli akceptujesz te ograniczenia, reszta tego
rozdziału będzie odpowiadać Twoim potrzebom.
Tabela 10.3.
Opcje eksportowania raportów w Accessie
Rysunek 10.15.
Okno dialogowe
Eksportuj
Aby wybrać jeden z omówionych formatów, wystarczy zaznaczyć raport i z menu plik wybrać Eksportuj. Wyświetlone
zostanie okno dialogowe, w którym możesz wybrać lokalizację, nazwę i format pliku.
Część III ♦ Interfejs użytkownika 174
Aby przeglądać raport w formacie SnapShot, należy posiadać przeglądarkę SnapShot Viewer. Umożliwia ona przeglądanie
raportu w sposób przypominający widok Podgląd wydruku Accessa. Przydaje się to w szczególności w przypadku
przesyłania raportów pocztą elektroniczną, gdyż umożliwia przeglądanie załączników bez zniekształceń.
Więcej informacji o pisaniu kodu umożliwiającego przesyłanie pocztą elektroniczną raportów i innych obiektów Accessa
znajdziesz w rozdziale 18., „Użycie automatyzacji ActiveX”.
Modyfikowanie raportu
podczas jego działania
Ponieważ raport jest takim samym obiektem jak wszystkie inne obiekty Accessa, istnieje możliwość napisania kodu, który
będzie wpływał na jego właściwości i w określony sposób reagował na zdarzenia. Pozostała część tego rozdziału będzie
poświęcona obiektowi Raport oraz jego właściwościom i zdarzeniom.
Ponieważ formularze i raporty są do siebie podobne, zajmiemy się jedynie cechami charakterystycznymi raportów lub tym
aspektom ich działania, które są dla nich wyjątkowe. Zdarzenia dla raportów i sekcji można podzielić na związane z
procesem projektowania oraz związane z funkcjonowaniem raportu. Podział ten jest bardzo ważny w przypadku roz-
wiązywania poważnych problemów związanych z raportami. Właściwości związane z procesem projektowania mogą być
ustawiane jedynie w widoku Projekt. Gdy raport już działa, nie można tych ustawień modyfikować. Właściwości związane
z funkcjonowaniem raportu mogą być modyfikowane za pomocą kodu, gdy raport jest otwierany, formatowany czy
drukowany, dając Ci dynamiczną kontrolę nad jego wyglądem i zawartością.
Aby modyfikować raport podczas jego funkcjonowania (a także w procesie projektowania) konieczne jest dogłębne
zrozumienie jego właściwości, zdarzeń i obiektów. Przejdźmy do przeglądu tych elementów.
Filtrowanie i sortowanie
Właściwości te działają prawie identycznie jak ich odpowiedniki z formularzy. Korzystając z właściwości Filtr, możesz
ograniczyć zawartość raportu. Filtrowanie działa tylko wówczas, gdy właściwość Filtr włączony ustawiona jest na Tak. Aby
zobaczyć jak działa filtrowanie w formularzu, postępuj w następujący sposób:
50. Otwórz raport Katalog w widoku Projekt.
51. Zmień właściwość Filtr włączony na Tak.
52. We właściwości Filtr wprowadź następujące wyrażenie:
175 Rozdział 10. ♦ Tworzenie raportów
[NazwaKategorii] = "Napoje"
53. Przejdź do widoku Podgląd wydruku. Wyświetlone powinny zostać jedynie napoje.
54. Powróć do widoku Projekt i ustaw właściwość Filtr włączony na Nie.
55. Przejdź do widoku Podgląd wydruku. Wyświetlone zostaną wszystkie kategorie.
lub
Reports![Katalog].Filter=[NazwaKategorii]= "Napoje"
HasData
Gdy raport główny wykonuje obliczenia na podraporcie, w którym nie ma danych, wyrażenie może wyświetlić komunikat o
błędzie. Do określenia, czy istnieją dane dla raportu lub formantu, możesz użyć właściwości HasData. Właściwość ta zwraca
trzy wartości:
Tabela 10.4.
Wartości właściwości HasData
Wartość Opis
Raport niezwiązany Raport nie posiada źródła rekordów
Raport związany, bez rekordów Raport posiada źródło rekordów, lecz jest ono puste
-1 – Raport związany, zawiera rekordy Raport posiada źródło rekordów zawierające co najmniej
jeden rekord
Przy otwarciu
Przy otwarciu jest to pierwsze zdarzenie po uruchomieniu raportu. Występuje przed otwarciem podległej kwerendy. Jest w
takim razie dobrym miejscem na dokonanie programowych zmian w kwerendzie lub na podanie jej określonych
parametrów. Kod napisany w zdarzeniu Przy otwarciu zostanie wykonany, zanim w raporcie stanie się cokolwiek innego.
Po zakończeniu tego zdarzenia raport podejmie działania konieczne do załadowania danych.
Przy błędzie
Jeśli tabela, na której poparty jest raport, otwarta jest przez innego użytkownika z wyłącznością lub po prostu nie istnieje,
aparat Jet stwierdzi błąd i uruchomi zdarzenie raportu Przy błędzie. Zdarzenie to połączone jest z procedurą
AccessError obiektu Application, więc do rozwiązania tego problemu nie możesz użyć Err.Description.
Najlepszym sposobem na radzenie sobie z błędami w raportach jest użycie modułu klasy raportu.
Przy stronie
Zdarzenie to umożliwia dokonywanie zmian w raporcie w ostatnim momencie, tuż przed jego wydrukowaniem lub
przeglądaniem w widoku Podgląd wydruku. Niektóre zmiany (związane na przykład z obramowaniem stron lub
obliczaniem niestandardowych podsumowań) łatwiej jest wykonywać po sformatowaniu raportu, jednak przed jego
wydrukowaniem.
Metoda Line spowoduje narysowanie linii wokół raportu, zanim zostanie on wydrukowany:
Me.Line (0, 0) – (Me.ScaleWidth, MeScaleHeight), , B
Przy zamknięciu
Zdarzenie to występuje zaraz po zamknięciu raportu, jednak przed jego dezaktywacją. Możesz chcieć zamknąć wraz z
raportem formularz służący do wprowadzania parametru lub zmienić pozycję innych okien. Zadania te, jak i inne
porządkujące czynności, mogą być wpisane w zdarzenie Przy zamknięciu.
Właściwość Sekcja
Raport w Accessie może zawierać maksymalnie 25 sekcji: Nagłówek/Stopka raportu, Nagłówek/Stopka strony, Szczegóły
oraz maksymalnie dziesięć Nagłówków/Stopek grup. Właściwość Sekcja zawiera tablicę opisującą wszystkie sekcje
raportu. Do sekcji można tworzyć odniesienia za pomocą numerów ich indeksów w tablicy (a także stałych Accessa).
Sekcje różnią się od innych właściwości Accessa tym, że nie zwracają własnej wartości, lecz odniesienie do sekcji. Aby w
raporcie widoczny był nagłówek raportu, należy użyć następującego kodu:
Reports![Produkty wg kategorii].Section(1).visible=true
lub
Reports![Produkty wg kategorii].Section(acHeader).visible=true
Nazwa
Jak wynika z tabeli 10.5, sekcje raportu posiadają również właściwość Nazwa, której można użyć do tworzenia odniesień.
Aby poprawić przejrzystość raportu, możesz w dowolnym momencie zmienić nazwę sekcji i tworzyć odniesienia,
używając nowo przyznanej nazwy.
Tabela 10.5.
Sekcje wraz z ich indeksami oraz stałymi
177 Rozdział 10. ♦ Tworzenie raportów
Wysokość
Właściwość ta umożliwia określenie wysokości sekcji.
Widoczny
Właściwość ta sprawia, że sekcja jest widoczna lub nie. Przyjmuje wartości Tak i Nie.
Właściwości sekcji
związane z procesem projektowania
Sekcje posiadają grupę właściwości, które mogą być odczytywane i zmieniane jedynie w procesie projektowania. Ważnym
jest odróżnianie ich od innych właściwości, które dostępne są podczas pracy raportu, po ich ustawieniu.
Formanty mogą zmieniać swoje rozmiary inaczej niż przewidywałeś, jeśli stykają się z innymi formantami. Ponieważ
właściwość ta dotyczy jedynie wysokości sekcji (nie wpływa na szerokość czy pozycję), pamiętaj, by sprawdzić, czy
formanty na pewno na siębie nie nachodzą.
Duże formanty (np. obiekty OLE) mogą utrudniać zmniejszanie innych formantów w sekcji, ponieważ powiększanie i
zmniejszanie odbywa się linia po linii. W celu zmniejszenia sekcji należy w formancie OLE umieścić pusty obrazek.
Rozmiar nagłówków i stopek stron nie może się zmieniać, więc umieszczone w tych sekcjach formanty muszą odpowiadać
ich rozmiarom.
Tabela 10.6.
Ustawienia właściwości Nowy wiersz lub kolumna
Powtórz sekcję
Użytkownicy i programiści aplikacji Accessa często skarżyli się, że zdarza się, iż gdy grupa przenoszona jest na nową
stronę, jej nagłówek pozostaje na stronie poprzedniej. Ustawienie właściwości Powtórz sekcję na Tak spowoduje, że
nagłówek bieżącej grupy zostanie umieszczony na nowej stronie.
Tabela 10.7.
Ustawienia właściwości Wymuszaj nową stronę
Trzymaj razem
Poprawne działanie tej właściwości zależy od spełnienia kilku warunków. Gdy ustawiona jest ona na Tak, Access będzie
usiłował wydrukować całą sekcję na jednej stronie. Jeśli to nie będzie możliwe, spróbuje on umieścić sekcję na nowej
stronie. Jeśli to również się nie powiedzie, grupa zostanie umieszczona na więcej niż jednej stronie. W przeciwieństwie do
analogicznej właściwości dla grupy, w przypadku sekcji Trzymaj razem dotyczy tylko jednej, konkretnej sekcji.
Właściwości te nadzorują sposób, w jaki raport odczytuje dane ze źródła, przygotowuje stronę do wydruku oraz drukuje
daną sekcję. Użyte razem, właściwości te mogą powtarzać dane, tworzyć puste wiersze, drukować różne wiersze w tej
samej linii lub pomijać określone wiersze.
Tabela 10.8 zawiera szczegóły użycia tych właściwości oraz ich rezultaty.
Tabela 10.8.
Sekcje wraz z ich indeksami oraz stałymi
LiczbaFormatowań
Właściwość ta zwiększana jest za każdym razem, gdy strona jest formatowana do druku. Sekcja może być formatowana
więcej niż jeden raz. Może się to zdarzyć, gdy sekcja powinna mieścić się na jednej stronie, jednak się nie mieści. W takim
przypadku, Access sformatuje ją raz na pierwotnej stronie i drugi raz na nowej stronie, ustawiając wartość Licz-
baFormatowań na 2. Ma to znaczenie w sytuacji, gdy wykonujesz obliczenia w zdarzeniu Przy formatowaniu, gdyż
obliczenia te mogą wystąpić więcej niż raz, jeśli nie są kontrolowane przez tę właściwość.
LiczbaDrukowań
Właściwość ta zwiększana jest za każdym razem, gdy sekcja jest drukowana. Sekcja może być drukowana więcej niż jeden
raz. Może się to zdarzyć, gdy sekcja powinna mieścić się na jednej stronie, jednak się nie mieści. W takim przypadku, Access
spróbuje wydrukować ją raz na pierwotnej stronie i drugi raz na nowej stronie, ustawiając wartość LiczbaDrukowań na 2.
Ma to znaczenie w sytuacji, gdy wykonujesz obliczenia w zdarzeniu Przy wydruku, gdyż obliczenia te mogą wystąpić
więcej niż raz, jeśli nie są kontrolowane przez tę właściwość.
ByłKontynuowany, BędzieKontynuowany
Są to właściwości o ograniczonym zastosowaniu. Ustawiane są, gdy sekcja przeszła lub przejdzie na nową stronę. Ich
zastosowanie jest ograniczone, gdyż osoba pisząca raport w Accessie nie jest w stanie stwierdzić, czy nakładanie się
spowodowane jest przez dane czy przez puste miejsca. Dlatego też, właściwość BędzieKontynuowany jest zazwyczaj usta-
wiona na True dla każdej strony raportu. Wydaje się, że jedynym sposobem na pokonanie tego braku „inteligencji”
programu jest upewnienie się, iż wysokość sekcji dzieli się równomiernie na możliwą do zadrukowania przestrzeń na
stronie.
Właściwość ByłKontynuowany ustawiana jest w zdarzeniu Przy formatowaniu. Ustawienie True występuje, gdy
kontynuowana była sekcja z poprzedniej strony. Jednakże trudno jest znaleźć zastosowanie dla tej właściwości, gdyż jej
wartość jest ustawiana zbyt późno, by wykorzystać ją w raporcie.
Przedstawiony moduł VBA mógłby, z pewnymi poprawkami, zostać umieszczony w zdarzeniu raportu Przy otwarciu i po
prostu modyfikować istniejący raport. By jednak dobrze zrozumieć tworzenie raportu z samego kodu, musi to być osobny
moduł.
Dla zachowania prostoty, w naszym przykładzie używamy obiektów DAO. Ponieważ obiekty ADO nie umożliwiają
tworzenia kwerend krzyżowych, użycie DAO oszczędzi nam konieczności tworzenia tymczasowej tabeli, umożliwi
wykorzystanie znanej już większości czytelników techniki uzyskiwania dostępu do danych oraz skoncentrowanie się na
kwestiach związanych z raportem.
Dim db As Database
Dim qrydef As querydef
Dim strSQL As String
Set db = CurrentDb
' Jeśli kwerenda nie istnieje, utwórz obiekt. Jeśli obiekt nie
' istnieje, obiekt Err zwróci komunikat o błędzie 3265.
If (3265 = Err) Then
End If
If (Err) Then
' W tym miejscu przekaż błąd do twojego modułu zajmującego
' się ich poprawianiem
Exit Function
End If
End Function
Funkcja PrepareCrosstabReport() zawiera dwa argumenty danych: datFrom i datTo. Zostaną one przekazane do
funkcji MakeCrosstabQuery. Funkcja ta będzie również korzystać z ikony bazy danych, obiektu recordset (zestaw
rekordów), bardzo ważnego obiektu Raport i kilku innych zmiennych, użytych jako liczniki.
True. Osobna pętla tworzy i rozmieszcza formanty zawierające funkcję Suma(). Ustawiana jest wysokość sekcji Szczegóły
(Detail), przydzielane jest źródło rekordów, by na końcu otworzyć raport.
Set db = CurrentDb()
For i = 0 To x
Set ctlNew = CreateReportControl(rpt.Name, acLabel, acPageHeader)
With ctlNew
.Height = 270
.Width = 1080
.Top = 0
.Left = (60 + .Width) * i
' Indeksy przyznawane są bez twojego udziału, więc
' kontroluj je!
rpt("label" & i + x + 1).Caption = rs.Fields(i).Name
End With
Next
DoCmd.RunCommand acCmdReportHdrFtr
rpt.Section(acFooter).Visible = True
For i = 0 To x
Set ctlNew = CreateReportControl(rpt.Name, acTextBox, acFooter)
With ctlNew
.Height = 270
.Width = 1080
.Top = 0
.Left = (60 + .Width) * i
' Indeksy przyznawane są bez twojego udziału, więc
' kontroluj je!
If i = 0 Then
rpt("text" & i + (2 * x) + 2).ControlSource = "='Suma'"
Else
rpt("text" & i + (2 * x) + 2).ControlSource = _
"=sum([" & rs.Fields(i).Name & "])"
End If
End With
Next
rpt.Section("detail").Height = 0
PrepareCrosstabReport = True
PrepareCrosstabReport_Exit:
Set rpt = Nothing
Część III ♦ Interfejs użytkownika 182
rs.Close
Exit Function
PrepareCrosstabReport_Err:
PrepareCrosstabReport = False
MsgBox Error$
Resume PrepareCrosstabReport_Exit
End Function
Mamy teraz raport oparty na kwerendzie krzyżowej, który jest dynamicznie tworzony za każdym razem, gdy tego
zażądamy. Ponieważ raport korzysta z wybranego źródła rekordów, nie jest nigdy problemem zmiana nagłówka kolumny
czy ilości regionów, których raport dotyczy (w ramach jego wewnętrznych ograniczeń).
Tworzenie sekcji
Sekcje również mogą być tworzone programowo, jednakże nie wszystkie sekcje tworzone są w ten sam sposób. Aby
utworzyć nagłówki i stopki grup, Access posiada funkcję CreateGroupLevel. Ponieważ pięć standardowych sekcji
(Nagłówek/Stopka raportu, Nagłówek/Stopka strony i Szczegóły) nie jest częścią schematu grupowania raportu, tworzone są
w inny sposób.
u StrExpr – wyrażenie poziomu grupy, zazwyczaj nazwa pola, rodzaj obiektu lub data.
u FHeader/FFooter – wartości logiczne, służące do tworzenia dodatkowego nagłówka lub stopki sekcji. Wartość
True – sekcja jest tworzona, False – nie.
createGroupLevel "_Kategorie i produkty" , "newGroupsection" , 1, 1
lub
intSection=createGroupLevel ("_Kategorie i produkty" ,
"newGroupSection" , 1, 1)
Aby utworzyć nagłówki i stopki raportu lub strony, skorzystaj z metody RunCommand obiektu DoCmd:
DoCmd.RunCommand acCmdReportHdrFtr
Wskazówki
Większość aplikacji posiada co najmniej jeden raport, który przysparza wielu problemów. Aby umożliwić Ci radzenie
sobie przynajmniej z częścią z nich, damy teraz kilka wskazówek związanych z raportami.
56. W oknie dialogowym Sortowanie i grupowanie ustaw właściwość Grupuj według na Pierwsze znaki.
57. Właściwość Przedział grupowania ustaw na 1 ( rysunek 10.16). Jest to ważne, gdyż stąd właśnie Access wie, ilu
znaków ma użyć, dzieląc klientów na grupy. W takim przypadku, będzie zwracał uwagę na pierwszą literę
nazwiska klienta.
Rysunek 10.16.
Ustawienia
grupowania
Rysunek 10.17.
Rezultat
numerowania
intCurrLine = intCurrLine + 1
End Sub
cLines = 0
End Sub
Dim x1 As Single
End Sub
End Sub
=ObecnyUżytkownik()
lub
=dlookup("TabelaUżytkowników" , "[Nazwisko]", "[IDUżytkownika]= " & ObecnyUżytkownik() & ")
End Sub
Kombinacja klawisza Shift i strzałek umożliwia zmianę rozmiaru formantów bez przesuwania ich.
Część III ♦ Interfejs użytkownika 186
Część IV
Tajniki VBA
W tej części:
u Tworzenie obiektów przy użyciu modułów klasowych.
u Usuwanie błędów w aplikacjach Accessa.
u Profesjonalna obsługa błędów.
u Optymalizacja aplikacji.
Rozdział 11.
Tworzenie obiektów przy użyciu
modułów klas
W tym rozdziale:
u Korzyści z używania obiektów.
u Przegląd obiektów, własności i metod.
u Tworzenie klas.
u Tworzenie właściwości.
u Tworzenie metod.
u Tworzenie zdarzeń.
u Użycie obiektów.
u Tworzenie kopii obiektów.
u Przegląd innych obiektów.
u Implementacja obiektu do obsługi błędów.
u Użycie obiektów w połączeniu ze zbiorami VBA.
Tworzenie obiektów jest jednym z najskuteczniejszych sposobów na pisanie i obsługę aplikacji. Zanim przejdziemy do
omówienia korzyści płynących z użycia obiektów, zdefiniujmy podstawowe pojęcia.
Obiekty to rzeczy. Samochody, budynki i komputery to różne typy obiektów. W języku programistów słowo obiekt
oznacza jedną, określoną rzecz, na przykład formularz lub formant. Z pewnością już spotkałeś się z tego typu
wbudowanymi obiektami.
W trakcie swojej ewolucji Microsoft Access stał się programem zorientowanym obiektowo, umożliwiającym tworzenie
własnych obiektów i metod dla tych obiektów. Takie obiekty to na przykład: obiekt klient, obiekt faktura, obiekt
użytkownik, obiekt łącze da-
nych czy obiekt dźwięk. Na dołączonej do książki płycie CD znajdziesz wiele stworzonych przez nas obiektów, które
będziesz mógł wykorzystywać do własnych potrzeb („Tworzenie obiektów z modułów klas.mdb” – rysunek 11.1).
Rysunek 11.1.
Przykłady obiektów
własnych, znajdujące
się na dołączonej
płycie CD-ROM
189 Rozdział 11. ♦ Tworzenie obiektów przy użyciu modułów klas
Obiekty tworzone są przy użyciu modułów klasowych. Moduł klasowy to odrębna, przenośna, zaprojektowana w
określonym celu jednostka kodu. Klasa określa właściwości i metody każdego z obiektów klasy.
Programiści często mieszają pojęcia klasa i obiekt. Klasa to opis lub szablon właściwości i metod obiektu. Gdy programista
chce użyć kodu w module klasy, tworzony jest egzemplarz klasy. Ten egzemplarz to obiekt.
Stąd też określenie „tworzenie egzemplarza obiektu” jest niepoprawne. Obiekt sam w sobie jest egzemplarzem! Pojedynczy
obiekt definiowany jest jako egzemplarz klasy. Z jednej klasy można utworzyć wiele obiektów, z których każdy będzie miał inne
właściwości.
Ukrywanie złożoności
Ukrywanie złożoności to jedna z korzyści płynących z używania obiektów. Doświadczony programista może tworzyć
złożone procedury, na przykład procedury Windows API, kod dostępu do danych, procedury ciągów i inne. Mniej
doświadczeni programiści mogą korzystać z obiektów, odwołując się do ich właściwości i metod bez konieczności zro-
zumienia kodu, dzięki któremu obiekty te działają.
cError.email
Rysunek 11.2.
Obiekty umożliwiają
Ci użycie technologii
Microsoft
IntelliSense
Zauważ, jak proste jest używanie obiektów. Korzystając z technologii Microsoft IntelliSense, wpisujesz po prostu nazwę
obiektu (cError) i kropkę, a wyświetlone zostaną wszystkie właściwości i metody tego obiektu. To znacznie ułatwia
pisanie odpowiedniego kodu.
Organizowanie kodu
Tworzenie klas ułatwia organizowanie kodu, co czyni go łatwiejszym do czytania, przeglądania i obsługiwania. Cały kod
dotyczący konkretnego zestawu funkcji zawarty jest wewnątrz danej klasy. Umieszczanie kodu w tym samym miejscu co
właściwości i metod opisujących obiekt nazywamy hermetyzacją.
Obiekt jest to element, który może być programowany, obrabiany i kontrolowany. W Accessie obiektami są formularze,
pola tekstowe, przyciski poleceń i inne. W tym rozdziale zajmiemy się tworzeniem własnych obiektów.
Właściwość jest to cecha obiektu. Może być ona postrzegana jako przymiotnik, gdyż opisuje i charakteryzuje obiekt. W
Accessie właściwościami pola tekstowego są: Nazwa, Widoczny, Kolor pierwszego planu i inne. Większość
właściwości obiektu może być zarówno ustawiana, jak i pobierana. W tym rozdziale pokażem,y jak tworzyć własne
właściwości i kontrolować, czy będą one ustawiane, czy pobierane.
Metoda jest to czynność, jaką można wykonać na obiekcie. Może być ona postrzegana jako czasownik. Przykładowo, jedną
z metod w formularzu Accessa jest Close. W tym rozdziale pokażemy, jak tworzyć własne metody dla obiektów.
Tworzenie klas
Do tworzenia klasy używany jest moduł klasowy. Klasa definiuje właściwości, metody i zdarzenia, tworząc jasno
określony i dobrze opisany interfejs.
Aby utworzyć klasę, wstaw do swojej aplikacji moduł klasy i nazwij go. Nazwa tego modułu klasy będzie nazwą Twojego
obiektu.
Aby wstawić moduł klasy, z menu Wstaw wybierz Moduł klasy. Uruchomiony zostanie edytor VBA. W oknie kodu możesz
wpisywać dowolne właściwości, metody i zdarzenia dla obiektu. Zanim przejdziemy dalej, nazwij ten moduł klasowy
(rysunek 11.3).
Rysunek 11.3.
Używaj jednolitego
nazewnictwa
modułów klasy
Tworzenie właściwości
Istnieją dwa sposoby tworzenia właściwości klasy: zmienne jawne i procedury właściwości.
Po wykonaniu tego prostego kroku użytkownicy mogą ustawiać i pobierać wartości tych właściwości. Do ustawienia tych
właściwości służy następujący kod:
cUser.Imię = "Michał"
cUser.TypUżytkownika = "Kierownik"
Procedury właściwości umożliwiają Ci określenie, kto może ustawiać i pobierać wartości właściwości. Kluczem do
zrozumienia funkcjonowania procedur właściwości jest to, że wartość właściwości ukryta jest w zmiennej prywatnej
modułu. Stąd też, pierwszy krok to utworzenie zmiennej prywatnej modułu, a następnie tworzenie instrukcji Property
Let i Property Get.
193 Rozdział 11. ♦ Tworzenie obiektów przy użyciu modułów klas
Poniżej znajduje się przykład tworzenia zmiennej niejawnej modułu dla właściwości Imię i TypUżytkownika obiektu
cUser:
Option Explicit
' Utwórz zmienną prywatną w części deklaracyjnej'
Private mstrImię as String
Private mTypUżytkownika as String
Property Let
Procedura Property Let używana jest do ustawiania wartości właściwości. Jeśli nie chcesz, aby inni mieli możliwość
ustawiania wartości właściwości, nie dołączaj tej procedury.
Poniższy przykład tworzy procedurę Property Let dla właściwości Imię obiektu cUser:
Public Property Let Imię (ImięUżytkownika as String)
' Weź wartość wpisaną do (ImięUżytkownika) i zapisz ją w zmiennej
' prywatnej (mstrImię).
mstrImię = ImięUżytkownika
End Property
Przyjrzyjmy się teraz tej procedurze. Po pierwsze, jako że procedura Property Let istnieje, właściwość Imię jest
dostępna na zewnątrz i może zostać ustawiona. Programista mógłby ustawić tę właściwość w następujący sposób:
cUser.Name = "Mariusz"
Gdy Mariusz zostanie wprowadzony w procedurze właściwości, zostanie przekazany do zmiennej ImięUżytkownika.
Procedura Property Let pobiera wartość zmiennej ImięUżytkownika (Mariusz) i ukrywa ją w zmiennej prywatnej
modułu – mstrImię. Procedura ta dotyczy jednego parametru, ale do procedury właściwości można przekazać ich wiele.
Wartość właściwości może być pobrana tylko wtedy, gdy istnieć będzie procedura Property Get.
Property Get
Procedura Property Get umożliwia pobieranie wartości właściwości. Jeśli nie chcesz, by inni mogli pobierać wartość
właściwości, nie dołączaj instrukcji Property Get. Instrukcja ta pobiera wartość właściwości ukrytą w zmiennej
prywatnej i zwraca ją jako wartość właściwości. Poniższy przykład zawiera instrukcję Property Get dla właściwości
Imię obiektu cUser:
Public Property Get Imię () as string
' Weź wartość ukrytą w zmiennej prywatnej (mstrImię) i
' umieść ją w wartości właściwości.
Imię = mstrImię
End Property
Użytkownik może z łatwością pobrać wartość właściwości (jeśli instrukcja Property Get istnieje), korzystając z
poniższego kodu:
MsgBox cUser.Imię
Typ danych Property Let musi być taki sam jak Property Get. Przy-
kładowo, instrukcja Property Let dla właściwości Imię akceptuje argu-
ment typu string (ciąg). W takim przypadku, procedura Property Get
musi również zwracać dane typu string.
Część IV ♦ Tajniki VBA 194
Property Set
Instrukcja Property Set umożliwia Ci tworzenie procedury właściwości, która ustawia odniesienie do dowolnego
obiektu. By określić obiekt, użyj w procedurze Property Set słowa kluczowego Set.
W naszym przykładzie użyliśmy obiektu cForm. Obiekt ten posiada właściwość Form, do której musi być przekazany
obiekt Form. Kod w module klasy cForm jest następujący:
Option Compare Database
' Zadeklaruj zmienną prywatną na poziomie modułu
Private mobjForm as Form
Public Property Get Form() As Variant
' Pobierz obiekt znajdujący się w zmiennej prywatnej (mobjForm) i
' umieść go w wartości właściwości.
Set Form = mobjForm
End Property
Po załadowaniu frmPropertySet formularz przekazywany jest do właściwości Form. Ponieważ jest to obiekt, używamy
słowa kluczowego Set. Nazwa formularz może być wyświetlona w oknie komunikatu. Oto kod dla formularza
frmPropertySet:
' W tym przykładzie korzystamy z obiektu "cForm". Obiekt
' ten posiada właściwość "Form". Gdy ładowany jest formularz
' (frmPropertySet), przekazywany jest jako obiekt do właściwości
' "Form". Gdy klikniesz przycisk "Property Set", pobrana zostanie
' nazwa formularza.
Private mobjForm As cForm
Private Sub cmdClose_Click()
DoCmd.Close acForm, "frmPropertySet", acSaveNo
EndSub
Zaletą procedur właściwości jest to, że umożliwiają tworzenie właściwości tylko-do-odczytu i tylko-do-zapisu.
Przykładowo, jeśli chcesz utworzyć właściwość Hasło, możesz chcieć pozwolić użytkownikom zmieniać je, ale nie
pobierać (tylko-do-zapisu). Aby utworzyć procedurę tylko-do-zapisu, wystarczy dołączyć instrukcję Property Let i jed-
nocześnie nie dołączać instrukcji Property Get.
Korzystając z procedur właściwości, możesz również wykonywać czynności w kodzie podczas ustawiania lub pobierania
właściwości.
Rysunek 11.5
Z rozwijanej listy
wybierz True
lub False
W części deklaracyjnej modułu klasowego do określenia wartości właściwości użyj słowa kluczowego Enum. Przykładowo,
załóżmy, że dla właściwości TypUżytkownika obiektu cUser chcesz dostarczyć rozwijaną listę z następującymi
wartościami: Menedżer, Administracja oraz Nieznany. Kod w części deklaracyjnej będzie następujący:
Public Enum ListaUżytkowników
Menedżer
Administracja
Nieznany
End Enum
Następnym krokiem będzie użycie wyliczeniowego typu danych (ListaUżytkowników) jako typu danych właściwości
TypUżytkownika klasy cUser. Ilustruje to poniższy przykład, z właściwością utworzoną jako zmienna jawna:
Wartości właściwości mogą być bez trudu ustawiane przy użyciu rozwijanej listy, dostępnej dzięki technologii IntelliSense
(rysunek 11.6).
Rysunek 11.6.
Przykład
wyliczeniowego typu
danych
Aby można było określić, która ze znajdujących się na liście wartości właściwości została wybrana, każdy typ danych jest
numerowany (rozpoczynając od zera, z przyrostem równym 1).
Część IV ♦ Tajniki VBA 196
Tworzenie metod
Metoda jest to czynność, jaką możemy wykonać na obiekcie. Aby utworzyć metodę dla klasy, wystarczy utworzyć
publiczną procedurę lub funkcję. Załóżmy, że za każdym razem, gdy użytkownik loguje się do aplikacji, chcesz zapisywać
czas i datę tego zdarzenia. Poniższy kod utworzy metodę Login, wprowadzającą do tabeli datę i czas zalogowania każdego
z użytkowników.
Public Sub Login()
' Utwórz zmienną obiektu dla zestawu rekordów
Dim rst As ADODB.Recordset
' Utwórz zmienną string
Dim strSQL As String
' Instrukcja SQL dla tblUsers
strSQL = "Select * FROM tblUsers"
' Utwórz zestaw rekordów ADO
Set rst = New ADODB.Recordset
' Otwórz zestaw rekordów
rst.Open strSQL, CurrentProject.Connection, adOpenKeyset, _
adLockOptimistic
' Dodaj nowy rekord
rst.AddNew
' Zapisz czas i datę logowania użytkownika
With rst
!Imię = Me.Name
!Data = Date
!Czas = Time
End With
' Zapisz nowy rekord
rst.Update
' Zamknij zestaw rekordów
rst.Close
' Zniszcz zmienną obiektu
Set rst = Nothing
End Sub
Użycie metod
Do użycia metody przy otwieraniu aplikacji służy następujący kod:
cUser.Login
Zauważ, że użytkownicy tej metody nie muszą rozumieć kodu ADO, aby aktualizować wartość w bazie danych.
Wystarczy, że używają właściwości i metod dostępnych dla obiektu wyświetlanego przez IntelliSense.
Tworzenie zdarzeń
Obiekty w Accessie posiadają swoje zdarzenia. Przykładowo, obiekt formularz posiada zdarzenie Przy załadowaniu, a
przycisk polecenia zdarzenie Przy kliknięciu.
Dla własnych obiektów również możesz tworzyć zdarzenia. W tym celu musisz użyć w części deklaracyjnej słowa
kluczowego Event i określić nazwę zdarzenia. Przykładowo, dodajmy zdarzenie Przy powitaniu, które będzie występowało
po otwarciu aplikacji przez użytkownika. W części deklaracyjnej modułu klasy umieść poniższy kod, który utworzy
wyrażenie:
197 Rozdział 11. ♦ Tworzenie obiektów przy użyciu modułów klas
Event PrzyPowitaniu ()
Aby użyć zdarzenia, umieść je w metodzie obiektu. Służy do tego polecenie Raise. W naszym przykładzie, umieścimy
zdarzenie Przy powitaniu w metodzie Login obiektu cUser.
Gdy użytkownik uruchomi aplikację, nastąpi odwołanie do metody Login. Spowoduje to uruchomienie zdarzenia Przy
powitaniu, które wyświetli ekran powitalny dla użytkownika, zawierający jego Imię. Służy do tego następujący kod:
Public Sub Login()
RaiseEvent PrzyPowitaniu
End If
Te kroki wystarczą, by utworzyć zdarzenie i umieścić je w module klasy. W następnej części omówimy użycie zdarzeń w
formularzu.
Użycie zdarzeń
Aby użyć zdarzenia Przy powitaniu z modułu formularza, w części deklaracyjnej zadeklaruj zmienną obiektu cUser i użyj
słowa kluczowego WithEvents. Umieszczenie tego słowa konieczne jest do użycia zdarzeń obiektu cUser. Użyj
następującego kodu:
' W części deklaracyjnej modułu umieść
Private WithEvents objUser As cUser
Po zadeklarowaniu używającej słowa kluczowego WithEvents zmiennej na poziomie modułu przyjrzyj się znajdującym
się u góry okna modułu listom wyboru. W lewym polu wybierz obiekt cUser. Następnie w prawej liście wyboru zobaczysz
zdarzenia dla tego obiektu. Wybierz zdarzenie Przy powitaniu, a procedura zostanie wyświetlona w oknie kodu. Tam też
będziesz mógł wpisać kod, który będzie reakcją na zdarzenie.
Poniższy przykład zawiera kod będący reakcją na zdarzenie Przy powitaniu (rysunek 11.7).
Rysunek 11.7.
Procedura
używająca zdarzenia
„Przy powitaniu”
obiektu cUser
W wyniku tego, przy otwieraniu aplikacji przez użytkownika wyświetlany będzie ekran powitalny (rysunek 11.8).
Część IV ♦ Tajniki VBA 198
Rysunek 11.8.
Ekran powitalny
Zdarzenie Przy inicjacji uruchamiane jest za każdym razem, gdy obiekt jest tworzony. Przykładowo, jeśli chcesz, aby
określony kod był uruchamiany, gdy tworzony jest obiekt cUser, umieszczasz go w zdarzeniu Przy inicjacji.
Zdarzenie Przy zakończeniu uruchamiane jest za każdym razem, gdy obiekt jest niszczony. Jest to dobre miejsce na
umieszczenie kodu porządkującego, który zamknie połączenia bazy danych, zwolni zmienne obiektów itp.
Użycie obiektów
W tym momencie, obiekt cUser istnieje i posiada właściwości oraz metody. Aby użyć go w module klasy, wystarczy
wpisać nazwę tego obiektu oraz kropkę. IntelliSense wyświetli listę właściwości i metody dla tego obiektu.
Aby użyć obiektu wewnątrz klasy, która go stworzyła, użyj słowa kluczowego Me. Przykładowo, aby ustawić nazwę
użytkownika:
Me.User = "Mariusz"
Użycie tego obiektu z zewnątrz modułu klasy cUser (w formularzach lub modułach standardowych) wymaga wykonania
dwóch czynności. Po pierwsze, zadeklarowania zmiennej obiektu, która zostanie użyta jako odniesienie do obiektu. Drugą
czynnością jest wykorzystanie słowa kluczowego Set do utworzenia odniesienia zmiennej obiektu do obiektu.
StrImię = "Mariusz"
I = 10
W tych przypadkach, zmienne zawierały określony typ danych, a informacje w nich przechowywane mogły być w razie
potrzeby pobierane.
Zmienna obiektu, podobnie do prostych zmiennych, deklarowana jest za pomocą polecenia Dim:
Dim objUser as cUser
Zawsze używaj instrukcji Dim i Set w osobnych liniach. Nigdy nie łącz ich
w jednej linii (np. Dim objUser = New cUser). Jeśli to zrobisz, kod
będzie działał dużo wolniej, a Ty nie będziesz wiedział, w którym mo-
mencie obiekt umieszczany jest w pamięci.
Użycie obiektu
Po utworzeniu i ustawieniu zmiennej obiektu będziesz mógł za pomocą IntelliSense używać właściwości i metod obiektu.
Właściwości mogą być ustawiane i pobierane, a metody wykonywane przy użyciu składni z kropką.
Ustawienie wartości właściwości: Obiekt.Właściwość = Wartość
Pobranie wartości właściwości: MsgBox Obiekt.Właściwość
Zwalnianie obiektu
Gdy zakończyłeś już pracę ze zmienną obiektu, zwolnij go, ustawiając obiekt na Nothing. W ten sposób odzyskasz
zarezerwowane zasoby. Prawidłowa składnia wygląda następująco:
' Zwolnij zmienną obiektu
Set objUser = Nothing
Po utworzeniu klasy powstaje kopia obiektu zawierająca podstawowy zestaw właściwości i metod (szablon). Od tego
momentu, obiekt staje się unikatowy i posiada własny zestaw wartości właściwości oraz metod.
Jedną z korzyści modułu klasy jest to, że można tworzyć wiele egzemplarzy klasy. Każda z nich posiada podstawowy
zestaw właściwości i metod, jednak każdą z nich można w różny sposób dostosowywać po utworzeniu obiektu. Załóżmy,
że utworzono pięć obiektów cUser. Każdy z nich posiada różne wartości właściwości i metody. Przykładowo, jeden z nich
może mieć wartość właściwości Imię Mariusz, a inny Beata.
Aby utworzyć kilka egzemplarzy obiektu, wystarczy stworzyć dodatkowe zmienne obiektu i przypisać każdą z nich do
nowego obiektu. Przyjrzyj się poniższemu fragmentowi kodu:
Public Sub WieluUżytkowników()
Dim objUser1 as cUser
Dim objUser2 as cUser
ObjUser1.Imię = "Mariusz"
ObjUser2.Imię = "Beata"
Część IV ♦ Tajniki VBA 200
Msgbox "Aktualni użytkownicy to: " & objUser1.Imię & " i "_
objUser2.Imię
Obiekt TextFile
Kod tego rozdziału zawiera obiekt cTextFile, który może być użyty do odczytywania i zapisywania informacji w pliku
tekstowym (rysunek 11.9).
Rysunek 11.9.
Przykład obiektu
TextFile
End Function
Public Function ReadAllText(strFileName As String) As String
pintFreeFile = FreeFile
Open strFileName For Input As pintFreeFile
Do Until VBA.EOF(pintFreeFile)
Line Input #pintFreeFile, pvarInfo
ReadAllText = ReadAllText & vbCrLf & pvarInfo
Loop
Close #pintFreeFile
End Function
Obiekt Timer
W kodzie rozdziału znajduje się również moduł klasy cTimer. Moduł ten ma dwa zastosowania: stoper (pozwala obserwować
mijający czas) oraz do powstrzymania wykonywania kodu przez określoną ilość sekund.
Option Explicit
Private msngStart As Single
End Sub
Public Function ElapsedTime() As Long
Dim sngTimerStop As Single
sngTimerStop = Timer
msngStart = 0
sngTimerStop = 0
End Function
Formularz frmTimer w bazie „tworzenie obiektów przy użyciu modułów klasy.mdb”” przedstawia, jak korzystać z zegara
w celu określenia pozostającego czasu i stworzenia „stanu oczekiwania”. Patrz rysunek 11.10.
Rysunek 11.10.
Użycie zegara do
określenia
pozostającego czasu
oraz stworzenia
„stanu oczekiwania”
Obiekt Sound
Zadaniem modułu klasy cSound jest odtwarzanie dźwięków w aplikacjach Accessa. Moduł ten zawiera tylko jedną metodę
(PlaySound), która przekazuje plik dźwiękowy do interfejsu API systemu Windows:
' Odwołanie do interfejsu API systemu Windows
Private Declare Function sndPlaySound Lib "winmm.dll" Alias _
"sndPlaySoundA" (ByVal lpszSoundName As String, ByVal uFlags _
As Long) As Long
End Sub
Rysunek 11.11.
Przykład obiektu
Sound
Część IV ♦ Tajniki VBA 202
Obiekt Letter
Zadaniem tego modułu klasy jest tworzenie listów w programie Microsoft Word. Listy te tworzone są przy użyciu
korespondencji seryjnej. Do stworzenia listu wykorzystywany jest szablon programu Word, a instrukcja SQL pobiera dane
do listu. Metoda ShowWord (logiczna) określa, czy Word będzie widoczny dla użytkownika. Czasami możesz chcieć
przesłać listy bezpośrednio do drukarki, bez ich edycji.
objWord.Documents.Add (Me.Template)
If ShowWord Then
Me.ShowWord
End If
End Sub
End Sub
End Sub
End Sub
Poniższy kod korzysta z właściwości i metod obiektu objLetter:
' Wymiary zmiennych
Dim objLetter As cLetter
Dim strPath As String
StrPath = CurrentProject.Path
Obiekt Outlook
Moduł klasy cOutlook służy do wyświetlania formularza Nowa wiadomość programu MS Outlook (rysunek 11.12). Jeśli
chcesz umożliwić użytkownikom pisanie wiadomości programu Outlook w aplikacjach Accessa, wystarczy, że odwołasz się
do metody NewEmailMessage.
Rysunek 11.12.
Wyświetlanie
formularza Nowa
wiadomość programu
Outlook w aplikacjach
Accessa
mMyItem.To = EmailAddress
mMyItem.Display
End Sub
End If
End Sub
End Sub
Używając narzędzia Object Browser, przyjrzyj się obiektowi cError (rysunek 11.13).
Rysunek 11.13.
Obiekt cError
w narzędziu
Object Browser
Użycie obiektów
w połączeniu z kolekcjami VBA
Kolekcje VBA to sposób na traktowanie obiektów własnych jako grupy. Przykładowo, jeśli istnieje pięć obiektów cUser i
chcesz na każdym z nich wykonać jakieś działanie, łatwiej i efektywniej będzie traktować te pięć obiektów jak jedną grupę
niż każdy z osobna.
Z pewnością zapoznałeś się już z wbudowanymi kolekcjami (np. „formularze” czy „formanty”). VBA również posiada
obiekt kolekcja (collection). Kolekcja jest to sposób traktowania grupy obiektów, jakby były odrębną jednostką. W życiu
codziennym też spotykamy takie grpy. Dyrygent orkiestry mówi: „A teraz wstaną wszystkie instrumenty dęte”. Jest to dużo
wygodniejsze rozwiązanie niż „Tomasz, Agnieszka, Marta i Rafał, wstańcie”. W podobny sposób można traktować
obiekty.
205 Rozdział 11. ♦ Tworzenie obiektów przy użyciu modułów klas
Najważniejsze w całej tej idei jest to, że kolekcja jest obiektem, który posiada własne metody i właściwości. Oto cechy
obiektu kolekcji:
u Jest obiektem posiadającym własne metody i właściwości.
u Do kolekcji można dodawać różne typy obiektów.
u Jego rozmiar się zmienia. Rośnie wraz z dodawaniem i zmniejsza się wraz z usuwaniem obiektów.
u Elementy kolekcji nie podlegają sortowaniu.
u Elementy kolekcji są indeksowane. Indeksowanie rozpoczyna się od wartości 1.
Wygodnie jest nazywać zbiory liczbą mnogą nazwy obiektów, które zawie-
rają. Obiekt, który będzie dodawany do zbioru w naszym przykładzie, to
użytkownik (User). Stąd nazwa zbioru – Użytkownicy.
Tabela 11.1.
Właściwości i metody obiektu collection
Następnie podaj zmienną obiektu dla każdego z obiektów dodawanych do kolekcji. Przykładowo, aby dodać do kolekcji
dwóch użytkowników, użyj zmiennej obiektu dla każdego z nich: objUser1 i objUser2. Następny parametr to wartość
Key (już znana), która będzie użyta do tworzenia odniesienia do obiektu. Jeśli wartość klucza nie jest określona, każdy
obiekt w kolekcji musi być powiązany z numerem indeksu.
Radzimy określanie wartości klucza. Dzięki temu pisanie kodu jest prost-
sze, a sam kod jest bardziej wiarygodny niż numery indeksu. Numery
indeksu mogą ulec zmianie, gdy ze zbioru zostanie usunięty jakiś element lub
gdy inny obiekt zostanie wstawiony w określone miejsce przy użyciu
argumentów metody Add.
Powyższy kod dodaje obiekt User1 do zbioru. Jako klucz służy wartość właściwości Imię obiektu. Obiekt User2 dodany
został w ten sam sposób. Zwróć uwagę na argumenty before i after (przed i po) metody Add, które określają miejsce
obiektu w zbiorze.
Aby użyć pętli For Each określ, który obiekt zbioru chcesz zbadać. A oto kod:
' Musisz zadeklarować zmienną obiektu
Dim User as cUser
Użycie dołączonych do Accessa narzędzi do usuwania błędów oraz opisanych w tym rozdziale technik usuwania błędów
pozwala na znaczne skrócenie czasu tworzenia aplikacji. Warto więc je poznać, gdyż zaowocuje to zauważalnymi
korzyściami w długim okresie czasu.
Nie myśl, że narzędzia do usuwania błędów przydają się tylko w przypadku bardzo skomplikowanych aplikacji. Zdarza się,
że nawet w najprostszych aplikacjach błędy są trudne do wykrycia.
Ważne, by błędy programu zostały wykryte i poprawione jak najszybciej. Mimo iż część z nich może mieć mały wpływ na
działanie programu, inne mogą naruszyć integralność bazy danych lub wywołać jeszcze poważniejsze konsekwencje.
Większość czasu spędzonego przy uruchamianiu aplikacji zabiera wyszukiwanie i poprawianie błędów logicznych. W tym
rozdziale zostaną przedstawione techniki oraz narzędzia do usuwania takich błędów.
Mimo, iż Visual Basic IDE jest osobną aplikacją, działa w połączeniu z Accessem. Jeśli aplikacja ta jest otwarta, to
zostanie zamknięta w momencie, w którym zamkniesz Access. Aby zamknąć Visual Basic IDE, z menu File wybierz
Close And Return to Microsoft Access.
Project Explorer
Project Explorer wyświetla listę formularzy, raportów i modułów klasy w danej aplikacji Accessa (rysunek 12.2).
Rysunek 12.2.
Okno Project
Explorer
Kliknij dowolny obiekt prawym klawiszem myszy, aby zobaczyć jego kod lub przejść do widoku Projekt formularza. Aby
otworzyć Project Explorer, z menu View wybierz Project Explorer lub naciśnij klawisze Ctrl+R.
Okno Code
Okno Code zawiera kod formularzy, modułów i modułów klasy (rysunek 12.3). Jako programista, spędzisz wiele godzin,
wprowadzając i modyfikując kod w tym oknie. Aby je otworzyć, z menu View wybierz Code lub naciśnij klawisz F7. U góry
okna Code znajdują się dwie rozwijane listy. Lista z lewej strony służy do wybierania obiektów (np. formularzy czy formantów
formularza). Druga lista służy do wybierania metody dla danego obiektu.
Część IV ♦ Tajniki VBA 210
Rysunek 12.3.
Okno Code
Okno Properties
Okno Properties służy do ustawiania i przeglądania właściwości formularzy, raportów i formantów na nich umieszczanych
(rysunek 12.4). Aby je otworzyć, z menu View wybierz Properties lub naciśnij klawisz F4.
Rysunek 12.4.
Okno Properties
Okno Immediate
Okno Immediate może być używane do oceny i ustawiania zmiennych, uruchamiania procedur oraz wykonywania
instrukcji Debug.Print. Aby je otworzyć, z menu View wybierz Immediate window lub naciśnij klawisze Ctrl+G.
Szczegóły związane z funkcjonowaniem tego okna omówimy w dalszej części tego rozdziału.
Okno Locals
Okno Locals przedstawia wyrażenia, wartości i typy wszystkich zmiennych, które są aktualnie analizowane. Aby je
otworzyć, z menu View wybierz Locals window. Szczegóły związane z funkcjonowaniem tego okna omówimy w dalszej
części tego rozdziału.
Okno Watch
Okno Watch może być użyte do obserwowania wartości wyrażeń podczas działania aplikacji. Aby je otworzyć, z menu
View wybierz Watch window. Szczegóły związane z funkcjonowaniem tego okna omówimy w dalszej części tego rozdziału.
211 Rozdział 12. ♦ Usuwanie błędów w aplikacjach Accessa
Object Browser
Aby otworzyć Object Browser, z menu View wybierz Object Browser lub naciśnij F2. Object Browser możesz używać
do przeglądania obiektów, właściwości i metod (rysunek 12.5).
Rysunek 12.5.
Object Browser
Jak widać, w IDE można korzystać z wielu okien. Dlatego też dużo łatwiej
jest pracować w rozdzielczości 1024 na 768 lub wyższych. Jeszcze lepszym
rozwiązaniem jest nowa opcja systemów Windows 98 i 2000 – multi-
monitor.
Aby ułatwić sobie pracę z oknami, naucz się ich klawiszy skrótów. Umoż-
liwi Ci to ich szybkie otwieranie i zamykanie. W zależności od potrzeb
okna te możesz przesuwać lub zmieniać ich rozmiar. Jeśli zmienisz
położenie okna, możesz mieć trudności z powtórnym umieszczeniem go na
swoim miejscu. Wystarczy wówczas kliknąć dwukrotnie pasek z jego
nazwą.
Obiekt Debug
Obiekt Debug posiada dwie metody, które są bardzo pomocne w usuwaniu błędów aplikacji – Debug.Print i Debug.Assert.
Debug.Print
Korzystając z Debug.Print, możesz wyświetlać informacje w oknie Immediate. Metoda ta może być wykorzystywana w
samym oknie Immediate lub w kodzie.
W oknie Immediate możesz testować wbudowane funkcje, wartości zestawu rekordów i inne (rysunek 12.6). Przykładowo,
poniższy kod służy do testowania wbudowanej funkcji Len:
Rysunek 12.6.
Do testowania
funkcji w oknie
Immediate używaj
znaku zapytania
Umieszczając w kodzie Debug.Print, w oknie Immediate możesz wyświetlać wartości i inne informacje. Gdy wykonany
zostanie poniższy kod, w oknie Immediate zostanie wyświetlona wartość stanu:
Sub Demo()
Debug.Print rst.States
Select Case rst.States
Case "Washington"
MsgBox "Washington"
Case "Oregon"
MsgBox "Oregon"
Case "California"
MsgBox "California"
End Select
End Sub
Okno Immediate nie przenosi tekstu do nowego wiersza, więc staraj się skrócić rezultat działania procedury. Nie musisz
usuwać instrukcji Debug.Print z kodu, ponieważ ostateczny użytkownik nigdy nie zobaczy okna Immediate. Jeśli
jednak instrukcji tych będzie dużo, będzie to miało wpływ na wydajność aplikacji.
Debug.Assert
Debug.Assert służy do warunkowego zawieszania wykonywania pojedynczych linii kodu. Przykładowo, jeśli instrukcja
napotka Debug.Assert False, wstrzyma wykonywanie tej linii kodu. Umożliwia to przejrzenie aplikacji i usunięcie
błędów.
Nigdy nie używaj w kodzie słowa kluczowego Stop. Jeśli bowiem zapom-
nisz go usunąć, to nie tylko zatrzyma wykonywanie kodu, ale będzie również
zatrzymywać używaną przez użytkowników aplikację. Zamiast tego zawsze
używaj Debug.Assert, ponieważ ta instrukcja jest zawsze usuwana przez
kompilator.
Podglądanie zmiennych
Aby podejrzeć wartość zmiennej w oknie Immediate, wprowadź znak zapytania, a po nim nazwę zmiennej (np. ?
strName). Pamiętaj, że możesz określić wartość zmiennej, ustawiając na niej kursor myszy w trybie pauzy.
Jeśli w oknie Immediate znajduje się kilka instrukcji kodu, nie musisz ich usuwać. Wystarczy, że umieścisz kursor w
instrukcji, którą chcesz uruchomić i naciśniesz klawisz Enter.
Aby przenieść punkt wprowadzania na początek okna Immediate, naciśnij klawisze Ctrl+Home. Naciśnięcie klawiszy
Ctrl+End spowoduje przeniesienie punktu wprowadzania na koniec okna.
Gdy program zostanie uruchomiony, wykonywanie zostanie zatrzymane w miejscu umieszczenia punktu zatrzymania
(rysunek 12.7). Moduł kodu zostanie automatycznie otwarty, a dana instrukcja zostanie podświetlona na żółto. Możesz
wówczas przejść przez kod, przeglądać lub zmieniać wartości zmiennych itp.
Aby usunąć punkt zatrzymania, z menu Run wybierz Clear All Breakpoints lub naciśnij klawisze Ctrl+Shift+F9.
Rysunek 12.7.
Wykonywanie kodu
zatrzymane
w punkcie
zatrzymania
Wykonywanie procedur
Zdarza się, że jedne procedury odwołują się do innych. Procedury, do których się odwołujesz, mogą być pewne (innymi
słowy, pełni przetestowane i bezbłędne). Aby szybko wykonać te procedury i nie przechodzić pojedynczo przez każdą
instrukcję kodu, z menu Debug wybierz Step Over lub naciśnij klawisz F8.
Po zakończeniu wykonywania tej procedury wykonywanie kodu zostanie ponownie zatrzymane. Od tego momentu możesz
kontynuować krokowe przechodzenie przez kod.
wybierając z menu Debug pozycję Step Out lub naciskając Ctrl+Shift+F8. Opcja ta przydaje się, gdy zapomniałeś użyć
opcji Step Over, a już znajdujesz się w procedurze.
Okno Immediate może być również wykorzystane do wyświetlenia wartości zmiennych. Przykładowo, umieszczenie w
oknie Immediate poniższego tekstu spowoduje zwrócenie wartości zmiennej o nazwie strName:
? strName
Rysunek 12.8.
Określenie wartości
zmiennej w trybie
pauzy
Przykładowo, po wpisaniu nazwy obiektu (np. Recordset lub Application) wpisz kropkę, a zobaczysz, czy użyłeś
właściwej nazwy i pisowni właściwości lub metody. Jeśli na wyświetlonej rozwijanej liście nie znajdziesz danej właściwości
lub metody, będzie to oznaczać, że użyłeś nieprawidłowej składni.
Rysunek 12.9.
Okno Locals
przedstawia
aktualnie
analizowane
zmienne
Rysunek 12.10.
Aby tworzyć
wyrażenie Watch,
użyj okna
dialogowego Add
Watch
Aby szybko utworzyć wyrażenie Watch, zaznacz dowolne wyrażenie kodu, a następnie z menu Debug wybierz Quick
Watch lub naciśnij klawisz F9. W oknie dialogowym Quick Watch naciśnij przycisk Add.
Rysunek 12.11.
Użycie okna
dialogowego
Quick Watch
Jeżeli przechodzenie przez kod to poruszanie się naprzód, to okno Call Stack umożliwia ci spojrzenie wstecz. Przedstawia,
które procedur były uprzednio wywoływane (rysunek 12.12). Aby otworzyć okno Call Stack, z menu View wybierz Call
Stack lub naciśnij klawisze Ctrl+L.
Rysunek 12.12.
Użyj okna Call Stack,
aby sprawdzić, które
procedury były
uprzednio
wywoływane
Najlepszym rozwiązaniem jest stworzenie pojedynczej wersji aplikacji, która będzie się zachowywać w różny sposób, w
zależności od okoliczności. Możesz wybrać, która część kodu aplikacji będzie kompilowana i uruchamiana warunkowo.
Przykładowo, przyjmijmy, że określona część kodu uruchamiana będzie w biurze w Warszawie i nie dotyczy innych biur.
Po pierwsze, wybierz stałą określającą to biuro, np. War. Wprowadź tę stałą jako argument kompilacji warunkowej dla
aplikacji. W edytorze Visual Basic, z menu Tools wybierz Application’s Properties. Otwarte zostanie okno dialogowe Project
Properties. Wybierz zakładkę General. W polu Conditional Compilation Arguments wpisz War = -1. Ustawia to stałą na
True.
Teraz możesz wprowadzić kod, który będzie wykonywany jedynie dla warszawskiej wersji aplikacji. Aby tego dokonać,
umieść kod w konstrukcji kompilacji warunkowej.
Na przykład:
#If War Then
' Kod ten będzie uruchamiany w warszawskiej wersji
' aplikacji.
#End If
Kompilacja warunkowa może być również pomocnym narzędziem do usuwania błędów. Załóżmy, że często opatrujesz
fragmenty kodu komentarzem. Ustaw argument kompilacji warunkowej na fComment = -1. Ten znacznik, komentarz
może być używany w konstrukcji kompilacji warunkowej w celu opatrywania części kodu komentarzem:
#If fComment Then
'Ten kod będzie uruchamiany
#End If
Numeracja od 0 czy od 1?
W VBA niektóre elementy numerowane są od 0, a inne od 1. Zależy to od tego, czy zaczynasz liczenie od 0 czy od 1.
Przykładowo, tablice numerowane są od 0, a kolekcje od 1. Jeśli nie jesteś pewien, jak numerowany jest dany obiekt,
sprawdź to. Pomyłka najprawdopodobniej zakończy się błędem.
Używaj komentarzy
Nie oszukujmy się, kilka miesięcy, tygodni czy nawet dni po napisaniu kodu trudno jest pamiętać wszystkie szczegóły
dotyczące konkretnej procedury. Pisz komentarze do kodu, a będzie on łatwiejszy w obsłudze. Komentarze nie zwalniają
219 Rozdział 12. ♦ Usuwanie błędów w aplikacjach Accessa
kodu, ponieważ są pomijane przez kompilator. Aby utworzyć komentarz, przed tekstem umieść pojedynczy cudzysłów. W
oknie kodu komentarze wyświetlane są na zielono.
Jeśli zapomnisz usunąć Stop przed oddaniem aplikacji użytkownikom, nie będzie ona działać poprawnie, natomiast
Debug.Assert jest podczas kompilacji usuwane z kodu.
End Sub
Obserwując, które z okien komunikatu wyświetlane jest przed wystąpieniem błędu, możesz określić, w której znajduje się
on linii. Dużo lepszym podejściem jest ustawienie punktu zatrzymania i przejście przez kod. Ustawienie punktu
zatrzymania jest bardziej przydatne, gdyż:
u Jest szybsze niż wpisywanie dużej ilości okien komunikatu.
u Okna komunikatu są modalne, więc nie możesz przejść do okna kodu, aby przejrzeć kod.
Część IV ♦ Tajniki VBA 220
u Przechodząc przez kod przy użyciu programu uruchomieniowego, możesz sprawdzać i zmieniać wartość
zmiennych itp.
u Po naprawieniu błędu nie musisz usuwać wszystkich wstawionych okien komunikatu.
u Nie musisz się martwić, że przypadkowo dostarczysz użytkownikom aplikację, z której zapomniałeś usunąć okien
komunikatu.
Testowanie aplikacji
Zanim przekażesz aplikację do rąk użytkowników, pamiętaj o dogłębnym jej przetestowaniu. Więcej informacji na ten
temat znajdziesz w rozdziale 2. „Planowanie procesu rozwoju”.
Wizytówką profesjonalnej aplikacji jest jej obsługa błędów. Jeśli aplikacja nie radzi sobie poprawnie z błędami, niezależnie
od tego jak jest rozbudowana, użytkownicy będą niezadowoleni.
Program nie posiadający obsługi błędów może się bez ostrzeżenia zamknąć, co zwykle wywołuje u użytkowników
frustrację, gdyż nie wiedzą, dlaczego to się stało i czy bezpiecznie jest kontynuować pracę.
Gdy występuje błąd, użytkownicy powinni otrzymać informację o tym, jak sobie z tym poradzić. Niezrozumiałe informacje są
prawie tak złe jak brak informacji (rysunek 13.1). Ilu użytkowników rozumie lub uważa za przydatne takie sformułowania jak
Niedozwolona operacja, Przepełnienie czy Błąd Ogólnego Zabezpieczenia?
Rysunek 13.1.
Przykład
nieczytelnego
komunikatu
o błędzie
Bez kompleksowej obsługi błędów programiści mogą stracić także cenne sprzężenie zwrotne na temat tego, jak funkcje
ich aplikacji są w rzeczywistości wykorzystywane. Poza tym, odnajdywanie i naprawianie błędów u klientów to bardzo
czasochłonne zadanie. Nie ulega wątpliwości, że w interesie programisty jest szybkie naprawianie błędów programu.
Bez narzędzi do obsługi błędów programiści muszą opierać się na opowieściach użytkowników o tym, co robili, gdy
wystąpił błąd programu. Najczęstszą odpowiedzią użytkownika w takiej sytuacji jest „Nie wiem”. Prowadzi to do
niepotrzebnej i czasochłonnej pracy, polegającej na odnalezieniu i poprawieniu błędów. W tym rozdziale pokażemy, jak
stworzyć zaawansowane narzędzie do obsługi błędów, które pomoże zarówno użytkownikom, jak i Tobie.
Istnieją trzy typy błędów programu: błędy składni, błędy logiczne oraz błędy wykryte w trakcie użytkowania.
Oczywiście w tym przypadku brakuje ważnej części kodu. Mianowicie nie określono typu danych. Prawidłowa instrukcja
wyglądałaby w następujący sposób:
Część IV ♦ Tajniki VBA 222
Jednym ze sposobów na wyeliminowanie błędów składni jest umieszczenie Option Explicit w pierwszej linii każdego
modułu. Zmusi Cię to do deklarowania każdej ze zmiennych używanych w aplikacji.
Deklarowanie wszystkich zmiennych ważne jest z kilku powodów. Błąd w nazwie zmiennej może mieć poważne
konsekwencje. Jeśli zmienna służy do wprowadzania wartości do bazy danych, może dojść do wprowadzenia
niewłaściwych danych bez żadnego ostrzeżenia. VBA traktuje po prostu nieprawidłowo nazwaną zmienną jako kolejną
zmienną.
VBA nie rozpozna BankBalence jako słowa kluczowego, więc przyjmie, że chcesz zadeklarować nową zmienną typu
Variant z domyślną wartością Empty. W rezultacie, zamiast umieścić w bazie żądaną wartość 4,576.98, umieści tam
wartość Empty.
Deklarowanie zmiennych ma również znaczenie dla optymalizacji pracy aplikacji. Niezadeklarowane zmienne typu
Variant zajmują dużo cennego miejsca. Przykładowo, różnice w zajmowanej przestrzeni dla zmiennej przechowującej
liczbę 5 są następujące:
u Dim bytNumber as Byte (1 bajt);
u Niezadeklarowana zmienna (tylko dane liczbowe) (16 bajtów);
u Niezadeklarowana zmienna (ciąg znaków) (22 bajty).
W tym przykładzie, niezadeklarowanej zmiennej przyznany jest typ danych Variant. Aby wymusić deklarowanie
zmiennych, przejdź do edytora Visual Basic i z menu Tools wybierz Options. Otwarte zostanie okno dialogowe Options.
Na karcie Editor włącz Require Variable Declaration (rysunek 13.2). Spowoduje to wstawianie Option Explicit u góry
każdego modułu. Nie spowoduje jednak aktualizacji już istniejących, pamiętaj więc o umieszczeniu Option Explicit w
każdym już utworzonym module.
Rysunek 13.2.
Aby wymusić
deklarowanie
zmiennych, wybierz
Require Variable
Declaration
lub
EndSeb
Błędy w pisowni tego typu słów zarezerwowanych powodują błędy składni. Podczas pisania kodu, jesteś zwykle o nich
informowany poprzez wyróżnienie błędnie napisanego tekstu oraz ukazanie się komunikatu ostrzegawczego.
W oknie dialogowym Options możesz zmieniać niektóre z ustawień kompilatora. Na karcie General znajduje się opcja
Compile on Demand, która umożliwia szybsze funkcjonowanie aplikacji, ponieważ moduły kompilowane są dopiero po ich
223 Rozdział 13. ♦ Profesjonalna obsługa błędów
załadowaniu do wykonania. Przy szybkości współczesnych komputerów zalecamy włączenie tej opcji w celu
wyeliminowania błędów.
Na tej samej karcie znajduje się opcja Background Compile. Po jej włączeniu uruchomione zostanie kompilowanie w tle, w
czasie, gdy komputer jest nieaktywny. Opcja ta może wpłynąć na poprawę szybkości wykonywania aplikacji. Aby ją
włączyć, opcja Compile on Demand musi być również włączona.
Aby mieć pewność, że wszystkie błędy składni zostały wykryte, ważne jest, by przed oddaniem aplikacji do rąk
użytkowników wszystkie moduły zostały skompilowane i zapisane. Z menu Debug wybierz Compile and Save All Modules,
aby skompilować i zapisać każdy moduł w bazie danych, niezależnie od tego czy są załadowane, czy nie.
Do usuwania błędów logicznych używaj rozbudowanego programu uruchomieniowego Microsoft Accessa. Temat ten
został omówiony w rozdziale 12., „Usuwanie błędów w aplikacjach Accessa”.
Usuwanie błędów
wykrytych w trakcie użytkowania
Nie istnieje sposób na wyeliminowanie wszystkich błędów wykrywanych w trakcie użytkowania aplikacji, lecz można się
na nie przygotować. Dlatego też narzędzie do obsługi błędów jest koniecznością.
W profesjonalnej aplikacji narzędzie do obsługi błędów umieszczone jest w każdej procedurze. Nic nie jest zostawione
przypadkowi.
To proste narzędzie stosuje się do standardowych konwencji programowych, które omówione są w następnej części.
ExitHere
Ta etykieta jest punktem wyjścia dla procedury. Dobrym zwyczajem jest umieszczanie tylko jednego punktu wyjścia dla
procedury. Jeśli procedura wykonywana jest bez błędów, wykonywany jest kod ExitHere i procedura jest zakończona. Kod w
Część IV ♦ Tajniki VBA 224
części ErrorHandler nie będzie wykonywany, gdyż znajduje się na samym końcu procedury. Wykonywanie kodu nigdy do
tego miejsca procedury nie dojdzie, bo wcześniej nastąpi wyjście.
Etykieta to świetne miejsce na umieszczenie kodu porządkującego. Przykładowo, można w tym miejscu zwolnić zmienne
obiektu, ustawiając je na Nothing, zamknąć bazę danych, przywrócić domyślne ustawienie klepsydry lub włączyć
aktualizację ekranu.
Instrukcja On Error Resume Next powinna być najczęściej pierwszą instrukcją procedury wyjścia. Jest to konieczne,
gdyż niektóre z instrukcji porządkujących mogą same powodować błędy. Przykładowo, jeśli przed otwarciem bazy
wystąpił błąd, a zmienna obiektu ustawiona jest na Nothing w procedurze wyjścia (Set db = Nothing), spowoduje to
powstanie błędu.
ErrorHandler
W tym miejscu znajduje się narzędzie zajmujące się obsługą błędów występujących w trakcie użytkowania programu.
Według konwencji znajduje się on u dołu procedury. Kod tego narzędzia będzie wykonywany tylko w przypadku
wystąpienia błędu. Efektem jego działania powinno być jednak coś więcej niż okno komunikatu z poprzedniego przykładu.
Radzimy dołączanie instrukcji Select Case, która umożliwi reagowanie w określony sposób na wszystkie błędy, jakie
programista może przewidzieć (więcej szczegółów w innej części tego rozdziału – „Reagowanie na błędy”). Narzędzie do
obsługi błędów powinno zawsze kończyć się instrukcją Resume.
Resume ExitHere
Tu następuje przekazanie wykonywania programu do kodu ExitHere.
Prawidłowy kod
ExitHere:
Exit Sub
ErrorHandler:
MsgBox "Wystąpił błąd"
Resume ExitHere
End Sub
225 Rozdział 13. ♦ Profesjonalna obsługa błędów
Jeśli któraś z instrukcji zawiera błąd, przebieg programu ulegnie zmianie, gdyż wykonany zostanie kod narzędzia do
obsługi błędów:
Sub Demo()
On Error GoTo ErrorHandler
Nieprawidłowy kod
ExitHere:
Exit Sub
ErrorHandler:
MsgBox "Wystąpił błąd"
Resume ExitHere
End Sub
Obiekt Err
VBA zawiera obiekt Err, który dostarcza wiele informacji, które możesz wykorzystać w narzędziu do obsługi błędów.
Obiekt Err jest obiektem globalnym, więc nie zachodzi konieczność tworzenia jego egzemplarza.
u Err.HelpFile – ścieżka dostępu do pliku pomocy Windows. Właściwość ta, użyta razem z HelpContext,
umożliwia umieszczenie w oknie komunikatu przycisku Pomoc.
u Err.HelpContext – identyfikator kontekstu dla tematu w pliku pomocy.
u Err.Last DLL Error – systemowy kod błędu uzyskany przez odwołanie do biblioteki DLL.
Err.Clear
Metoda Clear czyści właściwości obiektu Err. Każde z poniższych rozwiązań powoduje wyczyszczenie właściwości
obiektu Err:
u Odwołanie do metody Clear obiektu Err (Err.Clear).
Err.Raise
Metoda Raise generuje błąd związany z użytkowaniem aplikacji. Przydaje się to przy testowaniu aplikacji. Możesz
wykonać symulację błędu związanego z użytkowaniem aplikacji, przekazując kod do metody Raise obiektu Err. Ponadto,
gdy aplikacja odwołuje się do zewnętrznej biblioteki DLL, możesz przekazać wartość błędu z powrotem do aplikacji, która
zajmie się obsługą tego błędu.
Wywołując błędy, możesz generować błędy przez Ciebie definiowane. Pamiętaj jednak, by numer błędu był unikatowy i
dodaj go do stałej vbObjectError. Przykładowo, aby utworzyć numer błędu 50, przydziel do argumentu numeru
vbObjectError + 50:
Err.Number = vbObjectNumber + 50
Metoda Raise posiada pięć argumentów: Number, Source, Description, HelpFile i HelpContext (argumenty te są
takie same jak dla obiektu Err). Składnia wygląda następująco:
Err.Raise (Number, Source, Description, HelpFile, HelpContext)
Używając nazwanych parametrów, możesz przekazać tylko wybrane argumenty, dzięki czemu kod będzie lepiej opisany:
Err.Raise Number:= vbObjectError + 50, Description:= "Błąd Własny"
Reagowanie na błędy
Duża część kodu narzędzia do obsługi błędów powinna używać instrukcji Select Case. Spróbuj przewidzieć każdy
możliwy błąd, który może wystąpić, i umieść jego numer na liście w instrukcji Select Case. Wówczas będziesz mógł
radzić sobie z tym błędem we właściwy sposób.
Możesz nawet tworzyć ogólne procedury, które będą obsługiwały błędy określonego typu. Przykładowo, jeśli przyjrzysz się
w bazie danych Access and Jet errors.mdb tabeli błędów Accessa i Jet, zauważysz, że błędy o numerach między 58 a 76
dotyczą błędów plików (np. File already exists, Disk full, Too many files i inne). Mógłbyś stworzyć ogólną procedurę dla
tej grupy błędów i odwoływać się do niej z instrukcji Select Case w narzędziu do obsługi błędów:
ErrorHandler:
Select Case Err.Number
Case 58 to 76
'Ogólna procedura dla obsługi błędów plików
Call FileTypeErrors
Case Else
MsgBox "Wystąpił nieoczekiwany błąd. Numer błędu: " & _
Err.Number & "Opis błędu: " & Err.Description
Resume ExitHere
End Select
End Sub
227 Rozdział 13. ♦ Profesjonalna obsługa błędów
Instrukcje Resume
Poniższe instrukcje Resume umożliwią Ci przekazanie, w przypadku wystąpienia błędu, wykonywania programu do
różnych instrukcji.
Resume
Resume powoduje przekazanie wykonywania kodu do linii, w której wystąpił błąd. Gdy użytkownik zostanie
poinformowany o sposobie rozwiązania błędu, użycie instrukcji Resume spowoduje powrót do instrukcji, w której nastąpił
błąd. Ma to zastosowanie w sytuacji, w której przyczyna powstania błędu została usunięta i chcesz powrócić do tego miej-
sca w kodzie, w którym wystąpił błąd.
Resume Next
Resume Next powoduje przekazanie wykonywania kodu do linii następującej po linii, w której wystąpił błąd. Umożliwia
to wykonanie pozostałej części kodu.
Poniższy diagram ilustruje przebieg programu dla różnych instrukcji Resume (rysunek 13.3).
Rysunek 13.3.
Obsługa błędu przy
użyciu instrukcji
Resume
Obiekt Err dostarcza wielu informacji, lecz nie wszystkich. Dobrze zaprojektowane narzędzie do obsługi błędów powinno
dostarczać następujących, dodatkowych informacji o błędzie:
u Numer linii – identyfikuje numer linii, w której wystąpił błąd. Zastanów się, czy nie warto umieścić w każdym
module określonej liczby linii. Numery linii mogłyby być wstawiane po lewej stronie modułu, przed instrukcjami
kodu. Dzięki opcji Find Accessa mógłbyś szybko przechodzić do linii, w której wystąpił błąd (przy założeniu, że
numery linii się nie powtarzają). Numery linii w procedurze nie muszą być umieszczone po kolei.
u Nazwa formularza lub raportu – przedstawia nazwę formularza lub raportu, w którym wystąpił błąd. Jest to
kwestia przekazania nazwy formularza lub raportu do narzędzia zajmującego się obsługą błędów.
u Nazwa procedury – przedstawia nazwę procedury, w której wystąpił błąd.
u Nazwa aktywnego formantu – przedstawia nazwę formantu, który był aktywny w momencie wystąpienia błędu.
u Wartość aktywnego formantu – przedstawia wartość aktywnego formantu w momencie wystąpienia błędu. Zdarza
się, że błąd występuje tylko w przypadku wprowadzenia określonych wartości. Przykładowo, jeśli błąd występuje,
gdy w polu tekstowym wprowadzana jest wartość większa niż 20,000, to błąd taki można z łatwością
zidentyfikować, przekazując wartość z pola tekstowego do narzędzia zajmującego się obsługą błędów.
u Identyfikator bieżącego rekordu – przedstawia identyfikator (ID) rekordu, który był wyświetlany w formularzu w
momencie wystąpienia błędu. Czy zdarzyło ci się zauważyć, że jeden, konkretny rekord klienta powoduje więcej
błędów niż inne? Zapisując identyfikator bieżącego rekordu w narzędziu do obsługi błędów, będziesz mógł
porównać ten rekord z innymi, które nie powodują powstawania błędów. Najczęstszym błędem jest brak
wymaganych danych w którymś z pól.
u Nazwa programu – przedstawia nazwę aplikacji, w której wystąpił błąd.
u Poziom błędu – Możesz według własnego uznania przyznać błędom wartości (np. od 1 do 5). Dzięki tej informacji
będzie można mierzyć konieczność korzystania z pomocy osoby zajmującej się serwisowaniem aplikacji.
u Nazwa użytkownika – nazwa aktualnie zalogowanego użytkownika. Zauważyłeś kiedyś, że większość błędów
zdarza się określonym użytkownikom? Określenie, którzy użytkownicy mają najwięcej problemów, może być bardzo
cenne. Wielokrotnie przekonasz się, że problemem nie są błędy w programie, lecz braki w wyszkoleniu
pracowników. Aby otrzymać nazwę użytkownika, możesz użyć ekranu logowania, a w przypadku systemów
Windows 95/98/NT nazwa zalogowanego użytkownika może być uzyskana przez odwołanie do interfejsu API
systemu Windows.
u Data i czas – Data i czas wystąpienia błędu. Informacja ta pomaga w analizowaniu częstotliwości występowania
błędów. Prosty wykres powinien wystarczyć do wykazania, że z czasem błędy występują z mniejszą
częstotliwością.
u Notatki o błędzie – Użytkownicy mogą wprowadzać informacje o tym, co robili w momencie wystąpienia błędu.
Informacje te mogą być wprowadzane w polu tekstowym lub formularzu. Poinformuj użytkowników, że podanie
tych informacji nie jest obowiązkowe. Część z nich nigdy nie sporządzi żadnej notatki o błędzie, lecz inni docenią
możliwość udzielenia Ci informacji.
Dzięki informacjom zdobytym dzięki obiektowi Err oraz innym, opisanym tu sposobom, programiści powinni mieć
wystarczające podstawy do szybkiego i skutecznego naprawienia błędów wykrytych w trakcie użytkowania.
Na początku musisz zdecydować, jak to narzędzie zaprojektować i gdzie umieścić kod. Można umieścić cały kod narzędzia
w każdej procedurze, jednakże w ten sposób stworzyłbyś całą masę zbędnego kodu. Nie bez znaczenia byłby fakt, że
modyfikując później narzędzie, musiałbyś dokonywać zmian w każdej procedurze.
Lepszym podejściem jest użycie ogólnego narzędzia do obsługi błędów dla całej aplikacji. Ogólne narzędzie do obsługi
błędów jest obiektem tworzonym przy użyciu modułu klasy.
Jeśli nie miałeś okazji pracować jeszcze z modułami klasy, zajrzyj do roz-
działu 11., Tworzenie obiektów przy użyciu modułów klasowych”.
Tabela 13.1.
Właściwości obiektu cError
Właściwość Opis
Application Nazwa programu, w którym została stworzona dana aplikacja
(np. MS Access)
AVIFileLocation Nazwa i pełna ścieżka dostępu do pliku AVI, który został odtworzony
przy powiadomieniu o błędzie
Class Nazwa modułu klasy
ComputerName Nazwa komputera, na którym wystąpił błąd
ComputerTotalMemory Całkowita pamięć tego komputera
ComputerAvailableMemory Dostępna pamięć tego komputera
ComputerOperatingSystem System operacyjny i informacje o wersji
ComputerProcessor Informacje o procesorze
ControlName Nazwa aktywnego formantu
ControlValue Wartość aktywnego formantu
CurrentRecordID Identyfikator bieżącego rekordu
Description Opis błędu zwrócony przez obiekt cError
EmailAdress Adres e-mail użyty do powiadomienia o błędzie
ErrorDatabase Nazwa i pełna ścieżka dostępu do bazy danych (np. Accessa lub SQL
Server) zawierającej tabelę z błędami
ErrorNumber Numer błędu zwrócony przez obiekt cError
ErrorTextFile Nazwa i pełna ścieżka dostępu do pliku tekstowego, zawierającego
informacje o błędzie
HelpContext Identyfikator pliku pomocy zwrócony przez obiekt cError
HelpFile Nazwa i pełna ścieżka dostępu do pliku pomocy zwrócona przez
obiekt cError
LastDllError Systemowy kod błędu dla ostatniego odwołania do bibliotek DLL
Level Ustalona wartość oznaczająca wagę błędu
LineNumber Numer linii procedury, w której wystąpił błąd
Tabela 13.1.
Właściwości obiektu cError (ciąg dalszy)
Część IV ♦ Tajniki VBA 230
Właściwość Opis
Note Notatka sporządzona przez użytkownika, opisująca co robił w momencie
wystąpienia błędu
Now Data i czas wystąpienia błędu
Procedure Nazwa procedury, w której wystąpił błąd
SoundFile Nazwa i pełna ścieżka dostępu do pliku dźwiękowego
Source Nazwa obiektu lub aplikacji, która wywołała błąd
User Nazwa użytkownika, który natrafił na błąd
WaitStateFlag Znacznik stanu oczekiwania, używany do wstrzymania
wykonywania kodu
UserEnterNoteFlag Znacznik stwierdzający, czy użytkownik ma być proszony o sporządzenie
notatki o błędzie
W momencie powstania błędu, ustawiana jest większość, jeśli nie wszystkie z tych właściwości. Wówczas można pobrać te
informacje z obiektu cError i umieścić je w oknie komunikatu, e-mailu, kalendarzu, tabeli w bazie danych lub pliku
tekstowym.
Tabela 13.2.
Metody obiektu cError
Metoda Opis
AddToErrorHandlerOutlook Dodaj informacje o błędzie do kalendarza programu Outlook, o nazwie
Calendar ErrorHandler
Clear Czyści obiekt cError
Email W przypadku wystąpienia błędu, korzystając z programu Outlook,
wysyła programiście e-mail
EmailAllErrors Wysyła programiście e-mail, w którego załączniku znajdują się
wszystkie informacje z tabeli z błędami
GetActiveControlValue Pobiera wartość formantu aktywnego w momencie wystąpienia błędu
MessageBox Wyświetla użytkownikom okno komunikatu z informacjami o błędzie
MsgErrorDetails Grupuje informacje o błędzie, w celu umieszczenia ich w oknie
komunikatu lub e-mailu
Tabela 13.2.
Metody obiektu cError (ciąg dalszy)
Metoda Opis
OfficeAssistant W momencie wystąpienia błędu uruchamia Asystenta Pakietu Office
i pyta użytkowników, czy chcą sporządzić notatkę o błędzie
PlaySound W celu zwrócenia uwagi użytkowników w momencie wystąpienia błędu
odtwarza plik dźwiękowy
ProcessError Nadzoruje przetwarzanie informacji o błędzie na podstawie wcześniej
ustalonych zasad
ShowAVIForm Wyświetla formularz zawierający plik AVI, który informuje
użytkowników o wystąpieniu błędu
UserInputBox Wyświetla okno, w którym użytkownicy mogą wprowadzić swoje
uwagi o błędzie
UserName W systemach Windows, Windows NT pobiera nazwę zalogowanego
użytkownika
231 Rozdział 13. ♦ Profesjonalna obsługa błędów
Rysunek 13.4.
Obiekt cError
widziany w Object
Browser
Przetwarzanie błędu
W momencie wystąpienia błędu, narzędzie do obsługi błędów przekazuje informacje do obiektu cError. Metoda
ProcessError określa sposób przetwarzania błędu. Odwołuje się do tabeli tblErrorOptions (tabela ta opisana jest w
dalszej części rozdziału) w celu uzyskania informacji o tym, czy użytkownik ma sporządzać notatkę o błędzie lub czy
zostanie wysłany e-mail powiadamiający. Kod w metodzie ProcessError jest następujący:
Public Sub ProcessError()
Dim rst As ADODB.Recordset
Dim strSQL As String
Dim strVal As String
Me.ErrorTextFile = rst!ErrorTextFileName
Me.UserEnterNoteFlag = rst!UserEnterNoteAboutError
Me.AVIFileLocation = CurrentProject.Path & rst!AVIFileLocation
Me.OfficeID = rst!OfficeID
Me.OfficeName = rst!OfficeName
Me.OfficePhoneNumber = rst!OfficePhoneNumber
Me.OfficeFaxNumber = rst!OfficeFaxNumber
If rst!PlaySound Then
' W razie wystąpienia błędu odtwórz dźwięk
CError.PlaySound
End If
If rst!ShowOfficeAssistant Then
' Uruchom Asystenta Pakietu Office
CError.OfficeAssistant
End If
If rst!ShowAVIForm Then
' Otwórz formularz z plikiem AVI
Część IV ♦ Tajniki VBA 232
CError.ShowAVIForm
If rst!ErrorsToAccessTable Then
' Zapisz błąd w tabeli błędów Accessa
CError.WriteErrorToTable
End If
If rst!ErrorsToTextFile Then
' Zapisz błąd w pliku tekstowym
CError.WriteErrorToTextFile
End If
If rst!ErrorsToTextFile Then
' Zapisz błąd w pliku tekstowym
CError.WriteErrorToTextFile
End If
If rst!AddToErrorHandlerCalendar Then
CError.AddToErrorHandlerOutlookCalendar
End If
If rst!ShowMsgBoxErrors Then
' Wyświetl okno komunikatu z informacją o błędzie
CError.MessageBox
End If
rst.Close
Set rst = Nothing
End Sub
Jak widzisz, metoda ta może opierać się zarówno na właściwościach, jak i innych metodach obiektu cErrror.
Więcej informacji znajdziesz w kodzie modułu klasy cError.
Rysunek 13.5.
Asystent pakietu
Office informuje
użytkownika
o wystąpieniu błędu
Rysunek 13.6.
Formularz z plikiem
AVI informuje
o wystąpieniu
błędu
Wówczas możesz użyć obiektu cError do wyświetlenia formularza lub pola, które umożliwią użytkownikom opisanie
czynności, wykonywane w momencie wystąpienia błędu (rysunek 13.7). Niektórzy użytkownicy docenią taką możliwość, inni
po prostu ominą ten krok. Formularz z notatką zawiera informację, że sporządzanie jej nie jest obowiązkowe.
Rysunek 13.7.
Formularz
umożliwiający
użytkownikom
sporządzenie
notatki o błędzie
Można również wyświetlić okno komunikatu zawierające szczegółowe informacje o błędzie (rysunek 13.8).
Ostatni krok to wyświetlenie informacji o tym, że błąd został zapisany i można bezpiecznie kontynuować pracę (rysunek
13.9). Służy do tego formularz, który zamknie się automatycznie po trzech sekundach.
Dzięki tym wszystkim działaniom użytkownicy są przez cały czas wspomagani – nie są po prostu brutalnie wyrzuceni z
aplikacji. Narzędzie do obsługi błędów umożliwi kontynuowanie wykonywania kodu i aplikacja będzie działać nadal.
Użytkownicy będą natychmiast poinformowani o błędzie i będą mieli możliwość przekazania własnych spostrzeżeń. A co
najważniejsze, użytkownicy mają pewność, że informacja o wystąpieniu błędu została przekazana do programisty i że
mogą kontynuować pracę. Dzięki takiej obsłudze błędów użytkownicy będą przekonani o profesjonalizmie Twojej
aplikacji.
Rysunek 13.8.
Okno komunikatu
ze szczegółowymi
informacjami
o błędzie
Rysunek 13.9.
Poinformuj
użytkownika, że
może bezpiecznie
kontynuować pracę
Część IV ♦ Tajniki VBA 234
Zauważ, że narzędzie do obsługi błędów radzi sobie z tym na kilka sposobów. Obiekt cError posiada właściwości (tabela
13.1), które umożliwiają przechwycenie nazwy komputera, całkowitej i dostępnej wielkości pamięci, systemu operacyjnego i
typu procesora.
Wszystkie te informacje mogą być przydatne we wskazaniu, dlaczego dany komputer sprawia problemy. Podczas gdy inne
działają poprawnie. Najczęstszym problemem jest pamięć, dlatego też w razie wystąpienia błędu zwracaj uwagę na
informacje o całkowitej i dostępnej ilości pamięci.
Rysunek 13.11.
E-mail zawierający
informację
o pojedynczym
błędzie
u Wysyłanie e-maila o wszystkich błędach – przy użyciu metody EmailAllErrors informacje o wszystkich błędach z
tabeli z błędami mogą być przesyłane do Ciebie pocztą elektroniczną jako załącznik wiadomości programu
Outlook. Tabela ta zapisywana jest jako arkusz programu Excel i załączana do wiadomości.
u Zapisywanie informacji o błędzie w bazie danych Accessa – dzięki użyciu metody WriteErrorToTable każdy błąd
dodawany jest do tabeli w bazie danych.
235 Rozdział 13. ♦ Profesjonalna obsługa błędów
u Zapisywanie informacji o błędzie w pliku tekstowym – dzięki użyciu metody WriteErrorToTextFile wszystkie
błędy będą zapisywane w wybranym pliku tekstowym.
u Zapisywanie informacji o błędzie w kalendarzu programu Outlook – informacje o błędach mogą być zapisywane w
kalendarzu programu Outlook i przeglądane
Rysunek 13.12.
Kalendarz programu
Outlook, zawierający
informacje o błędach
Używając jednej lub kilku metod raportowania, otrzymujesz natychmiastowe powiadomienia o występowaniu błędów.
Posiadasz również wszystkie informacje niezbędne do odnalezienia i naprawienia błędu oraz narzędzia umożliwiające
analizę historyczną.
Tabela 13.3.
Możliwości dostępne w module obsługi błędów
Tabela 13.3.
Możliwości dostępne w module obsługi błędów (ciąg dalszy)
W zależności od wybranych opcji narzędzie do obsługi błędów będzie funkcjonować inaczej. Do przechowywania
informacji o opcjach obiektu cError służy tabela, więc kod aplikacji może być od niej zależny. Zamiast umieszczać
wartości nowych opcji w kodzie, możesz je po prostu wprowadzić do tabeli z opcjami. Jest to dużo prostsze rozwiązanie,
gdyż kod sam odnajdzie w tej tabeli potrzebne informacje.
Oczywiście nie należy kazać użytkownikom wprowadzać danych prosto do tabeli. Łatwe aktualizowanie i zmienianie opcji
związanych z błędami umożliwia formularz frmErrorOptions (rysunek 13.13).
Rysunek 13.13.
Formularz,
z poziomu którego
można modyfikować
opcje związane
z obsługą błędów
W tym momencie, masz już nie tylko zaawansowane narzędzie do obsługi błędów, ale co równie ważne, narzędzie, które
jest przyjazne i łatwe w obsłudze.
Narzędzie do obsługi błędów otrzymuje nazwę użytkownika, który napotkał błąd. Zamiast prosić użytkownika o podanie
swojej nazwy, narzędzie pobiera ją z interfejsu API. Odwołanie do interfejsu API systemu w systemach Windows
95/98/NT wygląda następująco:
' Odwołanie do interfejsu API systemu Windows w celu pobrania nazwy użytkownika.
Private Declare Function GetUserNAme Lib "advapi32.dll" _
Alias "GetUserNameA" (ByVal lpBuffer As String, nSize As Long)
W momencie wystąpienia błędu może być odtwarzany wybrany dźwięk, który zaalarmuje użytkowników. Do tego
potrzebne jest również odwołanie do interfejsu API:
' Odwołanie do interfejsu API systemu Windows w celu
' odtworzenia dźwięku.
Private Declare Function sndPlaySound32 Lib "winmm.dll" Alias _
"sndPlaySoundA" (ByVal lpszSoundName As String, _
ByVal uFlags As Long) As Long
Inne odwołania do interfejsu API mogą służyć do pobierania nazwy komputera, informacji o stanie pamięci, systemie
operacyjnym i procesorze.
237 Rozdział 13. ♦ Profesjonalna obsługa błędów
Obsługa błędów
w procedurach zagnieżdżonych
Często w kodzie możesz mieć procedury, które odwołują się do innych procedur, które odwołują się do jeszcze innych
procedur itd. Jak radzić sobie z obsługą błędów w takich przypadkach?
Służy do tego tworzona automatycznie lista zawierająca wszystkie odwołania do procedur (rysunek 13.14). Możesz
przeglądać tę listę w dowolnym momencie, wybierając z menu Tools Edytora Visual Basic pozycję Call Stack.
Rysunek 13.14.
Okno Call Stack
W momencie wystąpienia błędu jego obsługą zajmuje się narzędzie zawarte w bieżącej procedurze. Jeśli jednak w tej
procedurze takie narzędzie nie istnieje, obsługa błędu spadnie na narzędzie z procedury, z której nastąpiło odwołanie.
Innymi słowy, VBA będzie przeszukiwać listę odwołań, aż znajdzie narzędzie do obsługi błędów.
Zaawansowane zagadnienia
związane z błędami
Teraz, gdy już wiesz jak radzić sobie z błędami składni, logicznymi oraz błędami związanymi z użytkowaniem aplikacji,
przyjrzyj się bardziej zaawansowanym kwestiom związanym z obsługą błędów.
On Error GoTo 0
Powyższa instrukcja wyłącza obsługę błędów w procedurze. Powoduje to również wyzerowanie obiektu Err (tak jak w
przypadku użycia metody Clear obiektu Err (Err.Clear)). Metoda Err.Clear została opisana w jednym z
wcześniejszych rozdziałów książki.
Nie używaj instrukcji On Error Resume Next, gdy nie posiadasz żadne-
go narzędzia do obsługi błędów. W takim przypadku, wykonywanie kodu
będzie kontynuowane, a wszystkie błędy będą ignorowane. Może to mieć
katastrofalne konsekwencje. Przykładowo, w momencie wystąpienia błędu,
który powoduje utratę danych w bazie, ta instrukcja nakaże kontynuację
wykonywania kodu!
Metoda AccessError
Metoda ta może być użyta do zwrócenia opisu błędu Accessa. Przykładowo, wpisując ?AccessError(11) w oknie Immediate
otrzymamy Division by zero (Dzielenie przez zero).
Rysunek 13.15.
Użycie metody
AccessError
w oknie Immediate
Rysunek 13.16.
Ustawienia opcji
wyłapujących błędy
u Break on All Errors – w momencie wystąpienia błędu kod zatrzymuje się w danej linii, niezależnie od istnienia
narzędzia do obsługi błędów. Opcja ta jest dobra w momencie usuwania błędów aplikacji, pamiętaj jednak, by ją
wyłączyć, przekazując aplikację użytkownikom.
u Break in Class Module – w momencie wystąpienia błędu kod zatrzymuje się w danej linii jedynie w przypadku
modułów klasy, przy braku narzędzia do obsługi błędów.
u Break on Unhandled Errors – w momencie wystąpienia błędu kod zatrzymuje się w danej linii w każdej
procedurze, nie zawierającej narzędzia do obsługi błędów.
Optymalizacja aplikacji jest tematem niekończącej się dyskusji między programistami. Każdemu zależy na osiągnięciu
optymalnego rozwiązania, lecz co w tym przypadku jest rozwiązaniem optymalnym? Jedni uważają za takie dużą szybkość
aplikacji, więc dla nich najlepszymi technikami są najszybsze z nich. Inni uważają, że optymalne rozwiązanie powinno
zapewniać jak największą stabilność aplikacji, nawet za cenę zmniejszonej przez przesadną ostrożność szybkości działania.
Jeszcze inni za cel optymalny uważają jak największą elastyczność i łatwość w obsłudze. Kto ma rację? Jak to często w ży-
ciu bywa, żaden z nich. Optymalizacja polega na znalezieniu równowagi pomiędzy tymi trzema celami.
Rozwiązanie optymalne zapewnia użytkownikowi odpowiednią szybkość. Zazwyczaj użytkownik nie zaakceptuje zbyt
wolnej aplikacji. Jeśli jednak okaże się, że wybór tego rozwiązania prowadzi do utraty danych, będzie niewątpliwie
wyborem złym. Jeśli aplikacja działa z zadowalającą szybkością i do tego jest stabilna, istnieje duże prawdopodobieństwo,
że jej użytkownicy będą zainteresowani jej kolejnymi wersjami. Jednakże niekonwencjonalne rozwiązania w projekcie i
nieortodoksyjne jego wykonanie mogą sprawić, że dobrze przyjęta aplikacja będzie trudna do ulepszenia i rozbudowania.
Pod pewnymi względami, aplikacje są jak samochody. Niewiele osób chciałoby znaleźć się za kierownicą bardzo
szybkiego samochodu, który źle się prowadzi lub ma słabe hamulce. Natomiast większość z nas życzyłaby sobie mieć
samochód, który zapali każdego dnia i zawiezie nas tam, gdzie chcemy. Nie zapominajmy też o tym, że rachunki za serwi-
sowanie tego samochodu nie powinny rujnować naszego budżetu. Mimo iż rozdział ten dotyczy optymalizacji, pamiętaj o
tym, że aplikacja powinna być również stabilna i łatwa w rozbudowie.
W rozdziale tym omówimy wiele technik służących optymalizacji aplikacji. Prawie wszystkie z nich mają jakieś
ograniczenia, a niektóre mogą wręcz spowodować efekty odwrotne do zamierzonych. Nawet najlepsze z nich mogą nie
nadawać się do rozwiązania jakiegoś konkretnego problemu. Kilka technik zastosowanych razem może wzajemnie
pomniejszać efekty swojego działania. Jednakże z rozwagą stosując to, czego nauczy Cię lektura tego rozdziału,
powinieneś umieć poprawić wydajność swoich aplikacji.
Jedynym sposobem na sprawdzenie, czy techniki te będą działać w danym przypadku, jest eksperymentowanie. Rezultaty
mogą być często zaskakujące. Jednocześnie metoda, która w jednym przypadku dała zdumiewające rezultaty, w innym
może nie dać żadnych. Optymalizacja jest bardzo złożonym procesem, gdyż środowisko, w którym pracujemy, jest bardzo
złożone i podlega ciągłym zmianom, a prawdziwy cel optymalizacji jest dość trudny do zdefiniowania. Pisząc o
optymalizacji, należałoby omówić setki zagadnień. W rozdziale tym zaczniemy od omówienia problemów związanych ze
sprzętem i systemem operacyjnym, a zakończymy na różnych technikach kodowania.
241 Rozdział 14. ♦ Optymalizacja aplikacji
Nie powinno nikogo dziwić, że aplikacja Accessa (lub jakakolwiek inna) będzie działać szybciej na szybszym komputerze.
Jeśli masz możliwość poprawy szybkości komputera, na którym będzie uruchamiana aplikacja, zrób to. Opublikowane przez
Microsoft minimalne wymagania potrzebne do uruchomienia Accessa lub pakietu Office są niczym innym jak właśnie
minimalnymi wymaganiami. Programiści szybko przekonają się, że uruchomienie aplikacji Access na takim komputerze
będzie miało marny efekt. Tak naprawdę, komputer taki powinien spełniać co najmniej poniższe wymagania:
u Procesor Pentium 133 MHz.
u 32 MB RAM (szczególnie w przypadku systemu Windows NT).
u Jeśli masz wybierać między szybszym procesorem a większą ilością pamięci, wybierz pamięć. Jest to najtańszy
sposób na poprawę wydajności komputera. Pamiętaj również, że minimalne wymagania dla komputera, na którym
tworzy się aplikacje ,są dużo wyższe. Programista powinien dysponować komputerem, który posiada między
innymi procesor minimum Pentium 200 MHz oraz 32
– 64 MB RAM.
u Niezależnie od ilości posiadanej pamięci RAM, zawsze istnieje możliwość jej wykorzystania. Access, jak każda
poważna baza danych, do poprawnego funkcjonowania potrzebuje dużo pamięci. Powinieneś podjąć kroki w celu
zapewnienia aplikacji możliwie jak największej ilości pamięci.
u Aby to osiągnąć, usuń wygaszacze ekranu, tapety (chyba że jest to standardowa bitmapa), rysunki z tła i wszystko,
co może być zbędne. Tylko niezbędne aplikacje mogą korzystać z procesora w trakcie działania bazy danych. Im
więcej pamięci dostarczysz Accessowi, tym szybciej będzie działał.
u Nie używaj RAM-dysków. W nowoczesnych, 32-bitowych systemach nie ma na nie miejsca.
u Regularnie opróżniaj kosz i usuwaj pliki tymczasowe (szczególnie te, związane z Internetem i pocztą
elektroniczną). Bazy danych potrzebują do funkcjonowania dużo przestrzeni dyskowej, a takie pliki mogą
zajmować duże jej ilości.
u Korzystaj z narzędzi do defragmentacji dysków. W zależności od systemu operacyjnego, defragmentacja może
być automatyczna lub nie. Pliki komputerowe nie są przechowywane w jednym kawałku. Gdy tworzysz,
edytujesz, zapisujesz i usuwasz pliki, komputer rozdziela je i umieszcza w różnych miejscach. Tak samo jest z
plikami baz danych. Jeśli twardy dysk jest sfragmentowany, nawet proste przeszukiwanie może trwać dłużej niż
normalnie, gdyż komputer musi przeszukać cały dysk, by odnaleźć żądane fragmenty.
u Unikaj kompresji dysków (również kompresji NTFS). Uruchamianie bazy danych na skompresowanym dysku
będzie miało znaczny, negatywny wpływ na wydajność aplikacji.
u Kup większy dysk twardy. W zależności od rozmiaru aplikacji, możesz potrzebować 5 do 10 razy więcej wolnego
miejsca niż wynosi rozmiar pliku MDB. Brak wolnego miejsca spowoduje spadek wydajności dużych kwerend,
spowolni transakcje, kompilację, obsługę, importowanie i działanie kwerend. W ostatnich latach ceny przestrzeni
dyskowej znacznie spadły.
u Wyłącz dziennik programu Outlook. Opcja ta zapisuje każde otwarcie i zamknięcie aplikacji. Może to
spowodować utratę cennej przestrzeni dyskowej i niepotrzebne obciążenie procesora.
u Odbieraj brakującą pamięć. Aplikacje bardzo łatwo zajmują pamięć, lecz gorzej jest z oddawaniem. Otwieranie
wielu aplikacji, w tym Accessa, spowoduje zmniejszenie rzeczywistej, dostępnej ilości pamięci. Zamknięcie
Accessa spowoduje odzyskanie tej pamięci.
u Instaluj system Windows i pakiet Office lokalnie. Nie uruchamiaj ich przez sieć. Wydaje się to dziwne, lecz wciąż
istnieją miejsca, gdzie praktykuje się takie rozwiązania.
u Na poprawę wydajności aplikacji mogą również wpłynąć zmiany w pliku wymiany (pamięci wirtualnej). Gdy
Accessowi zabraknie pamięci, zaczyna korzystać z wirtualnej pamięci na dysku twardym. Jeśli wirtualnej pamięci jest
za mało, Access w celu wykonywania swoich operacji musi ciągle zapisywać i odczytywać informacje z dysku.
Zwiększenie ilości pamięci wirtualnej może poprawić wydajność bazy danych. Pamiętaj jednak, ze zapisywanie i od-
czytywanie informacji z dysku jest znacznie wolniejsze niż korzystanie z pamięci RAM. Zwiększenie pliku wymiany
ma sens tylko wtedy, gdy dysk jest zdefragmentowany.
Część IV ♦ Tajniki VBA 242
Wiele z wyżej wymienionych kwestii może być poza Twoją kontrolą, lecz tworząc aplikację Accessa, powinieneś rozważyć je i
w razie konieczności zaproponować. Jako projektant bazy danych Accessa masz większą kontrolę nad tym, czy korzystać z
możliwości optymalizacji.
Instalowanie aplikacji
w celu uzyskania optymalnej wydajności
Sposób, w jaki skonfigurujesz pliki, z których aplikacja korzysta, może mieć wpływ na jej wydajność. Poniższe wskazówki
powinny pomóc w osiągnięciu prawidłowego funkcjonowania aplikacji i umożliwić Ci skorzystanie z reszty tego rozdziału.
u Oddziel dane od aplikacji. Tworzenie pliku MDB z tabelami, umieszczanie go w sieci i instalowanie na
komputerach użytkowników innego pliku MDB zawierającego kwerendy, formularze, raporty itp. powinno być
standardem. Ma to również wpływ na wydajność, dostępność dla wielu użytkowników i łatwość obsługi aplikacji.
Ze wszystkich zawartych w tym rozdziale sugestii tę powinieneś ignorować tylko z naprawdę ważnych przyczyn.
u Używaj aktualnej wersji pliku grupy roboczej (system.mdw). Mimo iż możliwe jest użycie wcześniejszych wersji
pliku grupy roboczej w aplikacji, użycie aktualnej wersji powinno dać największą wydajność.
u Zmniejszaj bazę danych regularnie. Powinieneś kompaktować bazę za każdym razem, gdy importujesz, usuwasz
lub aktualizujesz większe ilości danych. Kompaktowanie bazy danych powoduje usunięcie pustych miejsc między
stronami danych i ponowne przeliczenie statystyk bazy, używanych w optymalizacji kwerend (więcej na ten temat w
dalszej części rozdziału). Proces ten powoduje również zwolnienie części przestrzeni dyskowej dla innych
procesów. Access 2000 posiada opcję kompaktowania bazy danych przy jej zamykaniu. Z menu Narzędzia
wybierz Opcje i na zakładce Ogólne zaznacz pole Kompaktuj przy zamknięciu. Niektórzy programiści zauważyli,
że we wcześniejszych wersjach Accessa kompaktowanie odnosiło rezultaty tylko wtedy, gdy było wykonywane
dwukrotnie. Spróbuj kompaktować swoją bazę przy uruchamianiu, a dzięki zaznaczeniu opcji Kompaktuj przy
zamknięciu, będzie ona zawsze kompaktowana dwukrotnie.
u Gdy tylko jest to możliwe, instaluj wersję MDE swojej aplikacji. Rozwiązanie to posiada kilka zalet. MDE
wymaga skompilowanych modułów, a moduły takie działają szybciej niż nieskompilowane. MDE daje większą
wydajność przy mniejszym zapotrzebowaniu na RAM i przestrzeń dyskową.
optymalizować tak jak inne elementy baz danych. Optymalizację silnika Jet powinieneś zacząć dopiero po ukończeniu całej
lub prawie całej aplikacji i po rozważeniu różnych technik optymalizacyjnych wewnątrz aplikacji.
Jet 4.0, silnik baz danych Accessa 2000, posiada kilka zalet odróżniających go od wcześniejszych wersji. Takie opcje, jak:
nowe typy danych, kompresja tekstu, indeksowanie pól memo, implementacja ANSI SQL-92, zarządzanie zabezpieczeniami,
zwiększona elastyczność dzięki indeksom klucza obcego, znacznie poszerzony schemat replikacji i poprawione blokowanie,
wpływają na znaczną poprawę wydajności aplikacji. Opcje te
zostały w pełni opisane w innych rozdziałach tej książki. Powinieneś je przejrzeć, by dowiedzieć się więcej o tych ważnych
opcjach. Teraz zajmiemy się jedynie ich wpływem na wydajność aplikacji.
Jet zajmuje się większością kwestii związanych z optymalizacją, bez żadnej interwencji programisty czy użytkownika. Ze
wszystkich czynności, jakie Jet wykonuje, około 15 z nich możesz zobaczyć w rejestrze. Ich ustawienia nie są zbyt
oczywiste i powinieneś podejść do nich z ostrożnością. Zmiana tych ustawień może przynieść efekt odwrotny
do zamierzonego. Nawet, jeśli aplikacja będzie działać szybciej, może mieć negatywny wpływ na inne ważne rzeczy, jak
stabilność czy zarządzanie współbieżnością. Lista dostępnych ustawień rejestru silnika Jet znajduje się w tabeli 14.1.
Tabela 14.1
Ustawienia rejestru dla silnika Jet 4.0
Tabela 14.1
Ustawienia rejestru dla silnika Jet 4.0 (ciąg dalszy)
Tabela 14.1
Ustawienia rejestru dla silnika Jet 4.0 (ciąg dalszy)
Tabela 14.1
Ustawienia rejestru dla silnika Jet 4.0 (ciąg dalszy)
Proponujemy korzystanie z trzeciej opcji. Nie tylko dlatego, że jest prosta w użyciu, ale również dlatego, że umożliwia
modyfikowanie ustawień dla każdej aplikacji z osobna. Aby naprawdę zoptymalizować wydajność, możesz nawet zmieniać
ustawienia w różnych częściach aplikacji.
Technika ta nigdy nie powoduje zmiany ustawień domyślnych, tak więc tworzenie nowych projektów rozpoczyna się w
tym samym miejscu.
Aby tymczasowo pomijać wartości rejestru, nie musisz odwoływać się do interfejsu API. Silnik bazy danych posiada
odpowiednią metodę i dwa argumenty. Składnia jest następująca:
DBEngine.SetOption StałaNazwaUstawienia, Wartość
Przykładowo, wydajność niektórych aktualizacji może wzrosnąć dzięki temu, że Jet będzie czekał przed wykonaniem transakcji
ukrytych. Kod, który czasowo wydłuży czas oczekiwania SharedAsyncDelay do 1 sekundy (1000 milisekund), wygląda
następująco:
DBEngine.SetOption dbSharedAsyncDelay, 1000
Ustawienie to działa do momentu, aż aplikacja dokona jego zmiany za pomocą metody SetOption, DBEngine wyjdzie poza
zakres lub aplikacja zostanie zamknięta. SetOption nie zapisuje wartości do Rejestru. Za pomocą metody SetOption nie
możesz zmieniać wartości domyślnych dla SystemDB, CompactByPKey ani wątków.
Narzędzia
służące do pomiaru wydajności
Ważne jest, czy łączny wynik Twoich działań spowodował poprawę, a nie obniżenie wydajności aplikacji. Do
monitorowania i oceny wydajności jednej techniki względem innej służy klika narzędzi. Pierwszym z nich jest zegar, który
mierzy czas wykonywania określonych procesów. Drugim z nich jest nieudokumentowana funkcja, która liczy operacje
wykonywane z użyciem dysku, bufora i blokowania. Trzecie narzędzie to opcja Accessa, dzięki której możesz przeglądać
plan wykonywania kwerendy. Pierwsze dwa z tych rozwiązań możesz stosować na prawie każdej z przedstawionych w tym
rozdziale technik. Plany wykonywania kwerend mają zastosowanie tylko w przypadku optymalizowania pracy kwerend.
Mimo iż VBA posiada funkcję Timer(), może ona być niewystarczająca do oceny działań optymalizacyjnych. Funkcja ta
mierzy w sekundach upływ czasu od momentu 0:00. Jest ona jednak mało precyzyjna i może nie być odpowiednia do
Twoich celów szczególnie, gdy chcesz mierzyć operacje trwające mniej niż 1 sekundę. Wielu programistów używa funkcji
GetTickCount. Mimo iż wydaje się, że funkcja ta zwraca czas w milisekundach, ponieważ jest ona związana z zegarem
komputera, w rzeczywistości mierzy ona czas co 1/18 sekundy, co nie do końca odpowiada milisekundzie. Interfejs API
systemu Windows posiada zegar, który mierzy czas w milisekundach. Funkcja timeGetTime() mierzy upływ czasu od
momentu uruchomienia systemu Windows. Ponieważ używa innego zegara sprzętowego niż GetTickCount, zwraca czas
mierzony z dokładnością do milisekundy.
Używając timeGetTime(), możemy wstawić linię kodu przed i za żądanym miejscem i otrzymamy bardzo dokładny
pomiar długości trwania danej czynności.
Do odwołania się do interfejsu API potrzebujemy dwóch rzeczy: deklaracji funkcji i zmiennej globalnej, która posłuży do
przechowywania początkowego czasu zegara. W części deklaracyjnej modułu wprowadź następujące trzy linie:
Private Declare Function a2ku_apigettime Lib "winmm.dll" _
Alias "timeGetTime" () As Long
Dim lngstartingtime As Long
Teraz możesz utworzyć procedurę, która uruchomi zegar i funkcję, która go zatrzyma.
Sub a2kuStartClock()
lngstartingtime = a2ku_apigettime()
End Sub
Function a2kuEndClock()
a2kuEndClock = a2ku_apigettime() – lngstartingtime
End Function
Dim db As Database
Dim qry As QueryDef
Dim rs As Recordset
Set db = CurrentDb()
'Uruchom zegar
a2kuStartClock
Set rs = qry.OpenRecordset()
rs.Close
End Sub
Spojrzenie za kulisy
Mimo iż mierzenie czasu jest ważne, nie pozwala ocenić wydajności w trakcie tworzenia aplikacji. Najprawdopodobniej
tworzenie aplikacji ma miejsce na platformie dużo szybszej niż te, na których będzie używana, a testowanie odbywa się na
mniejszym niż w rzeczywistości zestawie danych. Co więcej, zegar nie daje odpowiedzi na pytanie, jak aplikacja będzie działać
na komputerze z mniejszą ilością pamięci lub mniejszym twardym dyskiem. Aby zajrzeć za kulisy Twojej aplikacji, możesz użyć
kolejnej nieudokumentowanej funkcji: ISAMStats. Funkcja moża dać Ci kilka cennych wskazówek na temat funkcjonowania
aplikacji. Mierzy ona sześć operacji mających wpływ na wydajność: odczyty z dysku, zapisy na dysku, odczyty z bufora, odczyty
z wyprzedzeniem z bufora, ustanowienia blokowania oraz zdjęcia blokowania. Funkcja ta działa zarówno w Accessie 2000, jak i
we wcześniejszych wersjach tego programu. Jej składnia jest bardzo prosta:
DBEngine.ISAMStats (Opcja, [reset])
Opcjonalny argument reset umożliwia wyzerowanie indywidualnych liczników. W celu użycia tej funkcji do pomiaru
wydajności musisz odjąć jeden odczyt od drugiego lub wyzerować licznik i wykonać operację. Wydruk 14.2 zawiera
przykład użycia funkcji ISAMStats celem pomiaru wydajności:
Dim i As Integer
Debug.Print
Debug.Print "Zapis na dysku: " & ISAMStats(0, False)
Debug.Print "Odczyt z dysku: " & ISAMStats(1, False)
Debug.Print "Odczyt z bufora: " & ISAMStats(2, False)
Debug.Print "Odczyt z wyprzedzeniem z bufora: " & _
ISAMStats(3, False)
Debug.Print "Ustanowienie blokowania: " & ISAMStats(4, False)
Debug.Print "Zdjęcie blokowania: " & ISAMStats(5, False)
For i = 0 To 6
ISAMStats i, True
Next
End Sub
PrintStats pokaże, dlaczego jedna technika może być lepsza od innej. Informacja ta może Ci również pomóc w
dokonaniu racjonalnego wyboru między dwiema technikami, których czas wykonywania w milisekundach jest taki sam.
Dzięki tym informacjom zobaczysz, jak duży wpływ na wydajność różnych technik mają różnice w konfiguracji czy
wielkości zestawu danych.
Funkcje A2KU_TimeClock i PrintStats przydają się tylko w przypadku porównywania różnych technik między sobą.
Co więcej, wyniki tych testów będą wiarygodne tylko wówczas, gdy będziesz je przeprowadzał wielokrotnie, w różnych
warunkach, i wyciągał średnie z ich wyników. Możesz bez trudu połączyć te dwie funkcje w jedną, by za jej pomocą
przeprowadzać odpowiednie testy i sporządzać z nich raporty.
W dalszej części tego rozdziału wykorzystamy te dwie funkcje, aby pokazać, jak można ich używać i jak wykazać różnicę
między dwiema technikami.
249 Rozdział 14. ♦ Optymalizacja aplikacji
Projektowanie tabel
w celu osiągnięcia poprawy wydajności
Oprócz generalnej zasady, jaką jest normalizacja, podczas tworzenia tabel powinieneś pamiętać o poniższych punktach:
u Gdy pracujesz z połączonymi tabelami, spraw, by łącza między nimi miały charakter stały.
u Negatywny wpływ na wydajność ma użycie w tabelach prostych podarkuszy danych, gdzie podarkusz jest drugą
tabelą, a łącza pola nadrzędnego i podrzędnego używają pól indeksowanych. Jednakże użycie bardziej złożonego
podarkusza danych mogłoby zrównoważyć ten negatywny efekt. Zamiast w tabelach, używaj podarkuszy w
kwerendach. W ten sposób możesz z nich korzystać tylko wtedy, gdy tego potrzebujesz, a nie za każdym razem,
gdy otwierasz tabelę.
u Maski wprowadzania, pola odniesienia i reguły poprawności powinny również być używane tam, gdzie są
potrzebne – w formularzach. Najlepiej jest, by tabele były tak proste jak tylko to możliwe.
u Nie twórz większych pól niż to konieczne. Access rezerwuje miejsce na dane według rozmiaru danego pola.
Możesz zmarnować dużo miejsca (i czasu), używając typów danych lub ustawień właściwości zbyt dużych dla
danych, które znajdują się w tych polach.
Normalizacja danych
w celu osiągnięcia poprawy wydajności
O normalizacji już w tej książce mówiliśmy, teraz tylko zwrócimy uwagę na kilka jej aspektów:
u Znormalizowana baza danych pozwala zaoszczędzić przestrzeń dyskową, gdyż nie powtarza bez potrzeby danych.
u Znormalizowana baza danych używa mniejszej ilości stron danych i stron indeksów, co skraca czas wyszukiwania
danych.
u W znormalizowanej bazie danych prawdopodobieństwo wystąpienia konfliktu lub pomyłki w danych jest
mniejsze, gdyż powtarzają się one rzadziej.
u Kiedy można zrezygnować z normalizacji? Można to zrobić, gdy chcesz oprzeć aplikację na nieznormalizowanych
tabelach, jeśli będą one tabelami tymczasowymi, których tworzenie jest czasochłonne. Jednakże dane powinny
być zawsze przechowywane w znormalizowanej strukturze. Pamiętaj, że będziesz musiał stworzyć procedury,
które będą aktualizować znormalizowaną strukturę o czynności wykonywane, na nieznormalizowanej strukturze –
to może wpłynąć na poprawę wydajności. Łamanie reguł normalizacji powinno być jednak ostatecznością.
u Innym przypadkiem, w którym zazwyczaj możesz bezkarnie rezygnować z normalizacji, jest reguła
powtarzalności danych, gdy dotyczy ona danych drugorzędnych. Często zdarza się, że w jednej tabeli
przechowywanych jest mnóstwo informacji o kliencie lub produkcie, które, jeśli by przestrzegać zasad, powinny
być umieszczone w osobnych tabelach (np. służbowe i domowe numery telefonów, numery faksu, numery
telefonów komórkowych, numery pagerów, adresy e-mail itd.).
u Łam zasady normalizacji tylko wtedy, gdy ma to sens. Może to czasami wpłynąć korzystnie na wydajność części
aplikacji. Pamiętaj jednak, że może się to odbić na stabilności i późniejszej obsłudze bazy danych oraz na
integralności danych.
Idealny schemat normalizacji zakładałby tworzenie tabeli o przedstawicielach z polem ID klienta, typem kontaktu, innym
polem do przechowywania numerów telefonów i jeszcze innym do adresów e-mail. Jest to jednak pewna przesada i osiągnięta
w ten sposób integralność i elastyczność nie zrównoważyłyby utraty wydajności. Całkiem rozsądne jest przechowywanie tych
danych w tabeli o klientach i korzystanie z wyższej wydajności. Jednakże co do zasady, powinieneś normalizować wszystko
co tylko możliwe. Tego właśnie oczekuje silnik Jet, który najlepiej pracuje na znormalizowanych danych.
Część IV ♦ Tajniki VBA 250
Tworzenie indeksów
w celu przyspieszenia pracy kwerend
u Indeksy mogą dziesięciokrotnie przyspieszyć pobieranie danych.
u Indeksy mogą również spowolnić aktualizowanie i wprowadzanie danych, więc unikaj tworzenia zbędnych
indeksów.
u Twórz takie klucze podstawowe, które są zrozumiałe dla danych i dla użytkowników. Z punktu widzenia
wydajności umożliwienie Accessowi tworzenie pól klucza podstawowego przez wstawianie pola Autonumerowanie
jest praktycznie bezużyteczne. Powinieneś używać czegoś, co posiada większe znaczenie, chyba że użytkownicy nie
znajdują innego sposobu na identyfikowanie rekordów. Niech będzie to numer telefonu, numer PESEL, numer
konta, kod sprzedawcy itp. Aby indeks naprawdę wpływał na poprawę wydajności kwerendy, musi być
wykorzystywany w kwerendzie.
u Indeksuj wszystkie te pola w tabeli, których będziesz używał jako kryterium. Indeksowanie kilku pól w tabeli
ułatwi optymalizowanie utworzonych później kwerend.
u Indeksuj pola po obu stronach przewidywanego sprzężenia. Ponieważ pola Numer Zamówienia jest w relacji
zarówno z tabelami Szczegóły Zamówień, jak i Zamówienia, obie te tabele powinny posiadać odpowiedni indeks.
Jeśli jednak masz zamiar tworzyć wiele raportów według pola Data Zamówienia, również to pole powinno być
indeksowane.
Wcześniejsze tworzenie
relacji jako sposób na poprawę wydajności
Do tworzenia relacji między tabelami używaj okna Relacje. Wykonując tę czynność w tym oknie, masz możliwość
określenia właściwości tworzonej relacji. Dzięki temu również poinformujesz Jet o jej istnieniu. Będzie on wówczas w
stanie wykorzystać te informacje do przygotowania bardziej efektywnego planu optymalizacji, który zostanie wy-
korzystany podczas tworzenia kwerend. Ma to wpływ na poprawę wydajności.
Krótko mówiąc, normalizuj dane, gdy jest to konieczne twórz indeksy, bądź oszczędny przy określaniu typów danych i
rozmiarów pól oraz pamiętaj o tworzeniu prostych tabel. Ich celem jest przechowywanie danych, a nie ich prezentowanie.
Aby zrozumieć, jak działa optymalizacja kwerend, musisz poznać sposób, w jaki obchodzi się z nimi Jet. Każda kwerenda
przechodzi cztery etapy:
66. Definicja – przy użyciu jednego z kilku narzędzi tworzona jest instrukcja SQL.
67. Kompilacja – ciąg SQL jest dzielony na części.
68. Optymalizacja – używając działającego w oparciu o koszt algorytmu, Jet tworzy i testuje różne sposoby
otrzymania żądanego zestawu wyników.
69. Wykonanie – używając optymalnego planu, Jet dostarcza użytkownikowi zestaw wyników.
Kwerendę możesz definiować poprzez siatkę QBE, ciąg SQL wykonywany w kodzie, ciąg SQL we właściwości Źródło
wierszy formularza, raportu lub formantu lub w każdy inny sposób, który powoduje powstanie ciągu SQL.
Jet umieszcza części ciągu w hierarchicznej, wewnętrznej strukturze. Części te przypominają słowa kluczowe instrukcji
SQL. Tabela podstawowa użyta przez kwerendę (From) stanowi podstawę. Następnie ustawiane są kolumny zestawu
wyników (Select). Później ustawiane są kryteria i ograniczenia (Where), które musi spełnić kwerenda. Kolejnym ele-
mentem są informacje o relacjach tabeli podstawowej (Join). Ostatnia część to informacja o sposobie sortowania zestawu
wyników (Order by). Struktura ta charakterystyczna jest dla fazy optymalizacji.
251 Rozdział 14. ♦ Optymalizacja aplikacji
Optymalizacja to najbardziej złożony etap. Jet wycenia i oblicza koszt każdego z możliwych rozwiązań. Dokonuje tego na
dwa sposoby: uzyskując dostęp do tabel bazowych i sprawdzając istniejące między nimi sprzężenia. Zrozumienie sposobu,
w jaki Jet postrzega kwerendy, może pomóc Ci w projektowaniu szybszych kwerend w przyszłości.
Oczywistym jest, że jeśli to tylko możliwe, powinieneś unikać skanowania i jak najlepiej wykorzystywać indeksy. Ale jak
sprawdzić, czy najlepsze z rozwiązań – optymalizacja Rushmore – będzie działać na danej kwerendzie? Nie ma sposobu na
włączenie lub wyłączenie technologii Rushmore, nie istnieją również żadne opisujące ją wskaźniki. Jest ona zawsze włączona,
lecz tylko niektóre z rodzajów kwerend mogą z niej korzystać. Aby kwerenda wykorzystywała optymalizację Rushmore
muszą być spełnione trzy warunki:
u Kwerenda musi posiadać kilka indeksów.
u Kryteria kwerendy muszą dotyczyć pól z indeksami.
u Instrukcje kryteriów muszą używać tych indeksów na jeden z trzech sposobów:
u Część wspólna – wyrażenie kryterium z operatorem „AND”. Jet mógłby w tym przypadku skorzystać z
optymalizacji Rushmore, gdyż oba te pola są indeksowane.
WHERE NazwaFirmy='Ernst Handle' And Miasto='Graz'
u Połączenie – wyrażenie kryterium z operatorem „OR”. Jet mógłby w tym przypadku skorzystać z optymalizacji
Rushmore, gdyż oba te pola są indeksowane.
WHERE NazwaFirmy='Ernst Handle' Or Miasto='Graz'
u Zliczanie – podlicza kwerendę, zwracając jedynie liczbę rekordów. Rushmore zoptymalizuje tę kwerendę
nawet przy braku ograniczeń w warunku Where.
SELECT Count(*) FROM Klienci;
Upewnij się, że we wszystkich tabelach, które mogą z tego skorzystać, umieściłeś indeksy. Spróbuj również tak
konstruować kwerendy, by można było uzyskiwać części wspólne i połączenia tych indeksów. Wykorzystanie tych dwóch
wskazówek powinno załatwić sprawę operacji tabel podstawowych w planie wykonywania kwerendy.
Gdy Jet wybrał już sposób dostępu do danych w pojedynczych tabelach, musi sprawdzić, jakie między tabelami występują
relacje. Tę fazę optymalizacji można by nazwać określaniem strategii sprzężenia. W przewidywaniu strategii sprzężenia
planu wykonywania pomoże Ci znajdująca się w tabeli 14.2 charakterystyka typów strategii.
Tabela 14.2.
Typy złączeń: jak działają i jak je rozpoznać
Tabela 14.2.
Typy złączeń: jak działają i jak je rozpoznać
Indeks Pierwsza tabela jest Indeks użyty jest w polu Jeśli w drugiej tabeli jest
skanowana, (polach) relacji drugiej tabeli. niewiele rekordów, jeśli jej
a następnie, przy W indeksach tych możliwe są rekordy nie są wyświetlane
użyciu indeksów, wartości null. Ograniczenia nie w zestawie wyników lub
odnajdywane są używają indeksów jeśli ograniczenie
wiersze w drugiej w kryterium pierwszej tabeli
tabeli jest bardzo wąskie
Połączenie Obie tabele Dwie tabele sortowane według Obie tabele są duże
skanowane są sprzężonych pól. Dane z obu i sortowane według pól
jednocześnie tabel wyświetlane są w relacji
w zestawie wyników
Odnośnik Druga tabela jest Brak indeksów w polach Gdy druga tabela jest mała
sortowana sprzężonych obu tabel i nie ma indeksu w polu
i skanowana przed relacji tej tabeli
sprzężeniem
Iteracja Iteracja wiersz po Brak indeksów po obu Tylko na bardzo małych
zagnieżdżona wierszu przez każdą stronach sprzężenia tabelach i gdy nie ma innego
tabelę w relacji rozwiązania
Najpierw Jet wycenia opcje dostępu do tabel podstawowych. Każdy plan dostępu do tabeli podstawowej otrzymuje ocenę.
Następnie Jet wycenia dostępne opcje sprzężenia i przyznaje im oceny. Jet będzie brał jedynie pod uwagę sprzężenie
wyników relacji z tabelą podstawową. Nie bierze zaś pod uwagę sprzężenia wyników jednego sprzężenia z drugim.
Umożliwia to ograniczenie czasu, jaki Jet poświęci na optymalizację kwerend. Po przeanalizowaniu każdej możliwej strategii
sprzężenia i każdej możliwej strategii dostępu do tabeli podstawowej oraz po uwzględnieniu żądanego typu zestawu wyni-
ków Jet wybierze plan.
W przypadku tabel nie korzystających z ODBC Jet oczyści, zmniejszy i przekaże plan do wykonania.
Taka kompilacja i optymalizacja ma miejsce, gdy po raz pierwszy tworzysz, modyfikujesz lub uruchamiasz kwerendę.
Kwerenda może pozostać nieskompilowana, jeśli zmodyfikujesz ją i zapiszesz, ale nie uruchomisz. Również w przypadku,
gdy modyfikujesz indeksy tabeli lub schemat danych, kwerendy mogą nie być optymalizowane. Pamiętaj, by zawsze przed
dostarczeniem aplikacji użytkownikom otwierać kwerendy w widoku Projekt, zapisywać je i uruchamiać. Dzięki temu
będziesz miał pewność, że kwerendy są skompilowane.
W celu zoptymalizowania kwerend, Jet wykonuje kompleksową ocenę kosztów. Pośród elementów tej oceny znajduje się
przegląd statystyk bazy danych. Statystyki te mówią, ile w bazie danych istnieje stron danych, stron indeksowanych, wierszy w
tabelach i innych elementów. Statystyki te mogą być zniekształcone, jeśli baza została w nieprzewidziany sposób zamknięta,
wstrzymano transakcje lub baza wymaga zmniejszenia. Pamiętaj, by przed optymalizacją wykonać kompaktowanie bazy
danych.
Jak już pisaliśmy wcześniej, Jet tworzy plan wykonywania dla każdej kwerendy. Tworząc w rejestrze wpis
\HKEY_LOCAL_MACHINES\SOFTWARE\MICROSOFT\JET\4.0\ENGINES\DEBUG
i ustawiając jego wartość ciągu na On, Jet utworzy w bieżącym folderze plik tekstowy, zawierający plan wykonywania
kwerendy. Wiele z omówionych już tematów pojawia się w planie optymalizacji kwerendy. Nie masz możliwości
modyfikowania planu, chyba że poprzez zmianę schematu danych, konstrukcję kwerendy lub ograniczenia w kwerendzie.
Im plan bardziej szczegółowy, tym lepiej. Wydruk 14.3 przedstawia plan wykonywania kwerendy Zamówienia Kwartalne
w bazie Northwind.
253 Rozdział 14. ♦ Optymalizacja aplikacji
-Inputs to Query-
Table "Customers"
Using index "Primary Key"
Having Indexes:
Primary Key 91 Entries, 1 page, 91 Values
Which has 1 column, fixed unique, primary – key, no – nulls
Postal Code 91 Entries, 1 page, 87 Values
Which has 1 column, fixed
Company Name 91 Entries, 3 pages, 91 Values
Which has 1 column, fixed
City 91 Entries, 1 page, 69 Values
Which has 1 column, fixed
Table "Orders"
-End inputs to query-
Możesz zauważyć sekcję tabeli podstawowej, z analizą indeksów i liczbą elementów, baz danych, indeksowanych stron
oraz przetwarzanych wartości. Zauważ również, że Rushmore może optymalizować tę kwerendę dzięki indeksowi w polu
Data Zmówienia tabeli Zamówienia. Plan rozpoznaje sprzężenie między tabelami Zamówienia i Klienci jako sprzężenie
zewnętrzne. Indeksy i technologia Rushmore sprawiają, że kwerenda ta jest bardzo dobrze zoptymalizowana. Jeśli nie
jesteś pewien, jak zoptymalizowana jest dana kwerenda, przejrzyj jej plan wykonywania. Funkcja SHOWPLAN jest
nieudokumentowana. W przypadku niektórych kwerend nie zwróci planu, niektóre z planów mogą być nieprawidłowe,
wciąż jednak możesz ją wykorzystać.
Wydruk 14.4. Plan słabo zoptymalizowanej kwerendy, która nie korzysta z zalet optymalizacji aparatu Jet
SELECT Customers.CustomerID, Customers.CompanyName
FROM Customers INNER JOIN Orders ON
Customers.CustomerID = Orders.CustomerID
WHERE ((Not (Orders.ShipCountry)="USA"));
..Customers with Shipping Adress Outside USA
-Inputs to Query-
Table "Orders"
Table "Customers"
Using index "Primary Key"
Having Indexes:
Primary Key 91 Entries, 1 page, 91 Values
Which has 1 column, fixed unique, primary – key, no – nulls
Postal Code 91 Entries, 1 page, 87 Values
Which has 1 column, fixed
Company Name 91 Entries, 3 pages, 91 Values
Which has 1 column, fixed
City 91 Entries, 1 page, 69 Values
Which has 1 column, fixed
-End inputs to query-
01) Restrict rows of table Orders
by scanning
testing expression "Not Orders.ShipCountry="USA"
02) Inner Join result of "01)" to table „Customers”
using index "Customers!PrimaryKey"
join expression "Orders.CustomerID=Customers.CustomerID"
Przyczyną słabości tej kwerendy jest sposób, w jaki obsługuje ograniczenie. Ponieważ ograniczenie to nie używa indeksu,
kwerenda musi przeszukać tabelę i testować każdy z rekordów, by sprawdzić, czy spełnia on założone kryterium. Skanowanie
tabel jest kosztowne. Wprowadzenie indeksu wpłynęłoby na znaczną poprawę wydajności tej kwerendy.
u Kompaktuj bazę regularnie i sprawdzaj, czy statystyki używane przez aparat Jet do optymalizowania kwerend są
poprawne.
u Jeśli to możliwe, w celach testowych wypełniaj swoje aplikacje co najmniej taką ilością danych, jaką będą
wypełnione po zainstalowaniu na komputerach użytkowników. W ten sposób Jet zoptymalizuje kwerendy,
używając statystyk odzwierciedlających rzeczywiste warunki, w jakich kwerendy te będą uruchamiane.
u Indeksuj pola, które będą sortowane.
u Jeśli operujesz na statycznych danych, rozważ utworzenie tabeli na podstawie kwerendy, zamiast ciągle
uruchamiać kwerendę w bazie danych.
u Unikaj używania funkcji podsumowujących (Dlookup()) na tabelach, które nie należą do kwerendy.
Kwerendy są najbardziej skomplikowanymi obiektami Accessa. Na szczęście Jet czuwa nad tym, aby działały one jak
najlepiej. Dzięki informacjom zawartym w tym rozdziale będziesz mógł pomóc silnikowi Jet w przyspieszeniu pracy
kwerend. Do sprawdzenia, które rozwiązania zapewniają najlepszą wydajność, używaj funkcji SHOWPLAN oraz procedur
PrintStats i QueryTimer.
Przyspieszenie
funkcjonowania formularzy
Ponieważ większość swojego czasu pracy użytkownicy spędzą, pracując z formularzami, powinieneś dołożyć starań, by
wysiłek, jaki włożyłeś w optymalizację, nie został zniweczony przez wolne formularze. Przede wszystkim, formularze
powinny być proste i oszczędne.
Zacznijmy od początku
Pierwszą rzeczą, jaką widzą użytkownicy po uruchomieniu aplikacji, jest formularz startowy. Może to być tylko ekran
startowy z nazwą aplikacji oraz informacjami o niej lub panel przełączania, ułatwiający poruszanie się po aplikacji.
Niezależnie od tego, który to z nich, dobrze jest usunąć z niego kod. Umieść kod formularza startowego w standardowym
module i zostaw tylko te procedury, które są niezbędne do uruchomienia aplikacji. Ponieważ formularz będzie teraz ładował
się szybciej, zrobi lepsze wrażenie na użytkowniku. Niektóre z operacji mogą być przeprowadzone później. Po usunięciu
modułu z formularza zmień jego właściwość MaModuł na Nie. Dzięki temu uzyskasz prosty formularz, który powinien
działać lepiej. Jednakże zmieniając właściwość MaModuł na Nie, usuwasz cały kod formularza i jego formantów. Pamiętaj
o umieszczeniu tych funkcji i procedur w standardowym module, zanim zmienisz tę właściwość.
Formularz startowy nie powinien zawierać formantów ActiveX, gdyż ładują się one dużo dłużej niż inne formanty. Jeśli
jesteś zmuszony umieścić na formularzu formant ActiveX, ogranicz wówczas ilość pozostałych formantów.
Wybierz opcję otwierania formularza w menu Autostart zamiast używać samowykonujących się makr.
Spróbuj używać formantu Obraz dla umieszczania rysunków. Jeśli chodzi o wyświetlanie grafiki, jest dużo bardziej
wydajny niż związane i niezwiązane ramki obiektów.
Podczas ładowania formularza Access musi zamalować lub wyrenderować każdy z umieszczonych na nim formantów. Nic
dziwnego więc, że więcej czasu zajmuje mu renderowanie formantów, które na siebie nachodzą. Aby upewnić się, że
prawidłowo rozmieściłeś formanty i nie nachodzą one na siebie, użyj poleceń Format, Odstępy w pionie i Odstępy w
poziomie.
Staraj się zachować jak najmniejsze nasycenie kolorów na formularzu (najlepsze rozwiązanie to czarno – białe). Im większe
nasycenie kolorów bitmapy, tym więcej pamięci czasu wymagane jest do jej namalowania.
Nie umieszczaj elementów graficznych oraz innych, dużych obiektów (np. pól memo i obiektów OLE) w podstawowych
formularzach, tabelach i kwerendach. Przywołuj je za pomocą osobnych formularzy lub kwerend tylko wtedy, gdy
Część IV ♦ Tajniki VBA 256
użytkownik tego zażąda. Dzięki temu będziesz mógł zapobiec stracie czasu i zasobów na przedstawianie jakiegoś dużego i
pamięciochłonnego obiektu, który w danym momencie może nie być potrzebny. Pamięć użyta do załadowania obiektów
OLE nie jest zwolniona do momentu zamknięcia formularza, więc pamiętaj o zamykaniu formularzy, które nie są Ci już
potrzebne.
Wybierając formanty do formularza, pamiętaj o informacjach z tabeli 14.3. Można przyjąć, że im większy zestaw funkcji daje
Ci formant, tym więcej zasobów pochłania. Tabela 14.3 zawiera wszystkie formanty znajdujące się na pasku narzędzi
projektu formularza. Policzyliśmy ilość właściwości każdego z nich i modyfikując tę liczbę o złożoność funkcji
wykonywanych przez formant otrzymaliśmy względną wagę. Jest to jednak tylko wskazówka. W rzeczywistości, użycie
zasobów przez formanty formularza określa sposób, w jaki je wykorzystujesz.
Tabela 14.3.
Względne wagi formantów formularza
Tabela 14.3.
Względne wagi formantów formularza (ciąg dalszy)
Niektóre z formantów są wielokrotnie bardziej zasobochłonne niż inne, więc substytucja może okazać się dobrą techniką
optymalizacyjną. Bardzo często zdarza się, że pole listy może zastąpić pole listy wyboru lub nawet podformularz. Rysunki
mogą często korzystać z formantu Image zamiast ramki obiektu, a formant karta pomoże podzielić formularz na szybciej
ładujące się części, renderując jedynie formanty na widocznej karcie. Jeśli użytkownicy mieli już do czynienia z hiperłączami
w Internecie, możesz spróbować zastąpić nimi przyciski poleceń. Jeśli masz możliwość użycia prostszego formularza bez
zmniejszania jego zestawu funkcji, zrób to.
u Ogranicz do minimum liczbę wyświetlanych pól w polach listy i polach listy rozwijalnej, a także indeksuj pola w
nich wyświetlane. W polach listy rozwijalnej wyłączaj opcję Autorozwijanie, ustawiając ją na Nie. Nakazywanie
Accessowi obserwacji i reagowania na każde naciśnięcie klawisza pogarsza wydajność. Używaj tej opcji tylko
wtedy, gdy nie da się tego uniknąć. Jeśli musisz użyć opcji Autorozwijanie, upewnij się, że kolumna, do której
użytkownik wprowadza dane, jest polem tekstowym. Access może użyć tej funkcji jedynie na tekście. Jeśli
wprowadzone dane nie są tekstem, Access będzie musiał je konwertować, co zabierze więcej czasu.
u Jeśli ukrywasz pole związane formantu lista rozwijana, unikaj używania w nim lub w wyświetlanych polach
wyrażeń. Pole listy rozwijalnej nie wyświetli wyników tak szybko, jakby to miało miejsce, gdyby były one
obliczone wcześniej i umieszczone w tabeli.
u Unikaj używania w listach i listach rozwijalnych kwerend z ograniczeniami. Próbuj opierać je na prostych
tabelach. Możesz poprawić wydajność, tworząc tabelę na podstawie kwerendy i aktualizując ją co jakiś czas.
u Podczas odświeżania formularzy lub wszystkich formantów zawierających dane, które mogły ulec zmianie,
używaj metody Requery, która jest dużo szybsza niż Akcja PonówKwerendę makra. Pamiętaj o użyciu tej metody
po każdej aktualizacji lub usuwaniu danych, szczególnie w aplikacjach, których używa wielu użytkowników.
u Zamiast tworzyć jedną, dużą listę rozwijalną, zastanów się, czy nie ma możliwości umieszczenia w formularzu kilku
pól, które będą ograniczały swoją zawartość. Przykładowo, jedna lista rozwijana mogłaby służyć do wyboru woje-
wództw. Wybór ten ograniczałby zawartość drugiej listy do miast na obszarze wybranego województwa. Byłoby to
szybsze i bardziej wydajne rozwiązanie niż jedna lista, zawierająca nazwy wszystkich województw i miast.
u Tak samo, jak musisz być oszczędny w wyborze ilości i typów formantów na formularzu, powinieneś również
przemyśleć ilość pól przedstawianych w podległym formularzowi zestawie rekordów. Mimo iż formularze zawsze
ładują dane z tabeli szybciej niż z kwerendy, istnieje jedno zastrzeżenie. Gdy otwierasz formularz oparty na tabeli,
wszystkie jej pola są ładowane, nawet, jeśli formularz ich nie wyświetla. Czasami lepiej jest oprzeć formularz na
kwerendzie, co pozwoli na usunięcie zbędnych pól z zestawu rekordów.
u Podległy formularzowi zestaw rekordów sortuje jedynie w ostateczności. Wymuszenie zmiany kolejności
rekordów w tym samy czasie, gdy formularz przygotowuje się do ich prezentacji, może zauważalnie wydłużyć
czas otwierania formularza.
u Kiedy piszesz kod formularza (CBF), używaj słowa kluczowego Me. Stała ta zawsze odnosi się do aktywnego
formularz, i działa szybciej niż inne odniesienia.
u W przypadku konstrukcji formularz główny – podformularz, indeksuj nadrzędne i Podrzędne pola łączące. To
znacznie poprawi szybkość odniesień, które te formularze wykonują bardzo często.
u Jeśli użytkownicy nie będą edytować rekordów podformularza, ustaw jego właściwości w odpowiedni sposób.
Edycja dozwolona, Dodawanie dozwolone i Usuwanie dozwolone mają wpływ na wydajność, gdyż zwiększają
zestaw funkcji formularza. Możesz przyspieszyć jego działanie, pozbywając się zbędnych funkcji. W ten sam
sposób możesz przyspieszyć działanie formularza, wybierając odpowiedni zestaw funkcji. Jeśli otwierasz
formularz w celu wprowadzania danych, ustaw właściwość Wprowadzanie danych na Tak, aby nie pobierał on
niepotrzebnie rekordów.
u Co się tyczy ustawiania właściwości formantów i formularza w trakcie jego działania umożliwiaj to jedynie
wtedy, gdy jest to niezbędne i nie powoduje zmniejszenia wydajności.
u Czy dynamiczny zestaw rekordów jest konieczny? Może wystarczyłoby zdjęcie?
u Gdy jest to tylko możliwe, ukrywaj formanty przy użyciu podziału strony i formantu karta. Możesz również
przyspieszyć działanie aplikacji, ukrywając formularze. Dobrze jest w miarę możliwości załadować kilka najczęściej
używanych formularzy tak, by były niewidoczne. Możesz to uczynić podczas uruchamiania aplikacji lub przy
ładowaniu pierwszego formularza. Aby załadować formularz tak, by był niewidoczny, otwórz go z argumentem
WindowMode ustawionym na Hidden:
DoCmd.OpenForm "NazwaFormularza" , , , , acHidden
u Gdy użytkownik będzie chciał wyświetlić formularz, możesz go wyświetlić przy użyciu następującego polecenia:
Forms("NazwaFormularza").setfocus
u Jeśli użytkownik będzie znów potrzebował tego formularza, ukryj go zamiast zamykać. Metoda Hide spowoduje
ukrycie go, lecz pozostanie on załadowany do pamięci.
Formobject.hide
u Możesz znacznie poprawić wydajność interfejsu, unikając ładowania kwerend i formularzy oraz renderowania
formantów. Ceną tego jest zajmowanie pamięci przez ukryte formularze, co może mieć wpływ na inne części
aplikacji. Mimo iż nie możesz użyć tej techniki dla wszystkich formularzy w aplikacji, powinieneś ją zastosować
w przypadku tych najczęściej używanych.
Część IV ♦ Tajniki VBA 258
Gdy masz do czynienia z dużymi zestawami rekordów, spróbuj nie przedstawiać ich użytkownikowi jednocześnie. I tak,
większość użytkowników nie wiedziałaby co zrobić z dziesiątkami tysięcy rekordów naraz. Jeśli jednak z aplikacji korzysta
wielu użytkowników, a formularz otwiera zestaw rekordów oparty na dużej tabeli lub kwerendzie, wydajność aplikacji
spadnie na skutek wąskich gardeł w sieci, ograniczeń bufora, blokowania rekordów i stron oraz przeładowania
użytkowników. Lepiej jest znaleźć sposób na podzielenie danych na logiczne podzestawy przy użyciu ograniczeń. Jeszcze
lepiej jest przedstawiać użytkownikowi rekordy pojedynczo, pobierając je na podstawie klucza podstawowego lub
indeksowanego pola. W przypadku mniejszych aplikacji, może to mieć negatywny wpływ na wydajność, jednakże w
przypadku systemów z wieloma użytkownikami, jest to jedyny sposób. Aby tego dokonać, zmień instrukcje SQL w kodzie,
programowo zmień właściwość Źródło rekordów i ponów kwerendę formularza.
Największą, mającą wpływ na wydajność różnicą między formularzami i raportami różnicą jest sposób, w jaki zarządzają
swoimi sekcjami. W formularzu istnieje nagłówek formularza, sekcja szczegółowa i stopka formularza. W raporcie istnieje
nagłówek i stopka raportu, nagłówek i stopka strony, nagłówki i stopki sekcji oraz sekcja szczegółowa. Gdy otwierasz
formularz, kwerenda, na której jest oparty, przeprowadzana jest tylko raz. Gdy otwierasz raport, musi on utworzyć
kwerendę (opartą na tej ze źródła danych) dla każdej sekcji raportu. W przypadku złożonej kwerendy raport musi ją lub jej
części uruchamiać kilkakrotnie.
Wiele z technik umożliwiających poprawę wydajności formularzy ma również zastosowanie do raportów. Ta sekcja była
omówieniem technik charakterystycznych jedynie dla tych drugich.
poproszą o modyfikacje i lepiej jest wówczas mieć możliwość umieszczenia w niej dodatkowych elementów (np.
złożonych procedur sprawdzania poprawności) bez pogorszenia wydajności aplikacji.
Jeśli poświęciłeś trochę czasu na przejrzenie i wdrożenie niektórych z dotychczas omówionych technik, pisany przez
Ciebie kod będzie łatwiejszy do zoptymalizowania. Największą przeszkodą w tym przypadku będzie słaby projekt bazy
danych. Jeśli baza jest źle zaprojektowana, każda funkcja i procedura będzie wykonywana dłużej niż powinna.
Istnieje kilka prostych zasad oraz kilka alternatywnych technik, które sprawią, że funkcje i procedury Twojej aplikacji będą
wykonywane tak szybko jak to tylko możliwe. Część z nich, o ile nie wszystkie, ma raczej nieznaczny wpływ, gdy
występują osobno, jednakże gdy są wykorzystane razem i powtarzane, efekt będzie zauważalny.
Stąd też dobrze jest łączyć moduły w grupy w przemyślany sposób. Jeśli funkcje i moduły często się do siebie odwołują,
umieść je w tym samym module w celu zmniejszenia ilości załadowań modułu. Usuń również wszystkie zbędne funkcje i
procedury.
VBA ładuje moduł do pamięci również w sytuacji, w której odnosisz się do zmiennych publicznych tego modułu. Zadbaj o
to, by zmienne publiczne również były pogrupowane w modułach w przemyślany sposób.
Praca z modułami
Przed uruchomieniem modułów VBA musi je skompilować. Oznacza to, że VBA będzie kompilować moduł za każdym
razem, gdy będziesz chciał go uruchomić. Może mieć to znaczący wpływ na wydajność aplikacji.
Podczas kompilowania modułu VBA nadaje mu znacznie mniejszą, łatwiej wykonywalną formę. Mimo iż początkowy kod
jest zawsze przechowywany w pliku MDB, Access ładuje i uruchamia skompilowany kod VBA. Ponadto kod VBA nie
zawiera pustych miejsc, komentarzy, nagłówków i zajmuje dużo mniej miejsca niż napisany przez Ciebie kod źródłowy. Jeśli
chcesz uruchomić nieskompilowaną procedurę, VBA musi załadować do pamięci cały kod źródłowy (łącznie z pustymi
miejscami, komentarzem i nieużywanym kodem) i skompilować go przed wykonaniem. Dotyczy to również zawierających
kod formularzy i raportów.
Kompilowanie kodu
Aby skompilować kod, z menu Debug wybierz polecenie Compile nazwaprojektu. Pamiętaj o skompilowaniu aplikacji
przed dostarczeniem jej do klientów.
Dekompilacja
Moduł jest dekompilowany podczas edytowania go. Raport czy formularz dekompilowany jest w momencie
dokonywania w nim jakichkolwiek zmian, nawet bez ingerowania w kod. Tworzenie nowego formularza lub raportu
również pociąga za sobą dekompilację kodu. Podczas tworzenia aplikacji możesz używać opcji Compile on Demand
(aby ją włączyć, z menu Tools wybierz Options. Opcja Compile on Demand znajduje się na zakładce General). Dzięki
temu VBA będzie kompilować moduły aplikacji podczas pracy.
Nową opcją w Accessie 2000 jest Background Compile. Kompilując aplikację w tle, VBA pozwala Ci zaoszczędzić trochę
czasu. Jeśli kiedyś zdarzy Ci się to sprawdzić, skompilowana aplikacja zajmuje więcej miejsca na dysku niż jej
zdekompilowana wersja. Dzieje się tak, gdyż w skompilowanej aplikacji przechowywany jest zarówno źródłowy jak i
skompilowany kod. Nie wpływa to jednak na obniżenie wydajności. Jako, że do pamięci ładowany jest tylko
skompilowany kod, który działa szybciej niż źródłowy, w rzeczywistości następuje znaczna poprawa wydajności.
Ponieważ Access przez cały czas ładuje moduły do pamięci, powinieneś sprawdzić, czy nie zawierają one żadnych zbędnych
elementów (np. nie używanych funkcji czy procedur). Usuń z aplikacji kod, z którego zrezygnowałeś w trakcie procesu
tworzenia. Kompilator musi zajmować się również tym kodem, co spowalnia cały proces. Czasami podczas pisania
aplikacji powinieneś zamknąć projekt, co spowoduje wyczyszczenie pamięci. Nawet po skompilowaniu aplikacji wciąż
będziesz jednak chciał, by jak najmniejsza część kodu ładowana była do pamięci.
Część IV ♦ Tajniki VBA 260
Oprócz kwestii związanych z grupowaniem modułów, zarządzaniem pamięcią i kompilacją, istnieje kilka wskazówek,
których wykorzystanie przy pisaniu kodu pomoże Ci tworzyć szybsze aplikacje.
W przypadku ciągów znaków celem powinno być zmniejszenie ilości wykorzystywanej przez nie pamięci stosu. Spróbuj
zmienić ciągi o zmiennej długości na ciągi o stałej długości. Poniższy przykład przedstawia ciąg o zmiennej długości,
zadeklarowany jako ciąg o stałej długości w celu zmniejszenia używanej pamięci stosu.
Dim strString as string
Static strString as string * 30
użyj
Sub CycleControls(cntl as TextBox)
261 Rozdział 14. ♦ Optymalizacja aplikacji
Zamiast
If bFlag = False then
bFlag=True
Else
bFlag=False
EndIf
użyj
bFlag=Not bFlag
Wykonanie jednej linii kodu zajmuje dużo mniej czasu niż kilku, zawierających dodatkowo ocenę.
W przypadku większej ilości właściwości obiektu, możesz zmniejszyć ilość odwołań przy użyciu konstrukcji With...End
With. Przydaje się to szczególnie wtedy, gdy ścieżka odwołania jest długa.
Część IV ♦ Tajniki VBA 262
With Forms![frmMainForm]![txtCustomerName]
.left=200
.top=300
.height=200
.width=100
End With
Słowo kluczowe ME oznacza aktywny formularz, więc nie musisz deklarować zmiennej ani odnosić się do obiektu, by go
użyć. Ponieważ jest to możliwe tylko w CBF, nie będziesz mógł umieszczać go w standardowych modułach ogólnych.
With ME
.Height=500
.Width=500
End With
Jeśli chcesz opróżnić tablicę nie niszcząc jej struktury, możesz użyć słowa kluczowego Erase. Dzięki temu będziesz mógł
wyczyścić tablicę określonego rozmiaru, bez konieczności ponownego jej budowania.
Erase myArray
Jeśli chcesz powiększyć tablicę bez niszczenia danych w niej zawartych, użyj funkcji ReDim z parametrem Preserve.
ReDim Preserve myArray(Ubound(myArray+1))
Tablice często mogą zarządzać danymi z zestawu rekordów. Zamiast otwierać zestaw rekordów z całą jego zawartością,
użyj metody GetRows() i zamknij zestaw rekordów. Dzięki temu pamięć zostanie zwolniona i nie będzie problemów
związanych z obsługą wielu użytkowników. GetRows() posiada jeden argument: liczbę wierszy ładowanych do tablicy.
Dim db as Database
Dim rowArray as Variant
Dim rs as Recordset
Set db=CurrentDB()
Set rs=db.openrecordset("Zamówienia kwartalne")
RowArray=rs.GetRows(rs.RecordCount)
rs.close
...
Po załadowaniu danych do tablicy możesz obrabiać je w dowolny sposób lub umieścić je w niezwiązanym formularzu.
Poniższy kod ilustruje użycie zakładki w formularzu w celu przejścia do poprzedniego rekordu po dokonaniu aktualizacji.
263 Rozdział 14. ♦ Optymalizacja aplikacji
Użycie zakładki w celu przejścia do poprzedniego rekordu jest o 1300% szybsze niż wykonanie instrukcji FindFirst w
tej samej sytuacji.
Zamykaj i niszcz
Szybki kod to czysty kod. Pamiętaj o zamykaniu zestawów rekordów po zakończeniu pracy z nimi i o ustawianiu obiektów
na Nothing, gdy nie są Ci już więcej potrzebne. Pozostawienie ich ogranicza ilość pamięci dla innych części aplikacji.
rs.Close
Set db=Nothing
Jeśli musisz odwoływać się do danych za pomocą modelu obiektowego, zamiast DAO użyj ADO. Obiekty ADO to nowy
standard obróbki i definicji danych poprzez model obiektowy. Technologię DAO można uznać za schyłkową i nie są do
niej wydawane żadne rozszerzenia i poprawki. W książce tej omówiliśmy funkcjonowanie obiektów ADO w kilku
miejscach, zwłaszcza w rozdziale 6. „Wprowadzenie do obiektów danych ActiveX” i 7., „Zaawansowane ADO”.
odniesień do aktualnej bazy danych. Użycie Currentdb() powoduje automatyczne odświeżenie kolekcji bazy, co zabiera
trochę czasu. Pierwszy sposób (dbEngine(0)(0)) nie odświeża zbioru.
Set db=DBEngine(0)(0)
i szybszym niż
Set cntl =Forms![frmMyForm]![myControl]
Użycie numeru indeksu elementu zbioru przydaje się w szczególności w przypadku pętli.
Podczas tworzenia pętli w obiektach Collection będziesz chciał uniknąć zbędnego odświeżania kolekcji. Nawet w
przypadku małych baz danych odświeżanie kolekcji może spowodować znaczny spadek wydajności.
W przypadku użycia pętli For...Next możesz zaoszczędzić czas, nie umieszczając zmiennej w linii Next.
For i = 1 to 100
' zrób co chcesz
Next
Płynące z takiego rozwiązania korzyści są szczególnie widoczne w przypadku pętli zagnieżdżonych. Staraj się również
nie obliczać granicy w linii For. Górna granica powinna być już znana przed rozpoczęciem pętli.
Reccount=rs.recordcount/2
For i=1 to reccount
...
Next
Jeśli nie określisz wartości górnej granicy wcześniej, pętla będzie ją obliczać za każdym przejściem. Jest to strata czasu.
Używaj A2KU_Timer
Podczas mierzenia czasu wykonywania operacji w aplikacji używaj znajdującego się na płycie CD zegara A2KU_Timer.
Jest prawie 1000% szybszy niż wszystkie inne.
Kontroluj odświeżanie
Wyłącz Application.Echo lub kontroluj zawartość ekranu. Odświeżanie ekranu zabiera dużo czasu i może spowolnić
pracę aplikacji.
265 Rozdział 14. ♦ Optymalizacja aplikacji
Chleba i igrzysk
Jeśli nie jesteś w stanie sprawić, by dana operacja była wykonywana szybko, spraw, by przynajmniej na taką wyglądała.
Jeśli jakiś proces trwa na tyle długo, by wywołać znudzenie użytkownika, wyświetl ekran informujący go o tym, że coś się
dzieje. Użytkownicy często myślą, że aplikacja działa szybko, ponieważ otrzymują o tym informacje.
Część V
Access
i architektura klient-serwer
W tej części:
u Wprowadzenie do projektów programu Microsoft Access oraz narzędzi wizualnych.
u Tworzenie interfejsu użytkownika dla Microsoft SQL Server.
u Interfejs Accessa 2000 do Oracle.
Rozdział 15.
Wprowadzenie do projektów programu
Microsoft Access oraz narzędzi
wizualnych
W tym rozdziale:
u Wprowadzenie do Projektów programu Microsoft Access (ADP).
u Użycie ADP.
u Praca z ADP i istniejącymi bazami danych serwera SQL.
u Tworzenie projektów opartych o nową bazę danych.
Microsoft zintegrował Access 2000 z serwerem SQL, używając jako spoiwa OLE DB. Aby skorzystać z zalet tej integracji,
użyj ADP, nowego typu aplikacji w Accessie. Autorzy zalecają używanie ADP do współpracy z SQL Server 7.0. Jeżeli
chcesz użyć innego serwera niż SQL Server 7.0, zajrzyj do rozdziału 16., „Tworzenie interfejsu użytkownika dla Microsoft
SQL Server” i rozdziału 17. „Access jako interfejs użytkownika dla Oracle”. W tym rozdziale przedstawiony jest sposób
użycia ADP we współpracy z SQL Server 7.0.
Przedstawiciele Microsoftu zrozumieli, że potrzebujesz lepszej integracji z serwerami baz danych. W Accessie 2000 jest
dostępny nowy typ projektu bazy danych nazwany Projektem programu Microsoft Access (ADP), używany do integracji z
SQL Server 7.0. Ponieważ ADP jest silnie związane z OLE DB dla SQL Servera, możesz go użyć tylko z SQL Server 7.0
lub SQL Server 6.5 z zainstalowanym Service Pack 5.
Jeżeli chcesz użyć ADP razem z SQL Server 6.5, SP 5, powinieneś prze-
czytać uwagi do programu Office 2000 i wykonać plik poleceń SQL na
serwerze przed rozpoczęciem pracy z ADP i SQL Serverem 6.5.
u Z ADP masz tylko jedno połączenie do bazy dla wszystkich Twoich obiektów. Używając plików MDB, masz
wiele połączeń. Przykładowo, używając tabeli połączonej, formatka z 10 formantami posiada 10 połączeń do bazy
danych. Używając ADP, jest tylko jedno połączenie.
u ADP jest łatwe w użyciu.
u ADP umożliwiają użycie Accessa jako narzędzia do projektowania aplikacji.
Po przeanalizowaniu plusów i minusów i przeczytaniu tego rozdziału powinieneś wiedzieć wszystko, co jest Ci potrzebne, aby
stwierdzić, czy chcesz użyć ADP w Twoich aplikacjach.
Użycie ADP
Aplikacja ADP jest aplikacją Accessa 2000 z rozszerzeniem ADP. Używa ona serwera SQL jako silnika bazy danych.
Aby móc użyć ADP, musisz zainstalować serwer SQL na Twoim kompu-
terze lub mieć dostęp poprzez sieć do innego serwera SQL. Aby za-
instalować lokalną wersję serwera SQL dla Windows 95/98, postępuj
według wskazówek w instrukcji instalacji SQL Server 7.0. Jeżeli nie
posiadasz SQL Server 7.0, zainstaluj program Microsoft Data Engine
(MSDE), który jest lokalną wersją serwera SQL pozbawioną interfejsu
użytkownika. Znajduje się on na dysku instalacyjnym Office 2000 w ka-
talogu /SQL.
Tworzenie ADP
Aby utworzyć ADP, uruchom Access i wybierz Plik|Nowy z głównego menu. Na ekranie pojawi się okno dialogowe, jak na
rysunku 15.1, w którym wybieramy typ tworzonej aplikacji. Do wyboru masz: Baza danych|Projekt (istniejąca baza
danych) i Projekt (nowa baza danych).
Rysunek 15.1.
Okno dialogowe
Nowy
Gdy wybierzesz Baza danych, utworzysz zwykły plik MDB, który używa silnika bazy danych Jet. Wybranie Projekt
(istniejąca baza danych), spowoduje utworzenie ADP komunikującego się z istniejącą bazą danych na serwerze SQL. Gdy
wybierzesz Projekt (nowa baza danych), rozpoczniesz tworzenie ADP i nowej bazy danych na serwerze.
Utwórz przykładowy projekt oparty o istniejącą bazę danych. Podwójne kliknięcie ikony spowoduje wyświetlenie okna
dialogowego, w którym określa się położenie pliku ADP. Wygląd tego okna pokazany jest na rysunku 15.2.
Po utworzeniu pliku ADP, zostaniesz zapytany o informacje dotyczące bazy danych i serwera SQL, tak jak pokazane jest to
na rysunku 15.3.Pamiętasz, że gdy używałeś Data Links (w rozdziale 7., „Zaawansowane ADO”), musiałeś podać nazwę
serwera, nazwę użytkownika, hasło oraz nazwę bazy danych, której chciałeś użyć. Do naszego przykładu użyjesz bazy
danych „Northwind” w wersji na serwer SQL, która jest dostarczana razem z SQL Server 7.0. Po podłączeniu do bazy
269 Rozdział 15. ♦ Wprowadzenie do projektów programu Microsoft Access
danych pojawi się okno projektu z kilkoma nowymi elementami w oknie bazy danych. Okno to jest pokazane na rysunku
15.4.
Rysunek 15.2.
Określanie
położenia pliku
Rysunek 15.3.
Tworzenie
połączenia
do bazy danych
Rysunek 15.4.
Nowe okno bazy
danych dla ADP
Tabela 15.1.
Okno obiektów bazy danych dla ADP
Element Opis
Tabele Lista wszystkich tabel w bazie danych serwera SQL. W przeciwieństwie do tabel
połączonych, możesz dodawać, zmieniać i usuwać tabele bezpośrednio na serwerze
Widoki Lista widoków w bazie danych serwera SQL. Możesz dodawać, zmieniać i usuwać widoki
b ś d i
Część V ♦ Access i architektura klient-serwer 270
bezpośrednio na serwerze
Diagramy Lista diagramów bazy danych na serwerze. Możesz tworzyć diagram takimi samymi
bazy danych narzędziami jakie są w Visual InterDev 6.0
Formularze Formularze Accessa w Twojej aplikacji. Formularze są zapisane w pliku ADP, a nie na
serwerze. Mogą być połączone z tabelami, widokami i procedurami przechowywanymi
Raporty Raporty Accessa w Twojej aplikacji. Raporty są zapisane w pliku ADP, a nie na serwerze.
Mogą być połączone z tabelami, widokami i procedurami przechowywanymi
Strony Strony dostępu do danych aplikacji. Nie są one zapisane na serwerze, ale istnieją jako pliki
HTML na dysku (zajrzyj do rozdziału 26. „Użycie stron dostępu do danych”). Mogą być
połączone z tabelami, widokami i procedurami przechowywanymi
Makra Wszystkie Twoje makra. Makra zapisane są w pliku ADP
Moduły Moduły Accessa. Moduły są zapisane w pliku ADP
Praca z ADP
i istniejącymi bazami danych
serwera SQL
W czasie pracy nad projektem ADP może być potrzebne dodawanie, zmienianie i usuwanie obiektów bazy danych. W
rozdziale tym opiszę, w jaki sposób można manipulować obiektami serwera SQL istniejącymi w Twoim projekcie.
Praca z tabelami
ADP nie tworzy połączeń do tabel bazy danych tak jak tradycyjne aplikacje Accessa, lecz posiada bezpośredni dostęp do
tabel serwera SQL z okna bazy danych. Gdy usuwasz tabelę lub zmieniasz jej nazwę w Accessie, usuwasz ją lub zmieniasz
jej nazwę również na serwerze. Chociaż jest to bardzo wygodne, może być niebezpieczne. Powinieneś upewnić się, że
ustawiłeś odpowiednie mechanizmy zabezpieczeń serwera SQL tak, aby ograniczyć dostęp użytkowników do tabel. Jeżeli
chcesz zmienić strukturę tabeli, naciśnij przycisk Projektuj, co spowoduje otwarcie okna edytora struktury tabel, jak jest to
pokazane na rysunku 15.5.
Rysunek 15.5.
Edytor tabel
serwera SQL
w Accessie 2000
Edytor struktury tabel serwera SQL jest bardzo podobny to edytora tabel w Accessie. Należy podać nazwę kolumny i jej
atrybuty. W tabeli 15.2 zestawione są wszystkie dostępne atrybuty kolumn.
Tabela 15.2.
Atrybuty w edytorze struktury tabel serwera SQL
Rysunek 15.6.
Edytor widoków
serwera SQL
Gdy jest uruchomiony edytor, można pokazać listę tabel, wybierając Kwerenda|Pokaż tabelę z głównego menu. Zostanie
uruchomione okno z listą tabel i widoków, z którego można przeciągnąć obiekty do edytora (rysunek 15.7). Dla każdej
tabeli można połączyć pola, tak jak w QBE. Naciśnięcie przycisku SQL pokaże treść zapytania w SQL-u, tak jak pokazane
jest to na rysunku 15.8. Użycie podglądu SQL jest przydatne, jeżeli chcesz nauczyć się SQL-a lub chcesz wstawić
wyrażenie SQL do kodu programu.
Rysunek 15.7.
Edytor widoków
serwera SQL
z tabelami
Część V ♦ Access i architektura klient-serwer 272
Rysunek 15.8.
Edytor widoków
serwera SQL
z podglądem
wyrażenia SQL
Możesz użyć kolumny Criteria do zdefiniowania warunków, aliasów kolumn, grupowania i sortowania. Po utworzeniu
widoku należy go zapisać przed uruchomieniem, ponieważ jest to obiekt istniejący na serwerze.
Procedury przechowywane
Wszystkie procedury przechowywane na serwerze SQL mogą być zarządzane przez Accessa. Po wejściu w sekcję procedur
przechowywanych można dodać, modyfikować, zmienić nazwę lub usunąć procedurę. Aby dodać procedurę przechowywaną,
wybierz przycisk Nowy w oknie bazy danych. Pojawi się edytor procedur przechowywanych Accessa pokazany na rysunku
15.9.
Rysunek 15.9.
Edytor procedur
przechowywanych
Accessa
Chociaż edytor procedur przechowywanych wygląda bardzo prosto, wyniki jego pracy mogą być bardzo efektywne.
Możesz utworzyć każdą poprawną procedurę przechowywaną Transact SQL bezpośrednio w Accessie i zapisać ją na
serwerze SQL.
Aby uruchomić procedurę przechowywaną należy kliknąć dwa razy. Jeżeli procedura posiada parametr, Access „zapyta” o
jego wartość (rysunek 15.10).
Rysunek 15.10.
Parametr procedury
przechowywanej
Aby edytować diagram bazy danych, kliknij go dwa razy, a zostanie on pokazany na ekranie jak na rysunku 15.11.
273 Rozdział 15. ♦ Wprowadzenie do projektów programu Microsoft Access
Rysunek 15.11.
Diagram bazy
danych serwera SQL
Możesz przesuwać i zmieniać rozmiary tabel za pomocą myszki. Możesz także powiększyć fragment diagramu, aby
ograniczyć widok do określonych tabel. Najlepsze jest to, że możesz wydrukować cały diagram jako dokumentację.
Poprzez kliknięcie prawym klawiszem myszki możesz wybrać podgląd atrybutów kolumn i masz dzięki temu dostęp do
edytora struktury tabeli (rysunek 15.12)!
Rysunek 15.12.
Diagram
bazy danych
serwera SQL
z pokazanymi
atrybutami kolumn
Aby zarządzać serwerem, użytkownik ADP musi posiadać właściwe prawa dostępu do serwera SQL. Musisz nadać
użytkownikowi ADP prawa administratora bazy danych. Zapewne, do zarządzania serwerem będziesz chciał stworzyć
oddzielny projekt ADP.
Składowanie i odtwarzanie
Aby sporządzić kopię bieżącej bazy danych, wybierz Narzędzia|Narzędzia bazy danych| Kopia zapasowa z głównego
menu. Access, „zapyta” Cię o miejsce, gdzie ma zapisać kopię, tak jak wygląda to na rysunku 15.13.
Część V ♦ Access i architektura klient-serwer 274
Rysunek 15.13.
Kopia zapasowa
serwera SQL
wykonywana
przez Accessa
Baza danych zostanie zapisana w formacie czytelnym dla normalnej procedury odtwarzania serwera SQL. Możesz także
wybrać Narzędzia|Narzędzia bazy danych|Przywróć z głównego menu, aby przywrócić bazę danych z kopii zapasowej.
Rysunek 15.14.
Okno dialogowe
repliki
Rysunek 15.15.
Kreator publikacji
serwera SQL
Po uruchomieniu kreatora stosuj się do jego zaleceń, aby utworzyć publikację. Całkiem łatwo tworzy się publikację, a
nawet mamy możliwość utworzenia subskrybenta w postaci pliku MDB korzystającego z silnika bazy danych Jet (więcej
informacji znajdziesz w rozdziale 22. „Replikacja i JRO”). Aby zsynchronizować bazę danych z repliką, wybierz:
Narzędzia|Replikacja|Synchronizuj z głównego menu. Można również tak skonfigurować serwer SQL, aby automatycznie
wykonywał synchronizację w określonym przez nas czasie przy użyciu programu Enterprise Manager.
Bezpieczeństwo
Za pomocą Accessa 2000 można zarządzać mechanizmami bezpieczeństwa serwera SQL poprzez wybranie
Narzędzia|Zabezpieczenia|Zabezpieczenia bazy danych. Uruchomione zostanie okno dialogowe zarządzania prawami
dostępu użytkownika, bardzo podobne do używanego w Accessie (rysunek 15.6). Za jego pomocą można dodawać, usuwać
i edytować użytkowników, ich prawa dostępu do bazy, oraz tworzyć grupy użytkowników.
275 Rozdział 15. ♦ Wprowadzenie do projektów programu Microsoft Access
Rysunek 15.16.
System zabezpieczeń
w Accessie 2000
oparty jest o system
zabezpieczeń
w SQL Server 7.0
Zwykle użytkownik, który jest właścicielem bazy danych, ma nazwę DBO, natomiast użytkownik – gość nazywa się Guest.
Role są identyczne z rolami w SQL Server, użytkownik może mieć np. rolę „Administrator systemu”. Aby dowiedzieć się
więcej o systemie bezpieczeństwa, zajrzyj do książek elektronicznych dostarczonych z SQL Server.
Rysunek 15.17.
Ustanowienie
odwołania do
komponentu OLE
DB Service
Po ustanowieniu odwołania można przypisać ciąg połączeniowy do metody PromptNew obiektu DataLink. Następnie
możesz przypisać ten ciąg do metody CurrentProject.OpenConnection, aby aplikacja ADP przyłączyła się do nowej
bazy danych. Fragment programu z wydruku 15.1 przedstawia, w jaki sposób można wykonać taką operację.
Proc_Exit:
Exit Sub
Część V ♦ Access i architektura klient-serwer 276
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Tworzenie projektu
opartego na nowej bazie danych
W tym rozdziale pokażemy, w jaki sposób użyć narzędzi ADP, aby utworzyć od początku nową bazę danych. Utworzymy
prostą aplikację, która pokaże nam, jak duże możliwości posiada ADP. Uruchom Access 2000 i wybierz z menu Plik|Nowy,
a następnie wybierz z okna dialogowego Nowa baza danych. Access uruchomi kreatora baz danych serwera SQL (rysunek
15.18). Kreator poprosi o podanie nazwy serwera, nazwy użytkownika i jego hasła oraz nazwy bazy danych. Po podaniu
tych informacji Access utworzy na serwerze bazę danych. Teraz jesteś gotowy do tworzenia aplikacji.
Rysunek 15.18.
Kreator
bazy danych SQL
Tworzenie tabel
Chcemy utworzyć prosty system śledzenia wykonywania zadań. Aby to zrealizować, potrzebujemy kilku tabel. Aby
utworzyć tabelę, kliknij Utwórz tabelę w widoku projektu w oknie bazy danych. Zauważ, że jesteś od razu pytany o nazwę
tabeli, ponieważ obiekt ten istnieje na serwerze i musi być zgodny z wymaganiami serwera.
Rysunek 15.19.
Okno wyboru
nazwy tabeli
A teraz utwórz dwie tabele w edytorze, tblWydanie i tlkpTypTransakcji. Opis tblWydanie znajduje się w tabeli 15.3 a
tlkpTypTransakcji w tabeli 15.4.
277 Rozdział 15. ♦ Wprowadzenie do projektów programu Microsoft Access
Tabela 15.3.
Projekt tabeli tblWydanie
Tabela 15.3.
Projekt tabeli tblWydanie (ciąg dalszy)
Tabela 15.4.
Projekt tabeli tlkpTypTransakcji
Rysunek 15.20.
Właściwości tabeli
Rysunek 15.21.
Tryb edycji
diagramu
bazy danych
Rysunek 15.22.
Właściwości relacji
Tworzenie widoków
Zamierzasz utworzyć widok na serwerze SQL, który przedstawia wszystkie zakończone transakcje. Aby utworzyć widok,
wybierz Nowy w oknie bazy danych i przeciągnij dwie tabele do edytora, tak jak to jest pokazane na rysunku 15.24.
Utworzyłeś prosty widok, który jest wynikiem zapytania SQL przedstawionego na wydruku 15.2
279 Rozdział 15. ♦ Wprowadzenie do projektów programu Microsoft Access
Rysunek 15.24.
Edytor widoków
Rysunek 15.25.
Nasza formatka
utworzyć plik ADE, wybierz Narzędzia|Narzędzia bazy danych|Utwórz plik ADE, jak widać to na rysunku 15.26. Po
wybraniu lokalizacji pliku Access utworzy tam plik ADE. Od teraz wszystkie formularze, raporty, strony i moduły będą
zablokowane dla użytkownika aplikacji.
Od czasu wprowadzenia na rynek Microsoft Access jest uważany za wspaniałe narzędzie do tworzenia interfejsu
użytkownika dla zewnętrznych baz danych. Mimo że Access 2000 ma kilka wspaniałych nowych właściwości do pracy z
SQL Server 7.0 poprzez Projekty programu Access (ADP), właściwości te nie działają dobrze z SQL Server 6.5 i nie
działają wcale poprzez połączenie ODBC. W tym rozdziale pokażemy, jak tworzyć aplikacje oparte na SQL Server 6.5
lub Sybase System 10. W rozdziale 17., „Interfejs Accessa 2000 do Oracle” pokażemy, jak tworzyć aplikacje oparte na
Oracle Enterprise Server.
Aplikacja Accessa typu MDB połączona z serwerem SQL jest w rozumieniu tej architektury klientem. Access, gdy używa
połączenia ODBC, ładuje silnik bazy Jet, który pośredniczy w komunikacji z bazą danych. Aplikacja typu ADP we
współpracy z serwerem SQL używa nowszej technologii OLE DB, która komunikuje się z serwerem bez ładowania silnika
Jet. Chociaż podejście OLE DB ma wiele znaczących plusów, jego największą wadą jest brak wsparcia dla innych
serwerów SQL niż SQL Server. Mimo że ODBC i pliki MDB nie są tak szybkie jak nowe projekty ADP, są jednak
użyteczne i dosyć wydajne, co pokażemy w tym rozdziale.
Sybase SQL Server, musisz zainstalować właściwy dla niego sterownik ODBC, którego nie ma jednak na płycie z Office
2000). Po zainstalowaniu Accessa 2000 ze sterownikiem ODBC jesteś już gotowy do pracy z serwerem SQL.
Istnieją dwie metodologie dostępu do danych: tabele połączone oraz kwerendy przekazujące. Większość aplikacji używa
obydwu metod. Aby użyć tych metod, najpierw musisz utworzyć systemowe źródło danych ODBC.
71. Na pierwszej stronie kreatora (rysunek 16.1) wprowadź unikatową nazwę DSN (np. NorthWind), ewentualny opis
i nazwę serwera, na którym uruchomiony jest serwer SQL. Naciśnij Dalej, gdy wprowadziłeś te informacje.
72. Na drugiej stronie wprowadza się informacje o systemie użytkowników. Gdy chcesz użyć zwykłego systemu
serwera SQL (lub gdy nie wiesz, jaki chcesz wybrać), zaznacz Uwierzytelnianie serwera SQL, używając ID
logowania i hasła podanego przez użytkownika, wpisz nazwę użytkownika oraz hasło i naciśnij przycisk Dalej
(używając domyślnego użytkownika na SQL Server, nazwa użytkownika to „SA”, a hasło jest puste).
73. Trzecia strona kreatora pokazana jest na rysunku 16.2. Wprowadzasz na niej nazwę bazy danych, do której chcesz
się dołączyć. W celu pokazania przykładów w tym rozdziale przyłączymy się do bazy NorthWind.
Rysunek 16.2.
Wybór domyślnej
bazy danych podczas
tworzenia DSN
74. Czwarta strona zawiera opcje specyficzne dla ODBC, jak śledzenie. Zatwierdź domyślne opcje i naciśnij Zakończ.
75. Ostatnia strona pozwala na sprawdzenie nowo utworzonego połączenia. Dobrze jest sprawdzić tutaj połączenie i w
wypadku niepowodzenia testu, wprowadzić od razu poprawki.
Łączenie tabel
Aby zacząć pracę z nowo utworzonym źródłem danych ODBC, najczęściej stosowanym i najłatwiejszym rozwiązaniem
jest połączenie tabel serwera SQL z plikiem MDB. Tym sposobem możesz uruchamiać proste zapytania SQL, aby np.
wypełnić pola listy. Dla naprawdę małych tabel można nawet podłączyć formularze bezpośrednio do tabeli i w ten
sposób umożliwić użytkownikom wprowadzanie danych (więcej informacji o łączeniu formularzy do danych z serwera
SQL znajdziesz w części tego rozdziału zatytułowanej „Formularze w aplikacji”). Aby dołączyć tabele poprzez ODBC,
wykonaj następujące czynności.
283 Rozdział 16. ♦ Tworzenie interfejsu użytkownika dla Microsoft SQL Server
76. Upewnij się, że istnieje prawidłowe źródło danych (zajrzyj do „Tworzenie źródła danych ODBC (DSN)”).
77. Otwórz bazę danych Access i wybierz z menu: Plik|Pobierz dane zewnętrzne|Połącz tabele.
78. Na ekranie pojawi się lista wszystkich źródeł danych ODBC. Wybierz ten DSN, na którym chcesz pracować, i
naciśnij OK.
79. Access wyświetli teraz listę tabel, które możesz dołączyć (rysunek 16.3). Gdy wybierzesz tabele, możesz zapisać
razem z nimi hasło dostępu do bazy danych. Gdy to zrobisz, użytkownicy aplikacji nie będą musieli podać tego
hasła podczas pierwszego uruchomienia aplikacji.
Rysunek 16.3.
Wybór tabel
z bazy danych
ODBC
80. Teraz Access łączy tabele z plikiem MDB. Nazwy tabel poprzedzone zostaną prefiksem „dbo_”, ponieważ
właścicielem tabel w SQL Server jest „Database Owner” (właściciel bazy danych).
81. Gdy w tabeli serwera SQL nie ma zdefiniowanego klucza głównego, Access nie może połączyć takich tabel w trybie
odczytu i zapisu, więc daje Ci możliwość utworzenia lokalnego unikatowego indeksu w sposób pokazany na rysunku
16.4. Jeżeli użyjesz tego mechanizmu, będzie można zapisywać do tabeli, a Jet 4.0 będzie utrzymywał indeks na
Twoim komputerze.
Rysunek 16.4.
Tworzenie
unikatowego
identyfikatora
rekordu
Po połączeniu tabel możesz tworzyć kwerendy, formularze i raporty odnoszące się do tych połączonych tabel.
Aby wydobyć całą moc z serwera SQL, powinieneś użyć procedur przechowywanych. Procedura przechowywana na
serwerze SQL jest podobna do pytania zapisanego w Accessie. Jest to skompilowane wyrażenie SQL, które pobiera
parametry i zostanie wykonana na serwerze. Wielu programistów wysyła wyrażenia SQL do serwera, ponieważ jest to o
wiele szybsze niż użycie tabel połączonych. Metoda ta jest jednak wolniejsza od procedur przechowywanych, ponieważ
procedura posiada utworzony podczas kompilacji plan wykonania tak, aby zapytanie wykonywało się z największą
możliwą prędkością. Użycie procedur przechowywanych daje najlepsze wyniki przy zaangażowaniu najmniejszym wysiłku.
Oprócz zwiększenia prędkości procedury przechowywane zmniejszają ruch w sieci. Wysyłasz do serwera tylko małe 1 kB
polecenia uruchomienia procedury zamiast dużego 100 kB lub większego nieskompilowanego wyrażenia SQL. W obu
przypadkach serwer odsyła Ci tylko te dane, których potrzebujesz.
Procedury przechowywane
i kwerendy przekazujące
Dobrze jest oprzeć raporty Accessa na procedurach przechowywanych, ponieważ są one szybkie i efektywne. Problem
stanowi to, że nie możesz połączyć się z procedurą tak jak, łączysz się z tabelą na serwerze SQL. Możesz jednak użyć
kwerendy przekazującej, aby uzyskać te same możliwości. Kwerenda przekazująca to wyrażenie SQL wysłane do
przetworzenia przez serwer SQL. Silnik Jet nie przetwarza takiego wyrażenia, a Access otrzymuje od serwera wyniki.
Kwerendy przekazujące umożliwiają wykorzystanie całej mocy obliczeniowej serwera bazy danych.
Tworzenie procedur przechowywanych wykracza poza ramy tej książki, jednak jeżeli utworzysz widok w projekcie ADP
(zajrzyj do rozdziału 15.), możesz skopiować wyrażenie z okna podglądu SQL i wstawić je do procedury przechowywanej.
Wydruk 16.1 przedstawia przykład procedury przechowywanej z bazy danych NorthWind, która zwraca informacje o
zamówieniach z zadanego zakresu dat. Wydruk 16.1 tworzy procedurę przechowywaną sp_OrdersByDate, która wymaga
dwóch argumentów, @StartDate i @EndDate.
Uruchomienie procedury przechowywanej jest proste. Logujemy się do bazy danych i wpisujemy polecenie EXECUTE w
oknie SQL. Jeżeli procedura wymaga parametrów, należy je podać. Aby uruchomić procedurę sp_OrdersByDate
(wydruk 16.1) za pomocą narzędzia SQL Server T/SQL, powinieneś wpisać takie polecenie:
Execute sp_OrdersByDate @StartDate='07/01/94' , @EndDate='09/30/94'
Wynik działania procedury sp_OrdersByDate pokazany jest na rysunku 16.5. Procedura ta zwraca zamówienia klientów
uporządkowane według dat wraz z wartością każdego zamówienia.
Rysunek 16.5.
Wynik działania
procedury
przechowywanej
Rysunek 16.6.
Tworzenie kwerendy
przekazującej
Nie możesz używać tabeli QBE do tworzenia kwerend przekazujących, musisz wpisywać wyrażenie SQL bezpośrednio do
okna SQL. Należy używać składni SQL zgodnej ze składnią bazowego serwera (w tym rozdziale używamy składni
Microsoft SQL Server 6.5, ale będziemy musieli użyć innej w rozdziale 17. „Interfejs Accessa 2000 do Oracle”, w którym
zajmiemy się bazą Oracle).
Po wpisaniu wyrażenia SQL musisz utworzyć ciąg połączeniowy ODBC. Ciąg ten „mówi” Accessowi, do której bazy
danych ma wysłać wyrażenie SQL. Należy otworzyć okno właściwości i ustawić właściwość Ciąg połączenia ODBC. W
Accessie dostępny jest konstruktor uruchamiany przez naciśnięcie przycisku „...” obok pola właściwość. Możesz samemu
wpisać prawidłowy ciąg połączenia lub uruchomić konstruktor i wybrać właściwe źródło danych ODBC z zainstalowanych
w systemie, tak jak pokazane jest na rysunku 16.7.
Zapisz kwerendę przekazującą jako qsptOrdersbyDate. Zauważ, że kwerenda przekazująca ma inną ikonę niż normalna
kwerenda (jak widać na rysunku 16.8).
Rysunek 16.7.
DSN zainstalowane
w systemie
Część V ♦ Access i architektura klient-serwer 286
Rysunek 16.8.
Zapisana kwerenda
przekazująca
Można tworzyć raporty na wiele sposobów. Najprostszą metodą jest połączenie tabeli ODBC i utworzenie kwerendy w
Accessie jako bazy dla raportu. Mimo że jest to najszybszy sposób stworzenia raportu, nie jest polecany ze względów
opisanych dalej w tym rozdziale.
Zwykle komputery, które służą za serwery baz danych SQL, są dużo szybsze i posiadają więcej pamięci RAM niż średni
komputer w biurze. Prześledzę sposoby na zwiększenie wydajności raportów klient-serwer, aby w pełni skorzystać z mocy
serwerów, na których zainstalowana jest baza danych.
Kolejne przykłady będą oparte o przykładową bazę danych „NorthWind” dostarczaną z SQL Server.
Aby uruchomić raport oparty na kwerendzie przekazującej, uruchom Kreator raportów i wybierz kwerendę przekazującą
qsptOrdersbyDate. Utwórz teraz taki raport, jaki potrzebujesz. Przykład gotowego raportu pokazywany jest na rysunku
16.9. Zapisz gotowy raport jako qsptOrdersbyDate.
Rysunek 16.9.
Raport oparty
o procedurę
przechowywaną
Zaawansowane możliwości:
przekazywanie parametrów do procedury przechowywanej w czasie
działania programu
Jesteś przyzwyczajony do tworzenia kwerend z parametrami na potrzeby raportów w Accessie, które wymagają podania
przez użytkownika dat lub innych wartości. W Accessie, jeżeli użyjesz pola formularza w warunku kwerendy, możesz zapytać
użytkownika o parametr, jak jest to pokazane na rysunku 16.10. Przy użyciu procedur musisz powtórnie utworzyć
polecenie Execute z nowymi parametrami wewnątrz kwerendy przekazującej qsptOrdersbyDate za każdym razem, gdy
287 Rozdział 16. ♦ Tworzenie interfejsu użytkownika dla Microsoft SQL Server
uruchamiasz raport. Na formatce służącej do wprowadzania parametrów, pokazanej na rysunku 16.10, oprogramowane jest
zdarzenie Click tak, aby ustawić właściwą postać wyrażenia Execute w kwerendzie i uruchamia procedurę z nowym
zakresem dat. Kod, który to realizuje, zamieszczony jest na wydruku 16.2. Zauważ, że potrzebujesz odwołania do DAO 3.6
w aplikacji. Aby ustawić to odwołanie, otwórz główny moduł i z głównego menu w edytorze VBE wybierz Tools|References. W
oknie dialogowym zaznacz bibliotekę DAO 3.6 Object Library.
Rysunek 16.10.
Formularz
pobierania
parametrów
do uruchomienia
raportu
Set db = CurrentDb
Db.QueryDefs("qsptOrdersbyDate").SQL = strSQL
DoCmd.OpenReport "qsptOrdersbyDate", acViewPreview
Click_Exit:
Exit Sub
Click_Err:
MsgBox Err.Description
Resume Click_Exit
End Sub
End Function
Dim db DAO.Database
Dim strSql As String
Część V ♦ Access i architektura klient-serwer 288
Click_Exit:
Exit Sub
Click_Err:
MsgBox Err.Description
Resume Click_Exit
End Sub
I na koniec niezłym pomysłem jest drukowanie w nagłówku raportu informacji o filtrze oraz jego wartości. Dodatkowo
powinieneś ostrzegać użytkownika o pustym raporcie za pomocą zdarzenia raportu NoData. Fragment programu, który to
realizuje, jest na wydruku 16.4.
Formularze w aplikacji
Formularze są zwykle centralną częścią aplikacji Accessa. Nie inaczej jest, gdy używasz Accessa jako interfejsu do serwera
SQL. Możesz użyć formularzy w dwóch trybach – związanym i niezwiązanym.
Formularze związane
Jest możliwe oparcie formularzy na procedurach przechowywanych, jednak wtedy możliwy jest tylko odczyt. Jeżeli Twoi
użytkownicy są przyzwyczajeni do formularzy związanych, a ty chcesz użyć ich zamiast tabel połączonych, to nie ma nic
do zrobienia, poza napisaniem zapytania, które ograniczy ilość rekordów wyświetlanych na formularzu. Używając
formularza związanego opartego na procedurze przechowywanej i zapytaniu przekazującym powinieneś zmieniać parametry
procedury przed otwarciem formularza (identycznie jak na wydruku 16.2). Jeżeli masz dużą ilość danych lub chcesz modyfi-
kować dane, użyj ADO i formularzy niezwiązanych w sposób opisany w następnych częściach tego rozdziału.
289 Rozdział 16. ♦ Tworzenie interfejsu użytkownika dla Microsoft SQL Server
Formularze niezwiązane
Gdy używasz formularzy związanych, tracisz sporo czasu na ich obsługę, szczególnie w wypadku dołączonych tabel. W
czasie obsługi dołączonych tabel Jet musi zarządzać komunikacją ODBC. Dodatkowo tworzone są połączenia do bazy
oddzielnie do każdego formantu, co zużywa sporo czasu i pamięci na obsługę. Dobrą alternatywą jest zastosowanie
formularzy niezwiązanych. W niezwiązanych formularzach możesz zapytać użytkownika o klucz główny lub inną szukaną
wartość, a następnie otworzyć zestaw rekordów w ADO i wypełnić pola edycyjne znalezionymi wartościami, tak jak
pokazane jest na rysunku 16.11.
Rysunek 6.11.
Formularz
niezwiązany
Możesz wypełnić listę rozwijalną za pomocą kwerendy przekazującej opartej na procedurze przechowywanej i użyć kodu
przedstawionego na wydruku 16.5 do obsługi zdarzenia After Update.
DoCmd.Hourglass False
Proc_Exit:
DoCmd.Hourglass False
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Gdy zaczniesz tworzyć niezwiązane formularze, będziesz chciał zmieniać, kasować dane oraz wykonywać inne operacje w
ADO. Poniżej opiszemy, jak używać ADO oraz OLE DB dla serwera SQL.
Część V ♦ Access i architektura klient-serwer 290
With conn
.Provider = "SQLOLEDB"
.ConnectionString = "data source=(local);" & _
"user id=sa;initial catalog=NorthWindCS"
.Mode = adModeRead
.Open
End With
With cmd
.CommandText = strSQL
.ActiveConnection = conn
.CommandType = adCmdText
End With
Set rst = cmd.Execute
Debug.Print rst!OrderDate
rst.MoveNext
Loop
rst.Close
conn.Close
Długa droga
Najlepiej rozpocząć od najbardziej pracochłonnej metody wykonywania procedur. Chociaż nikt nie będzie chciał pracować
w taki sposób, można nauczyć się kilku rzeczy. Po pierwsze, docenisz inne metody wykonywania procedur, a po drugie,
zrozumiesz zależności pomiędzy obiektami Connection, Command i Parameter, których będziesz używał w swoich
programach. Aby uruchomić polecenie z parametrem, musisz utworzyć obiekt Command i Parameter, a następnie
dołączyć obiekt Parameter do Command (patrz wydruk 16.8).
' Zakończenie
rst.Close
conn.Close
Set rst = Nothing
Set conn = Nothing
Set cmd = Nothing
Set prm = Nothing
End Sub
' Zakończenie
rst.Close
conn.Close
Set rst = Nothing
Set conn = Nothing
Set cmd = Nothing
End Sub
Użycie Refresh
Użycie metody Refresh ze zbioru parametrów obiektu Command jest bardzo podobne do użycia metody
CreateParameter, poza tym, że nie musisz tworzyć żadnego obiektu parametru. Zamiast tego, po podłączeniu do bazy
ustawiasz obiekt Command na procedurę przechowywaną i odświeżasz zbiór parametrów. Operacja ta zwróci zbiór
parametrów gotowych do wypełnienia. Metoda ta pozwala na dużą elastyczność (można tworzyć ogólne obiekty poleceń),
jednak na razie na 100 procent działa jedynie z SQL Server 7.0. Używając SQL Server 6.5, napotkałem kilka problemów,
które spowodowały, że poczekam z użyciem Refresh na następne wersje ADO. Nawet mimo tych ograniczeń powinieneś
293 Rozdział 16. ♦ Tworzenie interfejsu użytkownika dla Microsoft SQL Server
poznać składnię i sposób użycia metody Refresh do użycia z SQL Server 7.0 i kolejnymi wersjami ADO. Ważną rzeczą,
o której należy pamiętać, jest to, że program wykonuje dodatkowe operacje na bazie danych w czasie wykonania metody
Refresh, aby odczytać informacje o parametrach. Mimo prostoty użycia należy zawsze sprawdzić wydajność tego
rozwiązania.
' Zakończenie
rst.Close
conn.Close
Set rst = Nothing
Set conn = Nothing
Set cmd = Nothing
End Sub
Po wykonaniu polecenia możesz odczytać wartość zwracaną z zestawu parametrów, po użyciu metody Refresh (popatrz
poprzedni akapit), identyfikując ją przez numer kolejny wartości zwracanej, tak jak tutaj:
cmd.Parameters(0).Value
cmd.Execute
MsgBox "Wartość zwracana: " & cmd.Parameters(0).Value
conn.Close
Set conn = Nothing
End Sub
Gdy programujesz w ADO, powinieneś przyzwyczaić się do korzystania z klasy Connection. Na podstawie tej ogólnej
klasy tworzy się obiekt połączenia ADO. Gdy cały kod odpowiedzialny za dostęp do danych opiera się na tej szczególnej
klasie tworzącej połączenie do bazy, musisz utrzymywać małe fragmenty kodu odpowiedzialne za informacje o połączeniu.
W tym rozdziale utworzysz prostą klasę DBConnection, która będzie miała jedną publiczną metodę, Connect. Connect
jest prostą funkcją VBA, która zwraca obiekt ADO Connection. Funkcja zamieszczona na wydruku 16.12 tworzy obiekt
ADO Connection i ustawia wartość zwracaną na utworzony obiekt (Klasa Connection jest bardzo prosta. Możesz
rozszerzyć ją tak, aby używała pliku UDL, jak jest opisane w rozdziale 7. „Zaawansowane ADO”).
End Sub
Rozdział 17.
Interfejs Accessa 2000
do Oracle'a
W tym rozdziale:
u Dostęp do danych Oracle'a przez Accessa
u Funkcje w Oracle'u i Accessie
u Poznajemy widoki i procedury przechowywane
u Tworzenie niezwiązanego interfejsu do Oracle'a
Na przekór dominacji Oracle'a w aplikacjach tworzonych w Accessie jest mało publikacji na temat ich współpracy. W
rozdziale tym chcę wypełnić tę lukę.
Mimo że nowe projekty ADP zapewniają możliwość tworzenia wyrafinowanych aplikacji klient-serwer, w wielu
przypadkach musisz użyć bogatego środowiska programowania zwykłej aplikacji Accessa. Na przykład w wypadku, gdy
tworzysz prototyp aplikacji lub chcesz skorzystać z możliwości zarządzania heterogenicznymi danymi.
Oracle jest wyjątkowo potężną i wyrafinowaną bazą danych, więc w tym rozdziale nie możemy przedstawić wszystkich
niuansów i jej złożoności. Mimo to, poprzez poznanie prostych technik i wytycznych, możesz wyzwolić jej siłę bez
specjalnych kłopotów.
Zasadniczo, dobre programowanie Access/Oracle wymaga użycia mechanizmów Oracle'a i pozwolenia mu na zarządzanie
danymi, ponieważ właśnie to robi świetnie. Może to brzmi dziwnie, ale w praktyce nie jest to tak proste do zrealizowania.
Wielu programistów Accessa zostało zobligowanych do użycia Oracle'a w swoich aplikacjach i często nie inwestują zbyt
wiele czasu w udoskonalanie struktury bazy danych, tak jak robią to przy projektowaniu dla Accessa. Często muszą
używać mniej optymalnych struktur danych lub hurtowni danych. Dodatkowo, wielu programistów Accessa uważa się za
zwolnionych z użycia w swoich aplikacjach czegokolwiek więcej z Oracle'a, niż ODBC i konto użytkownika. W rozdziale
tym prześledzimy sposoby ominięcia takich wyzwań, jak również użycia podstawowych narzędzi Oracle'a, które
niewielkim nakładem pracy mogą Ci służyć.
Tabele połączone
Ponieważ w Accessie bardzo prosto tworzy się tabele połączone pochodzące z wielu źródeł danych, większość danych
Oracle'a pochodzi z tych właśnie tabel. Tabele połączone używają ODBC, pomimo tego, że podstawowym modelem
dostępu do danych w Accessie 2000 jest ADO. Powoduje to konieczność instalowania na komputerze zarówno
sterowników ODBC, jak i ADO.
Poprzez ODBC możesz: połączyć się do bazy, pracować z tabelami, widokami i procedurami oraz wysyłać do wykonania
wyrażenia SQL.
Każda część ciągu może być opuszczona, więc jeżeli ciąg nie będzie zawierał potrzebnych informacji, użytkownik będzie
musiał je podać.
Tabela 17.1.
Składniki ciągu połączeniowego ODBC
Składnik Opis
DSN Nazwa źródła danych
UID Nazwa użytkownika
PWD Hasło
Database Jeśli nazwa DSN nie jest nazwą bazy, należy tutaj wpisać nazwę bazy
APP Nazwa aplikacji używającej połączenia
Rysunek 17.1.
Wpisywanie
informacji o DSN
i używać go w aplikacji. Access zajmie się tym, jeżeli połączysz tabelę z Oracle'em. Trzyma on wtedy otwarte połączenie,
a Ty możesz go użyć poprzez obiekt Table. Rysunek 17.2 przedstawia, jak można na podstawie tabeli połączonej
zbudować kwerendę.
Rysunek 17.2.
Buduj kwerendy
na tabelach
połączonych
identycznie jak na
tabelach lokalnych
Lecz takie podejście jest kosztowne. Gdy uruchamiasz kwerendę na tabeli połączonej, Twoje zapytanie SQL jest zapisane
w Accessie, więc Oracle nie wie nic o nim. Sterownik ODBC i Jet muszą zanalizować wyrażenie. Sterownik ODBC
analizuje kwerendę i może wysłać przetworzony fragment Twojego zapytania do Oracle'a, zwykle przetwarzając jedną
tabelę. Zwykle kończy się to tym, że Oracle wysyła ogromne ilości danych przez sieć do komputera klienta, gdzie są one
przetwarzane przez Jet. Ponieważ Jet jest jedyną częścią tego łańcucha, która rozumie naszą kwerendę, całe przetwarzanie
odbywa się na komputerze klienta. Może być to niezbędne od czasu do czasu, ale nie jest to działanie prawdziwego
systemu klient-serwer.
Jeżeli chcesz przeglądać dane lub analizować strukturę tabel, a nie masz narzędzi Oracle'a, tworzenie tabel połączonych
jest dobrym sposobem. Łączenie jest również dopuszczalne, jeżeli chcesz dostać dane, które pozostaną w lokalnej tabeli,
lub chcesz zadać pytanie do danych pochodzących z wielu źródeł danych (kwerenda heterogeniczna). Jednak, jeżeli
zadajesz homogeniczne pytanie do danych Oracle'a, powinieneś pomyśleć o innym podejściu.
W czasie wykonania, Access wysyła to wyrażenie SQL bezpośrednio do Oracle'a poprzez połączenie ODBC. Jet nie jest
zaangażowany w jego wykonanie. Oracle odbiera to wyrażenie i po wykonaniu odsyła wynik (jeśli istnieje) do klienta.
Powinieneś zawsze sprawdzić, czy zastosowanie kwerend SPT ulepszy Twoją aplikację.
Oracle nie wymaga zakańczania wyrażenia średnikiem, gdy tworzymy kwerendę przekazywaną, mimo że jest on
wymagany w trakcie wykonywania zapytań z programu SQL Plus. Średnik na końcu wyrażenia SQL spowoduje błąd.
Nie można używać nawiasów kwadratowych do identyfikacji nazw tabel i kolumn. Ich użycie spowoduje błąd.
Mimo że Access zmienia kropkę z SCOTT.EMP na podkreślenie w SCOTT_EMP w trakcie łączenia tabeli, musisz
użyć separatora Oracle, którym jest kropka.
Wielkość liter
Wyrażenia SQL w Oracle'u mogą być pisane zarówno dużymi, jak i małymi literami oprócz porównywanych w frazie
Where wartości. Poniższe dwa wyrażenia są takie same:
Select eName, job FroM eMP
SELECT ENAME, JOB FROM EMP
Wyrażenie Select
Słowo kluczowe Select działa tak samo jak w Accesie. Select wskazuje bazie Oracle, które pola (kolumny) zwrócić
jako wynik. Nazwy kolumn wymienione po słowie Select muszą istnieć w tabelach wymienionych w następnej klauzuli
From.
SELECT ename, job, hiredate ...
Tabele lub widoki użyte w kwerendzie są wymieniane w klauzuli From, identycznie jak w Accessie. Również identycznie
jak w Accessie kolejność tabel w liście nie wpływa na wynik zapytania.
Select ename, job, hiredate FROM emp
Klauzula WHERE
Klauzula Where sprawia większości programistom Accessa sporo problemów na początku pracy z bazą Oracle, ponieważ
skupia się tutaj większość różnic pomiędzy SQL Accessa i SQL Oracle. W Oracle'u klauzula Where nie tylko ogranicza
ilość rekordów zwracanych przez serwer, jak to jest w Accessie, ale także definiuje zależności pomiędzy tabelami i
widokami użytymi w zapytaniu.
W tych przykładach znajomych dla większości programistów Accessa klauzula Where ogranicza rekordy w wyniku:
Select * from Emp WHERE mng=7698
Select * from EMP WHERE HIREDATE between '1/1/1990' and '1/1/1995'
Select * from EMP WHERE ename like 'M%'
Definiowanie zależności
Gdy w kwerendzie występuje więcej niż jedna tabela, klauzula Where w Oracle'u definiuje zależności.
SELECT emp.ename, dept.dname
FROM emp, dept
WHERE (emp.deptno=dept.deptno) AND (emp.ename like 'M%')
Pokazane powyżej wyrażenie zwraca rekordy, które mają te same wartości po obu stronach relacji zdefiniowanej przez
pola podane w klauzuli Where (emp.deptno=dept. deptno). Aby zwrócić rekordy, które nie są reprezentowane z obu
stron relacji, musisz utworzyć połączenie typu outer join. W Oracle'u połączenie takie tworzy się poprzez wstawienie znaku
(+) po tej stronie relacji, która będzie zwracała wartości null, gdy nie ma odpowiadającej wartości. Dobrze jest zapamiętać,
że wstawia się znak (+) po tej stronie, która zawierać będzie dodatkowe puste pozycje. Wyrażenie poniżej zawiera
połączenie typu outer join z lewej strony relacji. Wyświetli ono wszystkich pracowników, którzy mają przypisaną lub nie
nazwę oddziału.
SELECT emp.ename, dept.dname
FROM emp, dept
WHERE emp.deptno(+)=dept.deptno
Relacje w Oracle'u mogą być zapisywane jako wyrażenia. Nie jest to możliwe w Accessie. Użycie wyrażeń w relacjach nie
jest częste. Może być to potężne narzędzie, gdy pracujemy na nieoptymalnych strukturach danych lub w danych występują
szczególne zależności, co zdarza się w hurtowniach danych. Wyrażenie SQL poniżej przedstawia sposób użycia wyrażenia
w relacji.
Select emp.ename, dept.dname
From emp, dept
Where (emp.deptno=dept.deptno+10)
Jednak Access dopuszcza klauzulę Values tak samo jak Oracle (patrz poniżej), ale musisz ją wpisać samemu.
Zwróć uwagę jak w Oracle'u używa się To_Date(), aby sprawdzić, czy wpisana data jest prawidłowa. Więcej o tej i
innych funkcjach Oracle'a napisałem w dalszej części rozdziału.
Wersja dla Oracle'a jest prostsza od wersji Accessa o kilka nawiasów. Ponieważ ODBC wysyła ciąg ODBC bezpośrednio
do tabel użytkownika Scott, nie ma potrzeby kwalifikować nazw tabel nazwą użytkownika.
UPDATE emp
SET SAL = 7000
WHERE empno=9999
Podczas wykonania powyższego wyrażenia Oracle pobierze wszystkie rekordy z wartością pola deptno różną od 10 i
grupuje je według pola wymienionego w operacji GROUP BY. Na koniec Oracle przeszukuje rezultat i odrzuca rekordy,
których liczba (count(*)) jest większa od 6. Jedyną różnicą pomiędzy tym wyrażeniem SQL a wyrażeniem w SQL
Accessa jest występowanie nawiasów.
W dalszej części rozdziału zrobimy przegląd niektórych, najczęściej używanych funkcji Oracle'a, które możesz użyć w
kwerendach przekazujących.
Wiele z funkcji udostępnianych przez Oracle jest bardzo podobnych do funkcji operujących na ciągach w Accessie. Poniżej
przedstawię funkcje, które nie istnieją w Accessie, lub działają inaczej niż podobne do nich. Aby uzyskać pełną listę
funkcji, sięgnij do dokumentacji Oracle'a.
Część V ♦ Access i architektura klient-serwer 302
Ciągi
Większość typów danych, z którymi się spotykasz, to ciągi lub takie, które da się zamienić na ciągi. Zwykle będziesz chciał
przeszukiwać ciągi znaków, analizować je, zmieniać wielkość liter, łączyć lub inaczej mówiąc zmieniać je tak, aby
pasowały do twoich formularzy i raportów. W tej części opiszę niektóre z powszechnie używanych operacji na ciągach
znaków, które będziesz chciał wykonać w Oracle'u.
Łączenie
Oracle łączy ciągi znaków przy użyciu dwóch pionowych kresek (||) w odróżnieniu od Accessa, w którym używa się
znaku & lub +. Poniższe wyrażenie przedstawia w jaki sposób, łączyć ciągi.
SELECT ename || deptno
FROM emp
Podobnie Upper i Lower zmienia wszystkie litery ciągu na odpowiednio wielkie i małe.
Select INITCAP(ename)
FROM emp
Zwróci następujący wynik:
INITCAP(ENAME)
----------
Jp
Allen
Ward
Jones
Martin
Blake
Clark
Scott
King
Turner
Adams
James
Ford
Miller
SELECT UPPER(ENAME)
FROM emp
Zwróci następujący wynik:
UPPER(ENAME)
----------
JP
ALLEN
WARD
JONES
MARTIN
BLAKE
CLARK
SCOTT
KING
TURNER
ADAMS
JAMES
FORD
MILLER
SELECT LOWER(ename)
FROM emp
Zwróci następujący wynik:
LOWER(ENAME)
----------
jp
allen
ward
jones
martin
blake
clark
scott
king
turner
adams
303 Rozdział 17. ♦ Interfejs Access’a 2000 do Oracle’a
james
ford
miller
Instr
Instr zwraca pozycję znaku, który podałeś jako argument i może być bardzo przydatna, jeżeli chcesz analizować ciągi,
poszukując przecinków lub spacji. Jeżeli poszukiwany znak nie występuje w ciągu, zwracana jest wartość 0. Funkcja
Instr jest wrażliwa na wielkość liter w odróżnieniu od Accessa.
u String – wymagany. Ciąg znaków lub odwołanie do ciągu, który chcesz przeszukać.
u Start – nieobowiązkowy. Pozycja, na której powinno się rozpocząć szukanie. Domyślnie jest to pierwsza
pozycja.
u Occurrence – nieobowiązkowy. Jeżeli chcesz znaleźć drugie lub trzecie wystąpienie parametru Set, wpisz 2 lub
3.
Popatrz na wyrażenie SQL, w którym nie podamy wystąpienia ani pozycji startowej:
Select ename, instr(ename, 'A') from emp
Wynik:
ENAME INSTR(ENAME,'A')
---------- ----------------
JP 0
ALLEN 1
WARD 2
JONES 0
MARTIN 2
BLAKE 3
CLARK 3
SCOTT 0
KING 0
TURNER 0
ADAMS 1
JAMES 2
FORD 0
MILLER 0
Gdy funkcja zostanie wywołana z parametrem Occurence równym 2, znajdzie drugie wystąpienie szukanego znaku.
Select ename, instr(ename, 'A') from enp
ENAME INSTR(ENAME,'A')
---------- ----------------
JP 0
ALLEN 0
WARD 0
JONES 0
MARTIN 0
BLAKE 0
CLARK 0
SCOTT 0
KING 0
TURNER 0
ADAMS 3
JAMES 0
FORD 0
MILLER 0
LTrim/RTrim
Access ma trzy funkcje do wycinania znaków z ciągu: LTrim(), aby usunąć znaki z lewej strony, Rtrim, aby usunąć
znaki z prawej strony oraz Trim, aby usunąć znaki z obu stron. Oracle ma tylko Ltrim i Rtrim. Jednak funkcje obcinające
znaki w Accessie i Oracle'u różnią się w inny, bardzo ważny sposób.
W Accessie funkcje te obcinają tylko spacje, w Oracle'u mogą obcinać dowolny zbiór znaków.
Możesz użyć funkcji LTrim/RTrim, aby usunąć słowo 'THE' z początku tytułów poprzez wykonanie następującego
wyrażenia:
Select LTrim(Title, '"THE ') from Books
Należy pamiętać, że funkcje RTrim/LTrim są niewrażliwe na wielkość liter i ignorują kolejność podanych znaków do
usunięcia. Oznacza to, że tytuły książek zostaną zmienione w sposób pokazany w tabeli 17.2.
Tabela 17.2.
Przed i po obcięciu funkcją LTrim
Przed Po obcięciu
The Great Access Book Great Access Book
How to Develop in Access Ow to Develop in Access
The Ethical Developer ical Developer
Access 2000 Development Unleashed Access 2000 Development Unleashed
Funkcje LTrim/RTrim nie zwracają uwagi na kolejność liter w zbiorze liter do usunięcia ani na to, że powtarza ją się kilka
razy (tak jak: THE ETH... w The Ethical Developer). Aby uzyskać prawidłowe wyniki powinieneś prawdopodobnie użyć
kombinacji tej funkcji z Instr, Substr i Decode, aby dostać wyniki, jakich naprawdę potrzebujesz.
Soundex
Od roku 1988 Census Bureau używa algorytmu klasyfikacji nazwisk, które są podobnie wymawiane (w języku
angielskim). Algorytm ten nazywany jest Soundex. Działa on przez pobranie pierwszej litery i przypisanie liczby do każdej
następnej spółgłoski. Różne spółgłoski mają przyporządkowane te same wartości (na przykład [T] i [D] są tłumaczone na
3), oparte o ich brzmienie. Proces ten jest powtarzany aż do skompletowania 4. cyfrowego kodu. Słowa, które mają za mało
spółgłosek – są uzupełniane zerami tak, aby wygenerować czteroznakowy kod. Samogłoski są odrzucane, chyba że jest ona
pierwszym znakiem w słowie. Kody Soundex wyglądają następująco:
Select ename, soundex(ename) from emp
ENAME SOUNDEX(ENAME)
---------- --------------
JP J100
ALLEN A450
WARD W630
JONES J520
MARTIN M635
BLAKE B420
CLARK C462
SCOTT S300
KING K520
TURNER T656
ADAMS A352
JAMES J520
FORD F630
MILLER M460
Soundex może być użyteczny do wyszukiwania nazwisk w listach lub tytułach. Wyrażenie SQL takie jak poniżej:
Select ename from emp where soundex(ename) like soundex('muller')
Funkcja Soundex nie interpretuje kontekstu znaków, więc niektóre wyniki mogą nie być intuicyjne na pierwszy rzut oka.
Słowa o różnej długości mogą sobie odpowiadać według tego algorytmu. Mimo tych niedogodności można go użyć do
przeszukiwania list wysyłkowych i książek telefonicznych.
Substr
Substr można porównać do funkcji Mid w Accessie. Oracle nie ma bezpośredniego odpowiednika funkcji Right() i
Left() znanych z Accessa. Tak jak funkcja Accessa Mid(), Substr() pobiera trzy argumenty:
u End – podana jawnie lub obliczona wartość reprezentująca ilość znaków po prawej stronie pozycji Start
możesz użyć funkcji Substr() w połączeniu z Instr(), aby rozdzielić nazwisko na osobne pola.
SUBSTR(CustomerName, INSTR(CustomerName, ', ')+2) = Alastair
SUBSTR(CustomerName, 1, INSTR(CustomerName, ', ')-1) = MacIntyre
W pierwszym wypadku Substr pobierze wszystkie znaki z ciągu, zaczynając od drugiego znaku po znaku „,” aż do końca
ciągu. Pozostawienie trzeciego argumentu pustego spowoduje, że funkcja przyjmie go równego długości całego ciągu. W
drugim przypadku funkcja zwróci wszystkie znaki od początku ciągu aż do znaku poprzedzającego przecinek.
Decode
Wielu programistów Accessa przyzwyczaiło się opierać na natychmiastowym porównaniu (IIf()) w swoich kwerendach.
Oracle nie dostarcza podobnie nazywającej się funkcji, można za to użyć podobnie działającej funkcji Decode.
Decode jest serią testów If/Then zakończonych przez Else. To oznacza, że jest to raczej konstrukcja typu Case Select
niż IIf().
DECODE( value, if1, then1, if2, then2, ..., else)
Poniższe wyrażenie SQL jest prostym przykładem użycia funkcji Decode do zamiany nazw miast na regiony, w których
leżą:
Select loc,
DECODE(loc, 'NEW YORK', 'MID-ATLANTIC', 'DALLAS', 'SOUTH', BOSTON', 'NEW ENGLAND', 'CHICAGO', 'MIDWEST',
'UNKNOWN') REGION
FROM dept
Wynik tej kwerendy przedstawia, w jaki sposób zostały pokazane regiony i w jaki sposób obsłużone zostało nieznane
miasto przez część Else funkcji Decode.
Select loc,
DECODE(loc, 'NEW YORK', 'MID-ATLANTIC', 'DALLAS', 'SOUTH', BOSTON', 'NEW ENGLAND', 'CHICAGO', 'MIDWEST',
'UNKNOWN') As REGION
FROM dept
LOC REGION
---------- ------------
NEW YORK MID-ATLANTIC
DALLAS SOUTH
CHICAGO MIDWEST
BOSTON NEW ENGLAND
SUMMIT UNKNOWN
Obliczenia w Oracle'u
Dopóki dobry projekt struktury bazy nie będzie przechowywać większości wyników obliczeń, nie będziesz mógł tworzyć
sensownych interfejsów lub raportów bez poznania funkcji matematycznych Oracle'a. Funkcje Oracle'a są bardzo podobne
do tych, które występowały w VBA lub Accessie. Rozdział ten wskaże kilka różnic pomiędzy funkcjami Oracle'a i
Accessa.
Ceil()
Ceil() nie ma odpowiednika w Accessie. Zwraca on najbliższą liczbę całkowitą większą lub równą wartości zadanej.
CEIL(34.2) = 35
CEIL( -2.4) = -2
Floor()
Floor() jest przeciwnością Ceil(), także nie mającą odpowiednika w Accessie. Funkcja zwraca najbliższą liczbę
całkowitą mniejszą lub równą wartości zadanej jako argument.
Floor(34.2) = 34
Floor( -2.4 ) = -3
Część V ♦ Access i architektura klient-serwer 306
Nvl()
Funkcja Nvl() jest funkcją podstawiania wartości i jest podobna do funkcji NZ() w VBA. Umożliwia ona
podstawienie zadanej wartości, gdy argument jest wartością null. Pomaga ona zapobiegać błędom matematycznym
spowodowanym przez podstawienie wartości null do obliczeń.
u Substitute – wymagana. Wartość zwracana przez funkcję, gdy Value będzie null.
NVL(wartość, podstawienie)
NVL(238, 15)=238
NVL(null, 15)=15
Round()
W Accessie przez długi czas brakowało funkcji Round(). W Accessie 2000 użytkownicy nareszcie mogą z niej skorzystać.
Funkcja ma dwa parametry:
u Value – wymagana. Wartość lub odwołanie do wartości do przetworzenia.
u Precision – nieobowiązkowa. Ilość miejsc po przecinku, do ilu będzie zaokrąglana liczba. Domyślnie przyjmowane
jest zero.
Sign()
Sign() działa dokładnie tak jak funkcja Accessa Sgn(). Zwraca ona 1 dla liczb dodatnich i -1 dla ujemnych.
Trunc()
Zamiast zaokrąglać liczbę w górę lub w dół, Trunc() po prostu obcina liczbę do żądanej długości. Funkcja posiada dwa
parametry:
u Value – wymagana. Wartość lub odwołanie do wartości do przetworzenia.
u Precision – nieobowiązkowa. Ilość miejsc po przecinku, do ilu będzie obcięta liczba. Domyślnie przyjmowane
jest zero.
Greatest/Least
Greatest i Least używane są, aby wybrać pomiędzy dwiema lub więcej wartościami. Mogą być one użyte do liczb,
ciągów lub dat. Gdy używane są do porównywania dat, jak w tym przykładzie poniżej, daty podawane w postaci tekstu
muszą być konwertowane przez funkcję To_Date(), w przeciwnym wypadku zostaną potraktowane jako ciąg znaków i
wynik funkcji nie będzie taki, jakiego się spodziewamy.
W przykładzie użyta jest funkcja Least, aby wybrać wcześniejszą z dat, tę zapisaną w polu Hiredate lub 1 stycznia 1985.
Funkcja Least wybierze wcześniejszą lub mniejszą wartość z podanych możliwości, podczas gdy Greatest wybierze
największą.
SELECT ENAME, LEAST(HIREDATE, TO_DATE('1-JAN-85')) FROM EMP
ENAME LEAST(HIREDATE)
---------- --------------
JP 01-JAN-85
ALLEN 20-FEB-81
WARD 22-FEB-81
JONES 02-APR-81
MARTIN 28-SEP-81
BLAKE 01-MAY-81
CLARK 09-JUN-91
SCOTT 01-JAN-85
KING 17-NOV-81
TURNER 08-SEP-81
ADAMS 01-JAN-85
JAMES 03-DEC-81
FORD 03-DEC-81
MILLER 23-JAN-82
307 Rozdział 17. ♦ Interfejs Access’a 2000 do Oracle’a
Obliczenia na datach
Nie ma prawdopodobnie typu danych, który sprawia więcej kłopotu niż daty. Poniżej opiszemy kilka funkcji, które operują
na datach.
Arytmetyka
Date jest typem danych zarówno w Oracle'u jak i w Accessie. Tak jak w Accessie daty zapisują więcej informacji niż to
jest widoczne. W Oracle'u kolumna typu Date przechowuje rok, miesiąc, dzień, godzinę, minutę i sekundę. Oznacza to, że
możesz przeprowadzać obliczenia na datach. Jednak w odróżnieniu od liczb, gdy dodasz liczbę do daty, otrzymujesz nową
datę. Gdy odejmujesz jedną datę od drugiej, otrzymujesz liczbę oznaczającą czas pomiędzy tymi dwiema datami. W
zależności od formatowania czas ten może wyglądać dowolnie, od lat po sekundy. Jest również możliwe, że liczba ta nie
jest liczbą całkowitą – identycznie jak w Accessie.
Sysdate
Funkcja Sysdate() sięga do systemu operacyjnego i zwraca bieżącą datę i czas.
Select SYSDATE FROM sys.Dual
Add_Months
Jeżeli pierwsza ocena pracownika powinna być po 6 miesiącach pracy, możesz użyć funkcji Add_Months, aby zaplanować
ocenę.
Często, gdy planujemy zdarzenia, potrzebujemy określonego czasu realizacji zdarzenia, aby zdążyć wykonać zakładane
czynności. Można uzyskać datę rozpoczęcia realizacji poprzez wstawienie liczby ujemnej do drugiego argumentu funkcji
Add_Months().
Months_Between
Aby policzyć odstęp czasu pomiędzy dwiema datami, możesz odjąć jedną od drugiej. Miesiące jednak mają różną ilość dni
i aby podać ilość miesięcy pomiędzy datami, musiałbyś wykonać sporo obliczeń. Funkcja Months_Between() zwraca
różnicę w miesiącach pomiędzy datami, biorąc pod uwagę, które miesiące leżą pomiędzy nimi.
Poniższe wyrażenie zamienia miesiące na lata poprzez podzielenie ich przez 12. Użyjemy również zaokrąglenia, aby
otrzymać czytelny wynik.
SELECT ename, hiredate, ROUND(MONTHS_BETWEEN(SYSDATE, hiredate)/12,2) "YEARS SERVICE" FROM emp
ENAME HIREDATE YEARS SERVICE
---------- --------- -------------
JP 27-JUL-97 1.56
ALLEN 20-FEB-81 17.99
WARD 22-FEB-81 17.99
JONES 02-APR-81 17.88
Część V ♦ Access i architektura klient-serwer 308
Next_Day()
Jeżeli jakieś zdarzenie ma miejsce danego dnia tygodnia przed lub po podanej dacie (jak większość kalendarzowych świąt,
niektóre święta religijne i dni wypłaty), można policzyć daty, kiedy będzie ono wypadnie. Funkcja Next_Day() może
pomóc w takich obliczeniach.
Poniższe wyrażenie przedstawia pierwsze dni wypłaty pracowników, zakładając, że dostają pieniądze w każdy piątek.
SELECT ename, hiredate, next_day(hiredate, 'Friday') "PAYDAY!"
FROM emp
ENAME HIREDATE PAYDAY!
---------- --------- ---------
JP 27-JUL-97 01-AUG-97
ALLEN 20-FEB-81 27-FEB-81
WARD 22-FEB-81 27-FEB-81
JONES 02-APR-81 03-APR-81
MARTIN 28-SEP-81 02-OCT-81
BLAKE 01-MAY-81 08-MAY-81
CLARK 09-JUN-81 12-JUN-81
SCOTT 19-APR-87 24-APR-87
KING 17-NOV-81 20-NOV-81
TURNER 08-SEP-81 11-SEP-81
ADAMS 23-MAY-87 29-MAY-87
JAMES 03-DEC-81 04-DEC-81
FORD 03-DEC-81 04-DEC-81
MILLER 23-JAN-82 29-JAN-82
To_Date()
Funkcja To_Date() przeznaczona jest do zamiany daty zapisanej w postaci ciągu na wewnętrzny format daty
rozpoznawany przez Oracle. Często będziesz jej używał w wyrażeniach Insert i Update. Bez niej nie byłbyś często w
stanie przeprowadzić obliczeń na datach.
u String – wymagany. Ciąg reprezentujący datę (np.: 'July 27, 1997'). Domyślnym formatem daty jest „DD-
MON-YYYY”.
u Format – nieobowiązkowy.
SELECT TO_DATE('27-jul-97', 'dd-mon-yyyy') "Data sformatowana" FROM sys.dual
Data sformatowana
-----------
27-JUL-1997
Poniższe dwa wyrażenia SQL przedstawiają jak Oracle przypisuje daty do bieżącego stulecia (stulecia daty uzyskanej przez
funkcję Sysdate()), gdy nie określimy sposobu konwersji.
SELECT MONTHS_BETWEEN('27-JUL-2001', '27-JUL-1997') FROM SYS.DUAL
MONTHS_BETWEEN('27-JUL-2001', '27-JUL-1997')
--------------------------------------------
48
Pracując z datami, można użyć maski „RR”, aby konwertować zapisany dwucyfrowo rok na postać czterocyfrową według
następujących zasad: jeżeli rok zawiera się w przedziale 0–49, zostanie przypisany do XXI wieku, natomiast pomiędzy 50
a 99 do wieku XX.
SELECT TO_CHAR(TO_DATE('000727', 'RRMMDD'), 'DD-MON-YYYY') RRMMDD,
TO_CHAR(TO_DATE('000727', 'YYMMDD'), 'DD-MON-YYYY') YYMMDD
FROM SYS.DUAL
RRMMDD YYMMDD
----------- -----------
27-JUL-2000 27-JUL-1900
Poznajemy widoki
i procedury przechowywane
Przesyłanie wyrażeń SQL do wykonania przez Oracle jest świetnym sposobem na zwiększenie wydajności i zmniejszenie
ruchu w sieci, lecz przechowywanie wyrażeń SQL w aplikacji nie jest najlepszym możliwym rozwiązaniem. Aby
uruchomić całą siłę Oracle'a, skorzystać z pracy wykonanej w bazie danych, zmniejszyć koszty dodatkowych prac,
zabezpieczyć swoją pracę i utrzymywać spójność danych, powinieneś użyć widoków i procedur przechowywanych.
Widok w Oracle'u jest to po prostu zapytanie zapisane na serwerze. Tak jak kwerenda Select zapisana w Accessie, jest on
skompilowany i posiada plan wykonania. Oznacza to, że będzie działać szybciej niż pytanie przesłane do wykonania przez
SPT.
Jest wiele zalet stosowania widoków. Można je wywoływać poprzez nazwę, która jest o wiele krótsza niż średnie
wyrażenie SQL, przez co zmniejsza się obciążenie sieci. Ponieważ widok zapisany jest w bazie danych, posiada on dodatkowy
poziom bezpie-
czeństwa, co jest ważne w aplikacjach, które są słabo chronione. Ponieważ Twoja aplika-
cja prawdopodobnie nie jest jedyną, która korzysta z bazy danych, możesz skorzystać z gotowych widoków, co oszczędza czas i
zapewnia spójność danych w różnych aplikacjach.
Widoki można tworzyć za pomocą Accessa lub korzystając z narzędzi Oracle'a. Aby utworzyć widok lub przeprowadzić
inną zmianę struktury bazy danych, użytkownik, który pracuje musi mieć nadane prawo Resource. Sprawdź, czy
posiadasz wystarczające uprawnienia, lub zapytaj o to administratora bazy danych.
W tym rozdziale zajmujemy się dostępem do Oracle'a z Accessa, więc wszystko, co opiszę, można wykonać za pomocą
Accessa. Jeżeli jednak chciałbyś użyć SQL Plus lub innego narzędzia Oracle'a, sprawdź w dokumentacji jak ich używać.
Tworzenie widoków
Widok jest po prostu wyrażeniem SQL, które zwraca rekordy. Ponieważ widok jest częścią struktury bazy danych, może
być tworzony, zmieniany, używany lub usuwany za pomocą poleceń SQL.
Możesz utworzyć je w Accessie i uruchomić jako kwerendę przekazującą lub możesz utworzyć widok w Oracle'u i
wywołać ten widok.
Aby utworzyć widok z Accessa, utwórz kwerendę przekazującą, zawierającą wyrażenie definicji danych (DDL).
Wyrażenie takie rozpoczyna się słowami kluczowymi Create, Alter, Drop itd. Aby utworzyć widok, powinieneś użyć
następującej składni:
Create [or Replace]
View
[Nazwa widoku]
AS
[wyrażenie SQL zwracające rekordy]
Aby stworzyć widok z poprzedniego wyrażenia SQL, powinieneś użyć poniższego wyrażenia DDL uruchomionego przy
użyciu SPT:
Część V ♦ Access i architektura klient-serwer 310
Klauzula Or Replace powoduje, że nie zostanie wyświetlony błąd, gdy widok MyView już istnieje. Prawdopodobnie nie
będziesz chciał zawsze dołączać klauzuli Or Replace, ponieważ bardzo łatwo wtedy omyłkowo zmienić definicję już
istniejącego widoku.
Wykonanie tej kwerendy utworzy widok, który zwraca wszystkie kolumny z tabeli emp, których wartość pola sal jest
większa od 3000.
Aby sprawdzić, czy widok został prawidłowo utworzony, możesz podłączyć ją do Accessa, jak gdyby była to zwykła
tabela. Możesz również użyć go w dowolnym wyrażeniu SQL w kwerendzie przekazującej.
Select * from MyView
lub
Select MyView.ename, Dept.deptno from MyView, Dept
Where MyWiew.deptno=Dept.deptno
Utworzenie połączenia z Oracle'em pociągało zwykle za sobą wiele skomplikowanych wywołań API z ODBC lub RDO,
który jest podobnym do DAO interfejsem ODBC. Teraz mamy ADO i OLEDB, co zapewnia szybki, jednolity i elastyczny
interfejs do różnych źródeł danych, włączając w to Oracle.
Szczegółowy opis ADO i OLEDB znajduje się w rozdziale 6. „Wprowadzenie do obiektów danych ActiveX” i oraz w
rozdziale 7. „Zaawansowane ADO”.
W tej części rozdziału prześledzimy sposoby użycia ADO i OLEDB, aby połączyć się z bazą danych Oracle i wykonać
wyrażenia SQL.
Gdy używamy kwerend SPT, Oracle analizuje wyrażenia SQL i tworzy wynik. Oracle nie ma planu wykonania takiego
zapytania, więc czas jego wykonania może nie być optymalny. Ponadto, gdy kilka aplikacji używa takiego samego
zapytania lub procedury, musisz je zaprojektować i wstawić do wielu aplikacji. Lepszym podejściem jest utworzenie
widoku lub procedury przechowywanej na serwerze. Może być on dzielony pomiędzy wiele aplikacji, zapewniając za
każdym razem ten sam wynik. Ponieważ zarówno zapytanie tworzące widok, jak i procedura ma utworzony plan
wykonania, więc będzie wykonana z maksymalną możliwą wydajnością.
Omawialiśmy już, w jaki sposób utworzyć widok i procedurę przechowywaną przez użycie kwerend SPT. Wyrażenie SQL
jest takie samo, ale użycie kodu ADO do zestawienia połączenia i utworzenia widoku lub procedury przechowywanej jest
nieco inne.
Przykłady w tym rozdziale są napisane w oparciu o dostawcę „Oracle Native OLEDB” z firmy Microsoft. Dostawca ten
łączy z Oracle Call Interface (OCI), jednak w chwili obecnej nie wszystko, co da się zrobić za pomocą OCI, można
wykonać, używając dostawcy OLEDB. Większość potrzebnych rzeczy da się wykonać, wykorzystując istniejący zestaw
funkcji.
Program z wydruku 17.1 tworzy widok w Oracle'u, a później otwiera go i wyświetla jego zawartość w oknie debuggera.
cmd.ActiveConnection = conn
cmd.CommandType = adCmdText
311 Rozdział 17. ♦ Interfejs Access’a 2000 do Oracle’a
Create0racleView_Exit:
conn.Close
Set conn = Nothing
Set cmd = Nothing
Exit Function
Create0racleView Err:
' Błąd
Create0racleView = False
' Sprawdź, który błąd wystąpił przeszukując tablicę błędów
With conn
For i = 0 To .Errors.Count - 1
errDesc = errDesc & .Errors(i).Description & Chr(13)
Next
End With
' Powiadom użytkownika
MsgBox "Wystąpił błąd: " & errDesc
Resume Create0racleView Exit
End Function
Parametry
W Accessie programista może tworzyć kwerendy sparametryzowane, mają one jednak tylko podstawowy plan wykonania i
wykonują się w oparciu o ten plan z różnymi wartościami parametrów. Niestety Oracle nie udostępnia parametrów widoku
poprzez dostawcę OLEDB. Alternatywą jest zmiana istniejącego widoku, tak jak pokazaliśmy powyżej. Można również
użyć obiektu polecenia z OLEDB, aby utworzyć i dostarczyć parametry do wyrażenia SQL.
Głównymi zaletami procedur przechowywanych są ich szybkość, niezawodność i bezpieczeństwo. Mogą one być użyte do
wymuszania reguł biznesowych, kontroli poprawności i zapewnienia transakcyjności. Najważniejszą wadą procedur jest
sposób ich tworzenia i uruchamiania. Oracle nie dostarcza środowiska programowania podobnego do środowiska Accessa,
przez to tworzenie i edycja procedur przechowywanych jest trudna. Oracle 8 dostarcza program zarządzania strukturą bazy,
który umożliwia tworzenie i kontrolę poprawności procedur, jednak wciąż nie jest to idealne rozwiązanie. Dodatkowo z
racji tego, że procedury są zależne od serwera bazy danych, gdy zmieniasz serwer, musisz również zmienić procedury
przechowywane.
Architektura wielowarstwowa została tak zaprojektowana, aby ograniczyć tę niedogodność. Nie ma żadnego powodu, aby
umieszczać całą skomplikowaną logikę aplikacji na serwerze (tak samo jak nie ma powodu, aby umieszczać ją na kliencie),
dzięki temu procedury przechowywane są dużo prostsze od innych obiektów zapewniających logikę biznesową i inne
operacje.
Aby tworzyć procedury w swojej przestrzeni tabel bazy danych, trzeba posiadać prawo systemowe Create Procedure, które
jest częścią roli Resource. Aby utworzyć procedurę w innej przestrzeni tabel, musisz posiadać prawo Create Any
Procedure. Porozmawiaj z administratorem bazy, jeżeli nie jesteś pewien, jakie posiadasz uprawnienia.
Procedura wstawiająca rekord do tabeli z dwoma polami przedstawiona jest na wydruku 17.3.
Po utworzeniu procedury może być ona wywoływana poprzez kwerendę SPT lub VBA.
313 Rozdział 17. ♦ Interfejs Access’a 2000 do Oracle’a
Uruchamianie procedury
Wywołanie procedury z kwerendy SPT jest nieco inne niż wywołanie widoku:
{call MyStoredProcedure }
Nawiasy klamrowe udają składnię, jakiej spodziewa się Oracle, używając Oracle call interface, używanego przez dostawcę
OLEDB.
Wykonywanie procedury z VBA poprzez dostawcę OLEDB dla Oracle'a wygląda nieco inaczej. Funkcja przedstawiona na
wydruku 17.4 korzysta z tego, że procedury ujawniają swoje parametry w sposób, który może być użyty w VBA. Podając
nazwę procedury przechowywanej, nazwę tabeli, do której chcesz wstawić rekord i wypełniając wymagane argumenty w
tablicy paramArray uruchamianej funkcji, możesz uruchomić większość procedur przechowywanych za pomocą funkcji
przedstawionej na wydruku 17.4.
With conn
.Provider = "MSDAORA"
.ConnectionString = "Data Source=empexample;_
User ID=Scott;password=Tiger"
.Open
End With
cmd.ActiveConnection = Conn
cmd.CommandType = adCmdStoredProc
cmd.CommandText = ProcName
For i = 0 To UBound(ParamArgs())
With cmd.Parameters(i)
.Type = adChar
.Direction = adParamInput
.Value = ParamArgs(i)
End With
Next
cmd.Execute
Set rs = Nothing
conn.Close
RunOracleStoredProcedures = True
End Function
Wykonywanie wielu prostych procedur przechowywanych umożliwia tworzenie złożonej logiki w znanym środowisku
VBA, korzystając z jego zaawansowanych możliwości uruchamiania kodu i obsługi błędów.
jak na przykład Visual Basic. Przez to, że jesteś pewny, że przetwarzanie odbywa się na serwerze, możesz również uzyskać
lepszą wydajność.
W przedstawionym tu ćwiczeniu utworzymy prosty niezwiązany interfejs dla Oracle'a, który wygląda i zachowuje się
identycznie jak formularz związany. Aby pokazać elastyczność ADO, użyjemy wyrażeń SQL oraz metod obiektu
Recordset.
Formularz będzie wyświetlał rekordy tabeli EMP. Użytkownik będzie mógł wstawiać i usuwać rekordy z bazy danych
Oracle. Można będzie zmieniać rekordy w tabeli bez konieczności każdorazowego zapisywania zmienionego rekordu.
Rysunek 17.3.
Formularz z danymi
w trybie
projektowania
Dla uproszczenia, nazwy obiektów ekranowych odpowiadają nazwom pól w tabeli EMP:
u Empno,
u Ename,
u Job,
u Mgr,
u Hiredate,
u Sal,
u Comm,
u Deptno.
u BtnGotoPrevious,
u BtnGotoNext,
u BtnGotoLast,
u BtnEdit,
u BtnNew,
u BtnDelete,
u BtnSave,
u BtnClose.
FillForm
EditRec = True
End Sub
Oracle nie zwraca obiektów typu Recordset, ale dostawca OLEDB przechwytuje wynik wyrażenia SQL i zwraca go do
programu jako Recordset. Dostawca OLEDB przykrywa wywołania Oracle Call Interface tak, że dla aplikacji nie ma
różnicy pomiędzy Oracle'em a innymi źródłami danych. Używając globalnej zmiennej Recordset, można szybko i łatwo
wypełnić formularz danymi pochodzącymi z pierwszego rekordu. Następnie procedura ustawia zmienną EditRec na
true, co wskazuje, że dane na formularzu są gotowe do edycji. Zdarzenie OnOpen wywołuje funkcję FillForm, która
zamieszczona jest na wydruku 17.6.
FillForm = True
FillForm_Exit:
Exit Function
FillForm_Err:
FillForm = False
Exit Function
End Function
rs.MoveFirst
If Not rs.BOF Then
FillForm
End If
CurrentContext Me
End Sub
Część V ♦ Access i architektura klient-serwer 316
rs.MovePrevious
If Not rs.BOF Then
FillForm
End If
CurrentContext Me
End Sub
rs.MoveNext
If Not rs.BOF Then
FillForm
End If
CurrentContext Me
End Sub
rs.MoveLast
If Not rs.BOF Then
FillForm
End If
On Error GoTo 0
CurrentContext Me
End Sub
Bieżący stan przycisków nawigacyjnych zależy od pozycji w zestawie rekordów wyniku. Funkcja CurrentContext, która
pobiera jako argument obiekt formularza, włącza oraz wyłącza przyciski nawigacyjne (wydruk 17.11).
bFirstRec = (rs.AbsolutePosition = 1)
bLastRec = (rs.AbsolutePosition = rs.RecordCount)
With frm
If Not bFirstRec And Not bLastRec Then
!btnGotoFirst.Enabled = True
!btnGotoPrevious.Enabled = True
!btnGotoLast.Enabled = True
!btnGotoNext.Enabled = True
GoTo CurrentContext_Exit
End If
If bFirstRec And bLastRec Then
!btnEdit.SetFocus
!btnGotoFirst.Enabled = False
!btnGotoPrevious.Enabled = False
!btnGotoLast.Enabled = False
!btnGotoNext.Enabled = False
GoTo CurrentContext_Exit
End If
If bFirstRec Then
!btnGotoLast.Enabled = bFirstRec
!btnGotoNext.Enabled = bFirstRec
!btnGotoLast.SetFocus
!btnGotoFirst.Enabled = Not bFirstRec
!btnGotoPrevious.Enabled = Not bFirstRec
GoTo CurrentContext_Exit
End If
If bLastRec Then
!btnGotoFirst.Enabled = bLastRec
!btnGotoPrevious.Enabled = bLastRec
!btnGotoFirst.SetFocus
317 Rozdział 17. ♦ Interfejs Access’a 2000 do Oracle’a
End Sub
' Próba zmiany pola przy użyciu metody update obiektu Recordset
rs.Update FieldName, NewValue
UpdateField_Exit:
Exit Function
UpdateField_Err:
' Błąd
UpdateField = False
Resume UpdateField_Exit
End Function
Funkcja UpdateField może być wywoływana przez każde zdarzenie AfterUpdate, gdy zaznaczymy wszystkie pola
tekstowe na formatce i wstawimy wyrażenie pokazane na wydruku 17.13. Alternatywą do zapisywania zmian natychmiast
może być buforowanie zmian i zapisywanie ich po przejściu do innego rekordu. Możesz także użyć wywołania przez ADO
procedury przechowywanej i przekazać do niej nowe wartości.
Teraz, gdy przechodzisz między rekordami i zmieniasz dane pracowników, zmiany zapisane będą w bazie po przejściu do
innego rekordu.
Należy jeszcze napisać procedurę czyszczącą formularz. Dla naszych celów, może ona być zapisana w standardowym
module poza formularzem. Funkcja ta jest niezwykle prosta (wydruk 17.15).
Aby przyciski nawigacyjne odzwierciedlały zawartość formularza w czasie przeglądania dostępnych rekordów, przypisz
kod zamieszczony na wydruku 17.18 do zdarzenia OnCurrent formularza.
Current0ontext Me
End Sub
DoCmd.Close
Exit_btnClose_Click_Exit:
conn.Close
Set conn = Nothing
Część V ♦ Access i architektura klient-serwer 320
Set rs = Nothing
Exit Sub
Err_btnClose_Click_Err:
MsgBox err.Description
Resume Exit_btnClose_Click_Exit
End Sub
Poprzez wprowadzanie innych obiektów Recordset, trwałych obiektów Recordset oraz przez użycie uproszczeń
dostawcy OLEDB dla Oracle Call Interface możesz utworzyć cały niezwiązany interfejs użytkownika do Oracle'a,
korzystając z szybkości działania, skalowalności i odporności Oracle'a w Twojej aplikacji Accessa.
Część VI
Współoperatywność
W tej części:
u Użycie automatyzacji ActiveX.
u Integracja z Office 2000.
u Użycie Visual Basic z Accessem.
Rozdział 18.
Użycie automatyzacji ActiveX
W tym rozdziale:
u Co to jest automatyzacja ActiveX.
u Dlaczego używamy automatyzacji.
u Odróżnienie serwera automatyzacji od klienta automatyzacji.
u Określanie zasobów wymaganych przez automatyzację.
u Wielka trójka.
u Tworzenie i ustanowienie odwołania do innej aplikacji.
u Przypisywanie zmiennej obiektowej do aplikacji.
u Tworzenie egzemplarza aplikacji.
u Użycie metod i właściwości obiektów automatyzacji.
u Zwalnianie obiektu automatyzacji.
u Łączymy wszystko razem.
u Zamykanie aplikacji serwera automatyzacji.
W obecnych czasach, częściej niż do tej pory, żąda się od programistów szybkiego tworzenia skomplikowanych aplikacji,
które są zintegrowane z innymi programami.
Szczęśliwie, używając automatyzacji ActiveX (dawniej zwanej OLE Automation), aplikacje mogą współpracować ze sobą,
tworząc kompletne rozwiązania informatyczne. Może to poważnie skrócić czas tworzenia programów, ponieważ zamiast
tworzenia jakiejś funkcji programista może połączyć się z innym programem i użyć jego opcji.
W tym rozdziale opiszę zasady i techniki użycia automatyzacji ActiveX. W rozdziale 19. „Integracja z Office 2000” opiszę,
jak użyć automatyzacji ActiveX w celu zintegrowania Accessa 2000 z resztą pakietu Office.
Nie ma powodów, abyś tworzył swój edytor tekstów lub arkusz kalkulacyjny do użycia w Accessie. Dużo prościej użyć
automatyzacji i niektórych technik opisanych w tym rozdziale, aby użyć w Twojej aplikacji Worda czy Excela. Umożliwia
to skupienie się na opcjach niedostarczonych przez inne programy, co będzie bardzo korzystne dla użytkowników.
Na przykład, jeżeli przycisk w Accessie uruchamia drukowanie listu w Wordzie, serwerem automatyzacji jest Word,
natomiast klientem jest Access.
Określanie zasobów
wymaganych przez automatyzację
Ponieważ jedna aplikacja za pomocą automatyzacji kontroluje inną, zostaną otwarte co najmniej dwa programy. Zawsze,
gdy uruchamiamy kolejną aplikację, potrzebna jest dodatkowa ilość pamięci oraz mocy procesora. Jakie zasoby sprzętowe
są wymagane, aby sterować Wordem z Accessa, jest bardzo subiektywną decyzją. Minimalną akceptowalną wydajność
zapewnia procesor Pentium II z 24 MB pamięci RAM. Oczywiście szybszy procesor może istotnie poprawić wydajność,
jednak duża ilość pamięci RAM jest bardziej pożyteczna niż moc procesora. Jeżeli wydajność programów używających
automatyzacji jest niewystarczająca, najpierw dodaj pamięć, a dopiero później wymieniaj procesor na lepszy.
Wielka trójka
Mamy trzy etapy użycia automatyzacji:
91. Pobranie obiektu Automation. Utworzenie nowego albo odwołanie się do już istniejącego.
Przykładowo, jeżeli chciałbyś wydrukować list lub raport w Wordzie z Accessa, pierwszym krokiem powinno być
utworzenie lub pobranie odwołania do aplikacji Word. Następnie używamy obiektów, właściwości i metod Worda (takich
jak otwarcie, edycja lub wydruk dokumentu). Po zakończeniu pracy należy zwolnić aplikację Word.
Po ustanowieniu odwołania do aplikacji możesz przeglądać jej obiekty, właściwości i metody, oraz używać ich.
Rysunek 18.1.
Okno dialogowe
odwołań
Obiekt jest elementem, który może być lub będzie użyty do programowania. W Accessie obiektami są formularze, pola
tekstowe, przyciski i tego typu elementy. Używając automatyzacji, inne aplikacje i ich obiekty mogą być programowane za
pomocą Accessa. Microsoft Office zawiera ponad 500 obiektów, które możesz używać w swoich aplikacjach. Przykładowo
Word udostępnia obiekt Document, a Excel obiekt Worksheet.
Właściwość jest charakterystyką obiektu. Właściwość może być rozumiana jako przymiotnik opisujący obiekt. W Accessie,
właściwościami pola tekstowego są: nazwa, widoczność, kolor i inne tego typu cechy. Analogicznie, gdy używamy
obiektów z innych aplikacji, mają one właściwości, które mogą być zmieniane poprzez automatyzację. Na przykład,
podobnie do formularzy Accessa, aplikacje Word i Excel mogą być ukrywane i pokazywane poprzez ustawienie
odpowiedniej właściwości. Większość właściwości może być zarówno odczytywana jak i zapisywana.
Metoda to działanie na obiekcie. Może być rozumiana jako czasownik w zdaniu. Przykładem metody Accessa jest Close,
natomiast przykładem metody Excela jest Quit, która zamyka Excela.
Aby użyć Object Browser wybierz Object Browser z menu View w edytorze Visual Basica. Możesz również nacisnąć F2.
Object Browser pokazany jest na rysunku 18.2.
325 Rozdział 18. ♦ Użycie automatyzacji Active X
Rysunek 18.2.
Object Browser
pokazujący obiekty
Worda
Przy pierwszym otwarciu przeglądarki pole listy rozwijanej w lewym górnym rogu będzie ustawione na All Libraries. To
ustawienie powoduje, że są widoczne wszystkie obiekty aplikacji, do których ustawiliśmy odwołanie. Pierwszym krokiem
powinno być wybranie właściwej aplikacji na liście rozwijanej tak, aby widoczne były tylko jej obiekty. Przykładowo, gdy
wybierzemy Word, wyświetlone zostaną tylko obiekty Worda.
Druga lista służy do szukania. Przykładowo, jeżeli chcemy odnaleźć okno komunikatu, ustawiamy górną listę wyboru na
All Libraries, poniżej wpisujemy MsgBox i naciskamy na ikonę z lornetką (rysunek 18.3).
Lewy dolny panel zatytułowany jest Classes. W panelu tym wyświetlane są dostępne typy obiektów w wybranej
bibliotece. Gdy z listy zostanie wybrana klasa, na liście Member of zostaną wyświetlone właściwości, metody i zdarzenia.
Prawy dolny panel zatytułowany Members, przedstawia zawartość klasy wybranej po lewej stronie. Na przykład, jeżeli
wybrany zostanie obiekt Application, prawy panel będzie pokazywał wszystkie właściwości, metody, zdarzenia i stałe, które
zawiera obiekt zaznaczony na liście klas.
Rysunek 18.3.
Szukanie MsgBox
w Obiect Browser
Skąd Object Browser czerpie informacje o obiektach, właściwościach i metodach? Z większością aplikacji dostarczany jest
plik biblioteki typów, w którym zapisane są informacje o obiektach aplikacji, właściwościach, metodach i stałych. Object
Browser wyświetla informację z biblioteki typów. Biblioteki te zapisywane są zwykle w plikach z rozszerzeniem .TLB lub
.OLB.
Na samym dole okna wyświetlana jest składnia użycia wybranego elementu. Na przykład, po wybraniu obiektu Application z
Accessa i zaznaczeniu metody DLookup, w oknie na dole Object Browsera wyświetlona zostanie właściwa składnia. Po
dalsze informacje o wybranym elemencie można uzyskać, naciskając F1 i przeglądając pomoc podręczną.
StrName = "Bob"
I = 10
W przykładzie tym zmienne zawierają zadeklarowany typ danych i dane tych typów mogą być przypisywane do zmiennej i
z niej odczytywane.
Zmienne obiektowe deklaruje się instrukcją Dim, identycznie jak zmienne proste.
Dim objWord.application
Dim objExcel.application
używaj
Dim objWord as Word.Application
Aby sprawdzić, czy jest uruchomiony program, użyj funkcji GetObject. Funkcja ta zwróci odwołanie do aktualnie
uruchomionej aplikacji.
' Deklaracja zmiennej obiektowej objWord
Dim objWord as Word.Application
Zmienne obiektowe przechowują wskaźnik do obiektu. Gdy zmienna obiektowa zostanie przypisana do aplikacji Excel,
zawiera ona wskaźnik do aplikacji, a nie przechowuje całej aplikacji Excel. Gdy obiekty są przekazywane z jednej
procedury do drugiej, są one zawsze przekazywane przez „referencję”, a nie przez „wartość”.
327 Rozdział 18. ♦ Użycie automatyzacji Active X
' Gdy Word nie jest uruchomiony, wystąpi błąd. Ignorujemy go.
Słowo kluczowe New może być użyte, gdy tworzysz odwołanie do biblio-
teki typów aplikacji.
Jeżeli zmienna objWord zostanie zadeklarowana jako Object, łączenie z biblioteką typów Worda nastąpi w trakcie
wykonania programu, co znacznie spowolni program.
Niestety, w niektórych przypadkach nie można użyć wczesnego łączenia typów lub słowa kluczowego New. W takich
okolicznościach może być pomocna funkcja CreateObject.
' Gdy Word nie jest uruchomiony, wystąpi błąd. Ignorujemy go.
' Gdy znowu wystąpi błąd 429, MS Word 9.0 nie jest zainstalowany.
If Err.Number = 429 Then
MsgBox "MS Word 2000 nie jest zainstalowany"
End If
End If
' On Error GoTo ErrorHandler (Tu wstaw obsługę błędów)
Do funkcji CreateObject można przekazać w parametrze, którą wersję aplikacji ma ona utworzyć. Przykład poniżej
przedstawia użycie CreateObject w celu uruchomienia Worda 97.
' Deklaracja zmiennej obiektowej objWord
Dim objWord As Word.Application
' Gdy Word nie jest uruchomiony, wystąpi błąd. Ignorujemy go.
On Error Resume Next
Zamykanie aplikacji
serwera automatyzacji
Podczas nauki tworzenia sesji automatyzacji mogłeś użyć uruchomionego wcześniej egzemplarza aplikacji lub uruchomić
nowy egzemplarz. Ważne jest, aby zamykać serwer automatyzacji pod odpowiednimi warunkami.
Jeżeli aplikacja działa, gdy uruchamiasz sesję automatyzacji i używasz tego egzemplarza aplikacji, nie zamykaj aplikacji
podczas kończenia sesji. Użytkownicy będą bardzo sfrustrowani, jeżeli ich aplikacja zostanie zakończona przez Twój
program.
Jeżeli utworzyłeś nowy egzemplarz aplikacji, powinieneś zamknąć go po zakończeniu pracy. Jeżeli tego nie zrobisz,
aplikacja pozostanie otwarta, nieużywana przez użytkownika, ale zajmująca cenne zasoby systemu.
Aby zakończyć aplikację, użyj właściwej metody dla aplikacji. Przykładowo, dla Excela wywołaj metodę Quit, tak jak
pokazane jest na przykładzie:
' Zamknij aplikację Excel poprzez wywołanie jej metody Quit.
objExcel.Quit
Przykład poniższy otwiera Worda i sprawdza, w jaki sposób został otwarty, używając właściwości UserControl.
' Deklaracja zmiennej obiektowej objWord.
Dim objWord As Word.Application
Na początku należy sprawdzić, jakie zdarzenia są udostępniane przez aplikację. Najprostszą metodą dowiedzenia się tego,
jest użycie narzędzia Object Browser. Po wybraniu obiektu aplikacji możesz przeglądać udostępniane zdarzenia. Word 97
posiada tylko dwa zdarzenia udostępniane przez obiekt Application (DocumentChange i Quit). Word 2000 ma 12
zdarzeń udostępnianych przez obiekt Application. Są one pokazane na rysunku 18.4 w Object Browser. Gdy
przeglądamy zawartość obiektów, różne ikony wskazują właściwości (palec wskazujący kartkę papieru), metody (zielona
latająca gumka) i zdarzenia (błyskawica).
Rysunek 18.4.
Object Browser
pokazujący
zdarzenia
udostępnione
przez Microsoft
Word 2000
Microsoft Excel udostępnia więcej zdarzeń niż Word. Obiekt aplikacji Excel 2000 posiada 21 zdarzeń (rysunek 18.5).
Rysunek 18.5.
Object Browser
pokazujący
zdarzenia
udostępnione
przez Microsoft
Excel 2000
Uruchamiamy WithEvents
Normalnie, gdy używamy automatyzacji w procedurze, deklarujesz zmienną obiektową w następujący sposób:
Dim objWord as Word.application
Aby użyć WithEvents, usuń deklarację zmiennej z procedury i zamiast niej utwórz zmienną modułową. Słowo kluczowe
Dim powinieneś zmienić na Private lub Public. Należy również dodać klauzulę WithEvents, aby udostępnić zdarzenia
aplikacji.
Część VI ♦ Współoperatywność 332
Rysunek 18.6 przedstawia w jaki sposób zadeklarować zmienną modułową z użyciem klauzuli WithEvents.
Rysunek 18.6.
Deklaracja zmiennej
modułowej przy
użyciu klauzuli
WithEvents
Po zadeklarowaniu zmiennej modułowej przy użyciu klauzuli WithEvents sprawdź zawartość list wyboru na górze okna
modułu. W liście wyboru z lewej strony okna wybierz zadeklarowaną wcześniej zmienną, która reprezentuje serwer
automatyzacji. W prawej liście wyboru zobaczysz zdarzenia udostępniane przez aplikację. Po wybraniu zdarzenia w oknie
programowania pojawia się szkielet procedury, która jest wywoływana po zajściu zdarzenia. Możesz teraz wypełnić tę
procedurę kodem wykonywanym w odpowiedzi na zdarzenie. Na rysunku 18.7 pokazane są procedury używające udo-
stępnionych przez Worda zdarzeń DocumentChange i Quit.
Rysunek 18.7.
Procedury
używające
udostępnionych
zdarzeń programu
Microsoft Word
Ustanowienie odwołania,
użycie wczesnego wiązania typów
i słowa kluczowego New
Aby rozpocząć sesję automatyzacji, ustaw odwołanie do aplikacji w oknie dialogowym odwołań. Używaj szczegółowych
klas w trakcie deklaracji zmiennych obiektowych oraz słowa kluczowego New, aby utworzyć egzemplarz obiektu aplikacji.
Najlepszą techniką jest przełączenie ScreenUpdating na False, wykonanie pracy przez automatyzację i na koniec
przełączenie ScreenUpdating na True. Użytkownik zobaczy kompletny dokument, kiedy zostanie wykonany.
Informacja o przetwarzaniu
Jeżeli sesja automatyzacji trwa przez dłuższy czas, na pewno musisz informować użytkownika o trwającym procesie.
Można użyć paska postępu, klepsydry jako kursora myszy lub innego graficznego wskaźnika. Jeżeli tego nie zrobisz,
użytkownik może pomyśleć, że komputer się zawiesił i wyłączyć go. Pamiętaj, że w pracy poprzez automatyzację
uruchomiona jest więcej niż jedna aplikacja, więc niszczące skutki takiego wyłączenia mogą być znaczne.
Jako programista wiesz, że wyświetlanie informacji w trakcie przetwarzania spowalnia sam proces przetwarzania.
Jednak ważniejszy jest nie całkowity czas, jaki zajmie ukończenie procesu, ale czas „widziany”. Użytkownicy uważają,
że przetwarzanie trwa krócej, gdy widoczne są wskaźniki zaawansowania procesu, choć naprawdę trwa to nieco dłużej.
Inaczej mówiąc, niech aplikacja uruchamia własny kod. Jeżeli używane są obiekty, właściwości i metody Worda, umieść je
w kodzie VBA w Wordzie. W przeciwnym wypadku komunikacja między procesami Accessa i Worda będzie nawiązywana
dla każdego wyrażenia w kodzie programu. Używając tej techniki, istotnie polepszysz wydajność.
Przykład 1. Odwołanie do obiektu jest wykonywane w każdym wierszu kodu, co powoduje jego spowolnienie. Kod jest
trudniejszy do czytania.
objExcel.Range("F6").Select
objExcel.ActiveCell.FormulaRlC1 = "Sprzedaż roczna"
objExcel.Range("G6").Select
objExcel.ActiveCell.FormulaRlC1 = "Podsumowanie sprzedaży"
objExcel.Range("F7").Select
Przykład 2. Odwołanie do obiektu jest wykonywane tylko raz, co powoduje przyspieszenie kodu. Łatwiej się go czyta.
With objExcel
.Range("F6").Select
.ActiveCell.FormulaRlC1 = "Sprzedaż roczna"
.Range("G6").Select
.ActiveCell.FormulaRlC1 = "Podsumowanie sprzedaży"
.Range("F7").Select
End With
W poprzednim rozdziale zostały przedstawione zasady i techniki użycia automatyzacji. Teraz zastosujemy tę wiedzę,
używając wszystkich aplikacji w pakiecie Microsoft Office 2000.
W rozdziale tym zapoznamy się ze sposobami użycia w Accessie innych aplikacji firmy Microsoft, takich jak: Word,
Excel, PowerPoint, Outlook, Graph, MapPoint, FrontPage oraz Binder.
Zajrzyj do przykładów kodu dla tego rozdziału. Jest tam wiele wierszy
kodu automatyzacji dla programistów Access, Excel, PowerPoint, Outlook,
Graph, FrontPage i MapPoint (rysunek 19.1).
Część VI ♦ Współoperatywność 336
Rysunek 19.1.
Plik
Automation.MDB
Aby utworzyć kompletną aplikację, możesz użyć wielu możliwości aplikacji Office 2000 opisanych poniżej.
Użycie Worda
Word jest doskonałym wyborem, aby tworzyć faktury, listy, notatki i raporty. Word jest wspaniałym edytorem raportów.
Jako programista, możesz tworzyć ozdobne dokumenty w Accessie lub Excelu, ale czemu ponosić taki wysiłek? Word ma
wszystkie style i możliwości formatowania, jakich kiedykolwiek będziesz potrzebował.
Użycie Excela
Jeżeli potrzebujesz przetwarzać liczby, Excel jest świetnym wyborem. Możesz tworzyć imponujące wykresy i diagramy na
spotkania służbowe, negocjacje z klientami, zebrania rady nadzorczej itp.
Użycie PowerPoint
Gdy przychodzi czas na pokaz, użyj PowerPoint. Robiące wrażenie, wysokiej jakości prezentacje mogą być utworzone
relatywnie łatwo. Utwórz efektywne demonstracje dla sprzedaży produktów, zebrań personelu lub dyrekcji, prezentacje dla
inwestorów itp.
Użycie Outlooka
Outlook dostarcza licznych funkcji, które możesz włączyć do Twojej aplikacji. Użyj poczty Outlooka do poczty
korporacyjnej, internetowej, automatycznej wysyłki zamówień do działów ekspedycji, automatycznego zamawiania
produktów w razie potrzeb, fakturowania klientów i innych funkcji.
Zamiast tworzyć kalendarz w swojej aplikacji, możesz podłączyć się do tej funkcji z Outlooka. Pracownicy mogą
prowadzić swoje kalendarze, jak również kalendarze biurowe.
Outlook zapewnia zarządzanie zadaniami, które mogą być użyte do stworzenia list zadań do wykonania przez
pracowników, listy zadań do wykonania przez oddział, specjalnych projektów, itd.
337 Rozdział 19. ♦ Integracja z Office 2000
Kontakty Outlooka umożliwiają utworzenie prywatnych list adresowych, jak również wspólnych dla biura. Oczywiście
bazę zarządzania kontaktami można utworzyć w Accessie, ale Outlook jest gotowy do użycia natychmiast.
Użycie Graph
Microsoft Graph jest użytecznym narzędziem do tworzenia wykresów w Accessie i innych aplikacjach Office.
Użycie MapPoint
MapPoint jest narzędziem do szukania i wyświetlania informacji na mapach. Za pomocą automatyzacji adres może być
odczytany z bazy danych, a następnie zostanie wyświetlona mapa przedstawiająca dokładne położenie adresu.
Użycie FrontPage
Sieć jest istotna w dzisiejszym świecie biznesu. Użyj FrontPage do tworzenia i modyfikacji stron WWW oraz do innych
zastosowań sieciowych.
Użycie Bindera
Office Binder dostarcza sposobu integracji dokumentów Office za pomocą zunifikowanego narzędzia. Za pomocą
automatyzacji dokumenty Worda, Excela i PowerPointa mogą być łączone w Binderze, więc użytkownicy będą mogli
pracować z wszystkimi dokumentami jednocześnie.
Wszystkie dokumenty mogą być zapisane w formacie Bindera, więc kiedykolwiek użytkownik będzie chciał pracować na
nich znowu, to otworzy Binder, gdzie wszystkie te dokumenty będą w wygodny sposób dostępne.
Przeciwstaw się pokusom stworzenia wszystkiego w Accessie, ponieważ najlepiej znasz tę aplikację. VBA jest teraz
dostępny we wszystkich produktach Office. Teraz jest dużo łatwiej niż kiedyś przestawić się na Worda czy Excela i szybko
poczuć się komfortowo w czasie programowania.
Pomyśl o automatyzacji jak o zestawie usług, które możesz włączyć do swojej aplikacji:
u Access – usługi baz danych.
u Word – edycja tekstu i usługi małej poligrafii.
u Excel – obliczenia i usługi finansowe.
u PowerPoint – prezentacje
u Outlook – poczta, kalendarz, kontakty, zadania i inne usługi.
u Graph – wykresy i schematy.
u MapPoint – usługi związane z mapami.
u FrontPage – usługi tworzenia stron internetowych.
u Binder – usługi łączenia dokumentów.
Wszędzie VBA
Visual Basic for Applications (VBA) jest potężnym językiem programowania, który istnieje wewnątrz programów Office.
Ta unifikacja języka programowania pozwala programistom na łatwe łączenie aplikacji Office w zunifikowane rozwiązania
programowe.
Część VI ♦ Współoperatywność 338
Rysunek 19.2.
Okno dialogowe
rejestratora makr
Po wywołaniu rejestratora makr, wpisz nazwę makra i naciśnij OK, aby rozpocząć proces rejestracji. Na ekranie widoczny
będzie mały pasek narzędzi zawierający dwa przyciski. Przesuwając kursor myszy nad tymi przyciskami, możesz zobaczyć, że
jest to zatrzymanie i pauzowanie rejestrowania. Dodatkowo, aby zasygnalizować, że działa rejestrator makr, przy kursorze
myszy widoczna jest mała kaseta magnetofonowa (rysunek 19.3).
Rysunek 19.3.
Dokument Worda
z pracującym
rejestratorem makr
W czasie pracy rejestratora wszystkie czynności, jakie wykonasz zostaną skonwertowane do kodu VBA. Możesz wpisywać
tekst do dokumentu, formatować go a nawet zapisywać i drukować. Gdy zakończysz czynności, które miały być
zarejestrowane, naciśnij przycisk Zatrzymaj rejestrowanie. Aby zobaczyć kod VBA, jaki został zapisany przez rejestrator,
wybierz Makro z menu Narzędzia i z następnego menu Makra. Wybierz zapisane przez siebie makro i naciśnij przycisk
Edytuj. Otworzy się edytor VBA, pokazując kod realizujący makro (rysunek 19.4).
Rysunek 19.4.
Kod VBA
wygenerowany przez
rejestrator makr
w edytorze VBA
339 Rozdział 19. ♦ Integracja z Office 2000
Rejestrator makr nie zawsze generuje optymalny kod, więc zawsze należy
go przejrzeć przed użyciem w aplikacji. Dodanie konstrukcji With/ End
With jest również dobrym pomysłem.
Aby użyć tych makr należy za pomocą VBA utworzyć w module funkcję o nazwie odpowiedniego makra automatycznego.
Przykładowo, aby utworzyć makro automatyczne AutoOpen, powinieneś utworzyć taką procedurę:
Private/Public Sub AutoOpen ()
' Kod wykonywany podczas otwierania dokumentu
End Sub
Microsoft Forms
Programy Office: Word, Excel i PowerPoint używają oddzielnego modułu formularzy Microsoft Forms. Niekiedy, gdy
używasz innych aplikacji, takie formularze mogą się przydać.
Doświadczeni programiści Accessa nie będą mieli trudności w użyciu Microsoft Forms. Tworzenie formularza, używając
Microsoft Forms, przebiega według następującego scenariusza. Z menu Insert wybierz User Form lub naciśnij Shift+F7.
Używając paska narzędzi, dodaj na formularz formanty. Napisz obsługę komunikatów formularza i formantów, używając
VBA. Do formularza takiego można również dodać formanty ActiveX.
Object Browser
Gdy pracujesz z różnymi aplikacjami omawianymi w tym rozdziale, nie zapominaj o użyciu narzędzia Object Browser.
W poprzednim rozdziale szczegółowo omówiłem, jak go używać.
Aby wywołać Object Browser, w oknie edytora VBA wybierz Object Browser z menu View lub naciśnij F2 (rysunek 19.5).
Część VI ♦ Współoperatywność 340
Rysunek 19.5.
Object Browser
wyświetlający
obiekty Worda
Binder Office.Binder
Excel Excel.Application
Excel.Sheet
Excel.Chart
FrontPage FrontPage.Application
Graph Graph.Application
MapPoint MapPoint.Application
Outlook Outlook.Application
PowerPoint PowerPoint.Application
Word Word.Application
Word.Document
Przykład automatyzacji
Podstawy automatyzacji (przykładowo dla Worda: tworzenie lub pobieranie odwołania do Worda, użycie obiektów Worda,
zwalnianie obiektu) zostały przedstawione w poprzednim rozdziale.
Przykład poniższy drukujący informacje o Accessie w postaci dokumentu Worda ilustruje wszystkie wymienione kroki. Nie
zapomnij ustawić wcześniej odwołania do Worda.
Private Sub AccessApplicationReport()
DoCmd.Hourglass True
DoCmd.Hourglass False
End Sub
Automatyzacja Worda
W tej części opiszę specyficzne zagadnienia i przykłady automatyzacji Worda.
Część VI ♦ Współoperatywność 342
Model obiektów jest szablonową reprezentacją obiektów aplikacji. Jest to szybka i łatwa metoda poznania obiektów, które
można użyć do programowania.
Model Worda jest dosyć obszerny. Zawiera on ponad 180 obiektów dostępnych poprzez VBA. Często używane obiekty
Worda zebrane są w tabeli 19.1. Nazwy obiektów, które są kolekcjami mają końcówkę (s).
Tabela 19.1.
Obiekty Worda
Tabela 19.1.
Obiekty Worda (ciąg dalszy)
Aby utworzyć szablon Worda, otwórz nowy dokument Worda. Po wpisaniu potrzebnego kodu VBA wybierz Zapisz jako z
menu Plik, aby zapisać ten dokument jako szablon dokumentu (rozszerzenie .DOT).
Aby dodać kod do szablonu użyj Rejestratora Makr w sposób omówiony wcześniej. Uruchom Rejestrator, wykonaj
czynności które chcesz automatyzować a Rejestrator Makr utworzy dla Ciebie kod VBA.
Jak uruchomić kod VBA Worda z Accessa? Jest to bardzo proste. Należy użyć metody Run.
' Uruchom makro w Wordzie formatujące dokument
objWord.Run "FormatDocument"
Uruchamianie tego makra przez Worda jest dużo szybsze, ponieważ komunikacja między procesami musi zachodzić dla
każdej instrukcji automatyzacji. Dzięki umieszczeniu kodu w Wordzie, jest on uruchamiany przez jeden proces.
Mimo że program działa szybciej, gdy umieścimy go w szablonie Worda, czy nie będzie to sprawiało problemów
instalacyjnych? Nie, jeżeli zrobimy to odpowiednio. Szablony można zapisywać na każdej stacji roboczej lub jako
szablony grupy roboczej na serwerze. Zaletą zapisywania szablonów do katalogu szablonów grupy jest to, że gdy
zmienimy szablon, należy go skopiować tylko do współdzielonego katalogu na serwerze. Jednak, gdy używamy szablonów
grupy, następuje komunikacja przez sieć. Niektórzy programiści tworzą proste aplikacje, które kopiują szablony z serwera
do każdej stacji roboczej podczas startu aplikacji.
Aby zapewnić użytkownikom dostęp do szablonów grupy (na serwerze), wybierz Opcje z menu Narzędzia. Na zakładce
Położenie plików wpisz ścieżkę do katalogu szablonów grupy (patrz rysunek 19.6).
Rysunek 19.6.
Położenie plików
w opcjach Worda
Istnieją trzy sposoby, aby wysłać dane z bazy danych Accessa lub serwera SQL do dokumentu Worda: korespondencja
seryjna, zakładki oraz zastępowanie. Przykłady w tym rozdziale używają wszystkich tych sposobów.
Korespondencja seryjna
Użytkownicy często używają do tworzenia dokumentów korespondencji seryjnej. Można to także zrobić przy użyciu
automatyzacji.
Preferowaną metodą integracji z Wordem przy użyciu użycia automatyzacji jest korespondencja seryjna.
Część VI ♦ Współoperatywność 344
Rysunek 19.7.
Tworzenie raportów
w Wordzie
Aby stworzyć kod automatyzacji korespondencji seryjnej, uruchom rejestrator makr i wykonaj wszystkie kroki, które
wykonuje użytkownik w celu utworzenia takiego dokumentu. Wybierz Korespondencja seryjna z menu Narzędzia i
zrealizuj wszystkie kroki w pomocniku korespondencji seryjnej.
Gdy wybierasz źródło danych do połączenia z dokumentem, możesz wybrać tabelę Accessa lub kwerendę ze źródła
danych. Powinieneś wiedzieć, że jeżeli umieścisz dane w pliku RTF i użyjesz tak spreparowanego pliku jako źródło
danych, kod automatyzacji będzie działał wyraźnie szybciej.
Najważniejszą zaletą korespondencji seryjnej jest to, że użytkownicy mogą wstawiać pola danych do dokumentu. Pozwala
to użytkownikom na tworzenie swoich dokumentów, a także odciąża programistów od potrzeby tworzenia raportów.
Poprawnie zaprojektowane przez programistę szablony dokumentów zawierają odpowiednie pola danych, na podstawie
których użytkownicy mogą utworzyć swoje raporty (rysunek 19.8).
Rysunek 19.8.
Tworzenie raportów
przez użytkowników
Przykład procedury uruchamiającej korespondencję seryjną zaczerpnięty z pliku z przykładami do tego rozdziału:
Private Sub RunMailMerge()
With ActiveDocument.MailMerge
.MainDocumentType = wdFormLetters
ActiveDocument.MailMerge.OpenDataSource Name:= _
"C:\Automation\Automation.MDB", ConfirmConversions:=False, _
ReadOnly:=False, LinkToSource:=True, AddToRecentFiles:=False, _
PasswordDocument:="", PasswordTemplate:="", _
WritePasswordDocument:= ", WritePasswordTemplate:="", _
Revert:=False, Format:=wdOpenFormatAuto, _
Connection:="QUERY qryEmployeeLetters", SQLStatement:= _
"SELECT * FROM [qryEmployeeLetters]", SQLStatement1:=""
.Destination = wdSendToNewDocument
.Execute
End With
End Sub
345 Rozdział 19. ♦ Integracja z Office 2000
Zakładki
Inną metodą wstawiania danych do dokumentów Worda jest użycie zakładek. Zakładka w dokumencie jest oznaczeniem
miejsca, gdzie będą wstawione dane. W czasie wykonania programu wyszukiwane są kolejne zakładki i w te miejsca są
wstawiane dane.
Niedogodnością zakładek jest to, że programista sam musi wstawić zakładki do szablonu i napisać program (lub użyć
rejestratora makr) wyszukujący zakładki i wstawiający dane. Użytkownicy nie mogą tworzyć swoich dokumentów z
danymi, jak w przypadku użycia korespondencji seryjnej.
Inną niedogodnością tej metody jest to, że zakładki nie są widoczne w dokumencie, co utrudnia ich odszukanie i
identyfikację.
Aby zastosować tę metodę, utwórz szablon Worda i wpisz tekst. Następnie wstaw zakładki w miejsca, gdzie chcesz
wstawić dane, wybierając Zakładka z menu Wstaw. Wpisz nazwę zakładki i naciśnij przycisk Dodaj.
Użyj rejestratora makr do wygenerowania kodu VBA, przechodząc do zakładki i wpisując tekst. Przykład kodu
zamieszczony jest poniżej.
Selection.GoTo..... What:=wdGoToBookmark, Name:="MyBookmark"
Selection.TypeText "New Text"
Zastępowanie
Używając tej techniki, tekst jest wstawiany do dokumentu w oznaczone miejsca (np. {Nazwisko}). Program szuka
tych oznaczonych miejsc za pomocą funkcji Znajdź i zamienia je na odpowiednie dane. Inaczej mówiąc {Nazwisko}
zostanie odszukane i zamienione na „Kowalski”.
Zaletą tej metody w porównaniu z zakładkami jest to, że oznaczony tekst jest widoczny i czytelny w porównaniu z
zakładką. Jeszcze raz użyj rejestratora makr podczas wyszukiwania i zamiany, aby utworzyć kod VBA.
With Selection.Find
.ClearFormatting
.Text = "{Tekst do odszukania}"
.Replacement.Text = "Nowy tekst"
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute Replace:=wdReplaceAll
End With
Formatowanie dokumentów
Word ma ogromne możliwości formatowania dokumentów. Do utworzenia i sformatowania dokumentu można użyć
następującego fragmentu programu w VBA:
' Formatowanie tekstu
With Selection.Font
.Size = 14
.Bold = True
End With
Autokorekta
Autokorekta poprawia niektóre błędnie napisane słowa (np. „barzdo” zostanie zamienione na „bardzo”). Możesz także użyć
autokorekty, aby zaoszczędzić pisania (np. zamienić „MS” na „Microsoft”).
Autotekst
Autotekst jest bazą danych przechowującą często używane fragmenty tekstu i obiekty graficzne, które mogą być w łatwy
sposób wstawiane do dokumentu. W przykładach do rozdziału zamieszczony jest program wstawiający tekst i zdjęcia do
dokumentu.
' Tworzenie pozycji w autotekście.
NormalTemplate.AutoTextEntries.Add Name:="Microsoft", _
Range:=Selection.Range
Autopodsumowanie
Autopodsumowanie analizuje każde zdanie dokumentu, aby wygenerować podsumowanie. Podsumowanie może być
wyświetlane na kilka sposobów: jako wyróżniony tekst w dokumencie, jako streszczenie na początku dokumentu, w nowym
dokumencie lub tylko samo podsumowanie. Autopodsumowanie może również tworzyć streszczenia stron WWW.
' Tworzy podsumowanie dokumentu jako nowy dokument.
ActiveDocument.AutoSummarize Length:=25, _
Mode:=wdSummaryModeCreateNew, UpdateProperties:=True
347 Rozdział 19. ♦ Integracja z Office 2000
Widoki dokumentu
Po utworzeniu dokumentu trzeba wyświetlić go we właściwej postaci: normalnej, układu dla sieci WWW, układu strony i
konspektu.
' Układ normalny
ActiveWindow.View.Type = wdNormalView
Spis treści
Dawniej tworzenie dokumentu było uciążliwym zadaniem. Teraz w Wordzie jest to zautomatyzowany proces. Aby
tworzenie spisu przebiegło sprawnie, należy używać stylów w dokumencie. Gdy zastosujesz style Nagłówek 1, Nagłówek 2
itd., Word w oparciu o te informacje automatycznie utworzy prawidłowy spis treści.
' Tworzenie spisu treści
With ActiveDocument
.TablesOfContents.Add Range:=Selection.Range, _
RightAlignPageNumbers:= _
True, UseHeadingStyles:=True, UpperHeadingLevel:=1, _
LowerHeadingLevel:=3, IncludePageNumbers:=True, _
AddedStyles:=""
.TablesOfContents(1).TabLeader = wdTabLeaderDots
End With
Przypisy
Przypisy pomagają czytelnikowi odnaleźć i ocenić informacje, które odnoszą się do treści zawartych w dokumencie.
' Tworzenie przypisu
ActiveDocument.Footnotes.Add Range:=Selection.Range, _
Reference:=Selection, Text:="My New Footnote"
Nagłówki
Nagłówki są umieszczone na górze każdej strony dokumentu.
' Tworzenie nagłówka
ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageHeader
Selection.TypeText Text:="My Header"
Stopki
Stopki umieszczone są na dole każdej strony dokumentu.
' Tworzenie stopki
ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageHeader
If Selection.HeaderFooter.IsHeader = True Then
ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageFooter
Else
ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageHeader
End If
Selection.TypeText Text:="My Footer"
Hiperłącza
Hiperłącza umożliwiają użytkownikowi w łatwy sposób przeskakiwać do innych części dokumentu, otwierać inne
dokumenty, a nawet przeskakiwać do dokumentów umieszczonych w Internecie.
' Tworzenie hiperłącza do zakładki w dokumencie
ActiveDocument.Hyperlinks.Add Anchor:=Selection.Range, Address:= ", _
SubAddress:="MyBookmark"
Tworzenie tabel
Tabele zawierają informacje zorganizowane w wiersze i kolumny. Word pozwala na łatwe tworzenie nawet
skomplikowanych tabel.
' Tworzenie tabeli
ActiveDocument.Tables.Add Range:=Selection.Range,
NumRows:=3, NumColumns:=3, Selection.Tables(1).AutoFormat, _
Format:=wdTableFormatClassic3, ApplyBorders:=True, _
ApplyShading:=True, ApplyFont:=True, ApplyColor:=True, _
ApplyHeadingRows:=True, ApplyLastRow:=False, _
ApplyFirstColumn:=True, ApplyLastColumn:=False, AutoFit:=False
' Wstawianie wierszy do tabeli
Selection.InsertRows 1
Ustawienia strony
Okno dialogowe ustawień strony pozwala na ustawienie marginesów, rozmiaru papieru, orientacji, źródła papieru oraz
układu. Wszystkie te ustawienia mogą być modyfikowane programowo.
' Ustawienie marginesów
With ActiveDocument.PageSetup
.TopMargin = InchesToPoints(0.5)
.BottomMargin = InchesToPoints(0.5)
.LeftMargin = InchesToPoints(0.5)
.RightMargin = InchesToPoints(0.5)
End With
Podgląd wydruku
Aby wywołać podgląd wydruku, należy użyć poniższej instrukcji.
' Podgląd wydruku
ActiveDocument.PrintPreview
Pola
W Wordzie pola są używane do wstawiania do dokumentu różnych informacji, takich jak numery stron, daty i inne. Aby
wstawić pole do dokumentu, wybierz Pole z menu Wstaw. W czasie pracy z dokumentem można przełączyć się pomiędzy
tekstem i kodami pól przez naciśnięcie Alt+F9.
349 Rozdział 19. ♦ Integracja z Office 2000
Pola mogą być uaktualniane ręcznie przez naciśnięcie F9 lub automatycznie podczas drukowania dokumentu.
Tabela 19.2.
Pola Worda
Tabela 19.2.
Pola Worda (ciąg dalszy)
Informacje o dokumencie
W czasie tworzenia i zapisywania dokumentu zapisywane są informacje pozwalające na późniejsze przeszukiwanie
dokumentów. Na rysunku 19.9. znajdują się informacje zawarte w oknie dialogowym Właściwości.
Rysunek 19.9.
Informacje
o dokumencie Worda
Można również utworzyć zestaw własnych właściwości bazujących na specyfice firmy. Popatrz na zakładkę
Niestandardowe okna Właściwości.
Automatyzacja Excela
W tej części opisane są specyficzne dla Excela zagadnienia oraz przykłady automatyzacji.
W tabeli 19.3 zestawione zostały często używane obiekty Excela. Obiekty, które mają także kolekcje zakończone są literą
(s).
Tabela 19.3.
Obiekty Excela
With .Item(2)
.NumberFormat = "0.00"
.AutoFit
End With
End With
Tworzenie wykresów
Użyj rejestratora makr, aby szybko utworzyć kod automatyzacji. Użyj kreatora wykresów do wybrania odpowiedniego
wykresu. Poniższy przykład tworzy różne typy wykresów.
' Tworzenie wykresu kołowego
objChart.ChartWizard Source:=objSheet.Cells(1, 1).CurrentRegion, _
Gallery:=xlPie, Format:=4, PlotBy:=xlColumns, _
CategoryLabels:=1, SeriesLabels:=1, HasLegend:=2, _
Title:="Sprzedaż (Wykres kołowy)"
Program korzystający z automatyzacji może tworzyć w Excelu wykresy takie jak pokazany na rysunku 19.10.
Część VI ♦ Współoperatywność 352
Gdy odwołujesz się do obiektu w hierarchii obiektów aplikacji, możesz przesuwać się w obu kierunkach.
Rysunek 19.10.
Tworzenie wykresów
w Excelu
Aby przesunąć się w górę hierarchii, używamy właściwości Parent. Przykładowo, gdy pracujesz z arkuszem, możesz
odwołać się do zeszytu, który zawiera ten arkusz poprzez właściwość Parent. Fragment programu ilustrujący tę technikę
zamieszczony jest poniżej.
Private Sub ParentPropertyDemo()
Dim objExcel As Excel.Application
Dim objWorkBook as Excel.WorkBook
' Utworzenie obiektu Excela
Set objExcel = New Excel.Application
objExcel.Workbooks.Open _
("C:\Automation\Sales by Country Data.xls")
End Sub
W przykładzie tym otwierany jest zeszyt Excela. Poprzez właściwość Parent obiektu reprezentującego zeszyt
odwołujemy się w górę hierarchii do obiektu aplikacji Excel.
Automatyzacja PowerPoint
W tej części opisane są specyficzne dla PowerPoint zagadnienia oraz przykłady automatyzacji.
353 Rozdział 19. ♦ Integracja z Office 2000
W tabeli 19.4 zestawione zostały często używane obiekty PowerPoint. Obiekty, które mają także kolekcje, zakończone są
literą (s).
Tabela 19.4.
Obiekty PowerPoint
Dodanie slajdu
Do dodania slajdu do prezentacji używana jest metoda Add.
' Dodaj slajd
Set ppPres = objPP.Presentations.Add
Część VI ♦ Współoperatywność 354
Rysunek 19.11.
Prezentacja
PowerPoint
stworzona
za pomocą
automatyzacji
With objPresentation.Shapes(2).TextFrame.TextRange
.Text = Chr$(CharCode:=13) + "Spotkanie Rady Nadzorczej" _
+ Chr$(CharCode:=13) + "Informacja o wartości sprzedaży"
.Characters.Font.Color.RGB = RGB(0, 0, 255)
.Characters.Font.Shadow = True
End With
With objPresentation.Shapes("Rectangle 3").TextFrame.TextRange, _
Characters(1, 53).Font
.Size = 36
.Color.Scheme0olor = ppFill
End With
objPresentation.Shapes.AddPicture(FileName:=strFileName, _
LinkToFile:=msoFalse, SaveWithDocument:=msoTrue, _
Left:=110, Top:=260, Width:=250, Height:=250).Select
Uruchamianie prezentacji
Aby uruchomić prezentację, wykonaj:
objPresentation.SlideShowSettings.Run
Automatyzacja Outlook
W tej części opisane są specyficzne dla Outlooka zagadnienia oraz przykłady automatyzacji.
355 Rozdział 19. ♦ Integracja z Office 2000
W tabeli 19.5 zestawione zostały często używane obiekty Outlooka. Obiekty, które mają także kolekcje, zakończone są
literą (s).
Tabela 19.4.
Obiekty Outlook
Tabela 19.4.
Obiekty Outlook (ciąg dalszy)
Rysunek 19.12.
Wysłanie
wiadomości e-mail
z załącznikiem
z Accessa
With objMailItem
' Tworzenie odbiorcy przesyłki
Set objRecipient = .Recipients.Add("Steven Johnson")
objRecipient.Type = olTo
' Ustawienie tematu, treści i ważności przesyłki
.Subject = "To jest mój raport sprzedaży do oceny"
.Body = "Jeżeli potrzebujesz innych informacji, _
proszę o kontakt." & vbOrLf & vbCrLf
.Importance = olImportanceHigh
' Dołączenie arkusza i wykresu w pliku Excela: "Sales by Country."
Set objAttachment = .Attachments.Add_
("C:\Automation\Sales by Country.xls")
Tabela 19.6.
Stałe folderów
Kontakty GetDefaultFolder(olFolderContacts)
Dziennik GetDefaultFolder(olFolderJournal)
Notatki GetDefaultFolder(olFolderNotes)
Zadania GetDefaultFolder(olFolderTasks)
Outlooka.
Automatyzacja Graph
W tej części opisane są specyficzne dla Graph zagadnienia oraz przykłady automatyzacji.
Tabela 19.7.
Obiekty Graph
Tabela 19.7.
Obiekty Graph (ciąg dalszy)
Tworzenie wykresu
Skomplikowane dokumenty często zawierają wykresy i diagramy. Word i inne produkty Office używają Microsoft Graph
do tworzenia i formatowania wykresów.
W Accessie jest bardzo łatwo utworzyć wykres na formularzu, używając kreatora. Często jednak możesz chcieć pokazać
różne typy wykresów dla różnych danych. Zamiast tworzyć sześć formularzy z różnymi wykresami, możesz manipulować
wykresem na formularzu za pomocą automatyzacji, aby pozwolić użytkownikowi na obejrzenie różnych prezentacji
graficznych jego danych (rysunek 19.13).
359 Rozdział 19. ♦ Integracja z Office 2000
Rysunek 19.13.
Pojedynczy
formularz może
pokazywać różne
typy wykresów
Poprzez proste użycie właściwości i metod Microsoft Graph, możesz formatować i zmieniać wykres w zależności od potrzeb:
dodawać legendę, wskaźniki danych, etykietki, wzory tła itp.
Automatyzacja MapPoint
W tej części opisane są specyficzne dla MapPoint zagadnienia oraz przykłady automatyzacji.
Tabela 19.8.
Obiekty MapPoint
Map Mapa
PushPin Pineska
Rysunek 19.14.
Pokazanie mapy
w aplikacji Accessa
przy użyciu
MapPoint
Automatyzacja FrontPage
W tej części opisane są specyficzne dla FrontPage zagadnienia oraz przykłady automatyzacji.
Tabela 19.9.
Obiekty FrontPage
Theme(s) Temat
Web(s) Sieć FrontPage
WebFile(s) Plik w opartej na FrontPage sieci
WebFolder(s) Folder w opartej na FrontPage sieci
WebWindow(s) Otwarte okno w opartej na FrontPage sieci
Przykład poniższy automatyzuje FrontPage, aby utworzyć nową sieć, wstawić do niej nową stronę, wstawić dane Accessa
na stronę i zastosować schemat.
' Ustaw odwołania do ADO 2.1 oraz FrontPage 4.0 Web Objects.
Dim objFrontPage As FrontPage.WebWindow
Dim objWeb As Web
Dim objWebFile As WebFile
Dim objWebWindow As WebWindow
Dim strSQL As String
Dim ADOrs As ADODB.Recordset
Dim Conn As ADODB.Connection
With Conn
.Provider = "Microsoft.JET.OLEDB.3.51"
.Open "C:\Automation\Automation.mdb"
End With
objWebWindow.Visible = True
Automatyzacja Bindera
W tej części opisane są specyficzne dla Bindera zagadnienia oraz przykłady automatyzacji.
Tabela 19.10.
Obiekty Bindera
With objBinder
' Dodaj dokument Worda do bindera
.Sections.Add FileName:="C:\Automation\Northwind Magazine Ad.doc"
.Sections(1).Name = "Ogłoszenie Northwind Magazine"
' Dodaj arkusz Excela do bindera
.Sections.Add FileName:="C:\Automation\Sales by Country Data.xls"
.Sections(1).Name = "Arkusz automatyzacji"
' Dodaj prezentację PowrePoint do bindera
.Sections.Add FileName:="C:\Automation\Board Of Director _
Meeting.ppt"
.Sections(1).Name = "Prezentacja na spotkanie Rady Nadzorczej"
End With
objBinder.Visible = True
Program ten przy użyciu automatyzacji tworzy nowy binder z różnymi dokumentami Office (patrz rysunek 19.15).
363 Rozdział 19. ♦ Integracja z Office 2000
Rysunek 19.15.
Automatyzacja
Microsoft Binder
Access jest potężnym narzędziem programistycznym, ale jednak nie potrafi wszystkiego. Visual Basic to wspaniałe
uzupełnienie Accessa. Przy użyciu VB można tworzyć samodzielne komponenty ActiveX oraz formanty ActiveX.
W rozdziale tym zakładamy, że nie masz żadnego doświadczenia w programowaniu w Visual Basicu. Korzystając z
opisu, krok po kroku nauczysz się tworzenia formantów ActiveX, które będziesz mógł wykorzystać w swoich aplikacjach
w Accessie. Opiszemy także krok po kroku, jak tworzy się komponenty w Visual Basicu, które mogą być wykorzystane w
Accessie, Visual Basicu i innych aplikacjach Office.
Możesz zapytać, „Jaka jest różnica pomiędzy Visual Basic i Visual Basic for Appliccations (VBA)?” VBA jest językiem
programowania użytym w Visual Basicu, Accessie i innych aplikacjach Office. VBA w Office 2000 oraz Visual Basic 6 są
dokładnie takie same. Jednak Visual Basic 6 jest samodzielnym środowiskiem programistycznym, które będziesz używać
w tym rozdziale do tworzenia formantów ActiveX.
W rozdziale 11. „Tworzenie obiektów w modułach klasowych” tworzyłeś obiekt dźwiękowy przy użyciu modułu
klasowego cSound. W module klasowym plik dźwiękowy jest przekazywany do wywołania Windows API, aby odegrać
dźwięk. Kod w module klasowym zamieszczony jest na wydruku 20.1.
Problem z modułem klasowym polega na tym, że może być użyty tylko w aplikacji Accessa, w której istnieje ten moduł.
Jeżeli tworzymy nową aplikację, moduł musi zostać do niej zaimportowany. Jednak, jeżeli zmienisz w przyszłości kod
modułu, będziesz musiał wprowadzić ręcznie te poprawki w każdej aplikacji używającej tego modułu.
Poprzez utworzenie komponentu ActiveX dla obiektu dźwiękowego wszystkie aplikacje Accessa (jak również inne
aplikacje) mogą użyć komponentu ActiveX. Jeżeli musisz wprowadzić zmiany, wprowadzone zostaną w jednym miejscu.
Komponent ActiveX w postaci pliku EXE posiada własną przestrzeń procesu oddzielną od wywołującej go aplikacji.
Wywołania z aplikacji są przesyłane pomiędzy procesami do komponentu. Jest to wolniejsze niż gdyby komponent
ActiveX był wykonywany w tym samym procesie. Zaletą ActiveX w postaci EXE jest to, że jeżeli załamie się,
wywołująca go aplikacja może dalej działać.
Komponent w postaci biblioteki DLL wykonywany jest w tej samej przestrzeni procesu co wywołująca go aplikacja.
Ponieważ nie zachodzi komunikacja międzyprocesowa, szybkość wykonania jest wyraźnie większa. Jeżeli jednak
komponent spowoduje błąd, zostanie zatrzymana cała aplikacja. Najczęściej jednak będziesz korzystać z komponentów w
bibliotekach dynamicznych.
Rysunek 20.1.
Wybór ActiveX DLL
w oknie New Project
Gdy projekt zostanie otwarty w IDE, zauważysz jeden moduł klasowy nazywany Class1. W oknie Project Properties
zmień nazwę modułu na cSound.
Część VI ♦ Współoperatywność 366
Otwórz w Accessie aplikację z rozdziału 11. „Tworzenie obiektów z modułów klas.mdb”. Otwórz moduł cSound i w trybie
projektowania skopiuj jego zawartość do schowka. Wróć do projektu w Visual Basicu i wklej całą zawartość do okna kodu
modułu cSound w sposób pokazany na rysunku 20.2.
Rysunek 20.2.
Kopia cSound
w oknie modułu
klasowego
W oknie Project Properties można znaleźć właściwość Instancing. Jej domyślną wartością jest MultiUse. Ponieważ
komponenty ActiveX zawierają moduły klasowe, można tworzyć wiele egzemplarzy danej klasy. Dzięki temu pojedynczy
moduł kodu może być użyty wiele razy. Jeżeli właściwość Instancing jest ustawiona na MultiUse, aplikacja Accessa
może tworzyć obiekty dźwiękowe przy użyciu tego komponentu. Jeżeli programy będą kilkakrotnie żądały utworzenia
obiektu, zostanie utworzony tylko jeden. Zmniejsza to zużycie pamięci, ale jeżeli wystąpi drugie żądanie dostępu do obie-
ktu, program zostanie wstrzymany aż do zakończenia obsługi wcześniejszego żądania. Najczęściej używana jest domyślna
wartość MultiUse.
Następnym krokiem jest modyfikacja właściwości projektu. Wybierz Project1 Properties z menu Project.
Na zakładce General w oknie Project Properties (rysunek 20.3) wprowadź nazwę projektu cSoundObject (nazwa projektu
nie może zawierać spacji). W polu Project Description wprowadź opis projektu np.: Obiekt cSound. W polu tym mogą
występować spacje i jest to nazwa, która pojawi się w oknie References podczas ustawiania odwołania do komponentu.
Na zakładce Make w oknie właściwości projektu, która pokazana jest na rysunku 20.4, można podać numer wersji. Dobrze
jest zaznaczyć pole wyboru Auto Increment, co spowoduje, że za każdą kompilacją komponentu zostanie wprowadzony nowy
numer wersji.
Rysunek 20.3.
Zakładka General
okna właściwości
projektu
367 Rozdział 20. ♦ Użycie Visual Basic z Access’em
Rysunek 20.4.
Zakładka Make
właściwości projektu
W części Version Information można wprowadzić nazwę, informacje o prawach autorskich, nazwę produktu i inne
informacje. Pozostałe ustawienia nie muszą być zmieniane w tym przykładzie.
Na zakładce Compile, która jest pokazana na rysunku 20.5, domyślnym ustawieniem jest Compile to Native Code. Zwykle
nie będziesz musiał zmieniać tego ustawienia. Jeżeli zmienisz na Compile to P-Code, program będzie wolniejszy, ale
komponent będzie mniejszy. Szczegółowy opis ustawień na zakładce Compile znajduje się w pomocy Visual Basica.
Rysunek 20.5.
Zakładka Compile
właściwości projektu
Na zakładce Component, która pokazana jest na rysunku 20.6, domyślnym ustawieniem jest Project Compatibility. Takiego
ustawienia powinieneś używać przy tworzeniu komponentów. Inne ustawienia, No Compatibility oraz Binary Compatibility,
omówione zostaną później w części „Dystrybucja komponentów ActiveX”.
Rysunek 20.6.
Zakładka
Component
właściwości projektu
W tym przykładzie nie będziemy zmieniać ustawień z zakładki Debugging. Kliknij przycisk OK, aby zamknąć okno
właściwości obiektu.
Aby zapisać projekt i wszystkie moduły klasowe, wybierz Save Project z menu File. Najlepiej zapisywać projekt (plik .vbp)
oraz moduł klasy (plik .cls) w tym samym katalogu (np. Obiekt Sound).
Biblioteka DLL została utworzona i zarejestrowana w systemie. W Visual Basicu, gdy kompilujesz plik DLL, możesz od
razu rozpocząć korzysta z niego. W dalszej części rozdziału opisujemy, w jaki sposób rozprowadzać pliki DLL do innych
użytkowników.
Poniżej przedstawimy sposób użycia komponentu. Utwórz pustą bazę Accessa o nazwie np.: Sound i zapisz ją. Następnie
utwórz pusty formularz i umieść na nim przycisk do testowania komponentu. Utwórz procedurę obsługi zdarzenia Click
przycisku. W oknie modułu ustaw odwołanie do komponentu ActiveX cSound. Uruchom okno References z menu Tools i
zaznacz pole wyboru obok Obiekt cSound. Obiekt cSound to nazwa wprowadzona wcześniej w polu Description w oknie
właściwości projektu. Zamknij okno References przez kliknięcie przycisku OK.
Ustawienie odwołania do obiektu cSound jest niezbędne, ponieważ jest to komponent oddzielny od aplikacji Accessa.
Zauważ, że używasz obiektu cSound bez tworzenia żadnego modułu w aplikacji Accessa.
End Sub
Czy zauważyłeś w trakcie wpisywania tekstu programu działanie IntelliSense dla Twojego obiektu (rysunek 20.8)? Jest to
wspaniała pomoc ułatwiająca i przyspieszająca wpisywanie kodu programu.
369 Rozdział 20. ♦ Użycie Visual Basic z Access’em
Rysunek 20.8.
IntelliSense
działające dla
obiektu cSound
Przy użyciu kilku wierszy kodu można pokazać, jak łatwo utworzyć obiekt dźwiękowy z komponentu ActiveX i używać
jego właściwości, metod i zdarzeń. Możesz także używać komponentu cSound w innych aplikacjach Accessa. Zmiany będą
ułatwione, ponieważ wszystkie aplikacje Accessa i inne używają tego samego komponentu. Jeżeli zdecydujesz się dodać
lub zmienić właściwość, metodę lub zdarzenie w komponencie, zrobisz to tylko w jednym miejscu, w samym
komponencie.
Instalowanie komponentu
Najprostszą metodą instalacji komponentu na komputerze użytkownika jest użycie kreatora Package and Deployment
Wizard dostarczanego razem z Visual Basicem. Kreator ten tworzy program instalacyjny, który instaluje komponent i
wprowadza niezbędne wpisy do rejestru. Dostępne są także podobne programy innych firm.
Rysunek 20.9.
Pierwszy ekran
kreatora Package
and Deployment
Na następnej stronie kreatora należy wybrać rodzaj skryptu pakowania (Packaging Script). W tym przykładzie wybierz
None (rysunek 20.10).
Część VI ♦ Współoperatywność 370
Rysunek 20.10.
Wybór skryptu
pakowania
Na kolejnej stronie kreatora należy podać typ pakietu (rysunek 20.11). Dostępne są trzy typy pakietów:
u Standardowy program instalacyjny (Standard Setup Package): tworzy zwykły program instalacyjny.
u Instalacja internetowa: tworzy program instalacji przez Internet.
u Pliki zależne: program instalacyjny zawiera tylko pliki zależne.
Na kolejnym ekranie podajemy katalog, w którym umieszczone zostaną pliki instalacyjne (rysunek 20.12). Jeżeli docelowy
katalog nie istnieje, zostanie automatycznie utworzony.
Rysunek 20.11.
Wybór typu pakietu
instalacyjnego
Rysunek 20.12.
Wybór katalogu
na pakiet
instalacyjny
Następny ekran zawiera listę plików, które zostaną umieszczone w pakiecie (rysunek 20.13). Kreator ten automatycznie
umieszcza na liście wszystkie potrzebne pliki. Zauważ, że na liście oprócz samego komponentu znajdują się również
biblioteki Visual Basica i inne pliki. Jeżeli chcesz dodać jeszcze inne pliki do pakietu, kliknij przycisk Add.
371 Rozdział 20. ♦ Użycie Visual Basic z Access’em
Rysunek 20.13.
Lista plików
w programie
instalacyjnym
Na następnym ekranie ustawiamy parametry plików CAB. Pojedynczy plik CAB (plik jest skompresowany) może być
umieszczony na dysku CD-ROM lub w sieci, natomiast dla dyskietek należy utworzyć zwykle kilka plików.
Rysunek 20.14.
Ustawianie
parametrów
plików CAB
Na kolejnej stronie kreatora podajemy tytuł programu instalacyjnego (rysunek 20.15). Dobrze jest wpisać czytelną nazwę
programu, ponieważ właśnie ten napis zobaczy użytkownik po uruchomieniu programu instalacyjnego.
Rysunek 20.15.
Wpisywanie tytułu
instalacji
Na następnym ekranie wybieramy elementy, które umieszczone zostaną w menu Start (rysunek 20.16). Możesz utworzyć
grupę programów, w której będzie znajdowała się ikona instalowanego programu. Ponieważ zajmujemy się komponentem,
nie będzie potrzebna żadna grupa.
Część VI ♦ Współoperatywność 372
Rysunek 20.16.
Definiowanie
elementów menu
Start
Na kolejnym ekranie podajemy katalog, do którego będzie zainstalowany nasz komponent (rysunek 20.17). Zamiast
instalować komponent do katalogu Windows\System, umieść go w katalogu aplikacji, co ułatwi utrzymanie porządku.
Rysunek 20.17.
Definiowanie
katalogu docelowego
Na następnym ekranie zaznaczamy, czy nasz komponent będzie zainstalowany jako plik współdzielony, czy nie (rysunek
20.18). Plik współdzielony to taki, który jest używany przez więcej niż jedną aplikację.
Rysunek 20.18.
Definiowanie plików
współdzielonych
Na ostatniej stronie kreatora podajemy nazwę skryptu pakowania, który przechowuje wszystkie ustawione przed chwilą
ustawienia do późniejszego odtworzenia. Kliknij przycisk Finish, aby utworzyć pakiet.
Rysunek 20.19.
Wpisywanie nazwy
skryptu i tworzenie
pakietu
Po utworzeniu pliku (lub plików) CAB zostanie również utworzony raport z utworzenia pakietu zawierający dodatkowe
informacje. Jeżeli chcesz, możesz go zapisać do pliku.
373 Rozdział 20. ♦ Użycie Visual Basic z Access’em
Wszystkie pliki instalacyjne znajdują się teraz w katalogu, który podałeś w trakcie pracy kreatora (rysunek 20.20). Pliki te
należy rozesłać do klientów, którzy zainstalują komponent na swoich komputerach tak jak wszystkie inne programy.
Dwukrotne kliknięcie ikony programu instalacyjnego (lub poprzez funkcję Dodaj/Usuń Programy w Panelu Sterowania)
uruchomi program instalacyjny, który zainstaluje komponent i inne potrzebne pliki (rysunek 20.21).
Rysunek 20.20.
Utworzone pliki
instalacyjne
Rysunek 20.21.
Uruchomiony
program
instalacyjny
Rozprowadzanie plików
przy użyciu kreatora Package and Deployment Wizard
Po utworzeniu plików instalacji musisz rozprowadzić je do użytkowników. Część Deploy kreatora Package and Deployment
Wizard zawiera procedurę ułatwiającą ten proces.
Uruchom kreator i na pierwszym ekranie kliknij przycisk Browse, aby odszukać plik projektu (np. cSoundObject.vbp, tak
jak na rysunku 20.22). Następnie kliknij przycisk Deploy.
Rysunek 20.22.
Kliknij przycisk
Deploy
Rysunek 20.23.
Wybór skryptu
dystrybucji
Rysunek 20.24.
Wybór pakietu do
dystrybucji
Następny ekran zawiera listę dostępnych metod dystrybucji. Można umieścić pakiet w lokalnym lub sieciowym
katalogu albo wysłać na serwer WWW (rysunek 20.25). W tym przykładzie użyjemy katalogu na dysku.
Na kolejnym ekranie kreatora wybieramy katalog, do którego będą wysyłane pliki pakietu (rysunek 20.26). Może być to
katalog na serwerze sieciowym.
Rysunek 20.25.
Wybór metody
dystrybucji
Rysunek 20.26.
Wybór katalogu
docelowego
Na ostatnim ekranie można podać nazwę skryptu, do którego zostaną zapisane ustawienia (rysunek 20.27). Można go użyć
przy kolejnym użyciu tego kreatora. Aby zakończyć pracę kreatora i umieścić pliki w katalogu dystrybucji, kliknij Finish.
375 Rozdział 20. ♦ Użycie Visual Basic z Access’em
Rysunek 20.27.
Wpisywanie
nazwy skryptu
i rozprowadzanie
pakietu
Wpisy w rejestrze
Aby komponent mógł działać, do rejestru muszą być wprowadzone odpowiednie informacje. Komponentowi musi zostać
przypisany globalny unikatowy identyfikator (GUID). Jest to identyfikator generowany w sposób losowy.
Gdy instalujemy aplikację przy użyciu programu instalacyjnego utworzonego za pomocą kreatora Package and
Deployment Wizard, niezbędne wpisy są tworzone automatycznie. Jeżeli nie został użyty kreator, musimy sami
zarejestrować komponent.
Jeżeli komponent jest w postaci pliku EXE, jest on automatycznie rejestrowany po uruchomieniu z wiersza poleceń
lub poprzez dwukrotne kliknięcie jego ikony w Explorerze.
Jeżeli komponent jest w postaci pliku DLL, do jego rejestracji należy użyć programu REGSVR32.EXE, który znajduje się w
katalogu Windows/System (WINNT/System32 w systemie Windows NT).
Aby zarejestrować komponent, wpisz poniższy wiersz w oknie Uruchom (rysunek 20.28):
REGSVR32.EXE "C:\Componnets\SoundObject.Dll"
Rysunek 20.28.
Ręczna rejestracja
ActiveX DLL przy
użyciu programu
REGSVR32
Można również wyrejestrowywać komponenty. Dla ActiveX EXE wykonaj ten program z wiersza poleceń dodając jako
parametr /UNREGSERVER. Dla ActiveX DLL do programu REGSVR32 dodaj parametr /U.
Zgodność komponentów
Jak wcześniej wspominaliśmy, komponent musi zostać prawidłowo zarejestrowany. W rejestrze Windows tworzony jest
dla niego tzw. GUID. Co się stanie, gdy po zainstalowaniu komponentu zostanie on zmodyfikowany? Gdy instalujemy
zmodyfikowany komponent, czy musi on zostać powtórnie zarejestrowany pod innym identyfikatorem GUID?
Aby odpowiedzieć na te pytania, wróćmy do okna właściwości projektu na zakładkę Component. Na tej zakładce znajduje
się kilka opcji w części zatytułowanej Version Compatibility: No Compatibility, Project Compatibility oraz Binary
Compatibility.
W czasie gdy tworzymy komponent, powinna być wybrana opcja Project Compatibility. Uruchamia to funkcję
zarządzania kluczami w rejestrze za każdą kompilacją komponentu.
Gdy komponent trafi już do klientów, zmień ustawienie na Binary Compatibility (rysunek 20.29).
Część VI ♦ Współoperatywność 376
Rysunek 20.29.
Wybrana opcja
Binary Compatibility
oraz wpisana nazwa
wzorcowego
pliku DLL
W polu tekstowym poniżej tą opcją podajemy nazwę pliku DLL względem którego utrzymujemy zgodność. Za pomocą
klawisza „...” możemy odszukać na dysku wzorcowy plik DLL. Teraz, gdy utworzymy nowy plik DLL, będzie on zgodny z
plikiem wzorcowym.
Uważaj, aby nie usunąć wzorcowego pliku DLL, do którego odwołujesz się
w opcji Binary Compatibility. Nadaj mu specjalną nazwę i zapisz w bez-
piecznym miejscu. Przykładem nazwy może być Binary-cSoundObject.dll,
informująca o wykorzystaniu tego pliku jako wzorca w opcji zgodności
binarnej.
Kiedy używamy opcji No Compatibility? Załóżmy, że po rozesłaniu komponentu cSound zdecydowałeś się usunąć metodę
PlaySound, zastępując ją metodą o innej nazwie. Wszystkie aplikacje używające tego komponentu przestaną działać,
ponieważ polegają one na nazwie metody PlaySound. W takim przypadku wybierz opcję No Compatibility, dzięki czemu
zostanie utworzony nowy GUID. Najlepiej w takiej sytuacji utworzyć nowy pakiet instalacyjny i rozesłać go tak jak za
pierwszym razem.
Do tego rozdziału dołączony został jeszcze obszerniejszy moduł obsługi błędów, który używa komponentu cError
(cErrorObject.dll). Na dysku znajduje się kompletny projekt ActiveX DLL, więc możesz go od razu użyć jako „globalny
moduł obsługi błędów”. Przy użyciu tego pliku DLL możesz użyć tego modułu w Accessie, VB, Office i innych
aplikacjach.
377 Rozdział 20. ♦ Użycie Visual Basic z Access’em
Rysunek 20.30.
Formularz ustawień
pracy modułu
obsługi błędów
Komponent cError
Komponent obsługi błędów wykonuje dużo operacji. Zawiera on sześć modułów klasowych:
u cComputerName – pobiera nazwę komputera.
u cDBConnection – tworzy połączenie ADO.
u cError – przetwarza informacje o błędach.
u cSound – odgrywa pliki dźwiękowe.
u cSystemInformation – pobiera informacje o komputerze, takie jak: system operacyjny, procesor, ilość
zainstalowanej i wolnej pamięci.
u cUserName – pobiera nazwę użytkownika Windows.
Istnieją dwa rodzaje komponentów ActiveX: formanty interfejsu użytkownika i programowe. Formanty interfejsu
użytkownika to takie, którymi zajmowaliśmy się w rozdziale 9., jak TreeView czy ListView. Użytkownicy mogą nimi
manipulować. Formanty programowe są dostępne tylko dla programistów, użytkownicy nie mogą nimi manipulować.
Przykładem może być ImageList lub CommonDialog.
Część VI ♦ Współoperatywność 378
Skompilowany formant ActiveX jest zapisany w pliku zwykle z rozszerzeniem OCX. Pojedynczy plik OCX może zawierać
kilka formantów. Przykładowo MSCOMCTL.OCX, dostarczany przez Microsoft, zawiera następujące formanty ActiveX:
ImageCombo, ImageList, ListView, ProgressBar, Slider, StatusBar, TabStrip, ToolBar oraz TreeView.
Formanty ActiveX są wewnątrzprocesowymi serwerami automatyzacji. Dlatego formant ActiveX, który utworzysz i
użyjesz w aplikacji Accessa, jest uruchamiany w jednym procesie razem z aplikacją Accessa, co daje doskonałą wydajność
programu.
Visual Basic zawiera wbudowany formant Timer, który nie jest dostępny z Accessa. Timer VB to formant programowy,
który może wykonywać procedurę co zadany okres czasu. Aby użyć formantu VB Timer, umieść ją na formularzu i ustaw
właściwość Interval na określony czas w milisekundach (1000 milisekund to 1 sekunda), tak jak pokazane jest na
rysunku 20.31. Procedura obsługi zdarzenia Timer wykonywana jest co podany okres czasu. Można umieścić wiele
stoperów na formularzu. Każdy z nich pracuje niezależnie.
Rysunek 20.31.
Ustawianie
właściwości Interval
formantu Timer
W tej części rozdziału utworzysz własny formant ActiveX Timer, który może zostać użyty w Accessie i innych
aplikacjach.
Rysunek 20.32.
Wybór formantu
ActiveX z okna
dialogowego
New Project
Tworzenie interfejsu
Po otwarciu projektu to co widzisz, wydaje się być formularzem. Nie jest to jednak formularz lecz obiekt UserControl.
Obiekt ten używany jest do tworzenia interfejsu formantu ActiveX. W oknie właściwości zmień nazwę z UserControl1.
na ctlTimer.
Formanty ActiveX mogą zawierać inne formanty. W naszym formancie ctlTimer użyjemy formantu PictureBox
pobranego z paska narzędzi (rysunek 20.33). Nazwij formant PictureBox picClock i ustaw jego właściwość Picture
na CirClock.bmp z podkatalogu Bitmaps\Gauge w katalogu, gdzie zainstalowałeś Visual Basic. Ten rysunek zegara będą
widzieli programiści, używając tego formantu.
Rysunek 20.33.
Wstawianie
formantu PictureBox
do UserControl
Następnie przenieś formant Visual Basica Timer z paska narzędzi do naszego formantu i nazwij go ctlVBTimer (rysunek
20.34). Zauważ, że w oknie właściwości formantu znajduje się właściwość Interval. Będziemy używać tej właściwości
w naszym formancie ActiveX.
Rysunek 20.34.
Wstawianie
formantu VB Timer
do UserControl
Teraz zmniejszymy nasz formant. Najpierw przesuń formant VB Timer dokładnie na formant PictureBox, a następnie
wybierz Send to Back z menu Format. Spowoduje to ukrycie formantu. Teraz zmniejsz rozmiar obiektu UserControl tak,
aby był widoczny tylko formant PictureBox (rysunek 20.35).
Część VI ♦ Współoperatywność 380
Rysunek 20.35.
Zmniejszanie
UserControl
Ponieważ tworzymy formant programowy, użytkownik nigdy go nie zobaczy. We właściwościach obiektu UserControl
ustaw właściwość InvisibleAtRuntime na True.
Zapisywanie projektu
Aby zapisać projekt, wybierz Save Project z menu File. Najlepiej zapisać plik projektu (plik .vbp) i formant (plik .ctl) w
tym samym katalogu, np. Formant Timer.
Pierwszy ekran kreatora jest ekranem informacyjnym (rysunek 20.37). Kliknij przycisk Next.
381 Rozdział 20. ♦ Użycie Visual Basic z Access’em
Rysunek 20.37.
Ekran informacyjny
kreatora ActiveX
Control Interface
Wizard
Po prawej stronie ekranu mamy listę standardowych właściwości, metod i zdarzeń (rysunek 20.38). Usuń wszystkie
pozycje z tej strony. Po lewej stronie okna wybierz właściwość Interval oraz zdarzenie Timer i przenieś je na prawą
stronę. Kliknij Next.
Rysunek 20.38.
Ekran kreatora
Selected Interface
Members
Na ekranie Create Custom Interface Members kliknij Next, ponieważ dodaliśmy już wszystkie interesujące nas elementy
(rysunek 20.39).
Rysunek 20.39.
Ekran kreatora
Create Custom
Interface Members
Na ekranie Set Mapping wybierz właściwość Interval oraz zdarzenie Timer i przypisz je do UserControl (rysunek
20.40). Aby przejść do kolejnego ekranu, kliknij przycisk Next.
Rysunek 20.40.
Ekran Set Mapping
Na ekranie Set Attributes wybierz właściwość Interval i upewnij się, że typ jest ustawiony na Long (rysunek 20.41),
następnie kliknij przycisk Next.
Część VI ♦ Współoperatywność 382
Rysunek 20.41.
Ekran Set Attributes
Na ekranie Finished kliknij przycisk Finish (rysunek 20.42). Kreator utworzy program dodający właściwość Interval
oraz zdarzenie Timer do formantu ActiveX. Można również zapisać raport na dysku.
Rysunek 20.42.
Ekran Finished
Otwórz okno kodu dla obiektu UserControl i obejrzyj program (rysunek 20.43). Kreator utworzył Property Get oraz
Property Let dla właściwości Interval. Zostało również wygenerowane zdarzenie Timer.
Wywoływanie zdarzenia
Nasz formant ActiveX zawiera formant VB Timer, który posiada zdarzenie Timer. Nasz formant również posiada
zdarzenie Timer, które zostało dodane przez kreator ActiveX Control Interface Wizard. Musisz zsynchronizować te dwa
zdarzenia tak, aby po zajściu zdarzenia Timer z formantu Visual Basica uruchamiane było zdarzenie Timer naszego
formantu ActiveX.
Rysunek 20.43.
Kod wygenerowany
przez ActiveX
Control Interface
Wizard
383 Rozdział 20. ♦ Użycie Visual Basic z Access’em
Aby to zrealizować, będziesz musiał wywołać zdarzenie (ang. raise)w UserControl. W oknie programowania wybierz
ctlVBTimer z listy obiektów po lewej stronie u góry okna. Następnie wybierz Timer z listy zdarzeń obok listy obiektów.
Utworzona zostanie procedura obsługi zdarzenia Timer (rysunek 20.44). Wprowadź kod pokazany na rysunku 20.44, który
wywoła zdarzenie Timer.
Rysunek 20.44.
Wywołanie
procedury
RaiseEvent
Jaki jest efekt tych operacji? Gdy uruchomiona zostanie obsługa zdarzenia z obiektu Timer Visual Basica, wywoła on
zdarzenie Timer formantu ActiveX. Uruchomi to procedurę obsługi zdarzenia utworzoną dla formantu ActiveX.
Gdy programista umieszcza na formatce Twój formant Timer, ustawia właściwość Interval. Wartość właściwości
Interval musi być zsynchronizowana z właściwością obiektu VB Timer.
Formanty ActiveX zwykle są tworzone, gdy są dodawane do formularza przez programistów oraz gdy zawierający je
formularz jest otwierany. Odpowiednim miejscem do zsynchronizowania właściwości Interval jest zdarzenie
ReadProperties, ponieważ jest ono wywoływane w trakcie otwierania formularza zawierającego formant. Poniższy
fragment programu ustawia wartość właściwości Interval w obiekcie VB Timer na identyczną z tej samej właściwości
w Twoim formancie.
' Ustaw wartość właściwości Interval z obiektu VB Timer
' na taką samą jak w obiekcie Timer
UserControl.ctlVBTimer.Interval = Me.Interval
Mając otwarty projekt formantu ActiveX, możesz dodać projekt dla standardowego pliku EXE i przetestować formant na
formularzu VB. Aby dodać nowy projekt, wybierz Add Project z menu File. W oknie New Project wybierz Standard EXE.
Zauważ, że oba projekty są wyświetlane w oknie Project Explorer (rysunek 20.45).
Rysunek 20.45.
Dodajemy projekt do
testowania formantu
Ponieważ mamy teraz dwa projekty, ustaw Startup Project na Standard EXE (Project1). W oknie Project Explorer kliknij
prawym klawiszem myszy Project1. i wybierz Set as Startup. Teraz, gdy będziesz uruchamiał projekt, uruchomiony
zostanie Project1. Następnie zamknij wszystkie otwarte okna projektu. W menu Windows wybierz kolejno otwarte okna
(oprócz Form1) i zamknij je.
Część VI ♦ Współoperatywność 384
W trybie projektowania formularza Form1. otwórz pasek narzędzi. Zauważ, że znajduje się tam nowy formant o nazwie
ctlTimer. Wstaw ten formant na formularz VB (rysunek 20.46).
Nowy formant Timer może być używany identycznie jak inne formanty (np.: TextBox). Można ustawiać jego właściwości z
okna właściwości oraz tworzyć procedury obsługi zdarzeń.
Rysunek 20.46.
Wstawianie
formantu Timer
na testowy formularz
W oknie właściwości ustaw właściwość Interval na 5000. Ponieważ jest to czas w milisekundach, Timer będzie
wywoływany co 5 sekund.
Następnie wybierz Code z menu View, aby otworzyć okno programowania. Wybierz ctlTimer1. z listy obiektów oraz
Timer z listy zdarzeń. W procedurze obsługi zdarzenia wprowadź proste okno komunikatu (rysunek 20.47).
Rysunek 20.47.
Procedura obsługi
zdarzenia Timer
Uruchom projekt, wybierając Start z menu Run (lub naciśnij F5). Co pięć sekund na ekranie pojawi się okno komunikatu
(rysunek 20.48). Zauważ, że komponent nie jest widoczny w czasie wykonywania programu.
385 Rozdział 20. ♦ Użycie Visual Basic z Access’em
Rysunek 20.48.
Okno komunikatu
otwiera się
co 5 sekund
Otwórz projekt formantu ActiveX i wybierz Make cTimerControl z menu File. Zapisz plik OCX w tym samym katalogu co
projekt.
Otwórz nowy formularz w trybie projektowania w bazie danych Accessa. Z menu Wstaw wybierz Formant ActiveX. Wybierz
formant Timer (cTimerControl) z listy, a następnie kliknij OK, aby zamknąć okno (rysunek 20.49).
Rysunek 20.49.
Wybór
cTimerControl
z okna Wstawianie
formantu ActiveX
Tak jak robiłeś to na formularzu VB, ustaw właściwość formantu Interval na 5000. oraz utwórz okno komunikatu w
obsłudze zdarzenia Timer.
Rysunek 20.50.
Kilka formantów
Timer pracujących
jednocześnie
Część VI ♦ Współoperatywność 386
Rysunek 20.51.
Okno właściwości
formantu ImageList
Można również utworzyć okno właściwości dla naszego komponentu Timer. W oknie projektu komponentu ActiveX
wybierz Add Property Page z menu Project. W oknie dialogowym Add Property Page wybierz kreator VB Property Page
Wizard. Kliknij przycisk Open w celu uruchomienia kreatora.
Na ekranie Select the Property Pages kliknij przycisk Add i dodaj stronę General (rysunek 20.52).
Rysunek 20.52.
Kreator VB Property
Page Wizard: strona
Select the Property
Pages
Na ekranie Add Properties kliknij zakładkę General. Przesuń właściwość Interval z listy po lewej stronie okna do
listy po prawej (rysunek 20.53) a następnie kliknij Next.
Rysunek 20.53.
Kreator VB Property
Page Wizard: strona
Add Properties
Na ekranie Finished kliknij przycisk Finished. Kreator utworzy okno właściwości i dodatkowo może być utworzony raport.
Zauważ, że okno właściwości znajduje się w oknie Project Explorer (rysunek 20.54).
387 Rozdział 20. ♦ Użycie Visual Basic z Access’em
Rysunek 20.54.
Okno właściwości
w oknie Project
Explorer
Rysunek 20.56.
Dodanie formantów
Slider oraz UpDown
do obiektu
UserControl
Kliknij prawym klawiszem myszy formant ctlUpDown i wybierz Properties z menu kontekstowego, co spowoduje
otwarcie okna właściwości. W oknie właściwości należy związać formant UpDown z Slider przy użyciu właściwości
Buddy. Od tej chwili formanty będą działać razem bez pisania ani jednego wiersza kodu.
Kliknij zakładkę Buddy w oknie właściwości. W polu tekstowym Buddy Control wprowadź ctlSlider. Spowoduje to
połączenie formantów ctlSlider i ctlUpDown. Wybierz Value z listy Buddy Property, co spowoduje, że zmiana wartości
ctlUpDown zmieni wartość ctlSlider. Zaznacz pole wyboru AutoBuddy i kliknij OK, aby zamknąć okno właściwości
(rysunek 20.57).
Rysunek 20.57.
Ustawienie
właściwości Buddy
w oknie właściwości
Zapisywanie projektu
Zapisz projekt i obiekt UserControl, wybierając Save Project z menu File. Najlepiej zapisać projekt (plik .vbp) i obiekt
UserControl (plik .ctl) w tym samym katalogu.
Otwórz formularz w trybie projektowania w bazie Accessa. Wybierz Formant ActiveX z menu Wstaw, a następnie
wybierz cSliderControl z listy. Kliknięcie OK zamyka okno dialogowe.
Formant cSlider działa teraz na formularzu Accessa (rysunek 20.59). Gdy zostanie kliknięty UpDown, zmieni się również
pozycja formantu Slider.
Rysunek 20.59.
Formant ActiveX na
formularzu Accessa
Uruchom kreator i wybierz plik projektu komponentu cSlider (plik .vbp). Kliknij przycisk Package, aby przejść do
następnego ekranu (rysunek 20.60). Wybierz Internet Package i kliknij przycisk Next.
Rysunek 20.60.
Wybór pakietu
internetowego
Wybierz skrypt pakowania (rysunek 20.61). Ponieważ pierwszy raz wykonujesz pakiet internetowy, wybierz None i kliknij
Next.
Rysunek 20.61.
Wybór skryptu
pakowania
Rysunek 20.62.
Wybór typu pakietu
Wybierz katalog, gdzie zapisywane będą pliki pakietu i kliknij Next (rysunek 20.63). Domyślnie tworzony jest katalog
pakietu jako podkatalog foldera z plikiem projektu.
Rysunek 20.63.
Wybór katalogu
pakietu
Ekran Included Files zawiera wszystkie pliki niezbędne do użycia formantu ActiveX. Dołączone są również biblioteki VB i
inne niezbędne pliki (rysunek 20.64). Kliknij przycisk Next.
Rysunek 20.64.
Pliki zawarte
w pakiecie
internetowym
Na ekranie File Source podaj położenie plików zawartych w pakiecie instalacyjnym (rysunek 20.65). Plik, w którym
znajduje się Twój formant ActiveX (plik OCX), znajdzie się w skompresowanym pliku cab. Domyślnym ustawieniem dla
bibliotek VB i innych plików Microsoftu jest witryna WWW firmy Microsoft. Możesz pozostawić domyślne ustawienie,
ponieważ w razie potrzeby użytkownicy załadują potrzebne pliki z serwera WWW Microsoftu.
Na ekranie Safety wymieniony jest tylko formant cSlider. Wybierz Yes dla opcji Safe for Scripting oraz Yes dla Safe for
Initialization (rysunek 20.66). Jest to Twoja deklaracja, że komponent jest bezpieczny. Kliknij Next, aby przejść do
następnego ekranu.
Na ostatnim ekranie możesz podać nazwę skryptu, aby zapisać ustawienia wszystkich opcji w kreatorze. Używając
zapisanego skryptu, nie trzeba ponownie wybierać ustawień w kreatorze (rysunek 20.67). Kliknij Finish, aby wygenerować
pakiet.
391 Rozdział 20. ♦ Użycie Visual Basic z Access’em
Rysunek 20.65.
Wybór źródła plików
Rysunek 20.66.
Ustawianie ustawień
bezpieczeństwa
Rysunek 20.67.
Wybór nazwy dla
skryptu oraz
tworzenie pakietu
Po zakończeniu pracy kreator tworzy raport, który może zostać zapisany na dysku.
Dwukrotne kliknięcie pliku cSliderControl.htm otwiera stronę w przeglądarce internetowej. Formant cSlider działa w
przeglądarce identycznie jak w formularzach VB i Accessa.
Rysunek 20.68.
Pliki w katalogu
pakietu
internetowego
Część VI ♦ Współoperatywność 392
Rysunek 20.69.
Formant cSlider na
stronie WWW
Aby zobaczyć kod HTML strony WWW, otwórz ją w Internet Explorerze i wybierz Źródło z menu Widok. Zauważ, że w
kodzie HTML znajduje się formant cSlider oraz jego classID (rysunek 20.70):
<OBJECT CLASSID="clsid:5220cb21-c88d-11cf-b347-00aa00a28331">
<PARAM NAME="LPKPath" VALUE="LPKfilename.LPK">
</OBJECT>
-->
<OBJECT ID="cSlider"
CLASSID="CLSID:A3251E4A-CCCF-11D2-A8AC-0010A4F61FE6"
CODEBASE="cSliderControl.CAB#version=1,0,0,0">
</OBJECT>
Jeżeli chcesz używać formantu cSlider na innej stronie WWW, skopiuj kod obiektu HTML z jednej strony do innej.
Rysunek 20.70.
Formant ActiveX
w kodzie HTML
Część VII
Zagadnienia wielodostępu
W tej części:
u Zagadnienia wielodostępu, serwer plików, blokowanie.
u Replikacja i JRO.
u Bezpieczeństwo.
Rozdział 21.
Zagadnienia wielodostępu, serwer
plików, blokowanie
W tym rozdziale:
u Konflikty.
u Konfiguracja.
u Blokady Accessa i Jet.
u Blokady Oracle / SQL Server.
Gdy baza danych Accessa opuszcza swoje środowisko programistyczne i zaczyna być używana przez ludzi, dla których
była utworzona, jest narażona na efekty uboczne wielodostępu. Najbardziej irytującym problemem powodowanym przez
wielodostęp są konflikty w dostępie do rekordów.
Konflikty
Ważne jest, aby pamiętać, że każda wieloużytkownikowa baza danych jest narażona na problemy powodowane przez
blokady i konflikty. Ukrywanie komunikatów o błędach lub nadzieja na to, że wszystko dobrze pójdzie, nie usunie
problemów. Mimo że zagadnienia wielodostępu wydają się skomplikowane, dokładne zrozumienie, w jaki sposób Jet
blokuje dane i zarządza wieloma użytkownikami, nie jest trudne. Pozostawienie nierozwiązanych zagadnień wielodostępu
tworzy zwykle dużo większe problemy nękające użytkowników, klientów i wpływające na naszą reputację. Nieprawidłowe
rozwiązanie problemów wielodostępu prowadzi do następujących problemów:
u Nowe rekordy nie są zapisywane – nie ma nic gorszego dla użytkownika wprowadzającego dane do aplikacji, jak
zniknięcie wprowadzonych danych. Fakt, że prawdopodobnie nie będzie mógł powtórzyć tego błędu, nie znaczy,
że problem nie istnieje, raczej mają rację mówiąc, że aplikacja jest niepewna.
u Zmiany nie zostają zapisane – klient może nawet nie zauważyć, że zmiany nie zostały zapisane. Jednak kiedyś w
przyszłości arkusz bilansu będzie nieprawidłowy lub nie będzie zgadzać się stan magazynu, albo zamówienie
ważnego klienta zostanie wysłane pod zły adres. Są to skomplikowane problemy i często nie są wykrywane na
czas.
u Użytkownicy mogą otrzymywać tajemnicze komunikaty, że system nie może zwrócić żądanych danych. Mimo że
jest to mniej dramatyczna sytuacja, nie należy rozczarowywać użytkowników, gdy system załamuje się przy
niewielkim obciążeniu.
W Accessie zagadnienia wielodostępu to nie tylko blokowanie i zdejmowanie blokad. Ponieważ aplikacja przechowywana
jest w pojedynczym pliku, a aplikacja ma formularz związany bezpośrednio z danymi, dyskusja na temat wielodostępu
musi zawierać zagadnienia dotyczące zarządzania plikami, konfiguracji, technik tworzenia interfejsu użytkownika oraz
właściwości kwerend i formularzy. Zwykle aplikacja Accessa wymaga kombinacji kilku taktyk, ponieważ napotkasz różne
problemy wielodostępu w kilku różnych miejscach aplikacji.
395 Rozdział 21. ♦ Zagadnienia wielodostępu, serwer plików, blokowanie
Konfiguracja
Aplikacja Accessa może być skonfigurowana na kilka sposobów, aby przystosować ją do obsługi wielu użytkowników.
Każdy z nich ma swoje wady i zalety. Podstawowe zalety i wady są opisane poniżej.
u Konfiguracja sieciowa. W takiej konfiguracji pojedynczy plik MDB umieszczony jest na serwerze sieciowym, a
użytkownicy uruchamiają aplikację z tego serwera. Zaletą takiej konfiguracji jest łatwość konserwacji, ponieważ
wystarczy zamienić jeden plik programu. Jednak wszystkie formularze, raporty, moduły, kwerendy oraz Access i
biblioteki DLL muszą być przesłane poprzez sieć, co powoduje duże obciążenie sieci prowadzące do obniżenie
wydajności aplikacji. W tej konfiguracji do manipulacji danymi prawdopodobnie używasz formularzy
związanych. Jak jest to przedstawione później, formularze związane powodują konflikty przy jednoczesnym
dostępie do danych.
u Oddzielenie danych od programu. Taka konfiguracja jest zwykle nazywana konfiguracją z użyciem zdalnej bazy
danych (zauważ, że określenie „zdalny” przechodzi transformację w czasach Internetu i niedługo może okazać się
archaiczne w tym kontekście), ponieważ dane są oddzielone od programu, ale silnik bazy danych pozostaje na
maszynie użytkownika. W odróżnieniu od konfiguracji klient – serwer silnik bazy danych Accessa pobiera dane,
blokuje je oraz zwalnia blokady w pliku MDB na serwerze. Zdolność do wielodostępu w takiej konfiguracji zależy
od zdolności silników bazy danych wszystkich użytkowników do współdziałania oraz od serwera plików, który
utrzymuje cały ruch w sieci. Jak do tej pory jest to zalecana metoda pisania aplikacji wielodostępnych w Accessie.
Główną zaletą tej metody jest dobra wydajność oraz, jeżeli jest odpowiednio zaimplementowana, kontrola nad
danymi. Ponieważ dane znajdują się na serwerze sieciowym, tylko one są przesyłane, więc obciążenie sieci jest
znacznie zmniejszone. Główną wadą takiego rozwiązania jest konieczność zainstalowania na każdym komputerze
klienta Accessa oraz aplikacji jako plik MDB lub MDE (skompilowana wersja formularzy, kwerend, raportów i
modułów aplikacji), co zwiększa nakłady na utrzymanie systemu.
u Replikacja. W konfiguracji z użyciem replikacji użytkownicy współdzielą dane, ale nie są one wspólne jak przy
użyciu konfiguracji sieciowej czy zdalnej bazy danych. Każdy użytkownik lub małe grupy użytkowników mają
prywatne kopie danych, które są aktualizowane między sobą przy użyciu mechanizmu replikacji Jet. Zaletą tego,
że użytkownicy mają swoje kopie danych, jest wyeliminowanie blokad, ale są one zastąpione problemami
replikacji, które są równie skomplikowane jak problem konfliktów. Inną zaletą jest umożliwienie użytkownikom
asynchronicznej replikacji danych, jeżeli odłączają się od sieci. Wadą tej metody jest to, że nawet w małych
grupach użytkowników używających wspólnych danych aplikacja musi radzić sobie zarówno z problemami
wielodostępu jak i replikacji. I na koniec, replikowane bazy danych są zwykle większe od tych, które nie używają
tej techniki.
u Konfiguracja klient-serwer. Access 2000 wreszcie umożliwia programistom tworzenie aplikacji klient-serwer przy
użyciu projektów dostępu do danych (ADP). W konfiguracji klient-serwer zarówno dane jak i silnik bazy danych
pozostają zdalne. Serwer Oracle, SQL Server lub inny centralnie zarządza danymi i blokadami oraz dba o
zapewnienie wielodostępu. Nie znaczy to, że nie musisz się tym przejmować, znaczy to, że musisz brać pod uwagę
inny zestaw założeń, możliwości i reguł. Najważniejszą zaletą takiej konfiguracji jest wydajność, stabilność i
możliwość obsłużenia dużej liczby użytkowników. Wadą jest koszt rozwiązania oraz zwiększony stopień
skomplikowania.
W tym rozdziale zajmiemy się zagadnieniami wspólnymi dla konfiguracji sieciowej, zdalnej bazy danych oraz klient-
serwer. Użycie replikacji przedstawione będzie w rozdziale 22. „Replikacja i JRO”.
W Accessie mamy możliwość wielu ustawień na poziomie bazy danych, na formularzach, kwerendach, zestawach
rekordów oraz na poziomie wykonania programu, które należy odpowiednio ustawić, aby aplikacja mogła niezawodnie
obsługiwać wielu użytkowników. Prawie wszystkie tematy przedstawiane w tym rozdziale znajdują się w różnych
miejscach aplikacji oraz techniki lub kombinacje technik różnią się od rodzaju aplikacji. Podstawą sukcesu w
wielodostępnej aplikacji jest planowanie, przewidywanie i testowanie.
Omówienie blokowania
Przed oddaniem wielodostępnej bazy danych musi być ona umieszczona w miejscu, do którego mają dostęp użytkownicy,
oraz baza musi zostać otwarta w trybie współdzielonym. Można to wykonać na kilka sposobów.
W oknie Opcje (Narzędzia, Opcje, Zaawansowane) znajduje się opcja Domyślny tryb otwarcia. Można ustawić tryb
wyłączny (tylko jeden użytkownik) lub tryb udostępniony.
Gdy wybrany jest tryb wyłączny, bazę danych może otworzyć tylko jeden użytkownik. Gdy baza danych dostanie otwarta
w tym trybie, Access zmienia nagłówek pliku LDB lub pliku blokad Accessa (więcej informacji o tym pliku w części
rozdziału: „Plik LDB”), aby zapobiec otwarciu bazy przez innego użytkownika. Oczywiście ta opcja nie może być
używana w aplikacjach wielodostępnych. Jednak czynności konserwacyjne, jak kompresowanie i naprawianie, muszą być
wykonywane przy bazie otwartej na wyłączność.
Ustawienie trybu udostępnionego pozwala na otwarcie bazy danych przez kilku użytkowników jednocześnie. Przy
otwieraniu bazy informacja o użytkownikach jest zapisywana w pliku LDB oraz przeprowadzana jest negocjacja
blokowania i zwalniania stron i rekordów.
Ustawienie tych opcji jest możliwe przy użyciu parametrów w wierszu poleceń przy uruchamianiu Accessa. W tabeli 21.1
opisane są niektóre parametry.
Tabela 21.1.
Parametry wiersza poleceń Accessa
Parametr Opis
/Excl Otwiera bazę na wyłączność. Może być użyte nawet z bazą ustawioną na tryb udostępniony
/Ro Tylko do odczytu. Baza jest dostępna dla wielu użytkowników, ale nie mogą być zapisane
zmiany. Nie są zakładane żadne blokady
Brak Jeżeli nie zostanie podany żaden parametr, baza otwierana jest w trybie ustawionym
w oknie opcji
Programista ma możliwość ustawienia w bazie domyślnego trybu blokowania rekordów. Możliwe są dwa tryby:
blokowanie rekordu i blokowanie strony.
W Accessie 2000, Jet 4.0 daje programistom możliwość wyboru pomiędzy blokowaniem stron a blokowaniem rekordów.
Teraz użytkownik może zablokować tylko edytowany rekord bez niepotrzebnego blokowania innych rekordów. Ponieważ
rekord może zostać zablokowany tylko na chwilę (jak w przypadku wykonywania instrukcji SQL Delete, Update lub
Insert), szansa konfliktu dwóch użytkowników podczas edycji rekordu jest mniejsza, niż gdy zostanie zablokowanych
kilka rekordów podczas blokowania strony. Do tej pory szansa konfliktu była zwielokrotniana przez ilość rekordów na
stronie, co było trudne do określenia. Ilość rekordów na stronie zależy od rozmiaru rekordu oraz kiedy był wprowadzony, więc
trudno jest przewidzieć potencjalne konflikty.
Blokowanie rekordów jest domyślnym ustawieniem, jednak nie oznacza, że jest to zawsze najlepszy wybór. W sytuacjach,
gdy wydajność jest najważniejsza a potencjalne konflikty są rzadkie lub możliwe do zarządzania, nakład czasu na
blokowanie rekordów może okazać się zbyt duży. Rozważmy system obsługi bankowego kantoru wymiany walut, gdzie
397 Rozdział 21. ♦ Zagadnienia wielodostępu, serwer plików, blokowanie
rekordy są częściej wprowadzane niż poprawiane. Ponieważ taki system powinien działać szybko, z rzadkimi
przestojami powodowanymi przez konflikty. W przedstawianym przez nas przypadku blokowanie stron może być
odpowiednie.
W innym przypadku, gdzie współbieżność jest duża i jest niedopuszczalna edycja więcej niż jednego rekordu naraz,
blokowanie rekordów odpowiada tym warunkom. Jest to szczególnie ważne, gdy rekordy są często zmieniane. Wracając do
przykładu banku, baza danych obsługująca operacje na rachunkach klientów musi być cały czas dostępna. Powinna ona
zablokować rekord na wyłączność w trakcie jego edycji, ponieważ występuje ryzyko zapisania zmian zrobionych przez
innego użytkownika. Ponadto, gdy jest zmieniany rekord rachunku, nie może on blokować żadnych sąsiednich rachunków.
Blokowanie rekordów jest również odpowiednie w sytuacjach, gdy rekord musi być otwarty przez dłuższy okres czasu i
zabezpieczony przed zmianą przez innych użytkowników. Przykładem może być kontrola zgodności z przepisami informacji
o kliencie lub sprawdzenie zdolności kredytowej. Nie chcesz, aby rekord zmienił się, dopóki nie skończysz kontroli. Zwykle,
gdy użytkownik trzyma zablokowany rekord przez dłuższy czas, skutkuje to zablokowaniem kilku innych rekordów na czas
edycji. Dobra praktyka mówi, aby nie blokować rekordu na długi okres czasu chyba, że jest to absolutnie konieczne.
Od teraz programiści mają możliwość kontrolowania wielodostępu na poziomie stron lub rekordów. Taka kombinacja daje
dużą elastyczność.
Plik LDB
Plik blokad jest plikiem tymczasowym tworzonym przez Access w czasie otwierania bazy danych. Zawiera on informacje
o blokadach założonych w bazie danych oraz użytkownikach używających bazy. Gdy baza jest zamykana, plik zostaje
usunięty. Plik ten ma nazwę identyczną z nazwą obsługiwanej bazy danych i rozszerzenie LDB. Zawsze tworzony jest w
tym samym katalogu co baza danych.
Blokowanie optymistyczne
Jako domyślne w Accessie, blokowanie optymistyczne jest najłatwiejsze do implementacji i zwykle jest dobrym wyborem.
Gdy rekord jest optymistycznie zablokowany, zakłada się, że nie wystąpi konflikt i rekord jest blokowany tylko na czas
zapisu do bazy. Powoduje to, że dane są łatwo dostępne, ponieważ nikt nie blokuje na długo dostępu do danych. Podczas
gdy użytkownik wprowadza zmiany do rekordu, inni użytkownicy mogą również zmieniać ten rekord i pierwszy
użytkownik, który zapisze dane, zablokuje innych użytkowników. Mimo że optymistyczne blokowanie jest łatwe do
wykonania, zwykle powoduje kilka problemów. Ten typ blokowania wywołuje najstarsze zagadnienie wielodostępności –
czyje zmiany powinny zostać zapisane. Jeżeli Karol otworzy rekord i umieści na nim optymistyczną blokadę, nic nie
przeszkodzi Katarzynie otworzyć ten sam rekord, aby wprowadzić zmiany. Gdy Katarzyna zapisze swoje zmiany przed
Karolem, Karol zobaczy komunikat:
"Silnik bazy Microsoft Jet zatrzymał proces, ponieważ inny użytkownik próbuje zmienić te same dane w tym samym
czasie."
Wcześniejsze wersje Accessa przedstawiały okno dialogowe, które pozwalało użytkownikowi wybrać między nadpisaniem
zmian innego użytkownika, niezapisywaniem własnych zmian lub skopiowaniem danych do schowka. Okno konfliktu przy
zapisie nie przedstawiało odpowiednio dużo informacji, aby dokonać sensownego wyboru wśród prezentowanych opcji.
Nowe okno konfliktu przy zapisie prze to, że nie oferuje żadnego wyboru, jest jednoznaczne. W dalszej części rozdziału
przedstawimy konflikty przy zapisie i omówimy kilka sposobów na lepszą obsługę błędów.
Blokowanie pesymistyczne
Blokowanie pesymistyczne jest odwrotnością blokowania optymistycznego. Gdy rekord jest pesymistycznie zablokowany,
nikt z innych użytkowników nie może go otworzyć aż do jego zapisania. Wiele systemów baz danych używa tego sposobu
blokowania,
więc powinno być znane wielu programistom a użytkownicy zaznajomieni z jego konsekwencjami. Mimo że blokowanie
pesymistyczne eliminuje konflikty przy zapisie, nie jest pozbawione problemów.
Część VII ♦ Zagadnienia wielodostępu 398
Gdy zostanie uruchomione blokowanie pesymistyczne, spada dostępność i współbieżność dostępu do danych obniża się.
Jeżeli zostanie użyte blokowanie stron, problem zostanie powiększony, ponieważ zablokowane zostaną również wszystkie
rekordy na stronie. Jeżeli proces edycji danych jest czasochłonny, a pracuje równocześnie wielu użytkowników, blokady
pesymistyczne powinny być dokładnie przemyślane. Niektóre aplikacje, jak obsługa sprzedaży i magazynu,
prawdopodobnie skorzystają na zastosowaniu blokad pesymistycznych, ponieważ jest tu bardzo ważna kontrola
rekordów, jednak systemy kontroli czasu prawdopodobnie przez zastosowanie pesymistycznego blokowania zanotują
spadek wydajności. Wiele z tych ostrzeżeń dotyczy blokowania pesymistycznego w kontekście mechanizmu blokowania
stron Accessa. Teraz, gdy dostępne jest blokowanie rekordów, pesymistyczne blokowanie powinno być częściej
akceptowane i używane.
Blokowanie rekordów
Najważniejszą zaletą blokowania rekordów jest zwiększenie wielodostępu. Przez możliwość zablokowania tylko
zmienianego rekordu więcej użytkowników może dostać się do danych bez wystąpienia konfliktów przy blokowaniu lub
zapisie. Użycie blokowania rekordów pozwala programistom na użycie blokowania pesymistycznego w większej ilości
aplikacji. Użytkownicy zauważą, że zachowanie aplikacji jest bardziej im znane i bardziej intuicyjne. Użytkownik
oczekuje, że po prostu otworzy rekord, zmieni go i zmiany zostaną zapisane. W poprzednich wersjach Accessa
blokowanie stron powodowało, że pesymistyczne blokowanie było zbyt kosztowne w przypadku dużej ilości
użytkowników. Użytkownicy musieli się liczyć z tym, że ktoś inny zablokuje ich zmiany, a programiści będą obmyślać
sposoby na przewidywanie zachowań użytkowników (rozszerzanie rekordów, tabele tymczasowe itd.). Blokowanie
rekordów jest najważniejszym ulepszeniem Jet 4.0 i powinno spowodować utworzenie wielu popularnych i elastycznych
aplikacji.
ADO dostarcza właściwości LockType w obiekcie recordset, która wskazuje na rodzaj blokady, jaka nałożona zostanie
na rekord w czasie jego edycji. Właściwość tę można zmieniać przed otwarciem zbioru rekordów, a po jego otwarciu
można ją tylko odczytywać.
399 Rozdział 21. ♦ Zagadnienia wielodostępu, serwer plików, blokowanie
W tabeli 21.2 opisane są stałe używane dla właściwości LockType w Mictosoft.Jet.OLEDB.4.0. Inni dostawcy OLEDB
dostarczają różnych opcji. Aby sprawdzić, która opcja jest dostępna, użyj metody .Supports z parametrem adUpdate lub
adUpdateBatch.
Tabela 21.2.
Stałe typów blokowania w Jet 4.0 udostępniane przez dostawcę Mictosoft.Jet.OLEDB.4.0
Stała Opis
AdLockReadOnly Domyślne ustawienie. Zbiór obiektów nie może być zmieniany, jest
otwierany tylko do odczytu i rekordy nie są blokowane
AdLockPessimistic Pesymistyczne blokowanie rekordów
AdLockOptimistic Optymistyczne blokowanie w czasie wywoływania zdarzenia Update
ADLockBatchOptimistic Optymistyczne blokowanie dla uaktualniania wsadowego
Znajomość stanu blokady rekordu jest ważne w czasie tworzenia, testowania i utrzymywania aplikacji. Każdy proces, który
obsługuje dane, powinien być sprawdzony, czy spełnia założenia projektu. Wykonanie tego jest proste. Zatrzymaj
wykonanie programu i sprawdź wartość właściwości LockType w obiekcie recordset (rysunek 21.1).
Rysunek 21.1.
Właściwość
LockType obiektu
recordset
przedstawia rodzaj
blokady
Inna właściwość wskazuje na to, czy recordset był zmieniany. Właściwość EditMode zmienia się z początkowego
adEditNone na adEditInProgress w trakcie edycji rekordu oraz znów na adEditNone po udanym zapisaniu rekordu.
Wartość właściwości EditMode wskazuje na stan bufora używanego do zmiany i tworzenia rekordów. Możesz użyć tej
wartości do sprawdzenia, czy potrzebujesz wywołać metodę Update lub CancelUpdate, gdy operacja została przerwana.
Tabela 21.3.
Wartości właściwości EditMode dla obiektu recordset ADO
Stała Opis
Część VII ♦ Zagadnienia wielodostępu 400
Sprawdzanie blokad
Sposobem na sprawdzenie, jaka blokada została nałożona na rekord, jest odczytanie wartości właściwości LockType i
EditMode, ale większym problemem jest sprawdzenie, czy została nałożona blokada przez innego użytkownika na
potrzebne nam dane. Jedynym sposobem na zweryfikowanie blokad jest spowodowanie konfliktu.
Dostawca Jet OLEDB zwraca niektóre informacje o blokadach użytkownika w przypadku wystąpienia błędu. W przypadku
konfliktu należy sprawdzić wartość właściwości
Connection.Errors(index).SQLState
aby stwierdzić, jaki błąd wystąpił. W tabeli 21.4 wymienione zostały niektóre kody błędów powodowanych przez
konflikty, które można odczytać z właściwości SQLState.
Tabela 21.4.
Błędy blokowania dostarczone przez dostawcę Jet 4.0 OLEDB
Kod Komunikat
3006 Baza danych <nazwa> jest otwarta na wyłączność
3008 Tabela <nazwa> jest otwarta przez innego użytkownika lub otwarta jest przez interfejs
użytkownika i nie może być zmieniana przez program
3009 Próbujesz zablokować tabelę <nazwa> w czasie jej otwierania, ale nie może być zablokowana,
ponieważ jest używana. Poczekaj chwilę i ponów operację
3027 Nie można uaktualniać rekordu. Baza danych lub obiekt jest tylko do odczytu
3046 Nie można zapisać, zablokowane przez innego użytkownika
3158 Nie można zapisać rekordu, zablokowany przez innego użytkownika
3164 Pole nie może być zmienione, ponieważ inny użytkownik lub proces zablokował związany
rekord lub tabelę
3186 Nie można zapisać, zablokowane przez użytkownika <nazwa> na komputerze <komputer>
3187 Nie można odczytać, zablokowane przez użytkownika <nazwa> na komputerze <komputer>
3188 Nie można zapisać, zablokowane przez inną sesję na tym komputerze
Tabela 21.4.
Błędy blokowania dostarczone przez dostawcę Jet 4.0 OLEDB (ciąg dalszy)
Kod Komunikat
3189 Tabela <nazwa> jest zablokowana na wyłączność przez użytkownika <nazwa> na komputerze
<komputer>
3197 Silnik bazy Microsoft Jet zatrzymał proces, ponieważ inny użytkownik próbuje zmienić te same
dane w tym samym czasie
3202 Nie można zapisać, zablokowane przez innego użytkownika
3211 Silnik bazy danych nie może zablokować tabeli <nazwa>, ponieważ jest używana przez inną
osobę lub proces
3212 Nie można zapisać, zablokowane
3218 Nie można zapisać, zablokowane przez użytkownika <nazwa> na komputerze <komputer>
3260 Tabela <nazwa> Jest zablokowana na wyłączność przez użytkownika <nazwa> na komputerze
<komputer>
3261 Nie można zablokować tabeli <nazwa>, używana przez użytkownika <nazwa> na komputerze
<komputer>
401 Rozdział 21. ♦ Zagadnienia wielodostępu, serwer plików, blokowanie
Tablica błędów zawiera inne użyteczne informacje dotyczące błędu blokowania, informacje o blokadach innego
użytkownika. Właściwość NativeError oraz Number informuje o blokadzie wstrzymującej twoją operację. Kombinacje
wartości i ich znaczenie przedstawione są w tabeli 21.5.
Tabela 21.5.
Sposób, w jaki wartości NativeError i Number wskazują na typ blokady
W tej chwili możesz niewiele zrobić z tymi wartościami, może poza użyciem ich jako wartości opóźnienia następnej próby
zapisu. Zapamiętaj te właściwości, mogą być one przydatne w przyszłości.
Konflikty zapisu
Błąd konfliktu zapisu (błąd numer 3197 w tabeli 21.4) jest jednym z najbardziej zagmatwanych błędów w
wieloużytkownikowym środowisku Accessa. Użytkownik 1 otwiera rekord z optymistyczną blokadą i w trakcie, gdy edytuje
rekord Użytkownik 2 otwiera ten sam rekord, zmienia go i zapisuje. Gdy Użytkownik 1 kończy pracę i próbuje zapisać go,
wystąpi błąd. We wcześniejszych wersjach Accessa, wyświetlane było mylące okno dialogowe pytające użytkownika, czy
nadpisać zmiany innego użytkownika (mimo że nie wiadomo, jakie to zmiany), anulować własne zmiany (nigdy nie było to
popularne) lub skopiować dane do schowka.
Systemowa obsługa tego błędu została zmieniona. W Accessie 2000 błąd konfliktu przy zapisie powoduje anulowanie
zmian użytkownika. Mimo że brzmi to brutalnie, jednak lepiej, gdy zakłada się, że większość aplikacji wielodostępnych w
Accessie jest tworzona szybko przez ludzi, którzy mogą nie mieć dostatecznej wiedzy na temat zagadnień
wielodostępności. Poza tym użytkownik nie powinien odpowiadać na pytania, o których nawet nie pomyślał, że może
Część VII ♦ Zagadnienia wielodostępu 402
zostać zapytany. Jeżeli aplikacja zakłada inne traktowanie konfliktów zapisu, można napisać własny podprogram obsługi
błędów.
Zablokowany rekord
Gdy w czasie normalnego używania aplikacji Użytkownik 1 spróbuje zablokować rekord, który jest zmieniany przez
Użytkownika 2, Użytkownik 1 spowoduje błąd „Zablokowany rekord” (błąd numer 3260 w tabeli 21.4). Typowa procedura
obsługi błędów spróbuje kilka razy zablokować rekord przed wyświetleniem komunikatu o blokadzie. Jeżeli Użytkownik 2
zablokował rekord w sposób pesymistyczny, rekord zostanie zwolniony zaraz po zapisaniu do bazy danych. Jest to zwykle
krótki okres czasu.
Transakcje
Transakcje łączą oddzielne operacje tak, aby zostały wykonane jak jedna. Zbiór instrukcji może zostać wykonany w całości
prawidłowo (zostają potwierdzone – commit) lub w całości się nie udać (zostają wycofane – rollback). Gdy transakcja nie
uda się, zmiany zostają cofnięte do stanu sprzed rozpoczęcia transakcji. Zapewnia to, że gdy przedmiot zostanie
zarejestrowany na rachunku, zostanie zdjęty z magazynu. Gdy na jednym rachunku jest przychód, to na drugim rozchód i
gdy rekord jest zmieniany, tworzony jest zapis w dzienniku operacji. W wysoce zmiennym środowisku aplikacji
wielodostępnej użytkownik wykonujący te operacje może napotkać błąd zablokowanego rekordu w jednej części procesu,
co może spowodować błąd w bilansie na koncie, sztucznie wypełniony magazyn lub wykonane zmiany, ale nie w pełni
zarejestrowane. W skrócie, transakcje pomagają utrzymać integralność danych przy częstych i wielokrotnych blokadach
rekordów. Przetwarzanie transakcyjne powinno być użyte w aplikacjach wielodostępnych wszędzie tam, gdzie jest to
możliwe.
Jednak transakcje nie są bezwarunkowo dobrą rzeczą. Jedynym sposobem na zapewnienie wykonania wszystkich operacji
jest zgromadzenie razem wszystkich blokad. Transakcja zakłada wszystkie blokady, jakie nakłada aplikacja, ale nie
zwalnia ich aż do pomyślnego zakończenia całego procesu. Ponieważ wiele blokad może być nałożonych i będą aktywne
przez dłuższy okres czasu, niż gdyby były nakładane bez transakcji, wielodostępność aplikacji jest zmniejszona. Jednak
baza danych jest łatwo dostępna, ale z niską integralnością danych nie jest zbyt dużo warta, więc transakcje wydają się być
rozsądnym rozwiązaniem.
Transakcje są realizowane przez metody obiektu Connection w ADO. W tabeli 21.6 opisane są te trzy metody.
Tabela 21.6.
Definiowanie transakcji
Metoda Opis
BeginTrans Od tego wywołania instrukcje będą wykonywane jak jedna.
CommitTrans Kończy zestaw instrukcji i zatwierdza je do bazy danych.
RollbackTrans W wypadku błędu anuluje wszystkie instrukcje i przywraca bazę danych do postaci
sprzed BeginTrans.
Err_TestTrans:
' Coś poszło źle, anulujemy transakcję i przywracamy stan poprzedni
Conn.RollbackTrans
End Function
Transakcje można zagnieżdżać, więc zatwierdzanie jednej transakcji zależy od zatwierdzenia innej. Gdy zagnieżdżamy
transakcje, są one wykonywane od najniższego poziomu do najwyższego.
403 Rozdział 21. ♦ Zagadnienia wielodostępu, serwer plików, blokowanie
Istnieją również inne strategie stosowane w SQL Server do zarządzania wielodostępnością. Między innymi: dynamiczne
blokowanie rekordów (SQL Server 7.0), unikanie, wykrywanie i korygowanie zakleszczeń, kontrola blokowania
optymistycznego i skalowalne narastanie blokad.
Dynamiczne blokowanie rekordów polega na tym, że zarządca blokad dostosowuje konfigurację blokad serwera do
wielkości używanej bazy danych. Powoduje to zmniejszenie zużycia zasobów oraz zmniejsza nakłady na ręczne zarządzanie
blokadami na serwerze.
Unikanie, wykrywanie i korygowanie zakleszczeń polega na tym, że SQL Server rozpoznaje sytuację, gdy dwa procesy
pozostają ze sobą w konflikcie. W takiej sytuacji jedna transakcja blokuje dane potrzebne w drugiej oraz druga blokuje dane
potrzebne w pierwszej transakcji. Pierwsza transakcja nie zwolni blokady, druga też tego nie zrobi. Bez interwencji silnika
bazy transakcje te pozostaną zakleszczone. SQL Server wykrywa taką sytuację, odwołuje jedną z transakcji, kończy drugą i
uruchamia pierwszą jeszcze raz, przełamując w ten sposób zakleszczenie. SQL Server aktywnie zapobiega zakleszczeniom,
ograniczając ilość blokad tabel.
SQL Server używa podejścia optymistycznego do zarządzania środowiskiem wielodostępnym. Przy użyciu tego podejścia
użytkownicy mogą używać kursorów po stronie serwera do przeglądania danych w przód i w tył bez użycia blokad.
Zamiast tego, SQL Server wykrywa zmiany rekordu i podejmuje stosowne działania (zwykle odrzuca zmiany, chyba że
dane zostały jawnie zablokowane).Podejście takie powoduje, że ogromne ilości danych są dostępne dla użytkowników bez
intensywnego zarządzania blokadami i związanych z tym narzutów.
Rozdział 22.
Replikacja i JRO
W tym rozdziale:
u Kiedy użyć replikacji.
u Kiedy nie używać replikacji.
u Przystosowanie bazy do replikacji.
u Replikacja przy użyciu aktówki.
u Użycie interfejsu użytkownika.
u Jet i model obiektowy replikacji.
u Opis metod i właściwości JRO.
u Obiekty repliki.
u Kolekcja Filters.
W czasach, gdy korporacje, coraz bardziej zależne od swoich danych, użytkownicy są coraz bardziej rozproszeni i żądają
od swoich sieci coraz więcej. W odpowiedzi na to, tworzone są zdecentralizowane i rozproszone systemy, aby dostarczyć
wszystkim informacji oraz rozładować obciążenie. Trend ten niesie z sobą nowe wyzwania. W jaki sposób korporacje mają
zapewnić wszystkim dostęp do danych? Jak zagwarantować, że użytkownicy podejmą decyzje w oparciu o aktualne dane?
Czy można zaufać danym? Jedną z technik spełniających te oczekiwania jest replikacja.
Rozdział ten zajmuje się tworzeniem i zarządzaniem replikami. Opisany został nowy model obiektowy Jet Replication
Model (JRO) używany do uruchomienia replikacji w aplikacjach i skorzystania z jej elastyczności. W silniku Jet
zrobiono zauważalne ulepszenia procesu replikacji. Między innymi: dwukierunkową synchronizację z SQL Server, lepsze
rozwiązywanie konfliktów, możliwość ustawiania priorytetów w schemacie bazy, rozdzielczość na poziomie kolumn oraz
zakresy widoczności. Te usprawnienia pozwalają na lepszą kontrolę przy definiowaniu topologii replikacji.
Jeżeli wydajność aplikacji spada z powodu wielu konfliktów blokad, spowodowanych dużym ruchem w sieci lub częstym
generowaniem raportów, można zauważyć, że podział bazy danych na dwie lub więcej replik i podział użytkowników
pomiędzy nimi może usunąć problem blokad. Te dwa źródła danych wymienią się zmianami pomiędzy sobą.
Podobnie, jeżeli każdy użytkownik potrzebuje tylko podzbioru danych w swojej bazie, częściowa replikacja może być
odpowiednia, aby polepszyć wydajność, usunąć konflikty i zabezpieczyć ważne dane (przykładem może być aplikacja
zarządzania działem kadr, która rozdziela zarządzanie pracownikami do kierowników poszczególnych działów i pozwala
na dostęp do danych pracowników tylko własnego działu). Aby zwiększyć szybkość działania, aplikacja zarządzająca
czasem pracy może dostarczyć repliki z historią czasu pracy każdego użytkownika. Co więcej, system taki dla progra-
mistów może zostać odłączony od sieci i zapisywać pracę wieczorem, w weekend lub u klienta. Schemat synchronizacji
powinien rozwiązywać problemy napotkane w takiej aplikacji.
405 Rozdział 22. ♦ Replikacja i JRO
Gdy ograniczasz zbiór danych, jaki może zobaczyć użytkownik, tworzysz w schemacie replikacji partycje. Może być to
efektywną metodą zabezpieczenia rekordów przed zmianą przez nieuprawnione osoby. Istnieją trzy typy partycjonowania:
pionowe, poziome i połączone poziome i pionowe.
Gdy tworzy się partycję pionową, do osobnej bazy danych przeniesione zostaną tylko wybrane kolumny. Można to zrobić
poprzez replikację przy użyciu kwerendy lub widoku, który ogranicza dane tylko do tych, które mają być udostępniane.
Gdy replikujemy partycję pionową, musisz umieścić klucz główny w zapytaniu partycjonującym.
Gdy tworzy się partycję poziomą, ograniczasz ilość rekordów do replikacji. Można to zrobić poprzez filtr replikacji lub
poprzez kwerendę. Gdy replikujesz partycję poziomą, replikujesz całe rekordy.
Partycjonowanie poziome i pionowe może zostać połączone, ograniczając zarówno wiersze jak i kolumny.
Gdy aplikacja musi pracować bez przerwy, tworzenie kopii danych może spowodować niespodziewane przerwanie
aplikacji. Replikacja może regularnie kopiować dane do repliki, która może być bezpiecznie archiwowana.
Replikacja jest odpowiednim rozwiązaniem, gdy dane użytkownika są odporne na opóźnienia aktualizacji. Oznacza to, że
użytkownicy mogą tolerować posiadanie przez jakiś czas nieaktualnych danych. Gdy raporty są wykonywane raz na
godzinę lub raz dziennie, lub są oparte o dane do określonej godziny (np.: na koniec miesiąca, koniec roku podatkowego
lub na koniec poprzedniego dnia), replikacja jest do zaakceptowania.
Mimo że replikacja jest zwykle używana do rozprowadzania danych, może być użyta do rozprowadzania innych obiektów
Accessa. Kiedyś użyłem replikacji, aby uaktualnić aplikację w Argentynie zmianami, których dokonałem w Nowym Jorku.
Czasami replikacja może łagodzić niektóre problemy utrzymania aplikacji.
Replikacja powoduje, że plik MDB jest dużo większy, ponieważ muszą zostać dodane dodatkowe obiekty, pola oraz dane
niezbędne do uruchomienia i zarządzania repliką. Jeżeli system, na którym pracuje aplikacja, posiada mało wolnych
zasobów, replikacja nie jest dobrym pomysłem.
Obciążone systemy, które przeprowadzają wiele transakcji, mogą powodować problemy z replikacją. Duża częstotliwość
transakcji i blokady zakładane w czasie tych transakcji zwykle prowadzą do konfliktów podczas synchronizacji danych.
Rozwiązywanie tych konfliktów może bardzo obniżyć wydajność systemu. Bez efektywnego rozwiązywania problemów
replikacja przyniesie aplikacji więcej kłopotów niż pożytku.
Kiedy aktualność danych jest bardzo ważna, replikacja jest nie do zaakceptowania, ponieważ zakłada, że użytkownicy oddają
aktualność danych w zamian za wydajność, współbieżność i mobilność.
Można użyć replikacji przy użyciu aktówki dla siebie lub innych użytkowników, którzy chcą współdzielić pliki pomiędzy
komputerem biurkowym i laptopem.
Przed użyciem replikacji przy użyciu aktówki (lub każdej innej metody replikacji) upewnij się, że baza danych nie posiada
hasła. Następnie należy wykonać następujące kroki:
Część VII ♦ Zagadnienia wielodostępu 406
Rysunek 22.1.
Wybór bazy danych
jako repliki
w aktówce
97. W pierwszym oknie dialogowym kliknij przycisk Tak. Baza danych musi się zwiększyć, aby mogła być
replikowana.
98. Pozwól aktówce wykonać kopię bazy danych, jeżeli masz odpowiednią ilość miejsca na dysku.
99. Jeżeli chcesz zmieniać tylko dane w bazie danych, w kolejnym oknie wybierz opcję niedopuszczania zmian
struktury oryginalnej kopii bazy danych. Jeżeli spodziewasz się, że będziesz zmieniał projekt bazy, wybierz opcję
Kopia aktówki.
100. Jeżeli otworzysz jedną z kopii, zauważysz w tytule okna Wzorzec projektowania lub Replika.
101. Skopiuj aktówkę na wymienny nośnik danych i zabierz ze sobą. Jednak, gdy komputery są połączone, przeciągnij
aktówkę do innego komputera.
102. Gdy skończyłeś prace poza swoim komputerem, skopiuj zaktualizowany plik do komputera i po otwarciu aktówki
wybierz Aktówka, Aktualizuj zaznaczenie.
Aktówka stwierdza, jakie zmiany muszą być wykonane w każdym kierunku. Gdy sam używasz aktówki, jest prawie
niemożliwe, abyś napotkał na konflikty w danych. W dalszej części rozdziału rozpatrzymy bardziej rozbudowane,
drobiazgowe i potężne sposoby replikacji.
Nie można odwrócić konwersji bazy w replikę, jednak można przywrócić bazę danych do niereplikowalnej formy. Aby to
zrobić, wykonaj następujące kroki:
103. Z bazy danych, którą chcesz zmienić na formę niereplikowalną, wybierz Narzędzia, Opcje i zakładkę Widok.
Wyłącz Obiekty systemowe.
104. Utwórz nową bazę danych i otwórz ją.
105. Zaimportuj wszystkie obiekty z repliki do nowej bazy.
106. Upewnij się, że na zakładce Widok w oknie dialogowym Opcje, wybrane jest pole wyboru Obiekty systemowe.
107. Usuń kolumny s_GUID, s_Lineage, s_Generation i s_colLineage z wszystkich tabel.
108. Zapisz nową bazę.
Rysunek 22.2.
Tworzenie repliki
przez interfejs
Accessa odbywa się
przez wybór z menu
111. Access zamknie bazę i otworzy ją ponownie. Następnie Access zapyta o możliwość utworzenia kopii bazy. Kopia
ma nazwę oryginalnej bazy danych i rozszerzenie BAK. Powinieneś pozwolić na utworzenie kopii.
Proces konwersji może potrwać kilka minut, w zależności od stopnia skomplikowania bazy i ilości danych. W czasie
procesu konwersji bazy do postaci repliki Access wykonuje następujące czynności:
u Tworzony jest nowy plik MDB i importowane są do niego wszystkie obiekty.
u Tworzy właściwość replicable dla każdego obiektu i ustawia jej wartość na T, więc zostanie on replikowany.
u Dodaje cztery pola o typach zamieszczonych w tabeli 22.1 do każdej tabeli w bazie danych.
Tabela 22.1.
Pola dodane do tabel w czasie ich przystosowania do replikacji
Pola te pozwalają na śledzenie przez Jet, zmian wprowadzonych do bazy danych i decydowanie o tym, co zrobić, gdy
wystąpi konflikt pomiędzy dwoma bazami. Nie możesz zmieniać zawartości, typu danych lub nazw tych pól, normalnie
nie są one widoczne w tabelach, chyba że zdecydujesz inaczej. Pola te zajmują trochę miejsca w bazie danych, w
zależności od ilości danych oraz ilości obiektów w bazie, rozmiar plików rośnie od 10 do 100 procent.
Jeżeli pole posiada typ Autonumerowanie, nie można oczekiwać, że replikacja będzie działać prawidłowo. Często stosuje
się pole typu Autonumerowanie, o wartościach 1, 2, 3... Jedynym sposobem uniknięcia konfliktów jest zmiana typu danych
przechowywanego w tym polu. Jeżeli pole ma typ Autonumerowanie z opcją Nowe wartości ustawioną na Przyrostowy, Jet
zmienia tę opcję na Losowy, aby zmniejszyć prawdopodobieństwo konfliktu. Jeżeli ta zmiana okaże się niewystarczająca,
można zmienić rozmiar takiego pola na ID Replikacji, co spowoduje nadanie każdego rekordu wartości GUID, który może
być używany jako identyfikator rekordu. Tworzenie liczb losowych lub ID Replikacji jest wolniejsze niż zwiększenie
wartości, ale czasami jest to konieczne i nieuniknione.
Do bazy danych zostaje również dodanych kilka tabel. Tabele te mają prefiks MSys i jako takie mogą zostać zmienione
przez Microsoft w kolejnych wersjach. Powinieneś poważnie się zastanowić przed napisaniem programu, który używa tych
tabel. Są one używane przez Jet i tak powinno pozostać. W tabeli 22.2 opisane jest przeznaczenie tych tabel.
Tabela 22.2.
Tabele dodane do bazy danych podczas przystosowania do replikacji
Tabela 22.2.
Tabele dodane do bazy danych podczas przystosowania do replikacji (ciąg dalszy)
Tabele te są tylko do odczytu, a niektóre dane są przechowywane jako obiekty OLE, więc nie mogą być wyświetlane.
Dodatkowo do bazy danych dodanych zostaje kilka właściwości, aby można było sprawować kontrolę nad replikacją.
Właściwości te to: Replicable, ReplicableID oraz DesignMasterID.
u Replicable wskazuje silnikowi Jet, że baza może być replikowana.
u ReplicableID w sposób jednoznaczny identyfikuje bazę danych i wyróżnia ją spośród innych replik.
Zmiany w projekcie można wprowadzać tylko do źródła projektowania. Powinna istnieć tylko jedna baza danych wskazana
jako źródło projektowania w schemacie replikacji lub zbiorze replik. Posiadanie więcej niż jednego źródła projektowania
prowadzi do uszkodzenia i utraty danych.
Niektóre obiekty są potrzebne tylko przez lokalną aplikację, więc powinieneś zauważyć, że szablony, większość tabel
systemowych i kreatorzy nie są replikowani. Jednak tabele systemowe biorące udział w śledzeniu procesu replikacji są
replikowane, a MsysAccessObjects oraz MsysCmdBars są również replikowane, co powoduje, że schemat bazy danych
oraz menu mogą być częścią schematu replikacji.
Domyślnie Access zaznacza wszystkie obiekty do replikacji. Zwykle jednak aplikacja posiada obiekty, które nie muszą być
replikowane. Mogą to być tabele zawierające ustawienia lokalne, tabele tymczasowe lub proste kwerendy, które nie będą
zmieniane (przykładowo Select * from Customers Order by CompanyName). Możesz kontrolować, które obiekty
będą zmieniane w trakcie synchronizacji poprzez ustawienie właściwości Replicable. Jeżeli obiekt jest replikowany,
właściwość posiada zaznaczone pole wyboru w oknie właściwości obiektu, gdy jest lokalny – pole jest wyczyszczone i
obiekt nie będzie synchronizowany.
Wzorzec projektowania, na którym obecnie pracujesz, jest specjalną bazą danych. Jest ona jedyna, na której możesz
dokonywać zmian i zmiany te zostaną przeniesione do replik. Zwykle wzorzec projektowania nie synchronizuje się z
replikami, ponieważ użytkownicy mogliby dostać niegotowy program. Dobrze jest izolować wzorzec od zbioru replik do
czasu, gdy chcesz rozesłać zmiany, jakie zrobiłeś w bazie danych.
Aby utworzyć topologię replikacji, powinieneś utworzyć odpowiednią ilość replik z właśnie stworzonej repliki. Nie
twórz kolejnych replik z oryginalnej bazy danych, ponieważ zostanie utworzonych wiele wzorców projektowania, co może
utrudnić życie.
Wszystkie repliki utworzone z tej repliki, lub z repliki tej repliki, będą członkami tego samego zbioru replik. Posiadają one
wspólny zestaw numerów GUID, co pozwala im na wymianę danych i informacji o schemacie bazy. Kolejność, w jakiej
tworzyłeś repliki, ma mały wpływ na kolejność replikacji. Każda replika może synchronizować się z każdym członkiem
zbioru, a Ty masz możliwość kontrolowania kolejności replikacji.
W czasie synchronizacji możesz wybrać replikę lub repliki, z którymi chcesz wymienić dane. Jak pokazane jest na rysunku
22.2, w Accessie można to zrobić poprzez menu Narzędzia, Replikacja, Synchronizuj. Domyślnym ustawieniem jest wybór
jednej repliki, z którą ma być wykonana synchronizacja, jednak masz do wyboru również inne opcje. Masz możliwość
wyboru replikacji w tle z każdą repliką, do której masz w danej chwili dostęp, lub z jedną repliką.
Zagadnienia te powinny być rozważone w czasie projektowania topologii replikacji lub mapy replik. Mapa taka określa
miejsce, gdzie znajduje się replika, w jakiej relacji pozostają ze sobą repliki, w jaki sposób tworzona jest replika i kiedy
następuje. Topologia replikacji jest kluczowa dla wydajności i pewności działania. Powinieneś dokładnie przemyśleć różne
dostępne topologie i wybrać tę, która najbardziej odpowiada Twoim wymaganiom. Nie pozwól, by wyborem topologii
rządził przypadek.
Ilość kombinacji możliwych topologii jest niemal nieograniczona, gdy uwzględnisz możliwość synchronizacji w jednym
lub dwóch kierunkach. Możesz wymusić na jednej replice zbieranie wszystkich zmian z replik i nieprzekazywanie ich
dalej. Może być to użyteczne do efektywnego dostarczania wyników pracy dnia do komputera kierownika, a kierownik
raportuje i analizuje dane bez dokonywania żadnych zmian. Replikacja może następować według tradycyjnego modelu,
gdzie dwie bazy synchronizują ze sobą dane, aby obie zawierały wszystkie zmiany zrobione w obu bazach.
Rysunek 22.3 pokazuje kilka możliwych topologii replikacji. Zwróć uwagę na zależności i przepływ danych.
W sieci lokalnej (LAN), użytkownicy mogą utrzymywać przez większość czasu stałe połączenia z innymi użytkownikami.
W takim wypadku gwiazda, pętla, wielokrotne połączenia, magistrala oraz drzewo będą dobrze działać. Każda z tych
topologii ma swoje zalety i wady. Wybrana przez Ciebie topologia powinna być kombinacją tych bazowych typów. W
tabeli 22.3 zostały opisane niektóre wady i zalety podstawowych typów.
Tabela 22.3.
Wady i zalety różnych topologii
Rysunek 22.3.
Podstawowe
topologie replikacji
Tabela 22.3.
Wady i zalety różnych topologii (ciąg dalszy)
W sieciach rozległych, gdzie utrzymanie stałego połączenia nie jest możliwe lub jest ono zbyt wolne, topologie te mogą
być łączone poprzez przypisanie jednej z replik roli odległej repliki dla innej topologii lub podsieci. Jet może
synchronizować bazy poprzez Internet lub Intranet.
Niezależnie czy używasz interfejsu Accessa do implementacji replikacji, czy używasz JRO lub DAO, powinny zostać
rozważone wszystkie topologie przed wybraniem właściwego rozwiązania, bazowanego na ich wadach i zaletach oraz
potrzebach aplikacji.
Niezależnie od podejścia, jakiego używasz do implementacji replikacji, jesteś jedynym, kto może spowodować, że
replikacja będzie miała miejsce. W przypadku prostego schematu możesz użyć okna z menu Narzędzia, Replikacja,
Synchronizuj lub przez wywołanie synchronizacji poprzez zdarzenie w aplikacji. Zdarzenie może być wykonywane
podczas uruchamiania aplikacji, w regularnych odstępach czasu (można użyć stopera na niewidocznym formularzu) lub po
określonej liczbie wykonanych zmian.
W trakcie synchronizacji, musisz wybrać pomiędzy schematem sterowanym i niesterowanym. Jeżeli zdecydujesz się na
użycie schematu sterowanego, możesz także zdecydować, czy replikacja ma być bezpośrednia czy pośrednia. Twoje
rozwiązanie może używać różnych ustawień w różnych miejscach, lecz jest bardzo ważne, aby wiedzieć, co one znaczą.
Synchronizacja bezpośrednia
Bezpośrednia synchronizacja zachodzi, kiedy obie bazy danych są jednocześnie otwarte i uaktualniane. Aby niezawodnie
wykonać bezpośrednią synchronizację, powinieneś mieć pewne i stałe połączenie pomiędzy replikami.
Synchronizacja pośrednia
Powinieneś używać synchronizacji pośredniej dla połączeń poprzez WAN lub dla wolnych połączeń. W czasie
synchronizacji pośredniej jedna baza jest otwierana, a pakiet zmian jest wysyłany do Managera synchronizacji. Gdy
wszystkie pakiety zmian zostaną dostarczone, pierwsza baza danych jest zamykana a druga jest otwierana i aktualizowana.
Taka operacja jest mniej podatna na przerwanie połączenia.
Po tych wyjaśnieniach wybierz Narzędzia, Replikacja, Synchronizuj i kliknij przycisk OK, aby rozpocząć synchronizację
poprzez interfejs użytkownika Accessa.
Gdy będziesz programował funkcje replikacji, możesz wybrać pomiędzy dwoma modelami obiektowymi, które mają różne
możliwości oraz inny interfejs. Można skorzystać z Data Access Objects (DAO) lub nowego Jet Replication Object. W
DAO możliwość replikacji danych jest wbudowana w obiekty razem z funkcjami manipulacji danych, bezpieczeństwa i
Część VII ♦ Zagadnienia wielodostępu 412
definiowania struktur danych. Jeżeli używasz do przetwarzania danych ADO (domyślne dla Accessa 2000), to nie ma
powodu ładować dużej biblioteki DAO (DAO360.dll ma wielkość 541 kB) duplikującej istniejące możliwości, jeżeli nie
potrzebujesz ich w całości. Zamiast tego użyj specjalizowanej i rozszerzonej biblioteki JRO (MSJRO.dll ma 97 kB). W
rozdziale tym przedstawimy sposób obsługi replikacji przy użyciu JRO.
Jet Replication Object jest interfejsem dla replikacji oraz podstawowej konserwacji w silniku bazy danych Jet. W
rozdziale tym przedstawimy tyko replikację pomiędzy bazami danych obsługiwanymi przez Jet, mimo że można używać
JRO do zaprogramowania replikacji pomiędzy SQL 7.0 i Jet 4.0. Tak jak ADO, ADOR i ADOX, JRO podąża za trendem
spłaszczania struktury modelu obiektowego. Model posiada tylko kilka warstw, więc metody i właściwości są łatwo
dostępne z poziomu obiektu.
Rysunek 22.4.
Model JRO
Poznajemy JRO
JRO udostępnia zestaw metod i właściwości pozwalający kontrolować możliwości replikacji Accessa. W tej części
rozdziału objaśnione zostaną części modelu obiektowego. W tabelach 22.4 oraz 22.5 znajdują się właściwości i metody
obiektu Replica.
Tabela 22.4.
Właściwości JRO.Replica
Tabela 22.5.
Metody JRO.Replica
Metoda Składnia
CreateReplica Replica.CreateReplica(NazwaRepliki, Opis [,TypRepliki]
[,Widoczność] [,Priorytet] [,Aktualizacja])
Tabela 22.5.
Metody JRO.Replica (ciąg dalszy)
Metoda Składnia
GetObjectReplicability Set ReturnValue = Replica.GetObjectReplicability
(NazwaObiektu, TypObiektu)
MakeReplicable Replica.MakeReplicable([CiągPołączenia] [,Śledzenie
kolumn])
PopulatePartial Replica.PopulatePartial(PełnaReplika)
413 Rozdział 22. ♦ Replikacja i JRO
SetObjectReplicability Replica.SetObjectReplicability(NazwaObiektu,
TypObiektu, Replikowalność)
Synchronize Replica.Synchronize(Cel [,TypSynchronizacji]
(,TrybSynchronizacji])
Tabela 22.6.
Właściwości kolekcji JRO.Filters
Tabela 22.7.
Metody kolekcji JRO.Filters
Metoda Składnia
Append Filters.Append(NazwaTabeli [, TypFiltra], KryteriaFiltra)
Delete Filters.Delete(Indeks)
Refresh Filters.Refresh
Tabela 22.8.
Właściwości JRO.Filter
Właściwość ActiveConnection
ActiveConnection jest obiektem Connection, należącym do repliki. Właściwość ta może być poprawnym ciągiem
połączeniowym, jeżeli obiekt Connection jest niedostępny.
Tak jak w całym ADO, jeżeli właściwość ActiveConnection ma wartość Nothing, wszystkie zależne obiekty są
odłączone od źródła danych.
Właściwość ConflictFunction
Jako wartość właściwości ConflictFunction można przypisać nazwę własnej funkcji rozwiązywania konfliktów
synchronizacji. Można utworzyć własną funkcję rozwiązywania konfliktów, jeżeli domyślna działa w sposób, który Ci nie
odpowiada.
Część VII ♦ Zagadnienia wielodostępu 414
We wcześniejszych wersjach Jet występowały błędy replikacji (błędy powtórzenia klucza, naruszenie więzów
integralności, problemy kontroli poprawności itd.) oraz konflikty replikacji (dwoje użytkowników wprowadziło zmiany
pozostające w konflikcie) i każda z tych sytuacji obsługiwana była oddzielnie.
W Jet 4.0 błędy replikacji i konflikty replikacji są traktowane jednolicie. Pozwala to na łatwiejsze rozwiązywanie pro-
blemów replikacji.
W czasie tworzenia schematu replikacji powinieneś spodziewać się następujących typów konfliktów:
u Jednoczesne zmiany. Dwóch użytkowników zmieniało ten sam rekord w tym samym czasie. Jeden z
użytkowników straci swoje zmiany, a jego rekord przesłany zostanie do tabeli konfliktów.
u Błąd powtórzenia klucza. W czasie synchronizacji dwa rekordy mają taką samą wartość w polu klucza.
u Naruszenie poprawności wartości w tabeli. W czasie synchronizacji rekord narusza zasady poprawności danych
zapisane podczas tworzenia projektu tabeli (puste ciągi znaków, wartości poza zakresem itp.). Gdy wystąpi naru-
szenie reguł poprawności, rekord jest odrzucany.
u Naruszenie więzów integralności. Gdy usunięty zostanie rekord w replice, który jest jedną ze stron relacji jeden
do wielu, wszystkie rekordy bazujące na kluczu obcym zostaną w trakcie synchronizacji odrzucone. Gdy
zmieniamy klucz główny rekordu w replice, zmiana klucza spowoduje, że rekordy bazujące na poprzedniej
wartości klucza w innych replikach zostaną odrzucone. Rekordy repliki z kluczem obcym bazującym na
nieprawidłowej wartości klucza głównego również zostaną odrzucone.
W każdym z tych przypadków kreator rozwiązywania konfliktów pokaże użytkownikowi odrzucony rekord. Użytkownik
może zdecydować, czy powtórnie wykonać zmiany, anulować zmiany lub zmienić dane powodujące konflikt.
Access używa wbudowanej procedury rozwiązywania konfliktów. Kreator rozwiązywania konfliktów pokazuje
użytkownikowi każdy konflikt i musi on zadecydować, który rekord zawiera prawidłowe dane.
Aby uniknąć tego procesu, można użyć właściwości ConflictFunction. Pozwala ona na użycie własnej procedury
rozwiązywania konfliktów, które wystąpiły w czasie synchronizacji lub może wskazać replikę, której rekordy są zawsze
najważniejsze w wypadku wystąpienia konfliktu. Jako wartość właściwości ConflictFunction należy przypisać nazwę
funkcji, która ma być wywołana w wypadku konfliktu. Musi być to nazwa funkcji, nie można podać nazwy procedury.
Jeżeli właściwość ta nie jest ustawiona, Access wywoła wbudowaną funkcję rozwiązywania konfliktów.
Funkcja rozwiązywania konfliktów jest wywoływana po zakończeniu synchronizacji. Gdy tworzymy funkcję
rozwiązywania konfliktów, operujemy na zawartości tablicy konfliktów w Twojej replice, aby ocenić konflikt oraz zmienić
rekord lub zbiór rekordów przy użyciu zwykłych mechanizmów manipulacji danymi (DAO, ADO, RDO lub SQL).
Gdy wprowadzasz własną procedurę rozwiązywania konfliktów, zastępujesz nią wbudowany algorytm rozwiązywania
konfliktów. Powinieneś dokładnie rozważyć sytuacje, w których jest to potrzebne. Jedną z możliwych sytuacji, kiedy
możesz skorzystać z napisania własnej funkcji rozwiązywania konfliktów jest to gdy chcesz sprawdzić przynależność
użytkownika do grupy, aby zdecydować, czy jego zmiany mają pierwszeństwo przed zmianami innego użytkownika.
Podejście takie pozwala na pracę użytkownika na różnych replikach bez względu na priorytet danej repliki w topologii
replikacji.
Domyślnie Jet 4.0 rozwiązuje konflikty przy użyciu dwóch algorytmów bazujących na priorytetach oraz unika konfliktów
przez ich poszukiwanie tylko na poziomie kolumn.
W Jet 4.0 każdej replice jest przypisana wartość priorytetu. Ta liczba wyznacza miejsce repliki w topologii. Jeżeli dwie
repliki spowodowały konflikt, Jet rozwiązuje go, bazując na ich relacjach w topologii. Zmiany repliki o wyższym
priorytecie są ważniejsze. W wypadku remisu ważniejsza jest replika z mniejszą wartością ReplicaID (replika utworzona
wcześniej). Algorytm ten jest zbliżony do używanego w SQL Server 7.0.
Wartość priorytetu przyjmuje wartości od 0 do 100. W trakcie tworzenia repliki otrzymuje priorytet równy 90% wartości
źródła.
W Jet 4.0 konflikty powinny wystąpić rzadziej niż we wcześniejszych wersjach. We wcześniejszych wersjach występował
konflikt, gdy dwóch użytkowników zmienia to ten sam rekord, nawet, gdy zmienili dane w różnych polach. W Jet 4.0
dwóch użytkowników może zmienić różne pola tego samego rekordu i konflikt nie nastąpi. Śledzenie zmian na poziomie
kolumn radykalnie redukuje częstość konfliktów i odciąża użytkowników od rozwiązywania tych konfliktów.
Śledzenie zmian na poziomie kolumn jest domyślnie włączone w Jet 4.0. Jeżeli Twoja aplikacja potrzebuje śledzenia zmian
na poziomie rekordów, opcja musi być zmieniona przed przystosowaniem tabel do replikacji. Aby wybrać pomiędzy
śledzeniem zmian na poziomie kolumn i rekordów, użyj parametru columntracking metody replica.Ma-
415 Rozdział 22. ♦ Replikacja i JRO
keReplicable. Ustawienie tego argumentu na True włącza śledzenie zmian na poziomie kolumn, a False włącza
śledzenie zmian na poziomie rekordów. Poniższa metoda powinna przystosować bazę do replikacji ze śledzeniem zmian na
poziomie rekordów:
Replica.MakeReplicable CurrentProject.Connection, False
Właściwość ConflictTables
Właściwość ta wskazuje na obiekt RecordSet zawierający listę tabel i skojarzonych z nimi tabel konfliktów.
Wywołanie właściwości ConflictTables zwraca RecordSet zawierający dwie kolumny: TableName i związaną z nią
ConflictTableName. Dla każdej tabeli z konfliktami istnieje tabela przechowująca rekordy powodujące konflikty.
Właściwość ConflictTables można tylko odczytywać.
Otwierając tabelę o nazwie podanej w polu ConflictTableName właściwości ConflictTables, można obejrzeć rekord
stracony przy synchronizacji oraz obejrzeć jego pola specyficzne dla replikacji.
Na wydruku 22.1 pokazany jest przykład prostej funkcji rozwiązywania konfliktów. Używa on ADO, ADOX i JRO do
przetworzenia wszystkich konfliktów przy użyciu właściwości ConflictTables.
CustomDataConflictResolver = True
CustomDataConflictResolver _Exit:
conflrs = Nothing
rs = Nothing
jro = Nothing
Exit Function
CustomDataConflictResolver Error:
' Obsługa błędów
CustomDataConflictResolver = False
Resume CustomDataConflictResolver _Exit
End Function
Sposób, w jaki rozwiążesz konflikty, należy całkowicie do ciebie. Możesz brać zawsze ostatni rekord, zawsze rekord z
określonej grupy lub określonego użytkownika, pobierać rekord w oparciu o największą lub najmniejszą wartość albo użyć
kombinacji wszystkich tych sposobów.
Część VII ♦ Zagadnienia wielodostępu 416
Właściwość DesignMasterID
Wartość DesignMasterID jest identyfikatorem GUID, który określa wzorzec projektowania w zbiorze replik. Właściwość ta
jest ustawiana w trakcie tworzenia wzorca projektowania.
Możesz zmienić replikę we wzorzec projektowania, gdy oryginalny wzorzec zostanie stracony, jednak replika nie może
zmienić innej repliki we wzorzec projektowania.
Obiekty repliki
Każda baza danych utworzona z wzorca projektowania lub innej repliki jest obiektem Replica dostępnym poprzez JRO.
Poniższe właściwości i metody pozwalają rozróżnić repliki i kontrolować ich zachowanie i współpracę z innymi replikami.
Właściwość ReplicaID
Właściwość ta w sposób jednoznaczny identyfikuje bazę danych repliki i zawiera GUID typu Variant. Wartość GUID
jest tworzona razem z repliką i jest możliwy tylko jej odczyt.
Właściwość ReplicaType
Właściwość ta wskazuje na typ repliki. Właściwość ta zawiera jedną ze stałych wymienionych w tabeli 22.9.
Tabela 22.9.
Wartości ReplicaType
Właściwość ReplicaType (tylko do odczytu) wskazuje na to, czy baza jest replikowana a jeżeli jest, w jaki sposób jest
replikowana. Jeżeli ReplicaType ma wartość jrRepTypeNotReplicable, baza nie była przygotowywana do replikacji.
Można użyć parametru ReplicaType metody CreateReplica, aby utworzyć pełną lub częściową replikę.
Właściwość RetentionPeriod
Właściwość ta wskazuje, ile dni (od 5 do 32000) przechowywać historię replikacji. Historia zawiera szczegóły o usuniętych
rekordach, zmianach projektu oraz inne specyficzne dla systemu informacje. Jeżeli baza danych została przygotowana do
replikacji poprzez ADO, RDO lub manager replikacji, domyślną wartością jest 60 dni. Jeżeli baza została przygotowana do
replikacji poprzez interfejs użytkownika Accessa, wartością domyślną jest 1000 dni.
Właściwość Visibility
Właściwość Visibility wskazuje na to, czy replika jest globalna, lokalna lub anonimowa. Visibility zarządza
oddziaływaniem pomiędzy replikami i zawiera jedną ze stałych wymienionych w tabeli 22.10.
Tabela 22.10.
Możliwe wartości właściwości Visibility
Z repliki globalnej można utworzyć replikę dowolnego typu. Wszystkie zmiany w globalnej replice są śledzone i mogą być
wymieniane z każdą globalną repliką w zbiorze. Globalna replika może również wymieniać zmiany z każdą lokalną lub
anonimową repliką, które przynależą do jednego węzła.
Lokalne i anonimowe repliki wymagają globalnej repliki, która będzie węzłem w ich topologii. Nie mogą synchronizować
się z innymi replikami w tym zbiorze replik. Wszystkie anonimowe i lokalne repliki mają priorytet 0, więc zawsze
przegrywają przy rozwiązywaniu konfliktów z węzłem.
Tylko replika będąca węzłem „wie” o istnieniu lokalnych replik i tylko ona może zaplanować replikację z lokalnych replik.
Repliki anonimowe mogą być używane w topologii internetowej, gdzie dane są silnie rozproszone, ponieważ nie są
utrzymywane informacje systemowe, przez co rozmiar repliki jest silnie zmniejszony. Żadna replika, nawet replika
będąca węzłem nie może nawiązać połączenia z repliką anonimową. Replika węzłowa nie może zaplanować replikacji z
repliką anonimową.
Visibility jest właściwością niezmienną i nie może być zmieniana po utworzeniu repliki przy użyciu metody
CreateReplica.
Metoda CreateReplica
Metoda ta tworzy nową replikę na podstawie bieżącej replikowalnej bazy danych.
Replica.CreateReplica(NazwaRepliki, Opis [,TypRepliki] [,Widoczność] [,Priorytet] [,Aktualizacja])
Tabela 22.11.
Możliwe wartości parametru TypRepliki
Widoczność – parametr opcjonalny. Wartość tego parametru określa widoczność repliki. Wartością domyślną jest
jrRepVisibilityGlobal. Prawidłowe wartości stałych dla tego parametru opisane są w tabeli 22.12.
Tabela 22.12.
Możliwe wartości parametru Widoczność
Priorytet – parametr opcjonalny. Jest to wartość typu Long, która wskazuje, która replika wygrywa w trakcie
rozwiązywania konfliktów. Domyślną wartością jest -1, co oznacza, że baza danych powinna ustalić właściwą
wartość. Gdy tworzysz globalne repliki, ich domyślny priorytet jest ustawiany na 90% wartości priorytetu repliki
źródłowej. Jeżeli jesteś administratorem bazy, możesz ustawić dowolną wartość od 0 do 100. Repliki lokalne i
anonimowe zawsze mają priorytet 0 i nie może być on zmieniany. Wartość ta jest wymuszana podczas tworzenia
repliki i próby jej zmiany są ignorowane.
Aktualizacja – parametr opcjonalny. Wartość parametru określa, czy możliwe są zmiany w replice. Domyślną
wartością jest jrRepUpdFull. Stała jrRepUpdReadOnly uniemożliwia użytkownikom wprowadzanie zmian do
replikowanych tabel. Jednak, gdy synchronizujesz nową replikę z inną ze zbioru replik, zmiany struktury i danych są
przenoszone do nowej repliki. W tabeli 22.13 wymienione są stałe dopuszczalne dla parametru Aktualizacja.
Tabela 22.13.
Możliwe wartości parametru
Replika dziedziczy dokładnie taką samą charakterystykę lub jest bardziej restrykcyjna od repliki, na podstawie której
została utworzona. Przykładowo, na podstawie globalnej repliki tylko do odczytu, można utworzyć lokalną lub anonimową
replikę tylko do odczytu lub lokalna replika może utworzyć inną lokalną replikę o tej samej charakterystyce.
Metoda GetObjectReplicability
Metoda ta wskazuje na to, czy obiekt w bazie jest lokalny czy replikowany. Składnia prawidłowego wywołania
GetObjectReplicability przedstawiona jest poniżej:
Set ReturnValue = Replica.GetObjectReplicability(NazwaObiektu, _
TypObiektu)
Metoda zwraca wartość logiczną wskazującą na to, czy obiekt może być replikowany. W bazach danych
nieprzystosowanych do replikacji funkcja zwraca dla wszystkich obiektów True, ponieważ każdy z tych obiektów może
zostać replikowany, mimo że nie został ustawiony żaden schemat replikacji. Jeżeli baza zostanie przekształcona do postaci
replikowalnej, metoda zwróci True. W bazach replikowalnych metoda ta zwróci False dla wszystkich nowych obiektów,
ponieważ domyślnie nie są one częścią schematu replikacji.
Metoda GetObjectReplicability wskazuje, czy obiekt jest lub może być replikowany.
Parametry NazwaObiektu i TypObiektu są ciągami zawierającymi nazwę obiektu (np. Klienci) i nazwę części okna bazy
danych (np. Tabele). Jeżeli obiekt o podanej nazwie i typie nie występuje w bazie, lub którykolwiek z ciągów będzie
dłuższy niż 64 znaki, wystąpi błąd.
Aby dowiedzieć się, w jaki sposób zmieniać stan replikacji obiektu, popatrz na opis metody SetObjectReplicability.
Jeżeli obiekt określony parametrami NazwaObiektu i TypObiektu nie istnieje, wystąpi błąd.
Metoda MakeReplicable
Metoda ta przystosowuje bazę danych do replikacji. Składnia jej jest przedstawiona poniżej.
Replica.MakeReplicable([CiągPołączenia] [,ŚledzenieKolumn])
419 Rozdział 22. ♦ Replikacja i JRO
CiągPołączenia – parametr opcjonalny. Ciąg zawierający nazwę i pełną ścieżkę dostępu do bazy danych. Wartość tego
parametru zastępuje właściwość ActiveConnection.
ŚledzenieKolumn – parametr opcjonalny. Wartość logiczna wskazująca na sposób śledzenia zmian, na poziomie kolumn
lub na poziomie rekordów. Wartością domyślną jest True. Śledzenie zmian na poziomie kolumn pozwala na połączenie
zmian w rekordzie, jeżeli dotyczyły różnych pól. Konflikt wystąpi, jeżeli różni użytkownicy zmienią to samo pole w
rekordzie. Jeżeli w bazie często zdarzają się nakładające się zmiany tego samego rekordu, ustawienie tego parametru może
spowodować polepszenie wydajności.
Jeżeli nie poda się parametru CiągPołączenia oraz nie ma ustawionej właściwości ActiveConnection, wystąpi błąd. Po
pomyślnym zakończeniu działania metody, zostaje ustawiona właściwość ActiveConnection.
Metoda PopulatePartial
Metoda ta służy do ładowania repliki częściowej.
Replica.PopulatePartial(PełnaReplika)
PełnaReplika – pełna ścieżka dostępu i nazwa bazy danych repliki, z którą będą wymieniane dane.
Gdy synchronizujesz replikę częściową z pełną repliką, możliwe jest pozostawienie osieroconych rekordów w replice
częściowej. Przykładowo, masz ustawiony filtr dla tabeli Klienci zawierający warunek Region ='NJ'. Jeżeli użytkownik
zmieni w replice częściowej pole Region z NJ na OR i uruchomi metodę Synchronize, zmiana zostanie przeniesiona do
pełnej repliki. Jednak rekord zawierający OR w polu Region pozostanie osierocony w replice częściowej, ponieważ nie
spełnia warunków filtra.
Aby uniknąć pozostawiania osieroconych rekordów w trakcie replikacji rekordów, należy użyć metody PopulatePartial.
Metoda ta czyści wszystkie rekordy z repliki częściowej i ponownie ładuje je, bazując na ustawionym filtrze. Metoda
PopulatePartial jest podobna do Synchronize, ale po synchronizacji wszystkich zmian z repliki częściowej do pełnej
repliki usuwa wszystkie rekordy z repliki częściowej i ponownie ładuje replikę częściową, bazując na bieżącym filtrze
repliki. Gwarantuje to, że zmiany poczynione w replice częściowej nie zostaną osierocone z powodu konfliktu filtra.
Zawsze używaj metody PopulatePartial, gdy tworzysz replikę częściową lub zmieniasz warunek filtra repliki. Jeżeli
aplikacja zmieniła warunek filtra, powinieneś wykonać następujące kroki:
115. Zsynchronizuj pełną replikę z replikami częściowymi, w których ma zostać zmieniony warunek filtra.
116. Użyj obiektu Filter, aby wprowadzić zmiany do warunku filtra repliki.
117. Wywołaj metodę PopulatePartial, aby usunąć wszystkie rekordy z repliki częściowej i przesłać wszystkie
rekordy spełniające warunek filtra z pełnej repliki do repliki częściowej.
Jeżeli zmieniony zostanie warunek filtra i zostanie wywołana metoda Synchronize bez wcześniejszego wywołania
PopulatePartial, mogą wystąpić błędy.
Metoda PopulatePartial może być wywołana tylko wtedy gdy replika częściowa zostanie otwarta na wyłączność. Co
więcej, nie można wywołać PopulatePartial z programu działającego w replice częściowej. Zamiast tego, należy
otworzyć na wyłączność replikę częściową z pełnej repliki lub innej bazy danych i wtedy wywołać metodę
PopulatePartial.
Metoda SetObjectReplicability
Metoda ta decyduje, czy obiekt jest lokalny, czy replikowany. Ustawienie replikacji obiektu jest wykonywane przez
wywołanie metody w następujący sposób:
Replica.SetObjectReplicability(NazwaObiektu, TypObiektu, _
Replikowalność)
Metoda SetObjectReplicability powoduje, że obiekt jest replikowany lub pozostaje lokalny. Jeżeli baza danych nie
została jeszcze przystosowana do replikacji, ustawienie parametru Replikowalność na False powoduje, że obiekt
pozostanie lokalny po przystosowaniu bazy do replikacji. Obiekty w niereplikowalnych bazach danych są domyślnie
replikowalne. Jednak nowe obiekty tworzone w replikowalnych bazach danych nie są domyślnie replikowalne. Aby
zmienić nowy obiekt w replikowalnej bazie danych z lokalnego na replikowalny, należy ustawić parametr Replikowalność
na True.
Parametry NazwaObiektu i TypObiektu są ciągami zawierającymi nazwę obiektu (np. Klienci) i nazwę części okna bazy
danych (np. Tabele). Jeżeli obiekt o podanej nazwie i typie nie występuje w bazie lub którykolwiek z ciągów będzie
dłuższy niż 64 znaki, wystąpi błąd.
Metoda SetObjectReplicability jest ignorowana dla wszystkich obiektów Accessa następujących typów: Formularze,
Raporty, Strony, Makra i Moduły. Replikowalność tych obiektów jest kontrolowana poprzez tabelę MsysAccessObjects i
może być ustawiona przed przystosowaniem bazy danych do replikacji. Domyślnie obiekty te są replikowalne.
Informacje na temat sprawdzania replikowalności obiektów zawarte są przy opisie metody GetObjectReplicability.
Metoda Synchronize
Metoda ta powoduje synchronizację ze sobą dwóch replik zgodnie z ich właściwościami replikacji i parametrami
wywołania metody.
Replica.Synchronize(Cel [,TypSynchronizacji] (,TrybSynchronizacji])
Cel – ciąg zawierający nazwę i ścieżkę dostępu do repliki, z którą będzie się synchronizowała bieżąca replika,
nazwę synchronizatora, który zarządza docelową repliką, lub serwer internetowy zawierający docelową replikę.
TypSynchronizacji – parametr opcjonalny. Wartość wyliczeniowa określająca typ wykonywanej
synchronizacji. Domyślną wartością jest jrSyncTypeImpExp. Prawidłowe wartości parametru wymienione
zostały w tabeli 22.14.
Tabela 22.14.
Wartości parametru TypSynchronizacji
Tabela 22.15.
Wartości parametru TrybSynchronizacji
Replika podana jako wartość parametru Cel musi być częścią tego samego zbioru replik. Jeżeli obie repliki mają tę samą
wartość właściwości ReplicaID, lub obie są wzorcami projektowania dwóch różnych zbiorów replik, replikacja się nie
uda. Jest to wymuszone przez dostawcę.
Jeżeli synchronizacja jest pośrednia, wartością parametru Cel musi być nazwą synchronizatora. Jet w czasie replikacji
pozostawia zmiany w buforze. Synchronizator zarządzający docelową repliką pobiera te zmiany i nanosi je. Aby
synchronizacja pośrednia działała prawidłowo, Synchronizator musi być uruchomiony na komputerze lokalnym
i docelowym.
Gdy synchronizacja ma zachodzić przez Internet, wartość parametru Cel musi być w postaci adresu URL zamiast ścieżki w
sieci lokalnej. Jeżeli Cel jest w postaci adresu URL, a parametr TrybSynchronizacji nie jest jrSyncModeInternet,
wystąpi błąd.
Gdy tryb synchronizacji jest bezpośredni, obie repliki są jednocześnie otwierane i synchronizowane. Przy
synchronizowaniu przez sieć WAN lub odległą sieć, pewność i wydajność procesu można poprawić używając
synchronizacji pośredniej. Można również synchronizować dane z SQL Server i bazami danych Jet przez ustawienie
parametru Cel na ServerName.Database.Publication i tryb synchronizacji na inny niż bezpośredni.
Manager replikacji jest wymagany do zainstalowania i konfiguracji programów Synchronizer i Replman, za pomocą
których można monitorować stan synchronizacji pośrednich i internetowych. Są one dostępne w wersji Developer Edition
Office 2000. Więcej informacji na temat managera replikacji znajduje się w pomocy Accessa.
Kolekcja Filters
Kolekcja ta zawiera wszystkie obiekty Filter w replice. Każdy obiekt filtra pozwala na ograniczenie ilości
replikowanych rekordów.
Tabela 22.16.
Właściwości i metody kolecji Filters
Właściwość Opis
Właściwość Count Zwraca ilość filtrów w kolekcji
Metoda Item Umożliwia dostęp do kolumn w kolekcji
Metoda Append Dodaje nowy filtr do kolekcji
Metoda Delete Usuwa filtr z kolekcji
Metoda Refresh Uaktualnia obiekty w kolekcji, aby odzwierciedlić bieżące zmiany w projekcie bazy
Właściwość Count
Właściwość ta przechowuje ilość obiektów w kolekcji.
Możesz użyć właściwości Count, aby sprawdzić, ile obiektów znajduje się w kolekcji. Ponieważ numerowanie elementów
kolekcji zaczyna się od zera, powinieneś zawsze używać pętli rozpoczynających się od elementu zerowego i kończących
się na wartości właściwości Count – 1. Jeżeli używasz Microsoft Visual Basic i chcesz utworzyć pętlę przebiegającą przez
wszystkie elementy kolekcji, użyj konstrukcji For Each ... Next.
Metoda Item
Metoda ta zwraca obiekt z kolekcji identyfikowanej przez nazwę lub numer. Wywołanie metody pokazane jest poniżej:
Set object = Collection.Item ( Indeks )
Indeks – wartość typu Variant, która może być nazwą lub numerem obiektu w kolekcji.
Część VII ♦ Zagadnienia wielodostępu 422
Użyj metody Item, aby zwrócić określony obiekt w kolekcji. Jeżeli metoda nie może znaleźć obiektu odpowiadającego
podanej wartości indeksu, wystąpi błąd. Niektóre kolekcje nie umożliwiają nazywania obiektów, dla nich musisz używać
adresowania numerem.
Właściwość Item jest właściwością domyślną dla wszystkich kolekcji, więc poniższe instrukcje są równoważne:
Collection.Item( Indeks )
Collection( Indeks )
Metoda Append
Metoda ta dodaje nowy obiekt Filter do kolekcji obiektów Filters w replice częściowej. Składnia metody Append jest
następująca:
Filters.Append(NazwaTabeli [, TypFiltra], KryteriaFiltra)
TypFiltra – wartość wyliczeniowa wskazująca na wartość właściwości FilterType określająca, czy filtr bazuje na
tabeli, czy na relacji.
KryteriaFiltra – ciąg zawierający kryteria, które spełniać musi rekord, aby był replikowany z pełnej repliki. Ustawia
właściwość FilterCriteria.
Jeżeli replika nie jest repliką częściową, wystąpi błąd. Jeżeli filtr o takiej samej nazwie i typie już istnieje, również wystąpi
błąd.
Wystąpi błąd, gdy spróbujesz dodać drugi filtr typu jrFltrTypeTable do tej samej tabeli.
Metoda Delete
Metoda ta usuwa obiekt Filter z kolekcji Filters w replice.
Filters.Delete( Indeks )
Indeks – wartość typu Variant zawierająca nazwę lub numer obiektu Filter do skasowania.
Jeżeli są dwa filtry o takiej samej nazwie, skasowany zostanie pierwszy. Użycie numeru pozwala na jednoznaczną
identyfikację filtra w przypadku takich samych nazw filtrów.
Jeżeli filtr o podanej nazwie lub numerze nie istnieje w kolekcji, wystąpi błąd.
Metoda Refresh
Metoda ta uaktualnia obiekty w kolekcji, aby odzwierciedlały dostępne obiekty. Wywołanie metody Refresh jest proste.
Collection.Refresh
Obiekt Filter
Właściwość ta definiuje kryteria, jakie musi spełniać rekord, aby został replikowany z pełnej repliki.
Właściwość FilterCriteria
Umożliwia zapis i odczyt ciągu zawierającego kryteria. Dla filtrów opartych o tabelę ciąg powinien reprezentować klauzulę
Where kwerendy SQL bez słowa Where. Dla filtrów opartych o relację ciąg zawiera nazwę relacji. Po ustawieniu wartości
właściwość ta jest tylko do odczytu i może być zmieniana tylko przy użyciu metody Append.
Właściwość FilterType
Właściwość ta określa typ filtra.
423 Rozdział 22. ♦ Replikacja i JRO
Właściwość jest typu wyliczeniowego. Prawidłowymi wartościami są stałe zamieszczone w tabeli 22.17. Właściwość ta
jest tylko do odczytu i można ją zmieniać tylko za pomocą metody Append.
Tabela 22.17.
Wartości FilterType
Stała Opis
jrFltrTypeTable Wartość domyślna. Filtr jest oparty o tabelę
jrFltrTypeRelationship Filtr jest oparty o relację
Właściwość TableName
Właściwość ta przechowuje nazwę tabeli, na którą nakładany jest filtr.
Właściwość przechowuje ciąg określający nazwę tabeli. Dla filtrów opartych o relacje, jest to tabela będąca po stronie
relacji wiele. TableName jest tylko do odczytu i może być zmieniane przy użyciu metody Append.
Rozdział 23.
Bezpieczeństwo
W tym rozdziale:
u Elementy bezpieczeństwa.
u Tworzenie grupy roboczej.
u Użytkownicy i grupy.
u Tworzenie systemu bezpieczeństwa przy użyciu opcji startowych.
u Zagadnienia bezpieczeństwa przy użyciu replikacji.
u Ochrona dzielonych baz danych.
u Bezpieczeństwo systemu klient-serwer.
u Zabezpieczanie bazy danych krok po kroku.
u Częste błędy bezpieczeństwa.
Aplikacje, a w szczególności aplikacje wieloużytkownikowe, nie są dokończone, dopóki nie zostaną zabezpieczone. Bez
prawidłowo wykonanego systemu ochrony aplikacje są podatne na ataki złośliwych hackerów i niewinną ciekawość
niedoświadczonych użytkowników. Jednak pomimo olbrzymich możliwości systemu bezpieczeństwa Jet jest on zwykle w
bazach Accessa zaniedbywany lub niewłaściwie tworzony. Częściowo dlatego, że opracowanie właściwej struktury
bezpieczeństwa jest niełatwym zadaniem. Opisy sposobów tworzenia systemu bezpieczeństwa są mylące, a sposób, w jaki
Jet obsługuje system bezpieczeństwa, różni się od innych systemów baz danych.
Elementy bezpieczeństwa
W tym rozdziale skupimy się na modelu bezpieczeństwa opartym o grupę roboczą stosowanym w Jet. Wskażemy wiele
praktycznych zagadnieniach, które musisz rozważyć w trakcie zabezpieczania bazy danych. Pokażemy również techniki
ActiveX Data Object Extensions for Database Definition Language and Security (ADOX) do tworzenia funkcji
zabezpieczeń. ADOX korzysta z interfejsu programistycznego DAO dla definicji danych i zarządzania ochroną. ADOX
zapewnia prostszy model obiektowy, a gdy używamy dostawcy OLEDB, model nie zawiera różnic syntaktycznych.
Ponieważ ADOX obsługuje tylko źródła danych oraz obiekty oparte na danych, takich jak tabele, kwerendy, widoki i
procedury, omówione zostaną podstawy interfejsu i techniki DAO. Pozwoli to zastosować system bezpieczeństwa dla
formularzy, raportów i makr.
kompromisem, gdy wszyscy użytkownicy mają te same prawa i hasło. Użytkownicy są nieodróżnialni od siebie.
Dodatkowo, jeżeli hasło zostanie zapomniane, nie ma sposobu na jego odtworzenie. I na koniec, założenie hasła na bazę
danych wyklucza użycie replikacji. Samo hasło bazy danych nie jest najlepszą metodą na zabezpieczenie poważnej
aplikacji wieloużytkownikowej, jednak może być używane razem z grupą roboczą.
System bezpieczeństwa grupy roboczej jest bardziej skomplikowany od hasła bazy. W tym rozdziale skupimy się na tym
zagadnieniu.
Taki system oparty o użytkowników nie jest administrowany przez Access ani Jet. Jest administrowany za pomocą pliku
grupy roboczej (system.mdw). Plik grupy roboczej zawiera informacje na temat uprawnień użytkowników i grup
użytkowników i jest używany przez Accessa do odczytywania tych uprawnień. W Accessie system zabezpieczeń jest
zawsze włączony, jednak nie jest on zwykle widoczny. Plik grupy roboczej jest zawsze używany, niezależnie od tego czy
efekty są widoczne. Z tego powodu bardzo ważne jest ustawienie odpowiedniej grupy roboczej przed rozpoczęciem prac
nad systemem bezpieczeństwa.
Stosowanie takiego modelu (z oddzielną administracją) powoduje, że grupy użytkowników mogą mieć różne aplikacje
zabezpieczane i administrowane przez jeden centralny plik bezpieczeństwa. Plik MDW używany przez bazę danych
definiuje grupę roboczą. Grupa robocza jest zbiorem użytkowników, ich grup i baz danych, których mogą używać. Jak
pokazane jest na rysunku 23.1, silnik bazy danych polega na jego przestrzeni roboczej, aby dostarczyć informacji na temat
użytkowników bazy danych.
Rysunek 23.1.
Zauważ, że w tym
schemacie nie ma
obiektów bazy
danych.
Mimo że użytkownik jest centrum systemu bezpieczeństwa, nie jest możliwe tworzenie użytkownika lub przeprowadzenie
znaczącej dyskusji o nim, bez umieszczania go w kontekście grupy. Grupa robocza musi istnieć, aby działał system
bezpieczeństwa. Możesz mieć wielu użytkowników lub tylko jednego, ale grupa musi być utworzona.
Plik grupy roboczej jest specjalną szyfrowaną bazą danych, która zawiera następujące informacje:
u nazwa użytkownika;
u hasło użytkownika;
u identyfikator użytkownika (PID);
u właściwości użytkownika (ustawienia paska narzędzi i niektóre wartości domyślne);
u ostatnie cztery bazy otwarte przez użytkownika (widoczne w menu Plik);
u nazwy grup;
u grupy (PID);
u członków grup (użytkownicy należący do grupy).
Część VII ♦ Zagadnienia wielodostępu 426
Aby to wykonać, należy użyć programu wrkgadm.exe, który zwykle jest instalowany w ...\Microsoft
Office\Office\wrkgadm.exe.
Program ten pozwala na tworzenie nowych grup roboczych i przyłączanie się do już istniejących. Po utworzeniu grupy
wynikowy plik MDW powinien być umieszczony w sieci w katalogu dostępnym dla wszystkich spodziewanych
użytkowników. W czasie tworzenia pliku grupy roboczej nie musisz mieć szczegółowego planu struktury systemu
bezpieczeństwa, jednak dobrze jest utworzyć plik grupy roboczej w trakcie tworzenia aplikacji najszybciej jak to tylko
możliwe, aby uniknąć w przyszłości pomyłek.
W czasie pracy wrkgadm.exe musisz wybrać pomiędzy podłączeniem do istniejącej grupy lub tworzeniem nowej.
Po wybraniu tworzenia nowego pliku grupy roboczej musisz podać informacje na temat przynależności do grupy roboczej.
Jak widać na rysunku 23.2 w oknie są trzy pola. Administrator grupy roboczej wypełnia dwa z tych pól, odczytując je z
instalacji Office 2000 lub Accessa 2000. Możesz zmienić te dwa pola albo zostawić je bez zmian, jednak musisz
wprowadzić identyfikator grupy.
Rysunek 23.2.
Przed utworzeniem
grupy roboczej
zapisz te krytyczne
informacje
Rysunek 23.3.
Access automatyzuje
wprowadzanie
niektórych
informacji
w Administratorze
grupy, jednak nadal
możesz je zmienić
Identyfikator grupy dostarcza ziarna dla algorytmu szyfrowania pliku grupy roboczej. Jest to informacja, która nie jest
tworzona w trakcie instalacji. Administrator pozwala na pozostawienie tego pola pustego, ostrzegając wcześniej o tym
fakcie, jednak neguje to cel tworzenia grupy roboczej. Identyfikator grupy zawiera do 20 znaków i wielkość znaków jest
istotna. Ciąg, który wprowadziłeś zapewnia, że grupa robocza będzie unikatowa po utworzeniu binarnego identyfikatora
nazywanego Workgroup Security ID (SID). Jeżeli właściwie zabezpieczysz identyfikator grupy, nie może ona zostać prze-
jęta. System bezpieczeństwa tak silnie chroni ten ciąg, że masz jeszcze tylko jedną szansę na zobaczenie lub zmianę jego
wartości. Zapisz ten ciąg i przechowuj tak, aby osoby niepowołane nie miały do niego dostępu.
Następnym krokiem jest znalezienie odpowiedniego miejsca dla pliku grupy roboczej. Powinien być umieszczony w
katalogu, w którym wszyscy użytkownicy grupy mają prawo do zapisu i odczytu. Jednak, gdy użytkownicy nie zmieniają
się, można skopiować plik MDW do komputerów wszystkich użytkowników. Jeżeli plik zmieni się, operację należy
powtórzyć, co może spowodować, że większe nakłady na administrację przeważą zysk wydajności. Umieszczenie pliku
MDW na dysku sieciowym zwiększa szanse, że będzie on regularnie składowany, co ułatwia odzyskiwanie danych w wy-
padku awarii.
427 Rozdział 23. ♦ Bezpieczeństwo
Nie ulegaj pokusie nazwania pliku MDB tak samo jak aplikacji lub źródła
danych, jeżeli pliki te umieszczone są w tym samym katalogu. Plik MDW
tworzy plik LDB do przechowywania informacji o swoich blokadach, tak
samo jak źródło danych i aplikacja. Jeżeli pliki MDB i MDW mają tę samą
nazwę, to mimo że nie są ze sobą w konflikcie, to ich pliki LDB nie zgodzą
się ze sobą. Dobrym rozwiązaniem jest poprzedzenie nazwy pliku ciągiem
„SYS” lub „SYS_”.
Ostatnią szansą na zmianę lub obejrzenie informacji o grupie jest okno potwierdzenia danych o grupie roboczej. Upewnij
się, że prawidłowo zapisałeś wszystkie te informacje, a w szczególności identyfikator grupy, ponieważ może być on
potrzebny, aby odtworzyć plik MDW.
Jeżeli potwierdzisz informacje o grupie, administrator potwierdzi fakt utworzenia grupy roboczej i powróci do pierwszego
okna dialogowego. Zauważ, że podłączyłeś się do nowej grupy roboczej. Możesz teraz tworzyć bazy danych,
użytkowników i grupy, przypisywać użytkowników do grup oraz nadawać i odbierać prawa w tej grupie roboczej. Jeżeli
podłączysz się do innej grupy roboczej, możesz w niej pracować w obszarze przydzielonych uprawnień.
Aby nie zniszczyć żadnej istniejącej bazy danych, utwórz całkiem nową bazę danych, na której przetestujemy resztę cech
systemu bezpieczeństwa.
Jeżeli Access jest otwarty, zamknij go i uruchom ponownie. Spowoduje to uruchomienie Accessa w nowo utworzonej
grupie roboczej, chociaż nic na to nie wskazuje. Przed utworzeniem uprawnień jest bardzo ważne sprawdzenie, czy
dołączyłeś się do właściwej grupy roboczej.
Możesz ustawić przynależność bazy danych do grupy roboczej przez wpisanie odpowiednich parametrów wywołania bazy
danych:
Ścieżka do Access.exe Ścieżka do MDB /WRKGRP Ścieżka do pliku MDW
[/USER nazwa użytkownika /PWD hasło]
Użytkownicy i grupy
Użytkownicy są podstawą systemu bezpieczeństwa. Jet rozpoznaje użytkowników i wie, co każdy z nich może zrobić. Co
każdy z użytkowników może zrobić zależy od uprawnień nadanych bezpośrednio użytkownikowi lub które odziedziczył z
grup, do których należy. Uprawnienia użytkowników są sumą ich uprawnień pochodzących z grup (uprawnienia wynikowe)
oraz ich indywidualnych uprawnień (uprawnienia bezpośrednie). Użytkownik należy do co najmniej jednej grupy, grupy
Użytkownicy.
W trakcie logowania się do bazy danych Jet zawsze logujesz się jako użytkownik. Nie można zalogować się jako grupa.
System zabezpieczeń rozpoznaje, do jakich grup należysz i stosuje się do posiadanych przez Ciebie uprawnień.
Chociaż użytkownicy są podstawowym elementem systemu bezpieczeństwa, trudno jest dyskutować o nich bez brania pod
uwagę grup, ponieważ użytkownik zawsze należy do co najmniej jednej grupy, a grupy są stworzone do zarządzania
użytkownikami.
Rozważmy przypadek hipotetycznej grupy Urzędnik. Mimo że grupa może nie posiadać uprawnień do tworzenia i
modyfikacji obiektów, może być w niej jeden użytkownik, który jest wyznaczony do korygowania i tworzenia raportów.
Powinien on otrzymać bezpośrednie prawo do tworzenia i modyfikacji obiektów raportów, mimo że nikt w grupie Urzędnik
takiego prawa nie posiada. Mimo że to działa, powoduje kłopoty w administracji, ponieważ administrator zabezpieczeń
musi zajmować się indywidualnymi użytkownikami oraz grupami. Istnieje szansa, że jeżeli administrator zrobił jeden
wyjątek, zrobi i kolejny. Lepszym sposobem obsługi urzędnika tworzącego raporty jest przypisanie go do grupy, która
posiada uprawnienia do tworzenia i modyfikacji raportów. Tym sposobem administrator obsługuje funkcjonalne
możliwości pojedynczych użytkowników zamiast opracowywać ich indywidualne profile zabezpieczeń. Grupy nie mogą
należeć do grup.
Gdy tworzymy kolejnych użytkowników i grupy, nazwy grup i nazwy użytkowników nie mogą być takie same. Access
używa konwencji nazywania użytkowników w liczbie pojedynczej, a grup w liczbie mnogiej. Wydaje się być to dobrym
rozwiązaniem i należy stosować tę konwencję.
Najważniejszą grupą jest grupa Administratorzy, ponieważ ma ona specjalne uprawnienia, które nie mogą być nadawane
tworzonym przez Ciebie grupom. Aby tworzyć, zmieniać lub usuwać użytkowników, tworzyć lub usuwać grupy, zmieniać
przynależność do grupy lub wyczyścić hasło użytkownika, musisz być członkiem grupy Administratorzy. Użytkownik nie
będący członkiem tej grupy może oglądać dane o innych użytkownikach i sprawdzić, kto należy do grupy, ale nie może
zmienić żadnego z tych ustawień, nawet dla siebie. Może on tylko zmieniać swoje hasło. Oczywiście w bazie danych musi
być co najmniej jeden użytkownik należący do grupy Administratorzy.
Grupy nie są tylko zbiorem użytkowników. Mimo że nie mogą się logować do bazy i nie mogą posiadać własnego hasła ani
być właścicielem bazy danych, mogą jednak być właścicielami obiektów Accessa i posiadać różne uprawnienia. Ta
możliwość pozwala na ułatwienie administracji bazą danych i użytkownikami. Jako generalną zasadę powinieneś przyjąć,
że przypisujesz uprawnienia grupom, a następnie przypisujesz użytkowników do grup. Bardzo ułatwia to administrowanie
systemem zabezpieczeń.
Tworzenie użytkowników
Mimo że użytkownik może różnić się tylko szczegółami od innych użytkowników tej samej grupy, tworzenie
użytkowników jest niezbędne do prawidłowego funkcjonowania systemu bezpieczeństwa w bazie danych.
Rysunek 23.4.
Tworzenie nowego
użytkownika
i przypisywanie mu
identyfikatora PID
429 Rozdział 23. ♦ Bezpieczeństwo
Kliknij zakładkę Zmienianie hasła logowania, aby zmienić lub ustawić hasło. Hasło powinno posiadać od 1 do 14 znaków i
nie jest obowiązkowe. Wielkość liter w haśle ma znaczenie. Ponieważ hasło jest przeznaczone do tego, aby sprawdzić, że
użytkownik jest tym, za kogo się przedstawia, każdy powinien mieć założone hasło. Nie można podejrzeć hasła po jego
ustawieniu, więc lepiej je zapisać. W najgorszym przypadku, jeżeli użytkownik zapomniał hasła, administrator może je
usunąć. Na rysunku 23.5 widać, w jaki sposób ukrywane jest hasło podczas jego zmiany.
Rysunek 23.5.
Zmiana hasła
użytkownika poprzez
okno Accessa
Tworzenie grup
Jak wspomnieliśmy wcześniej, grupy pozwalają na ułatwienie administracji przez ustawianie identycznego profilu
zabezpieczeń wszystkim członkom grupy.
Rysunek 23.6.
Tworzenie grupy
przez nadanie jej
nazwy i PID przez
interfejs użytkownika
Aby zobaczyć wszystkie przypisania w bazie, użyj przycisku Drukuj użytkowników i grupy.
Ponieważ system bezpieczeństwa jest zorientowany na użytkownika, można kontrolować skład grupy tylko z zakładki
Użytkownicy, a nie zakładki Grupy.
Administratorzy – w odróżnieniu od zwykłych kont, grupa Administratorzy jest unikatowa w każdej grupie roboczej,
ponieważ jej SID jest generowany na podstawie SID grupy. Grupa Administratorzy musi zawsze posiadać co najmniej
jednego członka i Jet wymusza tę regułę. Mimo że członkostwo w grupie Administratorzy może być odebrane, grupa nadaje
specjalne niemożliwe do odebrania przywileje. Członek grupy Administratorzy może nadawać przywileje do każdego
obiektu w grupie roboczej. Przy użyciu DAO i ADOX możliwe jest zablokowanie tych przywilejów dla Administratorów do
obiektów bazy danych tak, aby specjalne przywileje posiadał tylko właściciel obiektów, jednak nie da się, ani używając
DAO ani ADOX, odebrać Administratorom prawa do administracji grupami i kontami użytkowników.
Administrator – jedyny domyślny użytkownik w Jet. Sam nie posiada żadnych specjalnych praw, jednak dziedziczy prawa z
grupy Administratorzy. Jeżeli nie zalogowałeś się do bazy za pomocą konta jakiegoś użytkownika, domyślnie jesteś
zalogowany jako Administrator. Jeżeli w grupie Administratorzy znajduje się jakiś inny użytkownik, możesz usunąć z niej
użytkownika Administrator. Jest to niezbędny krok do prawidłowego zabezpieczenia bazy danych i jest omówiony w tym
rozdziale w części „Zabezpieczanie bazy danych krok po kroku”.
Użytkownicy – po utworzeniu bazy grupa ta jest pusta i domyślnie posiada wszystkie prawa do bazy. Usunięcie wszystkich
praw z tej grupy jest niezbędnym krokiem do prawidłowego zabezpieczenia bazy danych i jest on omówiony w tym
rozdziale w części „Zabezpieczanie bazy danych krok po kroku”.
Właściciel – jest nim użytkownik, który utworzył obiekt, lub użytkownik, na którego zostało przeniesione posiadanie
obiektu. Właściciel obiektu jest najsilniejszym użytkownikiem i posiada do niego nieusuwalne prawa. Właścicielami
obiektów bazy danych muszą być użytkownicy, natomiast innych obiektów użytkownicy lub grupy.
Poznajemy uprawnienia
Tak jak trudno jest pisać o użytkownikach bez wspominania o grupach, równie trudno jest opisać uprawnienia bez
napisania o obiektach.
Po utworzeniu użytkowników i grup można rozpocząć tworzenie własnego systemu bezpieczeństwa. Uprawnienia
określają, co użytkownik lub grupa może, a czego nie może zrobić z tabelami bazy danych, kwerendami, formularzami,
raportami i makrami (moduły nie wchodzą już w skład systemu bezpieczeństwa). Typy uprawnień różnią się między
obiektami, a niektóre uprawnienia zależą od innych uprawnień. Przykładowo, jeżeli masz prawo do zmiany wyglądu
obiektu, musisz mieć możliwość otwarcia go (być może na wyłączność), odczytania i zapisu. Nie ma potrzeby
zapamiętywania niezależnych i zależnych zbiorów uprawnień. Interfejs Accessa będzie się troszczył o to za Ciebie, musisz
tylko wiedzieć, o co w tym chodzi. W tabeli 23.1 zestawione są obiekty, ich uprawnienia i ich konsekwencje.
431 Rozdział 23. ♦ Bezpieczeństwo
Uprawnienia nie są pamiętane w pliku MDW (w pliku MDW nie ma żadnej o nich informacji). Przechowywane są w
bazie danych, a tylko użytkownicy są autoryzowani za pomocą pliku MDW.
Tabela 23.1.
Uprawnienia i co one mogą dla Ciebie zrobić
Aby naprawić lub zmniejszać bazę danych, należy otworzyć ją na wyłączność. Tak samo należy otworzyć udostępnioną
użytkownikom wielodostępną bazę danych, jeżeli trzeba wprowadzić do niej zmiany.
Często pojawiają się problemy związane z zapytaniami. Można utworzyć dla użytkowników kwerendę, lecz nie chcesz, aby
mieli oni dostęp do tabel, na których ona bazuje. Włączenie opcji Uruchom uprawnienia właściciela daje dostęp na
poziomie rekordów i pól, ponieważ możesz ograniczyć użytkowników tylko do rekordów spełniających określone warunki
(na przykład: kody oddziałów, numery pracowników, bieżące daty, wartości pól itd.) oraz nie mogą oni zmieniać
utworzonych przez Ciebie zapytań.
Właściwości Uruchom uprawnienia znajduje się w oknie opcji dostępnym przez Narzędzia→ Opcje na zakładce
Tabele/Kwerendy. Wybranie Właściciela (rysunek 23.7) udostępnia wszystkie uprawnienia posiadane przez właściciela
kwerendy, na czas uruchomienia lub otwarcia kwerendy, jednak tylko właściciel może zmieniać zapytanie i tylko
właściciel może oddać posiadaną kwerendę innemu użytkownikowi. Wybranie Właściciela przesłania bieżące uprawnienia
użytkownika. Opcja ta może zostać uruchomiona z okna właściwości kwerendy oraz przez użycie klauzuli With
OwnerAccess w wyrażeniu SQL (więcej na ten temat w „Konsekwencje w czasie używania SQL”).
Rysunek 23.7.
Ustawienie
właściwości
Uruchom
uprawnienia
dla kwerendy
poprzez interfejs
użytkownika
Przez wszystkie lata tworzenia aplikacji baz danych nie spotkałem się z wieloma, o których można powiedzieć, że są
skończone. Jeżeli baza danych jest używana i użytkownicy ją lubią, jest zwykle rozszerzana. Aby obsłużyć ewentualne
nowe obiekty utworzone w przyszłości, Access dostarcza mechanizmu obsługi uprawnień obiektów, które jeszcze nie
zostały utworzone w trakcie tworzenia systemu bezpieczeństwa.
Część VII ♦ Zagadnienia wielodostępu 432
Wybranie <Nowe NazwaObiektu> w oknie dialogowym Uprawnienia użytkowników i grup nie zabezpiecza przed
tworzeniem nowych obiektów tylko definiuje, jakie będą uprawnienia nowo utworzonego obiektu. Nawet, gdy usunie się
wszystkie uprawnienia dla <Nowe NazwaObiektu>, użytkownicy będą mogli utworzyć nowe obiekty. Ponieważ
użytkownik tworzący obiekt jest jego właścicielem, może ustawić dowolne uprawnienia do obiektu. Jedyną metodą
zabronienia użytkownikom tworzenia obiektów jest interwencja w przypisywanie uprawnień przez ADO lub ADOX.
Właściciel obiektu jest najsilniejszym użytkownikiem obiektu i może zrobić z nim wszystko. Nie można praw związanych z
właściwością odebrać ani usunąć. Okno uprawnień może sugerować, że uprawnienia dla właściciela zostały odebrane, ale
w rzeczywistości tak nie jest. Jedynym sposobem na pozbawienie praw jest przeniesienie właściwości na innego
użytkownika.
Użytkownik, który utworzył bazę danych, jest jej właścicielem. Jego prawa do tworzenia obiektów w bazie danych nie można
odebrać, niezależnie co wskazuje okno nadawania uprawnień. Inni użytkownicy mogą tworzyć obiekty w bazie danych i stają
się ich właścicielami. Aby ułatwić administrację, należy prawo właściwości przenieść na grupę, tym sposobem każdy członek
grupy może administrować obiektem lub zbiorem obiektów.
Prawo właściwości obiektu może zostać przeniesione przez właściciela bazy danych lub właściciela obiektu. Aby zmienić
właściciela bazy danych, użytkownik musi posiadać prawa Czytanie projektu i Odczytaj dane w oryginalnej bazie danych.
Następnie należy utworzyć bazę danych w grupie roboczej, zaimportować wszystkie obiekty do nowej bazy, usunąć oryginalną
bazę oraz zmienić nazwę nowej bazy na taką jak usunięty oryginał.
Innym problemem do rozpatrzenia jest skład grupy Administratorzy. Ponieważ członkowie tej grupy mogą dodawać i
usuwać użytkowników oraz usuwać hasła, ważne jest, aby ostrożnie dobierać administratorów i utrzymywać najmniejszą
możliwą ich liczbę.
Gdy używana jest replikacja, niedostępne jest zabezpieczenie bazy danych hasłem.
Przy obsłudze tabel połączonych należy utworzyć dwa zbiory uprawnień: jeden dla źródłowej bazy danych, a drugi dla jej
klienta. Źródłem są tabele. W kliencie ustanowione są połączenia do tych tabel. Można ustawić uprawnienia do połączenia,
ale nie ma to większego sensu. Połączenie jest niczym więcej jak zbiorem właściwości.
Wiedząc, że w tabeli połączonej przechowywanej na komputerze klienta nie ma żadnych danych, możesz nadać pełne
prawa do tabeli połączonej. Takie postępowanie pozwala użytkownikom na odtworzenie definicji tabeli w razie potrzeby.
Gdy połączenie nie jest chronione, należy zabezpieczyć źródłową bazę danych w normalny sposób. W ten sposób
nierozpoznani użytkownicy nie będą mogli dostać się do danych innymi sposobami.
Jeżeli będzie potrzeba odświeżenia połączeń do tabel źródłowych, możliwe są trzy sposoby:
u RefreshLink – wymagane prawo czytania danych w tabeli źródłowej.
u RefreshLink – wymagane prawo czytania projektu w tabeli źródłowej.
u Właściwość Connect – bez wymaganych praw w tabeli źródłowej.
Jeżeli z bazy źródłowej zostaną usunięte wszystkie uprawnienia, trzecia możliwość jest jedyną możliwą. Opcje te muszą
być uruchamiane poprzez DAO lub ADOX. Interfejs użytkownika nie pozwala na zarządzanie uprawnieniami połączenia,
chyba że masz uprawnienia do czytania danych w bazie źródłowej. Można wykonać to w następujący sposób:
Set tbldef = db.CreateTableDef(strTableName)
With tbldef
.SourceTableName=strTableName
.Connect = ";Database=" & strTableName
.Appedn tdf ' dołącz pojedynczą tabelę
End With
Innym sposobem poradzenia sobie z zagadnieniem połączeń jest całkowite usunięcie połączeń i dostęp do tabel źródłowych
poprzez obiekt zdalnej bazy danych i wyrażenia SQL. Można również skorzystać z możliwości Accessa 2000 do związania
formularza z odłączonym obiektem recordset. Na wydruku 23.1 znajduje się przykład tego podejścia.
Łączenie tabel nie wpływa na ADOX poza jednym ważnym szczegółem, ADOX „nie interesuje się” obiektami
umieszczonymi w bieżącej bazie danych (currentdb()), a więc nie zna uprawnień dotyczących połączenia. Przy
użyciu ADOX dane są otwierane bezpośrednio w źródłowej bazie danych. Program na wydruku 23.2 otwiera połączenie
ADO do źródła danych i ustawia uprawnienia dla użytkownika „JP”.
With cnn
.Provider = "Microsoft.Jet.OLEDB.4.O"
.ConnectionString = "data source=F:\NorthWind_Traders\& _
NorthWind.mdb;jet oledb:system database=" &
"F:\NorthWind_Traders\sysnwind.mdw; " &
"user id=Chuck;Password=opensesame"
.Open
End With
Aby utworzyć zapytania wykorzystujące opcję With OwnerAccess, wykonaj następujące czynności:
132. Usuń wszystkie uprawnienia z tabel dla grup, które będą używać kwerendy.
133. Przy użyciu użytkownika, który ma prawo odczytaj dane i aktualizuj dane w tej tabeli (lub tabelach) utwórz
zapytanie, wybierz kolumny i ustaw warunki, które określają oczekiwany wynik.
134. Zmień opcje uprawnień kwerendy na Właściciela. Pozwoli to na jej uruchomienie tak, jakby była uruchamiana
przez użytkownika, ale tylko właściciel może wprowadzić do niej zmiany.
Posiadanie zapytania, które może być zmieniane tylko przez właściciela, może przeszkadzać w złożonych aplikacjach, nad
którymi pracuje więcej programistów. Najlepiej ustawić grupę jako właściciela kwerendy, co pozwoli na modyfikowanie
jej przez wszystkich członków grupy, gdy zajdzie taka potrzeba. Powinieneś przestawić opcję uprawnień kwerendy na
Użytkownika przed przeniesieniem właściwości kwerendy na grupę.
Jeżeli Twoja aplikacja jest oparta o dane z tabel na serwerze i chcesz ograniczyć możliwość zapisu i wstawiania danych do
tych tabel, możesz zrobić to poprzez uprawnienia Accessa, poprzez ADOX (użyj CurrentProject.Connection) lub
używając interfejsu użytkownika.
Zarządzanie użytkownikami
System zabezpieczeń Jet jest oparty o użytkowników, jednak nie oznacza to, że musisz obsługiwać wiele szczegółów na
jego temat. Zwykle wystarczy podać nazwę użytkownika, jego hasło i PID. Aby użytkownik mógł pracować, potrzebuje
uprawnień, a aby można było łatwo zarządzać użytkownikami, powinien należeć do przynajmniej jednej grupy. Poza tym
jest niewiele do zrobienia. Jeżeli wplączesz się w indywidualne ustawianie schematów zabezpieczeń dla poszczególnych
użytkowników, stworzysz sam sobie problemy administracyjne. Po przypisaniu nazwy, PID i hasła, powinieneś mody-
fikować tylko hasło. Unikaj nadawania praw do obiektu użytkownikom. Zamiast tego nadawaj prawa do obiektów grupom,
a następnie włącz użytkowników do tej grupy.
Na wydruku 23.3 znajduje się prosta funkcja, która ilustruje, w jaki sposób sprawdzić, czy użytkownik istnieje, utworzyć
go, usunąć, włączyć do grupy lub usunąć z grupy.
Wydruk 23.3. Przykład funkcji sprawdzającej istnienie użytkownika, jego usuwanie i tworzenie
Sub ADOXManageUser(strUserName, strPID, strPWD, _
435 Rozdział 23. ♦ Bezpieczeństwo
With cnn
.Provider = "Microsoft.Jet.OLEDB.4.O"
.ConnectionString = "data source=C:\Program Files\ & _
Microsoft Office\Office\Samples\Northwind.mdb; & _
jet oledb:system database=C:\Program Files\ & _
Microsoft Office\Office\Samples\sysnwind.mdw; &
user id=NWindAdmin;Password=opensesame"
.Open
End With
With cat
' Nie przewidujemy błędów
On Error ReSume Next
Aby utworzyć lub zmienić użytkownika, funkcja wymaga jako argumentu nazwy użytkownika, jego PID i hasła oraz w
tablicy parametrów listy grup, do których użytkownik powinien należeć.
Funkcja sprawdza, czy nazwa użytkownika znajduje się w kolekcji Users. Jeżeli znajduje się tam, usuwa go i ponownie
tworzy z nowym identyfikatorem PID. Następnie przegląda przez przekazaną tablicę parametrów i przypisuje użytkownika
do grup. Aby być zgodnym z interfejsem użytkownika, funkcja sprawdza, czy użytkownik znajduje się co najmniej w
domyślnej grupie Użytkownicy. Jeżeli grupa ta nie została wymieniona w parametrze, użytkownik zostanie do niej
automatycznie przypisany.
With cnn
.Provider = "Microsoft.Jet.OLEDB.4.O"
.ConnectionString = "data source=h:\books and articles\ & _
unleashed\securityexample.mdb; & _
jet oledb:system database=h:\books and articles\ &
unleashed\sysnwind.mdw;user id=Admin;Password=letmein"
.Open
End With
Debug.Print
Debug.Print
Debug.Print
End Sub
rst.MoveNext
Loop
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Ustawienie obu argumentów metody changepassword na puste ciągi znaków usuwa hasło. Mimo że członek grupy
Administratorzy nie może zobaczyć hasła innego użytkownika, może on usunąć dowolne hasło.
Zarządzanie grupami
Aby łatwiej zarządzać użytkownikami, możesz przypisać uprawnienia i właściwość obiektu do grup zamiast do
użytkowników. Ogranicza to ilość różnych profili uprawnień.
' Tutaj pracujemy na komputerze klienta, ale jeżeli chcesz pracować z innym
' plikiem MDB, po prostu utwórz i otwórz połączenie do niego
Set cat.ActiveConnection = CurrentProject.Connection
With cat
Debug.Print .GetObjectOwner(strObjectName, adPermObjTable)
.SetObjectOwner strObjectName, adPermObjTable, strGroupName
.Tables.Refresh
Debug.Print .GetObjectOwner(strObjectName, adPermObjTable)
cat.Tables.Refresh
End With
End Sub
Mimo że ADOX wciąż posiadał, w czasie pisania tej książki, kilka usterek, ale także posiada duży potencjał. Za jego
pomocą można administrować wszystkimi widocznymi grupami roboczymi z jednego miejsca. Nie wydaje się być to
niczym nowym, ale gdy rozważysz możliwość koordynowania zabezpieczeń Oracle i SQL Server oraz definicji danych w
Twojej lokalnej grupie roboczej, jest to imponujące. W chwili obecnej możesz wykonywać instrukcje DDL dla Oracle,
używając dostawcy MSDAORA i ADOX.
Gdy spotykasz się z implementacją systemu bezpieczeństwa oraz zagadnieniami definicji danych w wielu aplikacjach,
zwróć uwagę na ADOX i sprawdź, czy spełni wszystkie oczekiwania.
Właścicielem obiektów w bazie danych powinna być grupa. Strategia ta sprawdza się również w przypadku zarządzania
wieloma aplikacjami. ADOX pozwala na zarządzanie systemem bezpieczeństwa oraz wykonywanie poleceń DDL dla
wielu aplikacji z jednego miejsca, tym bardziej ważne jest przypisanie grupy jako właściciela wszystkich obiektów.
Ułatwia to również rozwój aplikacji. Jeżeli właścicielem obiektu jest pojedynczy użytkownik, tylko on może wprowadzić
do niego poprawki. W przypadku,
gdy właściciel nie jest osiągalny, proces rozwoju aplikacji poważnie zwalnia. Zamiast czekać na tę sytuację, lepiej
skorzystaj z grupy jako właściciela obiektów. Tym sposobem każdy członek grupy może wprowadzić niezbędne poprawki.
439 Rozdział 23. ♦ Bezpieczeństwo
Różne aplikacje mogą posiadać wspólną grupę roboczą (rysunek 23.1). Korzystaj z tej możliwości kiedykolwiek tylko
możesz. Istnieje duża szansa, że większość grup w różnych aplikacjach jest identyczna. Zmniejsza to ilość pracy dla
administratora.
Jeżeli jest to możliwe, staraj się, aby użytkownicy korzystali ze wspólnych plików, zamiast tworzyć schemat replikacji.
Mimo że replikacja jest świetnym narzędziem na współdzielenie danych i daje wiele możliwości dla aplikacji Accessa,
jednak pociąga ona zwykle duże koszty administracyjne.
Kluczem do zarządzania wieloma aplikacjami jest współdzielenie obiektów, użytkowników, grup, grup roboczych i
katalogów, gdziekolwiek jest to tylko możliwe. Zmniejszenie liczby zmiennych przy utrzymaniu tych aplikacji spowoduje,
że będą bardziej niezawodne i solidne.
Użycie SQL
Access 2000 dostarcza nowego sposobu obsługi podstawowych możliwości systemu zabezpieczeń w bazie danych oraz w
kliencie. Do dialektu SQL zostały dodane nowe słowa kluczowe, które pozwalają na tworzenie użytkowników i grup,
dodawanie użytkowników do grup, usuwanie użytkowników i grup, przypisywanie uprawnień oraz ich odbieranie.
Wyrażenia takie są wykonywane identycznie jak inne wyrażenia SQL, jednak zamiast zwrócić wynik lub zmienić definicję
bazy danych, wpływają na ustawienia zabezpieczeń wymienionych obiektów.
Create
Create User i Create Group wykonują dokładnie to, czego można się spodziewać. Do kolekcji użytkowników lub
grup w pliku systemowym bazy danych dodawany jest nowy użytkownik lub grupa. Jedyną różnicą pomiędzy tym sposobem
a użyciem ADOX jest brak identyfikatora PID. W wyrażeniu SQL nie można używać identyfikatora PID. Poniżej znajduje
się przykład tworzenia użytkownika i grupy za pomocą wyrażeń SQL.
CREATE USER użytkownik hasło [,użytkownik hasło, ...]
CREATE GROUP grupa hasło [,grupa hasło, ...]
Po utworzeniu użytkowników i grup można dodać użytkownika do grupy za pomocą wyrażenia Add User.
Add User
Add User wpływa również na kolekcję grup w pliku grupy roboczej. Gdziekolwiek występuje odwołanie do pliku grupy roboczej,
dotyczy bieżącej grupy. Za pomocą SQL nie można zmieniać innego pliku grupy roboczej niż ten, do którego jest zalogowany
użytkownik.
ADD USER użytkownik [, użytkownik, ...] TO grupa
Grant/Revoke
Po utworzeniu użytkowników i dodaniu ich do grup można nadać im uprawnienia. Wyrażenie Grant pozwala na nadanie
przywileju do obiektu użytkownikowi lub grupie.
GRANT {prawo [, prawo, ...]} ON
{TABLE tabela |
INDEX indeks |
QUERY kwerenda |
CONTAINER}
TO {użytkownik/grupa [,użytkownik/grupa, ...]}
Za pomocą tej metody możesz nadać mniej uprawnień niż za pomocą ADOX. Uprawnienia, które możesz nadać, są
następujące:
Select Selectsecurity Create
Delete Updatesecurity Selectschema
Insert Dbpassword Schema
Update Updateidentity Updateowner
Drop
Po nadaniu uprawnień można je odebrać za pomocą odwrotnego do Grant wyrażenia Revoke. Składnia i opcje są
identyczne jak dla wyrażenia Grant, a rezultat dokładnie odwrotny.
Część VII ♦ Zagadnienia wielodostępu 440
Drop
Po usunięciu uprawnień możesz usunąć użytkownika za pomocą wyrażenia Drop. Składnia i opcje są identyczne jak dla
wyrażenia Create poza słowem kluczowym Drop. Wynikiem wyrażenia jest usunięcie użytkownika lub grupy z pliku
grupy roboczej.
Jeżeli podczas implementowania systemu bezpieczeństwa wykonasz możliwie dokładnie poniższe kroki, w pełni
wykorzystasz możliwości ochrony Accessa. Niedotrzymanie któregoś z punktów może spowodować obniżenie poziomu
bezpieczeństwa.
135. Utwórz nową grupę roboczą. Użyj programu wrkgadm.exe opisanego na początku tego rozdziału. Wybierz opcję
tworzenia nowego pliku grupy roboczej.
136. Otwórz Accessa, używając pliku grupy roboczej utworzonego specjalnie dla Twojej aplikacji.
137. Otwórz lub utwórz bazę danych, którą chcesz zabezpieczyć.
138. Utwórz nowego użytkownika i dodaj go do grupy Administratorzy.
139. Zmień hasło użytkownika Administrator.
140. Usuń wszystkie uprawnienia dla grupy Użytkownicy z wszystkich obiektów w bazie danych.
141. Zamknij bazę danych.
142. Otwórz Accessa, logując się jako nowy administrator.
143. Otwórz bazę danych, którą chcesz zabezpieczać.
144. Uruchom kreatora zabezpieczania na bazie danych. Zaoszczędzi Ci wiele żmudnej pracy, zmieniając właściciela
obiektów.
145. Usuń użytkownika Administrator z grupy Administratorzy.
146. Utwórz użytkowników i grupy potrzebne w aplikacji.
147. Przypisz użytkowników do odpowiednich grup.
148. Ustaw odpowiednie uprawnienia dla grup.
149. Dodawaj i usuwaj grupowe uprawnienia, tak jak tego potrzebujesz.
Zwykle dzieje się to, ponieważ system bezpieczeństwa został utworzony w domyślnym pliku system.mdw. Systemowy plik
MDW nie jest zabezpieczony i nigdy nie może być zabezpieczony, ponieważ przy jego tworzeniu nie został podany PID.
Ponieważ użytkownik Administrator jest uniwersalny, ktokolwiek może dostać się do takiego systemu. Jest również
możliwe, że użytkownik Administrator nie został usunięty z grupy Administratorzy. Ponieważ użytkownik Administrator nie
jest unikatowy dla wszystkich grup roboczych, każda z nich będzie widziała użytkownika Administrator jako swojego
Administratora. Jeżeli w Twojej grupie Administrator będzie członkiem grupy Administratorzy, użytkownicy z innych grup
roboczych będą mogli zalogować się do Twojej grupy z pełnymi prawami.
Aby rozwiązać ten problem, musisz zabezpieczyć bazę danych z użyciem nowego pliku grupy roboczej.
Czasami baza danych wydaje się zabezpieczona, wszyscy mogą się zalogować, ale nie działają uprawnienia.
Zwykle jest to spowodowane pozostawieniem uprawnień w grupie Użytkownicy. Po utworzeniu wszystkie grupy robocze dają
użytkownikom pełne prawa dostępu do wszystkich obiektów w bazie danych. Wszyscy użytkownicy są domyślnie w
441 Rozdział 23. ♦ Bezpieczeństwo
grupie Użytkownicy. Nawet gdy nie nadasz praw administratora, wszyscy użytkownicy z grupy Użytkownicy odziedziczą je
z grupy. Upewnij się, że usunąłeś wszystkie uprawnienia z grupy Użytkownicy.
Nic nie ogranicza Cię w tworzeniu tylu grup, ile potrzebujesz. Ponieważ grupa Użytkownicy jest bezużyteczna z powodu
braku uprawnień, a Administratorzy jest zbyt potężna, nie masz wyboru i musisz opracować swój schemat bezpieczeństwa i
utworzyć grupy w nim przewidziane.
Część VIII
Publikowanie w sieci
za pomocą Accessa 2000
W tej części:
u Konfiguracja serwera WWW dla publikowania w sieci WWW.
u Przenoszenie Accessa 2000 do sieci WWW.
u Użycie stron dostępu do danych.
u Publikowanie w sieci przy użyciu Accessa 2000 i Active Server Pages.
Rozdział 24.
Konfiguracja serwera WWW dla
publikowania w sieci WWW
W tym rozdziale:
u Środowisko programistyczne a środowisko produkcyjne.
u Wybór platformy.
u Co to jest Option Pack.
u Uruchomienie serwera WWW.
u Zarządzanie i konfiguracja serwera WWW.
u Zabezpieczanie aplikacji WWW.
u Różnice pomiędzy witryną a katalogiem wirtualnym.
Większość programistów Accessa czuje się bardzo niepewnie, gdy ich szef lub klienci wspominają o publikowaniu w
sieci za pomocą Accessa 2000, ponieważ większość z nich jest ekspertami w zarządzaniu bazą danych oraz VBA,
natomiast niewiele wiedzą na temat uruchamiania i utrzymywania serwera WWW. W tym rozdziale wyjaśnimy, jak
skonfigurować komputer do programowania dla sieci WWW, jak uaktualniać serwer WWW i jak używać technologii
serwera WWW Microsoft. Nie znaczy to, że po zapoznaniu się z tym rozdziałem będziesz administratorem serwera
WWW, ale w razie potrzeby będziesz potrafił uruchomić serwer WWW.
W idealnym przypadku, Twoje środowisko programistyczne i produkcyjne powinny mieć identyczne konfiguracje
sprzętowe i programowe, ale powinny znajdować się na oddzielnych komputerach. Zwykle nie jest to osiągalne. Wielu
ludzi (włączając niektórych autorów tej książki) używa Windows 95/98 lub Windows NT Workstation jako ich środowisko
programistyczne, natomiast umieszczają pliki na komputerze Windows NT Server, który jest ich środowiskiem
produkcyjnym.
Wspaniałą możliwością technologii WWW Microsoft jest możliwość tworzenia i testowania aplikacji WWW Accessa 2000
na komputerze z Windows 95/98 i umieszczanie ich na Windows 2000/NT 4.0 bez żadnych zmian. Microsoft dostarcza
jednej technologii WWW, która działa na każdym ze wspomnianych systemów operacyjnych. Aby skorzystać tej
technologii, należy zainstalować serwer WWW na Twoich komputerach roboczym i produkcyjnym.
Część VIII ♦ Publikowanie w sieci za pomocą Access’a 2000 444
Wybór platformy
Microsoft wypuścił trzy różne aplikacje serwera WWW, po jednej na każdy poziom platformy Windows. Pierwszy z nich,
Personal Web Server 4.0 (PWS4), działa na Windows 95/98 i dostarcza podstawowych funkcji serwera WWW. Kolejny,
Peer Web Services (znów PWS4), jest również serwerem o ograniczonych możliwościach prawie identycznych z wersją dla
Windows 95/98, ale zmodyfikowany do pracy w Windows NT 4.0 Workstation. Ostatni, Internet Information Server 4.0
(IIS4), może pracować na Windows NT 4.0. Wersje działające na Windows 95/98 mają tak podobne możliwości i
funkcje, że w dalszej części książki będę je nazywał PWS, bez rozróżniania tych dwóch produktów.
Mimo wielu podobieństw występują również różnice, w większości mające związek z wydajnością i skalowalnością.
Powinny być one brane pod uwagę przy wyborze docelowej platformy produkcyjnej.
Ponieważ PWS nie został zaprojektowany do obsługi obszernych witryn WWW, brak w nim niektórych funkcji
zawartych w IIS4, takich jak Index Server, SMTP Server oraz Certificate Server. Istnieje również ograniczenie ilości
jednocześnie przyłączonych klientów, tylko jedno w przypadku Windows 95/98 i nie więcej jak 10 dla Windows NT
Workstation.
Instalacja obu produktów jest bardzo łatwa i dosyć podobna. Zaleca się instalowanie tylko tych usług, które będziemy
wykorzystywali. Załadowanie niepotrzebnych komponentów powoduje niepotrzebne obciążenie stacji roboczej lub
serwera.
445 Rozdział 24. ♦ Konfiguracja serwera WWW dla publikowania w sieci WWW
Teraz po zapoznaniu się z podstawowymi faktami na temat dostępnych serwerów WWW należy odpowiedzieć na pytanie,
którego należy użyć? Powinieneś w razie możliwości używać IIS4 i Windows NT 4 Server dla środowiska produkcyjnego.
Będziesz lepiej wyposażony do tworzenia aplikacji, mając jako swoje środowisko programistyczne maksymalnie podobne do
docelowego środowiska produkcyjnego. Zalecam więc IIS4 i NT Server jako środowisko programistyczne. Prawie każda
aplikacja Active Server Pages, jaką napiszesz, będzie działała na dowolnej platformie WWW: IIS4 lub PWS.
Aby zainstalować serwer Microsoft Web, należy zainstalować NT 4.0 Option Pack.
W trakcie instalacji NT Server 4.0, masz możliwość zainstalowania Internet Information Server (wersja 2), jednak nie
zapewnia on wymaganych możliwości do tworzenia Active Server Pages, która jest kluczową technologią Microsoftu i
tematem rozdziału 27. „Publikacja w sieci WWW za pomocą Access 2000 i Active Server Pages”.
Teraz, gdy jesteśmy przy tym temacie, nie zalecamy instalowania IIS
podczas instalacji Windows NT Server lub odinstalowania go przed dalszą
pracą. Zawsze lepiej jest rozpocząć od czystej instalacji niż od aktualizacji.
Najnowsza wersja serwera WWW wchodzi w skład Option Pack, który można otrzymać
z wielu źródeł. Jeżeli prenumerujesz MSDN, jest on do Ciebie automatycznie rozsyłany.
Możesz również kupić płytę CD-ROM lub załadować go z serwera WWW Microsoftu.
Option Pack dostępny jest pod adresem:
http://www.microsoft.com/ntserver/nts/downloads/recommended/NT40ptPk/default.asp.
Option Pack może zostać zainstalowany i uruchomiony na Windows 95/98, Windows NT Workstation oraz Windows NT
Server 4.0. Przed zainstalowaniem Option Pack powinieneś zainstalować Microsoft Internet Explorer 4.0 lub nowszy.
Zalecamy zainstalowanie najnowszej wersji przeglądarki, która posiada większość łatek i poprawek (w chwili pisania
książki jest to Internet Explorer umieszczony na dysku z Office 2000). Dodatkowo, jeżeli instalujesz Option Pack na
komputerze z Windows NT 4.0, musisz mieć zainstalowany Service Pack 3.
Przed instalacją Microsoft Option Pack powinieneś się upewnić, że twój komputer spełnia wymagania podane w tabeli
24.1.
Tabela 24.1.
Minimalne wymagania sprzętowe dla instalacji dla Windows NT Option Pack
Instalacja
Przed zainstalowaniem Option Pack muszą być spełnione wymagania określone wcześniej, takie jak: instalacja Internet
Explorer 4.01 i Service Pack 3 (w przypadku NT).
W czasie instalacji NT Option Pack musisz spełnić kilka wymagań, aby móc tworzyć aplikacje przy użyciu Office 2000.
Instalacja wielu z proponowanych komponentów jest zbędna, jeżeli zaakceptujesz domyślne wartości. W tej części
rozdziału wymienimy dostępne opcje instalacji, opcje, których zainstalowanie jest niezbędne oraz komponenty, które
powinieneś zainstalować nawet, gdy tylko planujesz ich użycia.
u Internet Connection Services for RAS. Zarządza wieloma połączeniami wdzwanianymi oraz książkami
telefonicznymi. Pakiet ten nie jest wymagany.
u Microsoft Data Access Component 1.5. Instalowane są komponenty ActiveX Data Components 1.5 (ADO) oraz
komponenty Remote Data Services (RDS). W komputerze umieszczane są sterowniki i dostawcy, które
umożliwiają połączenie do baz danych. Jest to komponent niezbędny do tworzenia aplikacji WWW Office 2000. Po
zainstalowaniu tego komponentu powinno się zainstalować najnowszą wersję komponentów MDAC (wersja 2.1).
Od czasu wypuszczenia Option Pack pojawiło się kilka kolejnych wydań pozbawionych zauważonych błędów i
zawierających dodatkowe funkcje wymagane przy tworzeniu aplikacji Office 2000 (sieciowych i innych).
u Microsoft Message Queue (MSMQ). Pozwala aplikacjom na przesyłanie informacji o transakcjach do innych
komponentów bez potrzeby czekania na odpowiedź. Funkcja ta powinna być zbadana, jeżeli tworzysz aplikacje
transakcyjne, a interfejsy, których używasz, są czasami niepewne. Przykładowo, jeżeli używasz MSMQ i wystąpi
chwilowa przerwa w połączeniu sieciowym, MSMQ będzie próbował dokończyć transakcję. Gdy przerwa w sieci
zostanie usunięta, transakcja może zostać zatwierdzona. Nie jest to wymagana funkcja, chyba że masz specjalne
wymagania i planujesz użyć tej usługi w aplikacjach.
u Personal Web Server (tylko Windows 95/98 i Windows NT Workstation). Komponent ten zawiera właściwą część
usługi WWW. Jest on wymagany, jeżeli planujesz testować aplikacje na Twoim komputerze.
u Internet Information Server (tylko Windows NT Server). Pakiet zawiera:
u Usługę File Transfer Protocol (FTP);
u Usługę NNTP (do utrzymywania grup dyskusyjnych)
u Internet Service Manager (ISM). Jest to komponent wymagany do administracji i konfiguracji usługi WWW
poprzez Microsoft Management Console.
u Usługę Simple Mail Transfer Protocol (SMTP). Pozwala na generowanie przesyłek e-mail z aplikacji i
wysyłania ich do adresatów.
u World Wide Web Server (usługa HTTP). Jest niezbędna, jeżeli chcesz tworzyć, testować i udostępniać
aplikacje WWW na Twoim serwerze.
u Przykładowa witryna WWW. Jeżeli rozpoczynasz programowanie dla WWW, powinieneś zainstalować te
przykłady, aby zapoznać się z użytymi konwencjami programowania i użytymi technikami.
u ISM w wersji HTML (Internet Service Manager). Pozwala on na zdalną administrację serwerem WWW
poprzez interfejs HTML.
u Microsoft Transaction Server 2.0 (MTS). Instaluje administratora COM i DCOM. Jest wymagany przy
programowaniu dla WWW.
u Microsoft Index Server (tylko NT Server). Pozwala na przeszukiwanie tekstu dokumentów umieszczonych na
serwerze WWW. Jest to świetne narzędzie do wyszukiwania zawierające wiele zaawansowanych funkcji. Jeżeli go
zainstalujesz, upewnij się, że go używasz. Uruchomienie procesu indeksowania wszystkich Twoich stron WWW
może być bardzo kosztowne. Nie jest to konieczna dla nas opcja.
u Microsoft Script Debugger (tylko NT Server). Pozwala na uruchamianie skryptów ASP. Może być użyty do
ułatwienia uruchamiania skryptów ASP. Jest automatycznie uruchamiany w razie wystąpienia błędu. Ze względów
wydajności i bezpieczeństwa nie powinien być instalowany na produkcyjnym serwerze WWW. Nie jest konieczny
do programowania z Office 2000.
u Windows Scripting Host. Pozwala na pisanie i uruchamianie lokalnych plików skryptów, które mogą wykonywać
niektóre funkcje administracji systemem. Nie jest konieczny do programowania z Office 2000.
u Microsoft Management Console (tylko Windows NT). Główne narzędzie w Windows NT, służące do zarządzania i
konfiguracji wszystkich usług zainstalowanych przez Option Pack. Jest to wymagany komponent w przypadku
Windows NT Server. Nie jest wymagany w przypadku NT Workstation (można użyć Personal Web Manager), ale
jest rekomendowany.
Część VIII ♦ Publikowanie w sieci za pomocą Access’a 2000 448
u Visual InterDev RAD Support. Pozwala aplikacjom Visual InterDev na zdalne rozpowszechnianie aplikacji na
Twój serwer. Nie jest to wymagana opcja przy programowaniu w Office 2000.
Jak widać, w NT Option Pack umieszczono wiele składników. Każdy z tych składników dodaje kolejne możliwości, ale nie
są one wymagane do podstawowego programowania dla WWW i mogą wnosić niepotrzebny narzut w systemie, jeżeli
są zainstalowane bez powodu.
Aby ułatwić instalacje NT Option Pack, Microsoft dołączył do programu instalacyjnego trzy prekonfigurowane opcje
instalacji. Komponenty instalowane przez te opcje są przedstawione poniżej.
Instalacja minimalna zawiera wszystko, co jest niezbędne do tworzenia podstawowych aplikacji WWW za pomocą Office
2000. Podczas instalacji w Twoim komputerze znajdą się następujące komponenty:
u Microsoft Data Access Components 1.5;
u Personal Web Server (tylko Windows 95/98 lub NT Workstation);
u Internet Information Server (tylko NT Server);
u Transaction Server;
u SMTP Service (tylko NT Server).
Jeżeli potrzebujesz jakiegoś zaawansowanego komponentu, który nie instaluje się automatycznie, powinieneś uruchomić
instalację niestandardową.
Jeden z przedstawionych wcześniej komponentów, Microsoft Transaction Server, jest tak ważnym usprawnieniem i
integralną częścią strategii WWW firmy Microsoft, że zdecydowaliśmy się omówić go bardziej szczegółowo w następnej
części tego rozdziału.
449 Rozdział 24. ♦ Konfiguracja serwera WWW dla publikowania w sieci WWW
MTS jest tak ważny dla pracy IIS, że Microsoft umieścił go jako część
Windows 2000 i zmienił jego nazwę na COM+.
MTS jest niezbędny do instalacji usług WWW Microsoftu, ponieważ nawet
gdy jawnie nie używałeś w aplikacji WWW tego składnika, MTS zarządza
wszystkimi aplikacjami ASP. Każda przetwarzana strona ASP jest
wykonywana przez MTS (zarządzający ASP.DLL). Jest to powód, dlaczego
IIS4 ma tak ogromną wydajność w porównaniu do IIS3.
MTS zapewnia dla obiektów COM to samo co serwer bazy dla wielu wyrażeń SQL. Dobrą praktyką jest podział aplikacji
na możliwie małe części i wyodrębnienie kodu, który może być wielokrotnie używany. Dla utworzenia naprawdę
skalowalnej aplikacji kod ten może być przeniesiony do COM i zarejestrowany w MTS. Po prawidłowej rejestracji MTS
określa które obiekty COM są niezbędne w transakcji i śledzi udane i nieudane wykonania każdego obiektu.
Oprócz zarządzania transakcjami MTS zarządza tworzeniem i usuwaniem obiektów. Pozwala to na tworzenie obiektów
COM wtedy, gdy są potrzebne, zwiększając szybkość wykonywania aplikacji i zapobiegając zwiększaniu obciążenia
serwera.
MTS zarządza także łączeniem połączeń do bazy. Pozwala to użytkownikom na współdzielenie połączeń zamiast
indywidualnego połączenia dla każdego użytkownika. Bez łączenia połączeń 500 użytkowników wymaga 500 połączeń do
bazy danych. MTS pozwala na około 10-krotne zmniejszenie ilości połączeń. Jeżeli połączenie jest nieużywane, jest ono
pożyczane do wykorzystania przez innego użytkownika, a następnie oddawane do wspólnej puli dostępnych połączeń. Ilość
połączeń jest zwiększana, gdy wszystkie dostępne połączenia są zajęte. Jest to wspaniałe usprawnienie i daje niesamowity
wzrost wydajności aplikacji.
Na rynku znajduje się wiele dobrych książek, które szczegółowo opisują działanie, konfigurację i uwagi dotyczące
programowania dla Microsoft Transaction Server. Szczegółowe opisywanie tych tematów wykracza poza ramy tej książki.
Jeżeli masz zamiar tworzyć aplikacje oparte o transakcje lub aplikacje wymagające wbudowanej skalowalności,
powinieneś na pewno poznać MTS.
Teraz, gdy już wiesz co zainstalować, jak zainstalować i jakie podstawowe funkcje są dostępne, omówimy konfigurację
usług WWW.
Część VIII ♦ Publikowanie w sieci za pomocą Access’a 2000 450
u Kolejna strona jest interfejsem do kreatora publikacji. Zgodnie z dokumentacją Microsoftu, kreator ten
automatycznie skopiuje pliki do katalogu sieciowego i doda połączenie do tego katalogu z Twojej strony
domowej. Jednak kreator nie zawsze działa najlepiej i zwykle lepiej samemu zmodyfikować odpowiednie pliki.
u Po wybraniu Web Site można utworzyć domyślną stronę domową lub zmienić istniejącą. Jest to bardzo proste
narzędzie i można się bez niego obejść, szczególnie, gdy jesteś prawdziwym programistą WWW.
u Tour dostarcza podstawowych informacji, prawdopodobnie nic ponad to, co już wiesz. Jeżeli jesteś ciekawy,
przejrzyj dostępne ekrany informacyjne.
u Większość funkcji potrzebnych do programowania WWW zawarta jest w części Advanced, która pokazana jest na
rysunku 24.2. Za pomocą tej opcji można tworzyć katalogi wirtualne, ustawiać domyślne dokumenty i zarządzać
właściwościami katalogów.
Katalogi wirtualne zostaną później szczegółowo objaśnione, ale powinieneś zapamiętać, że posiadają one trzy poziomy
dostępu ustawiane podczas tworzenia katalogu: Read, Execute i Script (rysunek 24.3). Zawsze zaznaczaj poziom dostępu
Read, jeżeli tego nie zrobisz, nikt nie będzie mógł oglądać Twojej witryny. Jeżeli masz zamiar oglądać strony ASP bez
451 Rozdział 24. ♦ Konfiguracja serwera WWW dla publikowania w sieci WWW
tworzenia katalogu wirtualnego, powinieneś zaznaczyć pole wyboru umożliwiające wykonywanie skryptów (ASP są
skryptami VBScript wykonywanymi na serwerze).
Rysunek 24.2.
Będziesz używał
strony Advanced
programu Personal
Web Manager do
tworzenia
i zarządzania
katalogami
wirtualnymi
Rysunek 24.3.
Prawa dostępu dla
nowego katalogu
wirtualnego
w Personal Web
Manager
Jeżeli zaznaczysz opcję Execute dla katalogu wirtualnego, wszystkie pliki wykonywalne w nim umieszczone będą mogły być
wykonywane, włączając w to interpretery skryptów (jak np. Perl) i pliki binarne Windows (pliki EXE i DLL).
Program konfiguracji usług WWW w systemie Windows NT / Windows 2000 jest nazywany Microsoft Management
Console i jest nieco bardziej wymagający. Jeżeli programujesz na Windows 95/98 i masz osobę, która administruje
serwerem produkcyjnym na Windows NT, możesz opuścić ten fragment rozdziału.
Po otwarciu MMC można zauważyć, że lewy panel posiada dwie rozwijalne opcje. Prawy panel jest oknem szczegółów i
będzie zawierał informacje specyficzne dla opcji wybranych po lewej stronie. Pierwszą pozycją w liście w lewym panelu jest
Console Root, właściwie jest to sam MMC. Każda pozycja poniżej nazywana jest wtyczką i pozwala na wykonywanie
specyficznych operacji zwykle ograniczonych do jednej usługi. Windows 2000 będzie posiadało wiele dostępnych wtyczek
dla MMC.
Rysunek 24.4.
Microsoft
Management
Console (MMC) jest
głównym narzędziem
do administracji
usługami sieciowymi
Opisanie każdej z tych opcji wykracza poza ramy tej książki, ale zajmiemy się kilkoma opcjami dotyczącymi konfiguracji
serwera WWW (gałąź Administration Web Site), ponieważ wpłyną one na pracę i wydajność Twoich aplikacji WWW.
Na początek wybierze nazwę lokalnego serwera i kliknij ją prawym klawiszem myszki. Tak jak w przypadku wielu
aplikacji Windows wyświetlone zostało menu z najczęściej używanymi opcjami (rysunek 24.5).
Wybierzemy Properties z menu. Spowoduje to wyświetlenie domyślnych opcji całego serwera. Można dostać się do tych
opcji przez wybranie właściwości poszczególnych witryn, ale wtedy trzeba wykonywać zmiany dla każdej witryny osobno.
Zmienimy teraz położenie plików śladu. Option Pack ustawia ich położenie w c:\winnt\ system32\logfiles\.Na pierwszy rzut
oka nie wzbudza podejrzeń, ale przecież pliki śladu mogą urosnąć do sporych rozmiarów na uczęszczanym serwerze. Może
to spowodować zatkanie dysku systemowego, czego należy unikać.
Rysunek 24.5.
Kliknięcie prawym
klawiszem na opcję
wyświetla menu
podręczne z listą
możliwych do
wykonania funkcji
Na dole zakładki Web Site wybierz Logging Properties. Następnie przejdź na zakładkę General i zmień położenie plików
śladu serwera WWW. Może być to katalog, który już istnieje w systemie. Może być to d:\logfiles\, jest poza partycją
systemową i jest łatwy do odszukania. Jeżeli wybierzesz zakładkę Extended Properties, możesz wybrać, które informacje
będą zapisywane do plików śladu, gdy klient zażąda strony.
Kliknij kilka razy przycisk OK, aby wrócić do głównego okna właściwości WWW.
Teraz zajmiemy się zakładką Documents. Możesz podać na niej jeden lub więcej domyślnych dokumentów (rysunek 24.6).
IIS używa tej informacji do wybrania pliku, który będzie załadowany jako pierwszy. Jeżeli ktoś wpisze
www.NazwaWitryny.com bez podawania nazwy pliku, IIS rozpoczynając od góry listy szuka pliku o podanej nazwie,
dopóki go nie znajdzie lub nie dojdzie do końca listy. Jeżeli plik nie istnieje na serwerze lub nie ma co najmniej jednego
wpisu do listy domyślnych dokumentów, użytkownik dostanie komunikat błędu. Ponieważ moja firma, ORCS Web, Inc
utrzymuje wiele serwisów klientów, zawsze dodajemy plik index.html do każdego serwera WWW, taki jest standard przyjęty w
systemie UNIX i wielu użytkowników jest do tego przyzwyczajonych.
453 Rozdział 24. ♦ Konfiguracja serwera WWW dla publikowania w sieci WWW
Rysunek 24.6.
Czasami będziesz
chciał zmienić nazwę
domyślnego
dokumentu lub
dodać więcej
domyślnych
dokumentów do listy
dla konkretnej
witryny
Przejdźmy znów do okna właściwości WWW i omówimy teraz zakładkę Directory Security. MMC pozwala na zarządzanie
dodatkowymi ustawieniami zabezpieczeń, które działają razem z Windows NT File System (rysunek 24.7). Znajdują się tu
trzy grupy opcji, które udostępnia IIS.
Rysunek 24.7.
Bezpieczeństwo jest
prawie zawsze
problemem każdego
systemu
przyłączonego
do Internetu
Wybierz Anonymus Access and Authentication Control. Masz do wyboru trzy opcje:
u Allow Anonymous Access (zezwolenie na dostęp anonimowy);
u Basic Authentication (podstawowe uwierzytelnianie, hasło przesyłane jest otwartym tekstem);
u Windows NT Challenge/Response (uwierzytelnianie próba/odpowiedź).
Jeżeli chcesz umożliwić anonimowy dostęp do Twoich stron, zaznacz pierwsze pole wyboru (Allow Anonymous Access).
Opcja ta powoduje, że IIS najpierw sprawdza, czy użytkownik IUSER (omówiony później w części „Co to jest IUSER ?”)
posiada prawo do dostępu do pliku lub strony. Jeżeli tak, przyjmuje, że klientem jest IUSER i przetwarza żądanie. Jeżeli
opcja ta nie jest aktywna lub użytkownik IUSER nie posiada prawa do żądanego pliku, proces autoryzacji jest ponawiany
dla pozostałych dwóch opcji.
Jeżeli włączona jest autoryzacja próba/odpowiedź i klientem jest Internet Explorer, nazwa użytkownika i hasło użyte do
zalogowania do klienta zostaną przesłane do serwera WWW i następuje próba autoryzacji. Przy użyciu tego sposobu
autoryzacji hasło jest przesyłane do serwera w bezpiecznej zaszyfrowanej postaci. Jeżeli użytkownik i hasło pasują do
konta na serwerze (lokalnego lub pochodzącego z domeny), użytkownik otrzymuje żądaną stronę lub nie, w zależności od
jego uprawnień. Jeżeli nie zostanie dopa-
sowane żadne konto użytkownika, żądanie dostępu zostanie odrzucone. Jeżeli klient nie używa przeglądarki Internet
Explorer, podczas uwierzytelniania hasło przesyłane będzie otwartym tekstem.
Aby autoryzować użytkowników, którzy nie używają przeglądarki Internet Explorer, IIS umożliwia uwierzytelnianie przy
użyciu nieszyfrowanego hasła. Metoda ta nie jest bezpieczna, ale jest wystarczająca, jeżeli musisz zabezpieczyć jakiś
fragment swojego serwera, a nie jesteś pewien, jakiej przeglądarki używają klienci. Uaktywnienie obu opcji jest zwykle
Część VIII ♦ Publikowanie w sieci za pomocą Access’a 2000 454
najlepszym wyborem. Na początku IIS spróbuje autoryzować się jako IUSER (jeżeli jest aktywny), a następnie spróbuje
autoryzacji Windows NT. Jeżeli nadal nie uzyska dostępu, spróbuje podstawowej autoryzacji.
Wybranie Secure Communication w oknie właściwości serwera WWW, gdy nie mamy jeszcze zainstalowanego klucza
bezpieczeństwa, powoduje otwarcie narzędzia Key Manager. Jeżeli zdecydujesz się na użycie Secure Socket Layer (SSL),
musisz od tego zacząć. W oknie tym można wygenerować żądanie wygenerowania klucza, które jest wysyłane do centrum
autoryzacji, np.: VeriSign. Po przetworzeniu żądania należy wprowadzić otrzymany certyfikat do Key Managera aby
zakończyć proces instalacji klucza.
Po zainstalowaniu klucza SSL przycisk zmienia się z Key Manager na Edit. Wybranie Edit pozwala na włączenie trybu
dostępu SSL do ochrony przesyłanych stron. URL umożliwiający dostęp do stron powinien być podawany wtedy w postaci
https:// zamiast http://.
Masz również możliwość ograniczenia dostępu do witryny, opierając się o adresy IP klientów. Nie jest to zbytnio
użyteczne, chyba że serwer jest używany w Intranecie. Większość adresów IP klientów w Internecie zmienia się, ponieważ
są one dynamicznie przydzielane przez ich ISP.
Jeżeli decydujesz się na ograniczenie dostępu oparte o adres IP, możesz podać listę klientów, którzy nie mają dostępu do
witryny, lub przeciwnie, podać listę klientów mających dostęp do witryny.
Powróćmy do okna właściwości serwera WWW na zakładkę Home Directory (rysunek 24.8). Tutaj wprowadzasz
ustawienia dotyczące Twojej aplikacji.
Pole tekstowe Local Path zawiera ścieżkę do katalogu zawierającego witrynę, której właściwości właśnie oglądamy.
Pola wyboru Access Permissions pozwalają zdecydować, czy serwer pozwala na odczyt, zapis, obie operacje lub odmawia
dostępu. Nie spotkałem się jeszcze z sytuacją, gdzie byłby potrzebny zapis, więc można zaznaczyć tylko pole Read.
u Log Access. Jeżeli pole to jest zaznaczone, włączasz zapisywanie informacji do plików śladu ustawionych na
zakładce Web Site. Wszystkie zgłoszenia HTTP będą powodowały pojawienie się wpisów w plikach śladu serwera
WWW.
u Directory Browsing Allowed. Jeżeli zaznaczymy tę opcję i nie będzie domyślnej strony domowej w przeglądarce
zostanie wyświetlona lista plików i katalogów.
u Index This Directory. Mówi usłudze Index Server, że należy śledzić i indeksować pliki zawarte, w tej witrynie dla
potrzeb przeszukiwania serwera.
u Front Page Web. Oznacza, że ta witryna jest witryną FrontPage lub Visual InterDev i obsługuje rozszerzenia
FrontPage Extensions.
W dolnej części tej zakładki znajdują się ustawienia aplikacji. Aplikacja w rozumieniu Microsoftu to niezależny zbiór stron
Active Server Pages, które współdziałają ze sobą w celu wykonania jakiejś operacji (to jest moja definicja, nie Microsoftu).
455 Rozdział 24. ♦ Konfiguracja serwera WWW dla publikowania w sieci WWW
Przed zmianami w tej części okna upewnij się, że uaktywnione jest prawo do wykonywania skryptów. Umożliwia ono
wykonywanie stron ASP na serwerze i wysyłanie wyników działania do przeglądarki. Widziałem u niektórych ludzi
włączone prawo do wykonywania programów (ponieważ było tak w IIS3), ale jest to absolutnie nieprawidłowe.
Dopuszczenie wykonywania programów jest niezbędne tylko dla katalogów zawierających CGI lub Perl, ale w innych
przypadkach nie powinno się włączać tego prawa. Umieszczenie pliku wykonywalnego w katalogu, w którym możliwe jest
uruchamianie, pozwala na uruchomienie tego programu na serwerze i spowodowanie nieprzewidzianych efektów.
Kliknij przycisk Configuration, aby uruchomić okno zawierające szczegóły wpływające na wydajność i możliwości stron
ASP.
Okno konfiguracji posiada trzy zakładki: App Mappings, App Options oraz App Debugging. Na zakładce App mapings
wymienia się wszystkie typy plików (rozszerzenia) i aplikacje, które są używane do przetwarzania tych plików. Musisz co
najmniej pozostwić
typy .asa i .asp uruchamiane przez ASP.DLL. Na liście znajduje się kilka innych typów plików, ale jeżeli jesteś pewien, że
ich nie używasz, możesz usunąć je z listy, poprawiając nieco wydajność serwera.
Na zakładce App Options można ustawić opcję pozwalającą na ustalanie sesji przez aplikację i określenie czasu, przez jaki
będzie ta sesja utrzymywana (rysunek 24.9). Bądź ostrożny przy modyfikacji tych ustawień, ponieważ mają one drastyczny
wpływ na działanie i wydajność serwera WWW. Większość programistów korzysta z korzyści ustanawiania sesji, jest to
jedna z najlepszych funkcji w ASP. Jeżeli jednak możesz uniknąć stosowania sesji, odczujesz ogromne przyśpieszenie
działania aplikacji.
Rysunek 24.9.
Ustawienia aplikacji
stają się ważne dla
pracy serwera,
gdy coraz lepiej
poznajesz
technologię WWW
firmy Microsoft
Na zakładce tej można również włączyć buforowanie (przyspiesza to działanie aplikacji), uaktywnić ścieżki względne
(pozwala to ASP na rozwijanie ścieżek względnych korzystając z katalogu rodzica) oraz podanie domyślnego języka
skryptów (zwykle jest to VBScript, ale może być JScript). Można również podać wartość limitu czasu dla skryptów.
Zwiększanie tej wartości pozwoli na wykonywanie dłuższych skryptów bez komunikatu błędu, ale niepotrzebnie blokuje
zasoby serwera. Lepiej pozostawić domyślne 60 sekund i podawać dłuższe limity czasu w stronach ASP w razie potrzeby
(<% Server.ScriptTimeout=180 %>).
Ostatnia zakładka, App Debugging, zawiera opcje pozwalające ustalić czy umożliwić debugowanie skryptu na serwerze,
kliencie, po obu stronach lub wyłączyć tę możliwość. Można również wprowadzić własny komunikat błędu wysyłany do
klienta, gdy strona ASP spowoduje błąd. Jest to dobra funkcja, ponieważ lepiej u klienta nie wyświetlać systemowego
komunikatu błędu. Jednak podczas uruchamiania aplikacji wyłącz tę funkcję, ponieważ nie będziesz wiedział, co poszło źle.
Istnieje kilka podstawowych czynności, które powinny być wykonane. Niektóre z nich opisane są później w „ASP/HTML
– położenie i uprawnienia” oraz „Bazy danych – położenie i uprawnienia”. Wymienione tam ustawienia zabezpieczeń są
wymagane dla zapewnienia podstawowego bezpieczeństwa wymaganego dla aplikacji WWW, jednak podane są
dodatkowe czynności, które mogą być podjęte, aby chronić ważne dane i zabezpieczać przed dostępem do witryny przez
niepożądanych ludzi.
Część VIII ♦ Publikowanie w sieci za pomocą Access’a 2000 456
Wiele firm uruchamia ściany ognia (ang. firewall) pomiędzy ich serwerami
a Internetem. Takie zabezpieczenie pozwala na uruchomienie szcze-
gółowych zabezpieczeń na to, kto może dostać się do serwera oraz w jaki
sposób. Bardzo często ściany ognia blokują dostęp z zewnątrz do serwerów
dla wszystkich portów poza portem 80 (port HTTP). Pozwala to na
przepuszczenie wywołań HTTP do serwera i uruchomienie aplikacji
WWW, jednak nie pozwala na dostęp do innych nieautoryzowanych
portów.
Opcje, które do tej pory omawialiśmy, i wprowadzone zmiany dotyczą całego serwera. Oprócz zmieniania ustawień dla
całego serwera można ustawić niektóre opcje konfiguracji dla katalogu wirtualnego.
Katalog wirtualny zawsze zawiera się w witrynie i jest przypisany tylko i wyłącznie do tej witryny. Katalog wirtualny
może mieć własne ustawienia dla WWW, które mogą być różne od ustawień dla reszty witryny, co umożliwia łatwe
zarządzanie zawartością witryny. Przykładowo, jeżeli chcesz uruchamiać CGI w witrynie (nie jest to zalecane ze względów
wydajności, ale możliwe), powinieneś umieścić wszystkie pliki CGI w jednym katalogu wirtualnym i nadać mu prawo
wykonywania programów.
Prawdopodobnie jedną z najlepszych funkcji katalogu wirtualnego jest to, że może być umieszczony gdziekolwiek na
serwerze. Może być również umieszczony na dysku sieciowym mapowanym z innego serwera (wymaga to specjalnych
ustawień konfiguracji, które wykraczają poza ramy tej książki). Więc jeżeli witryna ma adres www.witryna.com, a katalog
wirtualny o nazwie „użytkownik1” umieszczony jest w d:\użytkownik1, będzie on dostępny jako
http://www.witryna.com/uzytkownik1/ nawet, gdy katalog ten jest fizycznie odizolowany od obszaru serwera.
Jednym z najbardziej użytecznych zastosowań katalogów wirtualnych jest kontrola dostępu do zawartości WWW. Załóżmy,
że mamy serwis WWW położony w d:\wwwroot\. Masz również dwóch współpracowników, którzy chcą mieć własne
fragmenty serwera, którymi będą zarządzać sami. Niezależnie od tego, czy będą mieli dostęp do swoich katalogów poprzez
dysk sieciowy, czy FTP, trudno jest zabezpieczyć się przed możliwością uzyskania przez nich dostępu do głównego
obszaru serwera, jeżeli tylko utworzysz katalogi d:\wwwroot\user1\ i d:\wwwroot\user2\.
Jednym ze sposobów poprawienia bezpieczeństwa i ograniczenia dostępu użytkowników tylko do ich plików, jest utworzenie
katalogów d:\wwwroot\user1\ i d:\wwwroot\user2\ i przypisanie katalogów wirtualnych do tych obszarów.
Kolejną świetną funkcją katalogów wirtualnych jest funkcja dostępna tylko na Windows NT, możliwość podania punktu
startowego dla aplikacji. Pozwala to na odizolowanie zmiennych sesji i aplikacji oraz całkowite odizolowanie od innych
aplikacji WWW nawet, gdy znajdują się na jednym serwerze.
457 Rozdział 24. ♦ Konfiguracja serwera WWW dla publikowania w sieci WWW
Mimo że możesz tworzyć aplikacje WWW na Windows 95/98, nie ma sposobu na tworzenie wielu aplikacji i korzystanie z
ich izolacji, tak jak można to zrobić na Windows NT. Na serwerze WWW pracującym w Windows 95/98 wszystkie strony
udostępniane przez PWS traktowane są jako jedna aplikacja WWW. Zmienne sesji tworzone w katalogu wirtualnym na
Windows 95/98 są dostępna dla wszystkich katalogów wirtualnych tej witryny. Jeżeli chcesz uruchamiać wiele aplikacji
WWW na jednym serwerze, jest to jeszcze jeden powód, aby użyć Windows NT.
Wywołując okno właściwości katalogu wirtualnego na Windows NT, można ustawić opcje w inny sposób niż dla reszty
witryny. Wszystkie opcje wymienione we wcześniejszej części rozdziału dostępne są również dla katalogu wirtualnego.
Powoduje to większą elastyczność i zarządzanie pojedynczymi aplikacjami WWW i pozwala na ustawianie
specyficznych opcji, które mogą być niezbędne w jednej aplikacji a niepotrzebne w innej.
Na zakładce Home Directory mamy możliwość utworzenia aplikacji w katalogu wirtualnym, którego właściwości właśnie
oglądamy. Po wskazaniu tego katalogu jako aplikacji będzie ona pracować niezależnie od reszty witryny. Znaczy to, że ta
aplikacja posiada własny plik global.asa oraz oddzielną konfigurację. Wszystkie sesje oraz zmienne globalne aplikacji
dostępne są tylko i wyłącznie w tej aplikacji. Próba dostępu do tych zmiennych spoza bieżącej aplikacji, nawet z tego
samego serwera, nie powiedzie się. Umożliwia to izolację i podwyższony poziom bezpieczeństwa.
Jeżeli potrzebujesz jeszcze większej izolacji, możesz zażądać, aby aplikacja pracowała w oddzielnej przestrzeni pamięci.
Uaktywnienie tej funkcji wymaga od serwera WWW przełączania kontekstu i może mieć negatywny wpływ na wydajność
systemu. Korzyścią tego rozwiązania jest to, że aplikacja żądająca takiego traktowania jest izolowana i jej awaria nie
wpłynie na inne aplikacje pracujące na tym samym serwerze.
Czy teraz, gdy mamy zainstalowany serwer WWW i wiemy jak go skonfigurować, jest już wszystko gotowe? Nie do
końca. Jest jeszcze kilka punktów, o których musisz wiedzieć i brać pod uwagę podczas tworzenia i udostępniania aplikacji
WWW. Mimo że ustawiłeś podstawowe opcje w trakcie przygotowywania aplikacji, musisz zwrócić uwagę na środowisko
poza ustawieniami WWW. Jednym z ważniejszych zagadnień jest bezpieczeństwo oraz właściwe ustawienie aplikacji, aby
miała dostęp do odpowiednich plików i źródeł danych.
Co to jest IUSER ?
W trakcie instalacji IIS/PWS na Windows NT tworzone jest nowe konto użytkownika o nazwie
IUSER_<nazwa_komputera>, gdzie <nazwa_komputera> jest nazwą NetBios nadana serwerowi (w oknie właściwości
sieci).
Gdy ktoś chce obejrzeć stronę WWW, a na serwerze IIS uaktywniony jest anonimowy dostęp, IIS na początku sprawdza
prawo NTFS do odczytu pliku przez użytkownika IUSER. Jeżeli IUSER posiada wystarczające prawa do oglądania tej
strony, jest ona wysyłana do przeglądarki. Jeżeli IUSER nie ma odpowiednich praw do tego pliku lub IIS nie pozwala na
anonimowy dostęp, IIS spróbuje autoryzować użytkownika zgodnie z ustawieniami w MMC.
W trakcie instalacji IIS wprowadza się ścieżkę do głównego katalogu WWW. Zakładając, że znajduje się ona na drugiej
partycji, domyślną ścieżką jest d:\inetpub\wwwroot\. Jest to obszar, do którego IIS będzie kierował wszystkie żądania
WWW, chyba że konfiguracja została zmodyfikowana. Gdy spojrzysz na właściwości tego katalogu przy użyciu MMC,
zauważysz, że wszystkie przydziały adresów IP są ustawione na „nieprzydzielone”, więc nawet, gdy posiadasz wiele
adresów IP na serwerze, wszystkie żądania kierowane będą do tego katalogu. Upraszczając, przyjmiemy, że na serwerze
znajduje się jedna witryna umieszczona w katalogu d:\inetpub\wwwroot.
Aby obejrzeć dokument HTML, użytkownik IUSER musi mieć co najmniej prawo czytania pliku. Do obejrzenia
dokumentu Active Server Pages, użytkownik musi posiadać, co najmniej prawo uruchamiania tego pliku. Jeżeli przypisałeś
użytkownikowi prawo czytania tego pliku (rysunek 24.10), odpowiednim prawem NT, które należy przydzielić, jest prawo
Read & Execute (RX). Gdy mówimy o prawach Read & Execute, mamy na myśli najniższy poziom uprawnień NT, które
znajdują się w oknie specjalnych uprawnień pliku lub katalogu (rysunek 24.11). Mimo że pozwala to na dostęp zarówno do
stron HTML oraz ASP, nie jest to niezbędne ani najbardziej bezpieczne rozwiązanie, jeżeli bezpieczeństwo jest
priorytetem.
Rysunek 24.10.
NTFS na Windows
NT posiada niektóre
domyślne
ustawienia praw,
które w większości
przypadków
spełniają wymagania
bezpieczeństwa
Rysunek 24.11.
Jeżeli potrzebujesz
lepszej kontroli
uprawnień do pliku,
możesz zejść
do specyficznych
uprawnień używając
specjalnych
uprawnień do pliku
459 Rozdział 24. ♦ Konfiguracja serwera WWW dla publikowania w sieci WWW
Zabezpieczenie bazy danych może wydawać się pełne sztuczek, gdy nie zna się kilku szczegółów. Istnieją dwa sposoby
zabezpieczenia bazy danych, poprzez wbudowany w Access system zabezpieczeń lub poprzez ustawienie praw NTFS do
pliku.
Jeżeli posiadasz aplikację, która tylko odczytuje informacje i nigdy nie wprowadza informacji do bazy, sprawa jest prosta.
Nadaj użytkownikowi IUSER tylko prawo do czytania pliku bazy danych. Jeżeli teraz nie robisz nic poza czytaniem z bazy,
prawdopodobnie nie potrwa to długo. Jedną z największych korzyści aplikacji WWW jest dynamiczne wyświetlanie
informacji użytkownikom, jednak to tylko połowa sukcesu. Możliwość dopisywania danych do bazy przyniesie wiele
korzyści. Można zapisywać zwrotne informacje od użytkowników, informacje z listy dyskusyjnej, bieżące zamówienia i
inne dane. Pozwala to użytkownikom na lepszą interakcję z witryną i pomaga na lepsze obsłużenie klientów.
Załóżmy, że mamy bazę danych do zbierania zamówień przez sieć. Po ustawieniu uprawnień do zapisu i odczytu próba
zapisu do bazy kończy się niepowodzeniem. Gdy baza jest używana przez użytkownika, który ma prawo do zapisu, tworzy
on plik blokad. Ponieważ użytkownik IUSER posiada takie prawo, Access próbuje utworzyć plik i powoduje błąd
niedozwolonego dostępu. Aby nie występował ten błąd, użytkownik IUSER musi posiadać prawo do zmiany zawartości w
katalogu, w którym znajduje się baza danych. Prawo do zmian jest niezbędne, ponieważ plik blokad musi być uaktualniany
przy każdym wykonaniu polecenia SQL. Prawa do tworzenia i czytania nie wystarczą.
Jeżeli nie przeniosłeś bazy danych do osobnego katalogu, zaczyna to wyglądać źle. Jeżeli masz bazę danych w drzewie
katalogów witryny WWW, użytkownik IUSER musi posiadać prawa do czytania, zapisu i usuwania w katalogu bazy
danych, co jest BARDZO ZŁYM rozwiązaniem. We wczesnych etapach naszych eksperymentów z bazami danych,
aplikacjami WWW i wymaganiami bezpieczeństwa, jeden z autorów i ja zrobiliśmy tak, jak to opisałem wcześniej. Nie
czekaliśmy zbyt długo na hakera, który zauważył, że witryna jest dla niego szeroko otwarta i dokonał zmian w naszych
plikach.
Jeżeli używasz serwera SQL, system bezpieczeństwa jest zapewniany przez serwer bazy, co pozwala na uniknięcie
potencjalnych problemów przy zarządzaniu zabezpieczeniami na poziomie plików.
Rozdział 25.
Przenoszenie Accessa 2000
do sieci WWW
za pomocą komponentów sieciowych
Office
W tym rozdziale:
u Czym są komponenty sieciowe Office.
u Użycie formantu Office Arkusz.
u Użycie formantu Office Wykres.
u Użycie formantu Office Tabela przestawna.
Jak już wiesz, w obecnych czasach nie ignoruje się Internetu. Microsoft poszukiwał dla Office 2000 prostej metody przeniesienia
możliwie wiele z podstawowych możliwości Office 2000 do Internetu. Rezultatem prac są komponenty sieciowe Office 2000
oraz strony dostępu do danych (opisane w rozdziale 26., „Użycie stron dostępu do danych”). W tym rozdziale przedstawione
zostanie wprowadzenie do komponentów sieciowych Office.
Te trzy formanty graficzne (Spreadsheet, Chart oraz PivotTable) oraz formant DataSource są oparte o COM, więc
mogą być używane przez VBScript, JScript, VB, C++, Java oraz oczywiście VBA. To, że są one nazwane komponentami
sieciowymi, nie oznacza, że są dostępne tylko na stronach WWW. Mogą również spełniać ważną rolę w aplikacjach
Accessa. Rysunek 25.1 przedstawia prosty arkusz kalkulacyjny umieszczony na formularzu Accessa.
461 Rozdział 25. ♦ Przenoszenie Access’a 2000 do sieci WWW
Rysunek 25.1.
Komponent sieciowy
Office umieszczony
na formularzu
Accessa
Wymagane licencje
na użycie komponentów sieciowych
W przeciwieństwie do formantów ActiveX, komponenty sieciowe wymagają zakupienia licencji Office 2000 dla każdego
komputera klienta. Użytkownicy nie muszą mieć zainstalowanego pakietu Office 2000, jednak muszą mieć na niego
licencję. Jeżeli pracujesz w dużej firmie i chcesz użyć komponentów sieciowych oraz stron ADP (opisane w następnym
rozdziale), możesz skorzystać z licencji typu site i rozprowadzać komponenty sieciowe jeszcze przed zainstalowaniem
Office 2000.
Rozpoczynamy
Excel 2000 posiada funkcję radykalnie ułatwiającą użycie formantu Arkusz, jest to automatyczne przenoszenie arkusza
Excela do postaci strony WWW. W Excelu 2000 utwórz prosty arkusz. Następnie wybierz z głównego menu Plik, Zapisz
jako stronę sieci Web. Na ekranie pojawi się okno dialogowe pokazane na rysunku 25.2. Okno to pozwala na wybór
zakresu lub eksport całego arkusza. Jeżeli chcesz zapisać dane do interaktywnej strony WWW, musisz zdefiniować swoje
dane jako zakres w Excelu. Aby wyeksportować wybrany zakres do formantu Arkusz na stronie WWW, zaznacz pole wy-
boru Dodaj interakcję (rysunek 25.2).
Część VIII ♦ Publikowanie w sieci za pomocą Access’a 2000 462
Rysunek 25.2.
Okno Zapisz jako
stronę sieci Web
Po zapisaniu arkusza jako strony WWW przez Excela możesz otworzyć wynikową stronę w przeglądarce Internet Explorer
(rysunek 25.3).
Po otwarciu strony WWW możesz kliknąć prawym klawiszem myszy formant i otworzyć Przybornik właściwości (rysunek
25.4). Okno to utworzone w Dynamic HTML pozwala na formatowanie i zarządzanie układem formantu Więcej informacji na
temat użycia tego formantu w sieci WWW znajduje się w następnym rozdziale.
Rysunek 25.3.
Wynika zapisu
arkusza Excela 2000
jako strony WWW
Rysunek 25.4.
Okno przybornika
właściwości arkusza
Po wstawieniu formantu na formularz należy napisać procedurę pobierającą dane do arkusza w trakcie ładowania
formularza. Wydruk 26.1 zawiera procedurę obsługi zdarzenia Load formatki. Procedura otwiera recordset ADO oparty
o kwerendę „Dziesięć najdroższych produktów” w bazie danych Northwind. Następnie przegląda wynik. Dla każdego
wiersza użyta jest domyślna właściwość ActiveCell w celu wstawienia danych z wyniku kwerendy do komórek
arkusza. W trakcie przesuwania się w wyniku należy zwiększać właściwość ActiveCell, aby wstawić dane do kolejnych
wierszy arkusza. Jak widać, jest to podobne do programowania w Excelu.
Rysunek 25.5.
Okno dialogowe
Wstawianie
formantu ActiveX
Rysunek 25.6.
Formant Arkusz na
formularzu Accessa
w trybie edycji
Do Until rst.EOF
' Wypełnij bieżącą komórkę zawartością rekordu
Spreadsheetl.ActiveCell(intCount, 1) = "" & _
rst!TenMostExpensiveProducts
Spreadsheetl.ActiveCell(intCount, 2) = "" & _
rst!UnitPrice
' Przejdź do kolejnego rekordu i zwiększ wartość licznika
rst.MoveNext
intCount = intCount + 1
Loop
rst.Close
Set rst = Nothing
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Dodatkowo w rozdziale 27. „Publikowanie w sieci przy użyciu Accessa 2000 i Active Server Pages” przedstawimy, jak
używać tego komponentu do eksportowania rysunków GIF używanych w ASP.
Rozpoczynamy
Tak jak w przypadku formantu Arkusz rozpoczniemy od utworzenia prostego wykresu w Microsoft Excel 2000,
pokazanego na rysunku 25.7. Wybierz Plik, Zapisz jako stronę sieci Web, a następnie wybierz Zaznaczenie: Wykres oraz
zaznacz pole wyboru Dodaj interakcję. Wynik jest pokazany na rysunku 25.8. Można manipulować takim wykresem za
pomocą skryptów uruchamianych na komputerze klienta np.VBScript lub JScript. Aby używać formantu w skryptach,
musisz znać właściwości i metody, jakie udostępnia formant. Omówimy je w dalszej części rozdziału.
Rysunek 25.7.
Wykres w Microsoft
Excel 2000
Rysunek 25.8.
Formant Wykres
wyeksportowany
jako strona WWW
Aby to przedstawić, stworzyłem prostą kwerendę przestawną w demonstracyjnej bazie danych Northwind, za pomocą
następującego wyrażenia SQL:
TRANSFORM Sum(CCur([Order Details].[UnitPrice]*
[Quantity]*(1-[Discount])/100)*100) AS ProductAmount
SELECT Year([OrderDate]) AS OrderYear
FROM Products INNER JOIN (Orders INNER JOIN
[Order Details] ON Orders.OrderID = [Order Details]
ON Products.ProductID = [Order Details].ProductID
WHERE (((Orders.OrderDate)
Between #1/1/1997# And #12/31/1997#))
GROUP BY Year([OrderDate])
PIVOT "Qtr " & DatePart("q",[OrderDate],1,0)
465 Rozdział 25. ♦ Przenoszenie Access’a 2000 do sieci WWW
Podane wyrażenie SQL dzieli całkowitą sprzedaż na kwartały i wylicza wynik pokazany na rysunku 25.9.
Rysunek 25.9.
Prosta kwerenda
przestawna
w Accessie 2000
Teraz skorzystamy z utworzonej kwerendy przestawnej, aby utworzyć niezwiązany wykres w procedurze obsługi zdarzenia
Open formularza. Utworzona została tablica aHeaders, wypełniona nazwami nagłówków dla serii (w tym przypadku
czterema kwartałami roku podatkowego). Następnie otwierany jest recordset ADO oparty o zapisaną kwerendę
przestawną nazwaną qryQuarterlySales i wypełniana jest tablica aValues wartościami pól z wyniku kwerendy. Cały
tekst procedury przedstawiony jest na wydruku 25.2.
With ChartSpace1
.Border.Color = chColorAutomatic
' Można mieć więcej niż jeden wykres w
' obszarze wykresu, więc należy odwołać się do kolekcji
.Charts.Add
With .Charts(0)
.Type = chChartTypeColumnClustered
.SeriesCollection.Add
.SeriesCollection(0).Caption = "Sprzedaż w 1999"
' Wiązanie danych do wcześniej stworzonych tablic
.SeriesCollection(0).SetData _
chDimCategories, chDataLiteral, aHeaders
.SeriesCollection(0).SetData _
chDimValues, chDataLiteral, aValues
.HasLegend = True
End With
End With
rst.Close
Set rst = Nothing
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Rozpoczynamy
Tabele przestawne są jedną z najpopularniejszych funkcji programu Microsoft Excel. Dają one możliwość tworzenia od
ręki raportów w Excelu. Wielu użytkowników staje się entuzjastami tabel przestawnych po nauczeniu ich tworzenia.
Możliwość tworzenia tabel przestawnych i użycia ich jako część witryny WWW lub formularza Accessa jest świetną
możliwością.
Zacznij od stworzenia tabeli przestawnej w Excelu 2000 w sposób pokazany na rysunku 25.10.
Rysunek 25.10.
Prosta tabela
przestawna
w Excelu 2000
Po utworzeniu tabeli przestawnej wybierz Plik, Zapisz jako stronę sieci Web, jednak zamiast kliknąć Zapisz w oknie
dialogowym kliknij Opublikuj. Uruchomiony zostanie zaawansowane okno dialogowe Publikowanie jako strony sieci Web
(rysunek 25.11).
Okno pokazane na rysunku 25.11 pozwala na wybranie do wyeksportowania elementów tabeli przestawnej i ustawienie
opcji widoku. Ustawiając opcje widoku, można wybrać opcję tabeli przestawnej. Excel utworzy stronę WWW pokazaną na
rysunku 25.12.
Rysunek 25.11.
Okno dialogowe
Publikowanie
jako strony
sieci Web
Rysunek 25.12.
Tabela przestawna
Excela
wyeksportowana
do przeglądarki
Internet Explorer
Rozdział 26.
Użycie stron dostępu do danych
W tym rozdziale:
u Tworzenie pierwszej strony dostępu do danych
u Tworzenie interaktywnych odnośników
u Łączenie komponentów sieciowych Office z DAP
u Skrypty w stronach dostępu do danych
Jak chyba zauważyłeś, obecnie nie ignoruje się Internetu. Tworząc Office 2000 przedstawiciele Microsoftu, poszukiwał
prostej metody przeniesienia maksymalnie dużo możliwości Office do Internetu. Wynikiem tych prac są strony dostępu do
danych (DAP – Data Access Pages) oraz komponenty sieciowe Microsoft Office 2000. Rozdział ten przedstawia możliwości
stron dostępu do danych na podstawie przykładowych stron DAP.
Prawdopodobnie zapoznałeś się już z Internetem lub firmowym Intranetem oraz utworzyłeś kilka prostych stron dla
użytkowników Twoich programów. Coraz częściej użytkownicy pytają Cię o możliwość oglądania wykresów, diagramów,
odnośników oraz utworzenia bardziej interaktywnych, dynamicznych stron WWW. Odpowiadasz, że jesteś specjalistą od baz
danych, a nie od programowania dla WWW oraz, że szybkie zrealizowanie tych pomysłów jest bardzo trudne. Projektanci
z Microsoftu uświadomili sobie, że użytkownicy chcą więcej możliwości w tworzeniu raportów w sieci i stworzyli
w Accessie 2000 mechanizm zwany stronami dostępu do danych.
Rysunek 26.1.
Nowa sekcja w oknie
bazy danych
zawierająca strony
dostępu do danych
więc jesteś ograniczony tylko do przeglądarek Microsoftu. Dodatkowo Microsoft wymaga licencji na Office 2000 do
używania stron dostępu do danych.
Jedyną gwarancją poprawnej instalacji formantów sieciowych, ADO 2.1 oraz właściwych sterowników i dostawców
OLEDB jest instalacja Office 2000.
Zatytułuj stronę poprzez kliknięcie w górnej części strony i wpisanie „Kategorie”. Wywołaj listę pól, wybierając z menu
Widok, Lista pól. Lista pól pokazana jest na rysunku 26.3. Zawiera ona wszystkie tabele i kwerendy w bieżącej bazie
danych. Lista ta działa jak lista pól w typowym formularzu lub raporcie.
Po wyświetleniu listy pól przejdź do tabeli Categories i przeciągnij pola CategoryName oraz Description na stronę.
Rysunek 26.2.
Pusta strona dostępu
do danych w widoku
projektu
Rysunek 26.3.
Lista pól na stronie
dostępu do danych
Teraz, po dodaniu pól do strony, kliknij przycisk Zapisz z paska narzędzi, lub wybierz z menu Plik – Zapisz. Zauważ, że
jest wyświetlone okno dialogowe Zapisz jako stronę dostępu do danych (rysunek 26.4). Strony dostępu do danych nie są
zapisywane w pliku MDB jak inne obiekty bazy danych takie jak: tabele, kwerendy, formularze, raporty, makra i moduły.
Aby szybko sprawdzić położenie DAP, umieść kursor myszy nad nazwą DAP i poczekaj chwilę (rysunek 26.5).
Rysunek 26.4.
Zapisz jako stronę
dostępu do danych
Rysunek 26.5.
Podpowiedź
pokazująca ścieżkę
do strony dostępu
do danych
Zanim skupimy się na stronach dostępu do danych, przyjrzyjmy się funkcji Sortowanie i Grupowanie. Wybierz Widok,
Sortowanie i grupowanie z głównego menu. Wyświetlone zostanie okno dialogowe Sortowanie i grupowanie (rysunek
26.6).
Rysunek 26.6.
Okno dialogowe
Sortowanie
i grupowanie
w stronach dostępu
do danych
Większość z właściwości jest identyczna jak te używane w raportach, jednak są dwie, na które powinieneś zwrócić uwagę.
Pierwszą właściwością jest rozmiar strony danych. Określa ona ilość rekordów wyświetlanych na jednej stronie. Ustawimy
ten parametr na 1. Możesz eksperymentować tym parametrem, aby wyświetlić więcej rekordów. Drugą właściwością, z
którą powinieneś się zapoznać, jest: Sekcja nawigacji między rekordami. Ustawienie tej właściwości na Tak doda do strony
taką właśnie sekcję.
Po ustawieniu tych właściwości możemy zająć się formatowaniem strony. Aby formatować stronę dostępu do danych,
wybierz z menu Format, Motyw, co spowoduje wyświetlenie okna dialogowego Motyw (rysunek 26.7).
Część VIII ♦ Publikowanie w sieci za pomocą Access’a 2000 470
Rysunek 26.7.
Okno dialogowe
Motyw
Rysunek 26.8 przedstawia pokazuje stronę dostępu do danych w Accessie. Należy zauważyć, że można używać strony
dostępu do danych w aplikacji identycznie jak formularza czy raportu.
Można również oglądać stronę DAP w odpowiedniej przeglądarce WWW. Należy po prostu otworzyć odpowiedni plik
HTML z dysku lub serwera WWW. Rysunek 26.9 przedstawia stronę DAP otwartą w przeglądarce WWW.
Rysunek 26.8.
Strona dostępu do
danych wyświetlona
w Accessie
471 Rozdział 26. ♦ Użycie stron dostępu do danych
Rysunek 26.9.
Strona dostępu do
danych wyświetlona
w Internet
Explorerze
Zauważmy, że strony DAP wyglądają tak samo w przeglądarce jak i w Accessie. Nie tracimy żadnych możliwości.
przenosząc stronę z Accessa na stronę WWW. Oglądając stronę w przeglądarce, spróbujmy zmienić dane i przesunąć się
do kolejnego rekordu.
Można zauważyć, że dane pobierane są z bazy danych, a zmiany zostały do niej wprowadzone. Jeżeli utworzysz swoją
aplikację w oparciu o strony dostępu do danych zamiast w oparciu o formularze i raporty, możesz ją łatwo przenieść do
sieci WWW.
Rysunek 26.10.
Podrzędna sekcja
odnośnika dla tabeli
Products w trybie
projektowania
W trybie projektowania pojawił się przycisk ze znakiem +. Wyświetla on dane odnoszące się do bieżącego rekordu. Można
umieścić go w dogodnym miejscu, np. na dole sekcji.
Wróćmy jeszcze raz do okna Grupowanie i sortowanie. Ustaw dla sekcji Categories rozmiar strony danych na 1, a dla
sekcji Products na Wszystko, oraz Sekcja nawigacji między rekordami dla Products na Nie.
W wyniku dostaniemy stronę, która przedstawia wszystkie produkty danej kategorii (rysunek 26.11).
Rysunek 26.11.
Sekcja odnośnika
dla produktów
na stronie dostępu
do danych
Rysunek 26.12.
Strona dostępu
do danych
ze związanymi
komponentami
sieciowymi Office
Utwórzmy na początek prostą kwerendę krzyżową w przykładowej bazie danych Accessa NorthWind. Utworzymy
kwerendę krzyżową z wszystkimi kategoriami produktów i ich sprzedażą kwartalną w roku 1997. Zapis tej kwerendy w SQL
wygląda następująco:
TRANSFORM
Sum(CCur([Order Details].[UnitPrice]*[Quantity]*
(1-[Discount])/100)*100) AS ProductAmount
SELECT Categories.CategoryName
FROM (Categories INNER JOIN Products
ON Categories.CategoryID = Products.CategoryID)
INNER JOIN (Orders INNER JOIN [Order Details]
ON Orders.OrderID = [Order Details].OrderID)
ON Products.ProductID = [Order Details].ProductID
473 Rozdział 26. ♦ Użycie stron dostępu do danych
Zapisz tę kwerendę jako QuaterlyProducts i utwórz stronę dostępu do danych bazującą na tej kwerendzie.
Dodaj komórkę dla każdego kwartału, sąsiednią komórkę zwiąż z formatem przechowującym daną.
Tabela 26.1.
Wartości komórek w arkuszu
Q1 =document.txtQ1.value
Q2 =document.txtQ2.value
Q3 =document.txtQ3.value
Q4 =document.txtQ4.value
Komponent Wykres dodajemy do strony poprzez kliknięcie ikony Wykres i narysowanie komponentu na stronie. Po tej
operacji zostanie uruchomiony kreator wykresów. Na pierwszej stronie kreatora wybieramy typ tworzonego wykresu.
Dostępne typy wykresów są podobne do wykresów 2D Excela. Po wybraniu typu wykresu należy wybrać przycisk
Następny. Na drugiej stronie kreatora (rysunek 26.14) wybieramy źródło danych dla wykresu, może być nim tabela lub
kwerenda albo arkusz kalkulacyjny istniejący na stronie. Wybierz arkusz kalkulacyjny i kliknij Następny. Na ostatniej
stronie ustalamy zakres na arkuszu zawierający wartości i etykiety. Wprowadzamy =A1:A4 jako etykiety oraz =B1:B4 jako
wartości.
Część VIII ♦ Publikowanie w sieci za pomocą Access’a 2000 474
Rysunek 6.14.
Kreator wykresu
na stronie dostępu
do danych
Po zakończeniu pracy kreatora przełączamy się w tryb widoku strony i przeglądamy kolejne rekordy. Wykres powinien się
zmieniać po przejściu pomiędzy rekordami.
Rysunek 26.15.
Microsoft Script
Editor (MSE)
Zamiast panelu nawigacji dostarczanego przez Accessa utworzymy nasz własny. Utwórz cztery przyciski i zatytułuj je:
Poprzedni, Następny, Pierwszy, Ostatni. Kliknij prawym przyciskiem myszy stronę i wybierz Microsoft Script Editor z menu
kontekstowego.
Po uruchomieniu MSE w oknie Script Outline przedstawione są wszystkie obiekty i zdarzenia dostępne na stronie. Wybierz
w oknie Script Outline przyciski umieszczone na stronie i kliknij dwukrotnie zdarzenie onClick. W oknie z kodem HTML
powinien pokazać się fragment kodu HTML:
<SCRIPT event=onclick for=Polecenie0 language=vbscript>
<!--
-->
475 Rozdział 26. ♦ Użycie stron dostępu do danych
</SCRIPT>
Istnieje kilka metod, aby napisać kod dla obiektu, jednak wyrażenie For wskazujące na używany obiekt jest domyślnym
sposobem. Wewnątrz bloku skryptu wprowadźmy poniższe wyrażenie:
MSODSC.CurrentSection.DataPage.MoveFirst
Każda strona dostępu zawiera obiekt DataSource o nazwie MSODSC, który z kolei zawiera obiekt DataPage.
Użyjemy metod MoveFirst, MoveLast, MoveNext i MovePrevious w odpowiednich przyciskach. Po oprogramowaniu
wszystkich czterech przycisków kod powinien wyglądać podobnie do zamieszczonego na wydruku 26.1.
W stronach DAP zarządzaniem połączeniami zajmuje się niewidoczny komponent sieciowy DataSource, za pomocą
którego można dowolnie programować połączenia. Komponent DataSource posiada właściwość ConnectionString,
którą można zmieniać programowo. Aby zmienić źródło danych, należy tylko zmienić właściwość ConnectionString
obiektu DataSource w następujący sposób:
MSODSC.ConnectionString = strConnect
Zakładamy, że komponent DataSource nazywa się MSODSC (taka jest jego domyślna nazwa) i strConnect jest
prawidłowym ciągiem połączeniowym OLEDB. Twój program powinien dostarczyć właściwy ciąg połączeniowy.
Możesz zapytać użytkownika o ścieżkę do pliku bazy danych za każdym uruchomieniem strony DAP. Aby to zrealizować,
użyj InputBox lub innego standardowego okna dialogowego wewnątrz programu klienta. Na wydruku 26.2 pokazany jest
sposób realizacji przełączenia źródła danych przy użyciu okna InputBox. Program prosi użytkownika o podanie ścieżki do
pliku bazy danych Accessa (rysunek 26.16), tworzy właściwy ciąg połączeniowy i przypisuje go do obiektu DataSource.
Możesz połączyć tę technikę z użyciem pliku UDL po stronie klienta, aby wyeliminować konieczność ręcznego
wpisywania danych.
Rysunek 26.16.
Wprowadzanie
danych o połączeniu
MSODSC.ConnectionString = strConnect
-->
</SCRIPT>
Rozdział 27.
Publikowanie w sieci
przy użyciu Accessa 2000
i Active Server Pages
W tym rozdziale:
u Użycie Active Server Pages.
u Architektura Active Server Pages.
u Rozpoczynamy pracę z Active Server Pages.
u Active Server Pages.
u Przykład: Tworzenie strony WWW dostępnej dla członków grupy.
u Publikacja w sieci z Accessa 2000 przy użyciu XML.
u Tworzenie wykresów przy użyciu formantu Wykres.
Jeżeli chcesz rozwinąć swoje statyczne strony WWW, publikować dane na bieżąco oraz tworzyć interakcyjne strony
WWW, powinieneś zapoznać się z Active Server Pages (ASP).
Statyczne strony WWW odchodzą w przeszłość. Aby zadowolić użytkowników, powinieneś dać im dostęp do możliwie
aktualnych danych. Używając ASP, można zagwarantować, że witryna WWW dostarcza najnowszych informacji. ASP
eliminuje wiele czynności potrzebnych do utrzymania witryny WWW. Przykładowo, jeżeli jesteś administratorem witryny,
która zawiera stronę z listą użytkowników, powinieneś oprzeć tę stronę na bazie danych. Dawniej musiałbyś ręcznie
zmieniać informacje o użytkownikach za każdym razem, gdy dane się zmieniły. Przy użyciu ASP możesz dać użytko-
wnikom możliwość zmiany tych danych poprzez przeznaczoną do tego stronę WWW. Strona z listą użytkowników
zostanie automatycznie uaktualniona, gdy ktoś wczyta ją do przeglądarki, ponieważ dane są przechowywane w bazie
danych Accessa 2000.
Za pomocą ASP można tworzyć witryny interaktywne, które przechowują zmienne globalne ustawione przez użytkownika i
używane podczas wszystkich jego odwiedzin strony. Tradycyjne systemy klient-serwer mogły przechowywać stan sesji
pomiędzy kolejnymi stronami w zmiennych globalnych i klasach. Zarządzanie stanem sesji na stronach WWW nigdy nie
było takie łatwe. Przy użyciu ASP jest to bardzo łatwe zadanie. Przed ASP potrzebowałbyś skomplikowanych skryptów
478 Część VIII ♦ Publikowanie w sieci za pomocą Accessa 2000
CGI do zapamiętania, kto był na stronie i w jaki sposób przemieszczał się pomiędzy stronami. W ASP funkcjonalność ta
jest gotowa i nie wymaga pisania żadnego programu.
Tak jak jego poprzednik IDC/HTX, strony Active Server Pages są niezależne od przeglądarki oraz bardzo łatwe do
tworzenia i zmiany. ASP dostarcza ekstremalnej elastyczności w udostępnianiu danych z Accessa 2000 na witrynie WWW.
W tym rozdziale pokażemy, czym są strony ASP i jak je tworzyć.
Strona ASP zawiera HTML lub HTML i skrypty dla serwera. Podczas przetwarzania pliku ASP serwer wykonuje skrypt na
serwerze i wysyła do przeglądarki czysty HTML. Ponieważ skrypt wykonywany jest na serwerze, pliki ASP są niezależne
od przeglądarki. Jeżeli strona nie zawiera skryptów, jest po prostu wysyłana do klienta. Możesz dla przykładu zmienić
rozszerzenie zwykłego pliku HTML na ASP. Tym sposobem utworzyłeś najprostszą stronę ASP. Gdy zażądasz tej strony,
serwer wyśle cały kod
HTML z pliku ASP. Jeżeli dodasz skrypt do tego pliku, przykładowo zmieniając kolor tła w zależności od dnia tygodnia,
skrypt ten zostanie wykonany na serwerze i otrzymasz tylko HTML z prawidłowym znacznikiem <Backcolor=”XXX”>.
Domyślnym językiem skryptów stron ASP jest VBScript i na nim skupimy się w drugiej części tego rozdziału. VBScript
jest podzbiorem Visual Basica i Visual Basica for Applications. Jeżeli znasz już VB i VBA, powinieneś czuć się jak w
domu, programując za pomocą VBScript. Jeżeli znasz JavaScript, również możesz go użyć, ASP pozwala na użycie
JavaScript. Jeżeli używasz innego języka skryptów jak Perl, możesz użyć go na stronach ASP pod warunkiem
zainstalowania wtyczki obsługującej ten język w serwerze WWW. Wtyczkę taką trzeba uzyskać od producenta języka.
Ponieważ skrypty wykonywane są na serwerze, a do przeglądarki jest przesyłany tylko wynikowy HTML, skomplikowany
kod i reguły biznesowe zawarte w skryptach są bezpieczne. Jeżeli użytkownik obejrzy kod źródłowy strony, zobaczy tylko kod
HTML wysłany do przeglądarki. Kod uruchamianego skryptu nie będzie widoczny w przeglądarce.
W odróżnieniu do CGI, strony ASP wykonywane są w ramach jednego procesu, co powoduje drastyczną poprawę
wydajności. Ponieważ ASP jest wykonywane w ramach tego samego procesu, ładowany jest tylko jeden egzemplarz silnika
ASP dla wszystkich użytkowników aplikacji. Tworzy on wiele wątków obsługujących skrypty. ASP utrzymuje stan sesji
dla wszystkich użytkowników witryny. ASP można łatwo zintegrować z istniejącymi danymi, na przykład z bazą danych
Accessa 2000. Podczas, gdy trzeba włożyć nieco wysiłku w dostęp do danych ODBC ze skryptów CGI, dostęp poprzez
ODBC jest możliwy w Active Server Pages za pomocą ADO. Dodatkowo ADO używa dostawców OLEDB dla Jet, SQL
Server i Oracle w sposób przedstawiony w poprzednich rozdziałach, więc możesz używać również tych baz danych w
twoich skryptach.
478 D:\Kompakt !!!\Kompakt\Ksiazki 1 !\!done - Access 2000 - Księga eksperta\Access 2000 - Księga eksperta.doc
Rozdział 27. ♦ Publikowanie w sieci przy użyciu Accessa 2000 i Active Server Pages 479
Rozpoczynamy pracę
z Active Server Pages
Za pomocą Microsoft Access 2000 można wyeksportować każdy obiekt bazy danych jako stronę ASP. Gdy konwertujesz
obiekt bazy danych na Active Server Page, ASP będzie wyświetlało tabelę HTML z danymi w tym obiekcie. Użytkownicy
nie będą mogli zmieniać i kasować istniejących rekordów ani dopisywać nowych, chyba że dopiszesz odpowiedni fragment
programu. Funkcja eksportu jako ASP nie jest funkcją konwersji Accessa na ASP.
Aby skonwertować obiekt bazy danych do ASP przy użyciu interfejsu użytkownika Accessa, uruchom kreator, wybierając
z głównego menu Plik, Eksportuj. Wybierz typ pliku Active Server Pages. Następnie otwarte zostanie okno pokazane na
rysunku 27.1.
Rysunek 27.1.
Okno eksportu
do ASP
W oknie pokazanym na rysunku 27.1 należy podać nazwę źródła danych ODBC, hasło bazy danych, URL i limit czasu
sesji. Wprowadź dowolną nazwę źródła danych, nazwę użytkownika i hasło, ponieważ będziemy zmieniać wynikowy plik.
W polu URL wpisz URL serwera WWW, gdzie będzie umieszczony plik ASP (przykładowo www.mojserwer.com). Limit
czasu sesji jest czasem, jaki ASP będzie czekało przed zamknięciem połączenia, jeżeli nie będzie aktywności na stronie. Po
upływie tego czasu ASP usunie informacje o stanie sesji i zwolni zajętą pamięć. Domyślnie ASP przyjmuje 20 minut jako
limit czasu sesji.
Po wykonaniu eksportu w podanym katalogu znajdzie się plik ASP. Możesz zapisać stronę ASP w katalogu, który jest
katalogiem wirtualnym z prawem wykonywania skryptów w serwerze WWW. Sposób konfiguracji katalogu opisany jest w
rozdziale 24. Po zapisaniu pliku przez Accessa sprawdźmy, co zostało zrobione. Jako domyślnego dostawcę OLEDB do
eksportu ASP Access używa ODBC. Aby ominąć to ograniczenie, otwórz wygenerowaną stronę ASP w Notatniku. Treść
strony wygenerowanej przez kreatora zamieszczona jest na wydruku 27.1.
Wydruk 27.1. Wynik eksportu tabeli Klienci z bazy danych Northwind do ASP
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html;charset=windows-1250">
<TITLE>Klienci</TITLE>
</HEAD>
<BODY>
<%
If IsObject(Session("Northwind_conn")) Then
Set conn = Session("Northwind_conn")
Else
Set conn = Server.CreateObject("ADODB.Connection")
conn.open "Northwind","Admin",""
Set Session("Northwind_conn") = conn
End If
%>
<%
If IsObject(Session("Klienci_rs")) Then
Set rs = Session("Klienci_rs")
Else
sql = "SELECT * FROM [Klienci]"
Set rs = Server.CreateObject("ADODB.Recordset")
rs.Open sql, conn, 3, 3
If rs.eof Then
rs.AddNew
End If
Set Session("Klienci_rs") = rs
End If
%>
<TABLE BORDER=1 BGCOLOR=#ffffff CELLSPACING=0><FONT FACE="Arial"
ªCOLOR=#000000><CAPTION><B>Klienci</B></CAPTION></FONT>
<THEAD>
<TR>
<TH BGCOLOR=#c0c0c0 BORDERCOLOR=#000000 ><FONT SIZE=2 FACE="Arial" ªCOLOR=#000000>ID klienta</FONT></TH>
<TH BGCOLOR=#c0c0c0 BORDERCOLOR=#000000 ><FONT SIZE=2 FACE="Arial" ªCOLOR=#000000>Nazwa firmy</FONT></TH>
480 Część VIII ♦ Publikowanie w sieci za pomocą Accessa 2000
</TR>
</THEAD>
<TBODY>
<%
On Error Resume Next
rs.MoveFirst
do while Not rs.eof
%>
<TR VALIGN=TOP>
<TD BORDERCOLOR=#c0c0c0 ><FONT SIZE=2 FACE="Arial"
ªCOLOR=#000000><%=Server.HTMLEncode(rs.Fields("IDklienta").Value)%><BR></FONT></ªTD>
<TD BORDERCOLOR=#c0c0c0 ><FONT SIZE=2 FACE="Arial"
ªCOLOR=#000000><%=Server.HTMLEncode(rs.Fields("NazwaFirmy").Value)%><BR></FONT><ª/TD>
<TD BORDERCOLOR=#c0c0c0 ><FONT SIZE=2 FACE="Arial"
ªCOLOR=#000000><%=Server.HTMLEncode(rs.Fields("Przedstawiciel").Value)%><BR></FOªNT></TD>
<TD BORDERCOLOR=#c0c0c0 ><FONT SIZE=2 FACE="Arial"
ªCOLOR=#000000><%=Server.HTMLEncode(rs.Fields("StanowiskoPrzedstawiciela").Valueª)%><BR></FONT></TD>
<TD BORDERCOLOR=#c0c0c0 ><FONT SIZE=2 FACE="Arial"
ªCOLOR=#000000><%=Server.HTMLEncode(rs.Fields("Adres").Value)%><BR></FONT></TD>
<TD BORDERCOLOR=#c0c0c0 ><FONT SIZE=2 FACE="Arial"
ªCOLOR=#000000><%=Server.HTMLEncode(rs.Fields("Miasto").Value)%><BR></FONT></TD>
<TD BORDERCOLOR=#c0c0c0 ><FONT SIZE=2 FACE="Arial"
ªCOLOR=#000000><%=Server.HTMLEncode(rs.Fields("Region").Value)%><BR></FONT></TD>
<TD BORDERCOLOR=#c0c0c0 ><FONT SIZE=2 FACE="Arial"
ªCOLOR=#000000><%=Server.HTMLEncode(rs.Fields("KodPocztowy").Value)%><BR></FONT>ª</TD>
<TD BORDERCOLOR=#c0c0c0 ><FONT SIZE=2 FACE="Arial"
ªCOLOR=#000000><%=Server.HTMLEncode(rs.Fields("Kraj").Value)%><BR></FONT></TD>
<TD BORDERCOLOR=#c0c0c0 ><FONT SIZE=2 FACE="Arial"
ªCOLOR=#000000><%=Server.HTMLEncode(rs.Fields("Telefon").Value)%><BR></FONT></TD>
<TD BORDERCOLOR=#c0c0c0 ><FONT SIZE=2 FACE="Arial"
ªCOLOR=#000000><%=Server.HTMLEncode(rs.Fields("Faks").Value)%><BR></FONT></TD>
</TR>
<%
rs.MoveNext
loop%>
</TBODY>
<TFOOT></TFOOT>
</TABLE>
</BODY>
</HTML>
Chcemy zmienić informację o połączeniu ADO w pliku ASP tak, aby używał on OLEDB. Należy zmienić tylko jeden wiersz
kodu zawierający ciąg połączeniowy. Kreator próbuje otworzyć połączenie ADO za pomocą nazwy DSN, którą podaliśmy w
oknie kreatora. Ponieważ podaliśmy wymyśloną nazwę DSN, należy zmienić połączenie, aby używało dostawcy OLEDB
dla Jet (dla Accessa) i wskazać plik MDB na serwerze. Należy użyć odpowiedniej składni przedstawionej w rozdziale 6.
„Wprowadzenie do obiektów danych ActiveX”. Należy zmienić wiersz z postaci:
conn.open "Northwind", "Admin", ""
na:
conn.open "Provider=Microsoft.Jet.OLEDB.4.0;data source="c:\northwind.mdb"
Zapisz plik w Notatniku i otwórz go w przeglądarce poprzez URL. Rysunek 27.2 przedstawia końcowy wynik konwersji do
Active Server Page. Musisz otworzyć ten plik ASP w przeglądarce, używając prawidłowego adresu URL. Przykładowo,
aby otworzyć plik ASP na twoim komputerze przy użyciu protokołu HTTP, należy użyć adresu podobnego do:
http://localhost/nazwa_katalogu_wirtualnego/plik.asp.
480 D:\Kompakt !!!\Kompakt\Ksiazki 1 !\!done - Access 2000 - Księga eksperta\Access 2000 - Księga eksperta.doc
Rozdział 27. ♦ Publikowanie w sieci przy użyciu Accessa 2000 i Active Server Pages 481
Rysunek 27.2.
Tabela
skonwertowana
do postaci ASP
Przy użyciu tej metody możesz utworzyć niektóre robocze strony ASP, ale jeżeli chcesz tworzyć sprawniejsze strony
ASP, które dają dodatkowe możliwości lub używają OLEDB, musisz nauczyć się podstaw ASP. Kolejna część rozdziału
zaznajomi Cię z podstawami ASP.
Silnik ASP
Active Server Pages to jeden z interfejsów Internet Server Application Programming Interface (ISAPI), które zostały dodane
do Internet Information Server (IIS) 3.0 i późniejszych. Gdy przeglądarka żąda pliku z serwera WWW, filtr ISAPI
sprawdza, czy żądanie to dotyczy strony ASP. Jeżeli przeglądarka żąda strony ASP, uruchamiany jest interpreter ASP.
Przetwarza on plik ASP i rozpoczynając od początku pliku, wykonuje skrypty. Wynikowy kod HTML wysyłany jest do
przeglądarki. Następna część rozdziału zawiera informacje o skryptach wykonywanych na serwerze.
VBScript jest podzbiorem Visual Basica. VBScript posiada taką samą składnię i możliwości języka jak VBA. Jeżeli
używałeś VBA, nauczysz się VBScript bardzo szybko. VBScript nie posiada kilku ważnych funkcji VBA, jednak dzięki
temu jest bezpieczniejszy i mniejszy. Przykładowo usunięto obsługę plików, wywoływanie DLL i automatyzacji OLE.
Usunięto również wszystkie typy danych (Long, String itd.), a w zamian wszystkie zmienne są typu Variant. Tabela
27.1 zaczerpnięta z dokumentacji VBScript zawiera wszystkie właściwości VBA, które zostały usunięte z VBScript.
Tabela 27.1.
Wszystkie funkcje VBA niedostępne w VBScript
Tabela 27.1.
Wszystkie funkcje VBA niedostępne w VBScript (ciąg dalszy)
Obiekty Clipboard
Collection
Operatory Like
Opcje Deftype
Option Base
Option Compare
Option Private Module
482 D:\Kompakt !!!\Kompakt\Ksiazki 1 !\!done - Access 2000 - Księga eksperta\Access 2000 - Księga eksperta.doc
Rozdział 27. ♦ Publikowanie w sieci przy użyciu Accessa 2000 i Active Server Pages 483
VBScript jest celowo niewielki, aby zapewnić bardzo szybką i efektywną kompilację. Innym powodem ograniczenia
funkcjonalności jest to, że VBScript może być uruchamiany zarówno na serwerze, jak i na komputerze klienta. Jeżeli
skrypt jest uruchamiany w przeglądarce na komputerze klienta, nie można dawać mu dostępu do systemu plików
komputera. Pozwoliłoby to złośliwym programistom na utworzenie skryptów formatujących dysk.
Można nauczyć się języka VBScript poprzez próby i eksperymenty z programem VBA, sprawdzając, czy działa on pod
VBScript. Dodatkowo Microsoft udostępnił dokumentację języka VBScript. Jest ona dostępna do załadowania z
www.microsoft.com/vbasic i jest bezpłatna. Po załadowaniu i zainstalowaniu dokumentacji na komputerze zostaje zainsta-
lowany pełny opis języka oraz przykładowe pliki (rysunek 27.3).
Tabela 27.2.
Funkcje dostępne w VBScript
Przypisanie Set
Matematyka Atn, Cos, Sin, Tan, Exp, Log, Sgr, Randomize, Rnd
Tabela 27.2.
Funkcje dostępne w VBScript (ciąg dalszy)
Ciągi Asc, AscB, AscW, Chr, ChrB, ChrW, Filter, Instr, InstrB,
InstrRev, Join, Len, LenB, Lcase, Ucase, Left, LeftB,
Mid, MidB, Right, RightB, Replace, Space, Split,
StrComp, String, StrReverse, LTrim, RTrim, Trim
Rysunek 27.3.
Dokumentacja do
VBScript
Skrypty znajdują się w kodzie HTML pomiędzy znacznikami <%>. Możesz mieszać fragmenty HTML i skryptu.
Przykładowo, na wydruku 27.2 znajduje się skrypt ASP, który do zmiennej strName przypisuje nazwisko autora, a
następnie zamieszcza ten ciąg na stronie WWW.
Gdy użytkownik zażąda pliku ASP, którego treść znajduje się na wydruku 27.2, serwer WWW wykona skrypt zawarty
pomiędzy ogranicznikami <%> i utworzy stronę WWW, która została pokazana na rysunku 27.3. Kod HTML będący
wynikiem działania skryptu przedstawiony jest na wydruku 27.3. Wydruk 27.3 zawiera źródło strony WWW z rysunku
27.4.
484 D:\Kompakt !!!\Kompakt\Ksiazki 1 !\!done - Access 2000 - Księga eksperta\Access 2000 - Księga eksperta.doc
Rozdział 27. ♦ Publikowanie w sieci przy użyciu Accessa 2000 i Active Server Pages 485
Rysunek 27.4.
Strona WWW
utworzona
przez skrypt ASP
z wydruku 27.2
Porównaj plik ASP z wydruku 27.2 i plik HTML z wydruku 27.3 wygenerowany przez skrypt ASP. Zauważ, że kod
VBScript zawarty pomiędzy znacznikami <%> nie został umieszczony w wynikowym kodzie HTML. Fragment
<%=strName%> został zastąpiony w wynikowym kodzie przez wartość zmiennej. Fragmenty pomiędzy znacznikami <%>
są interpretowane i wykonywane przez serwer, a wyniki działania tego kodu są wysyłane do przeglądarki jako czysty kod
HTML.
W kolejnym przykładzie, zamieszczonym na wydruku 27.4, użyta zostanie pętla do zwiększania wartości zmiennej, która
jest używana w kodzie HTML.
Gdy użytkownik zażąda pliku ASP zamieszczonego na wydruku 27.4, VBScript pięć razy wykona pętlę, zwiększając za
każdym razem wielkość czcionki, co w wyniku da stronę HTML pokazaną na rysunku 27.5. Źródło wynikowej strony
zamieszczone jest na wydruku 27.5.
Rysunek 27.5.
Strona WWW
będąca wynikiem
wykonania skryptu
ASP z wydruku 27.4
Wydruk 27.5. Źródło strony WWW utworzonej przez skrypt ASP z wydruku 27.4
<HTML>
<HEAD>
<TITLE>Creating Hello World with Incremental Text Size Increase </TITLE>
</HEAD>
<BODY BGCOLOR=#FFFFFF>
<FONT SIZE=3>Hello WOrld</FONT><BR>
<FONT SIZE=4>Hello World</FONT><BR>
<FONT SIZE=5>Hello World</FONT><BR>
<FONT SIZE=6>Hello World</FONT><BR>
<FONT SIZE=7>Hello World</FONT><BR>
<BR>
<BR>
</BODY>
</HTML>
Jak zostało to pokazane na tych dwóch przykładach, strony ASP używają skryptów VBScript wykonywanych na serwerze
do generacji zwykłego kodu HTML. Aby zwiększyć możliwości stron WWW, należy skorzystać z niektórych
wbudowanych obiektów ASP, które teraz omówimy.
486 Część VIII ♦ Publikowanie w sieci za pomocą Accessa 2000
Do obiektu Application można dynamicznie dołączać właściwości, które są traktowane jak zmienne globalne dostępne we
wszystkich plikach aplikacji i dla każdego użytkownika aplikacji. Składnia użycia właściwości obiektu Application jest
następująca:
<%Application("nazwa_właściwości")=wartość %>
Przykładowo, możemy sprawdzić, ilu użytkowników jednocześnie używa aplikacji. Możesz przygotować właściwość
VisitorNum w następujący sposób:
<%Application("VisitorNum")=0 %>
Następnie po zalogowaniu się użytkownika do naszego systemu należy zwiększyć wartość zmiennej globalnej o jeden i
wyświetlić liczbę aktualnie pracujących użytkowników. Aby liczba ta była zgodna ze stanem faktycznym, po wylogowaniu
użytkownika należy zmniejszyć licznik. Aby zwiększyć wartość właściwości, użyj następującego wiersza:
<%Application("VisitorNum")= Application("VisitorNum")+1 %>
Podsumowując. Obiekt Application jest używany do przechowywania zmiennych globalnych, których można używać w
każdej stronie aplikacji i które są dostępne dla wszystkich użytkowników. Aby użyć indywidualnych zmiennych
globalnych dla poszczególnych użytkowników, należy skorzystać z obiektu Session, który jest opisany w kolejnej części
rozdziału.
Obiekt sesji tworzony jest przy dostępie użytkownika do witryny WWW i usuwany jest po opuszczeniu witryny lub po
upłynięciu czasu nieaktywności sesji. Aby odwołać się do niestandardowych właściwości obiektu Session, należy użyć
składni identycznej jak przy odwołaniach do obiektu Application:
<%Session("nazwa_właściwości")=wartość %>
486 D:\Kompakt !!!\Kompakt\Ksiazki 1 !\!done - Access 2000 - Księga eksperta\Access 2000 - Księga eksperta.doc
Rozdział 27. ♦ Publikowanie w sieci przy użyciu Accessa 2000 i Active Server Pages 487
Obiekt Response
Aby obsłużyć komunikację pomiędzy przeglądarką i serwerem, należy użyć obiektu Response. Obiekt Response posiada
on osiem metod dostępnych dla programisty, jednak na potrzeby ASP i Accessa 2000 omówimy tylko metody Redirect i
Write.
Response.Redirect
Gdy chcesz wyświetlić jakąś stronę w przeglądarce, powinieneś w skrypcie ASP użyć metody Redirect obiektu Response.
Przykładowo, wyobraźmy sobie stronę WWW, na której znajduje się formularz, w którym użytkownik podaje nazwę
użytkownika. Jeżeli użytkownik ten istnieje w bazie danych, użytkownik zostaje przeniesiony na stronę główną, jeżeli nie istnieje,
na stronę rejestrowania nowego użytkownika. Można skorzystać z konstrukcji If...Then razem z metodą
Response.Redirect w następujący sposób:
<%If fLogin=True then
'Użytkownik zautoryzowany
Response.Redirect "welcome.html"
Else
'Nie ma takiego użytkownika
Response.Redirect "newmember.asp"
End if%>
Response.Write
W trakcie tworzenia skryptu ASP, który wypisuje tekst do wynikowego pliku HTML, można użyć metody Write obiektu
Response. Response.Write ma bardzo prostą składnię:
Response.Write("ciąg tekstu")
Przykładowo, można tworzyć różne komunikaty umieszczane na stronie w zależności od zdefiniowanego warunku. Możesz
spytać użytkownika o wiek, a następnie utworzyć w zależności od odpowiedzi odpowiednią stronę, używając metody
Write. Podany poniżej fragment skryptu demonstruje taką właśnie technikę.
<%If intAge < 21 Then
Response.Write("Prawo w Nowym Jorku")
Response.Write("zabrania sprzedawania alkoholu")
Response.Write("młodzieży do lat 21")
Else
Response.Redirect "buy.asp"
End If%>
Obiekt Request
Aby sprawdzić, co użytkownik wpisał do pola tekstowego na stronie WWW, powinieneś użyć obiektu Request. Obiekt
ten potrafi pobrać informację z wielu miejsc w przeglądarce, jednak skupimy się teraz tylko na pobieraniu wartości z
formularza zawartego na stronie WWW. Każdy formularz zawarty na stronie HTML składa się z elementów HTML, takich
jak pola tekstowe i listy wyboru. Jeżeli nadasz tym elementom nazwy i wywołasz plik ASP, można odczytać wartości z
tych elementów za pomocą następującego wywołania:
Request.Form("nazwa_elementu")
Możesz użyć obiektu Request.Form do odczytania informacji o użytkowniku i wstawić je do bazy danych Accessa 2000,
lub utworzyć odpowiednie wyrażenie SQL. Można również przypisać do zmiennej ciąg, który wpisał użytkownik przy
użyciu wyrażenia podobnego do następującego:
<% intAge=Request.Form("txtWiek")%>
Plik global.asa
Strony ASP używają specjalnego pliku o nazwie global.asa. Jest on umieszczony w katalogu, który jest korzeniem drzewa
katalogu wirtualnego i służy on do zarządzania zdarzeniami obiektów Application i Session. Plik ten jest również używany
do tworzenia zmiennych Application i Session. Obiekty Application i Session posiadają zdarzenia, które są
wykonywane na początku i na końcu istnienia obiektów. Są to:
u Application_OnStart;
u Application_OnEnd;
u Session_OnStart;
488 Część VIII ♦ Publikowanie w sieci za pomocą Accessa 2000
u Session_OnEnd.
Można użyć tych zdarzeń do tworzenia zmiennych, wstawiania lub szukania rekordów w bazie danych oraz upewnić się, że
użytkownik wlogował się. Plik global.asa nie działa jak domyślny dokument w katalogu wirtualnym. Pierwsze odwołanie
do niego następuje, gdy użytkownik po raz pierwszy uruchomił dowolną stronę z katalogu wirtualnego. Plik global.asa nie
tworzy kodu HTML jak pliki ASP, zamiast tego wykonywany jest kod obsługi odpowiednich zdarzeń obiektów
Application oraz Session. Wraz z rozwojem ASP Microsoft doda kolejne zdarzenia do ASP, które będą obsługiwane
przez kod zawarty w pliku global.asa.
Kod zamieszczony na wydruku 27.6 jest przykładowym plikiem global.asa ze zdefiniowaną obsługą zdarzeń OnStart dla
obiektów Application i Session. Dla obiektu Application ustawiana jest zmienna VisitorNum w celu zliczania
ilości jednocześnie wlogowanych użytkowników. W obsłudze zdarzenia OnStart obiektu Session zestawiane jest
połączenie do przykładowej bazy danych, aby każda strona mogła używać utworzonego tu obiektu Connection (więcej o
połączeniach do bazy znajduje się w rozdziale 6. „Wprowadzenie do obiektów danych ActiveX” i rozdziale 7. „Zaawan-
sowane ADO”). Oprócz połączenia do bazy tworzonych jest pięć zmiennych dostępnych dla całej sesji zainicjowanych
informacjami pochodzącymi z bazy danych.
</SCRIPT>
<SCRIPT LANGUAGE=VBScript RUNAT=Server>
Sub Application_OnStart
' Przygotowanie zmiennych globalnych
Application("VisitorNum")=0
Application("Start")=Now
End Sub
Sub Session_OnStart
' Zestawienie połączenia z bazą danych
' Ustawiany jest również limit czasu oczekiwania itp.
Session("Start")=Now
Session("DataConn_ConnectionString") = _
"provider=Microsoft.Jet.OLEDB.4.O;" & _
"data source=C:/wwwroot/access2000/data/nyc.mdb"
Session("DataConn_ConnectionTimeout") = 15
Session("DataConn_CommandTimeout") = 30
Session("DataConn_RuntimeUserName") = ""
Session("DataOonn RuntimePassword") = ""
End Sub
</SCRIPT>
Przykładowa strona WWW używa zmiennych będących niestandardowymi właściwościami obiektów Application i
Session. W obiekcie Application utworzone zostały zmienne Start oraz VisitorNum. W trakcie obsługi zdarzenia
OnStart obiektu Application do zmiennej Start został przypisany bieżący czas. Jest on również przypisywany do
zmiennej Start z obiektu Session. Czas zapisany w obiekcie Session może nie być bieżącym czasem, ponieważ
zdarzenie OnStart obiektu Session jest wywoływane, gdy użytkownik odwoła się do dowolnej strony z katalogu
wirtualnego aplikacji. Wydruk 27.7 zawiera przykład użycia tych zmiennych na przykładowej stronie WWW.
488 D:\Kompakt !!!\Kompakt\Ksiazki 1 !\!done - Access 2000 - Księga eksperta\Access 2000 - Księga eksperta.doc
Rozdział 27. ♦ Publikowanie w sieci przy użyciu Accessa 2000 i Active Server Pages 489
Rysunek 27.6.
Obiekty ASP
</body>
</html>
Rysunek 27.7.
Wynik wykonania
skryptu ASP
używającego ADO
Kombinacja ASP, VBScript oraz ADO pozwala na tworzenie złożonych stron WWW opartych o dane zapisane w bazie
danych Accessa 2000. W następnej części rozdziału przedstawię przykład zaczerpnięty z własnej praktyki.
Aplikacja ta pozwala ludziom, którzy podali właściwą nazwę użytkownika i hasło, na dostęp do systemu. Po zalogowaniu
użytkownika do zmiennej sesji przypisywany jest identyfikator użytkownika, uwalniając go od konieczności wprowadzania
własnych danych na kolejnych stronach witryny. Na koniec do bazy wpisywana jest bieżąca data jako data ostatniej wizyty.
Aplikacja uruchamia się, gdy użytkownik wczytuje stronę logowania klubu NYC Access VB. Strona ta przedstawiona jest
na rysunku 27.8.
Rysunek 27.8.
Okno logowania
Strona logowania jest zwykłą stroną HTML zawierającą formularz, który wywołuje plik ASP. Na wydruku 27.9
zamieszczony jest kod HTML użyty do utworzenia formularza.
Po kliknięciu przez użytkownika przycisku OK uruchomiony zostanie plik login.asp. Skrypt ten sprawdza w bazie danych,
czy użytkownik znajduje się na liście członków. Baza zawiera tabelę z polami zawierającymi nazwę użytkownika, hasło,
datę ostatniego dostępu oraz inne pola. Na wydruku 27.10 zamieszczono treść pliku login.asp.
<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual InterDev 6.0">
<META HTTP-EQUIV="Content-Type" content="text/html;
charset=iso-8859-1">
<TITLE>Formularz logowania</TITLE>
</HEAD>
<BODY>
<BODY BGCOLOR=#FFFFFF>
<%
' Przeznaczenie: wszyscy użytkownicy muszą się zalogować
' Logowanie jest nieudane, jeżeli nie został wprowadzony prawidłowy
' identyfikator użytkownika lub hasło
' Zmienne
Dim rst
Dim strUserID
Dim strPass
Dim strSOL
Dim strConnect
Dim ado_OpenKeyset
Dim ado_LockOptimistic
Else
' Nieprawidłowe hasło
response.write "Nazwa użytkownika: <strong>" & _
strUSerID & "</strong> jest OK, Złe hasło!!!"
end if
end if
end if
' Zamknięcie obiektu rst
rst.close
%>
</BODY>
</HTML>
Pierwszą czynnością wykonywaną przez skrypt zamieszczony na wydruku 27.10 jest przygotowanie zmiennych używane
w dalszej części skryptu. Następnie przy użyciu danych podanych przez użytkownika w formularzu tworzone jest
wyrażenie SQL. Do przechowywania nazwy użytkownika używana jest zmienna strUserId. Wyrażenie SQL, które
pobiera informacje o użytkowniku, wygląda następująco:
StrSQL="SELECT Fname, LName, Email, lastLogin, pass, " & _
"Status FROM tblMembers WHERE (Email=" & "'" & strUserId & "'" & ")"
Jak można zauważyć, kluczem głównym tabeli tblMembers jest pole Email. E-mail użytkownika jest również jego
identyfikatorem. Jeżeli użytkownik nie poda identyfikatora lub hasła, za pomocą metody Response.Write wyświetlane
jest ostrzeżenie pokazane na rysunku 27.9.
Rysunek 27.9.
Ostrzeżenie o braku
identyfikatora
użytkownika
lub hasła
Jeżeli użytkownik poda właściwą nawę użytkownika, skrypt sprawdza, czy podane jest właściwe hasło. Sprawdzenie to
przeprowadzane jest w wierszu:
If rst("pass")=strPass
Jeżeli hasło jest niewłaściwe, użytkownik jest o tym powiadamiany przy użyciu metody Response.Write (rysunek
27.10).
Jeżeli użytkownik wprowadzi właściwe hasło, w zmiennej sesji zapamiętywana jest nazwa użytkownika i uaktualniane jest
pole tabeli lastlogin. Poniższy fragment skryptu realizuje te czynności.
' Ustawienie daty ostatniej wizyty
rst.update("lastlogin"), Date()
' Ustawienie globalnej zmiennej sesji
Session("User") = strUserId
Rysunek 27.10.
Informacja
o błędnym haśle
Po autoryzacji użytkownika używamy metody Response.Write do utworzenia strony WWW tylko dla członków grupy.
Można również użyć metody Response.Redirect, aby skierować użytkownika na zupełnie inną stronę. Strona ta
pokazana jest na rysunku 27.11.
492 D:\Kompakt !!!\Kompakt\Ksiazki 1 !\!done - Access 2000 - Księga eksperta\Access 2000 - Księga eksperta.doc
Rozdział 27. ♦ Publikowanie w sieci przy użyciu Accessa 2000 i Active Server Pages 493
Rysunek 27.11.
Strona tylko dla
członków grupy
Po zalogowaniu użytkownika do systemu można dostarczyć do kolejnych stron wszystkie informacje o nim. Dodatkowo,
jedną z lepszych cech ASP jest możliwość edycji przez użytkownika informacji o sobie. W naszej sytuacji dajemy
użytkownikowi tylko możliwość zmiany hasła. Po zalogowaniu użytkownika do części witryny tylko dla członków
dostępna jest opcja zmiany własnych danych. Strona ta pokazana jest na rysunku 27.12.
Rysunek 27.12.
Strona zmiany hasła
przez członków
grupy
Jest to formularz HTML umożliwiający wprowadzenie i weryfikację hasła. Jej kod HTML przedstawiony jest na wydruku
27.11.
Formularz przedstawiony na wydruku 27.11 wywołuje plik changepass.asp, który uaktualnia hasło użytkownika i
potwierdza je. Wydruk 27.12 zawiera kod źródłowy pliku changepass.asp.
<%
' Przeznaczenie: sprawdzenie potwierdzenia hasła i zmiana bazy danych
' Jeżeli hasło nie jest identyczne w obu polach tekstowych, przerwij
' Deklaracje
Dim rst
Dim strPass
Dim strVerify
Dim strSOL
Dim strConnect
Dim ado_OpenKeyset
Dim ado_LockOptimistic
ado_OpenKeyset=1
ado_LockOptimistic=3
Kod z wydruku 27.12 nie różni się wiele od tego z wydruku 27.10. Na początku należy się upewnić, czy użytkownik wpisał
identyczne napisy do obu pól tekstowych i kontynuuje tylko w przypadku takiej zgodności. Następnie przy użyciu
zmiennej globalnej User tworzone jest wyrażenie SQL. Jest to przykład utrzymywania stanu sesji przez ASP. Nie ma
potrzeby pytać powtórnie użytkownika o jego identyfikator lub wywoływać skomplikowane i obciążające serwer programy
CGI-BIN, które potrafiłyby utrzymać stan sesji.
Po otwarciu obiektu recordset używamy metody Update w celu uaktualnienia hasła użytkownika w bazie danych na
serwerze WWW. Podczas następnego logowania użytkownika należy użyć nowego hasła. Rysunek 27.13 przedstawia
ekran potwierdzający zmianę hasła.
Rysunek 27.13.
Ekran
potwierdzający
zmianę hasła
Na tym zakończymy omawianie tego przykładu. Możesz odwiedzić witrynę http://www. nycaccessvb.com, aby przejrzeć
listę witryn WWW używających Accessa 97 lub 2000 jako silnika bazy danych.
Mam nadzieję, że ten przykład i cały rozdział pozwoli Ci rozpocząć tworzenie świetnych internetowych aplikacji Accessa
2000.
Podstawy XML
XML jest zbiorem reguł tworzenia opisowych znaczników identyfikujących dane, z których zbudowany jest dokument.
Mimo że XML jest podobny do HTML, to jest od niego o wiele bardziej rozbudowany. Za pomocą XML tworzy się
znaczniki, które używane w dokumencie dzielą go na logiczne fragmenty. Litera X w XML pochodzi od słowa Extensible
494 D:\Kompakt !!!\Kompakt\Ksiazki 1 !\!done - Access 2000 - Księga eksperta\Access 2000 - Księga eksperta.doc
Rozdział 27. ♦ Publikowanie w sieci przy użyciu Accessa 2000 i Active Server Pages 495
(rozszerzalny), ponieważ w przeciwieństwie do HTML, który ma ściśle zdefiniowany zbiór znaczników, zbiór znaczników
w XML jest nieomal nieograniczony. Znaczniki opisujące te dane tworzy się w momencie, gdy są one potrzebne. Ponieważ
programiści baz danych codziennie pracują z danymi, XML jest dla nich bardzo użyteczny.
Utwórzmy prosty dokument XML opisujący tabelę Klienci w bazie danych Northwind. Ponieważ XML oparty jest o zestaw
znaków Unicode, można do jego stworzenia użyć dowolnego edytora używającego ASCII lub Unicode. Aby rozpocząć
tworzenie dokumentu XML wpisz w edytorze poniższy wiersz:
<?xml version="1.0"?>
Jest to wiersz deklaracji sygnalizujący interpreterowi XML, że jest to dokument XML. Gdy Twoje dokumenty XML będą
bardziej skomplikowane, część deklaracji będzie bardziej złożona. Przykładowo można zadeklarować, jakie znaczniki są
dopuszczalne w dokumencie lub gdzie znajdują się deklaracje arkusza stylów. Na razie zajmiemy się tylko podstawami.
Po deklaracjach należy zdefiniować główny element. Jest on elementem, który będzie opisywany w dokumencie. W
dokumencie może występować tylko jeden taki element. Ponieważ opisujemy dane klientów, nasz element główny
nazywać się będzie <Customers>.
Następnie należy zdefiniować węzły potomne. Węzły potomne są elementami tworzącymi dane. Utworzymy węzeł
potomny do głównego, nazwanego <Customer>. Wewnątrz każdego węzła klienta mamy węzły potomne zawierające dane.
Te węzły mają nazwy zgodne z nazwami pól w tabeli Klienci z bazy danych Northwind. Przykład takiego pliku pokazany
jest na wydruku 27.13.
Teraz możemy oddzielić dane od formatowania przy użyciu XML oraz Dynamic HTML. Wypełnimy tabelę HTML
danymi XML zapisanymi w pliku customers.xml. Możesz skorzystać z dostępnego w IE 4.0 i nowszych, łączenia danych z
pliku XML poprzez applet Javy. Wynik umieszczenia danych XML w tabeli HTML pokazany jest na rysunku 27.14. Aby
wczytać XML do strony WWW, utwórz prostą stronę zamieszczoną na wydruku 27.14.
Rysunek 27.14.
Dołączanie danych
XML do strony
HTML
</head>
<! -Java Applet->
<APPLET code="com.ms.xml.dso.XMLDSO.class"
MAYSCRIPT id=xmldso WTDTH="100%" HEIGHT="20">
<PARAM NAME="URL" VALUE=" Customers.xml ">' +
</APPLET>
<p> Dołączanie danych XML z pliku na dysku </p>
<table id="table" border="2" width="100%"
datasrc="#xmldso" cellpadding="5">
<thead>
<tr>
<th>ID e/th>
<th>Name </th>
</head>
</tr>
<tr>
<td align="center" valign="top"><div datafld="Id Klienta"></td>
<td align="center" valign="top"><div datafld="Nazwa firmy"></td>
</tr>
</table>
</body>
</html>
Aby przetworzyć plik XML, należy użyć appletu Javy, który jest dostarczany razem z IE 4.0 (można również ściągnąć do
ze strony WWW Microsoftu). Dodaj fragment z APPLET z wydruku 27.14 do Twojego pliku HTML i ustaw właściwość
URL na ścieżkę lub URL do pliku XML. Następnie należy użyć prostego łączenia Dynamic HTML za pomocą znacznika
datasrc="#xmldso" w deklaracji tabeli, gdzie #xmldso jest nazwą obiektu z appletu Javy. Na koniec przypisz
właściwości datafld każdego pola tabeli nazwy węzłów potomnych z pliku XML. Gdy zmienisz zawartość pliku XML,
wynikowa strona również się zmieni.
Utwórzmy w VB 6.0 projekt ActiveX DLL o nazwie XML_TOOL z jednym modułem klasowym o nazwie Database.
Nasza klasa posiadała będzie tylko jedną metodę, CreateXML. Należy również ustawić w menu Tools, References
odwołanie do ADO 2.0. Metoda ta używa ADO do podłączenia się do bazy danych, otwarcia wyniku i zwrócenia danych
XML do klienta. Metoda ta wymaga trzech argumentów: nazwy głównego elementu, ciągu połączeniowego i wyrażenia
SQL, które należy wykonać. Metoda ta jest zamieszczona na wydruku 27.15.
496 D:\Kompakt !!!\Kompakt\Ksiazki 1 !\!done - Access 2000 - Księga eksperta\Access 2000 - Księga eksperta.doc
Rozdział 27. ♦ Publikowanie w sieci przy użyciu Accessa 2000 i Active Server Pages 497
' Porządki
rst.Close
Set rst = Nothing
Proc_Exit:
Exit Function
Proc_Err:
' Prześlij błąd do aplikacji
Err.Raise Err, "XML DLL", Err.Description
Resume Proc_Exit
End Function
Teraz uruchomimy nasz komponent ActiveX. Po skompilowaniu DLL utwórz nową aplikację Visual Basica i ustaw
odwołanie do naszej biblioteki DLL. Program testujący metodę przedstawiony jest na wydruku 27.16. Trzeci parametr
wywołania (”Pubs”) jest nazwą DSN bazy danych na serwerze SQL.
Nasza aplikacja testująca drukuje kod XML w oknie uruchamiania, jednak można utworzyć plik XML przy użyciu
zwykłych operacji wejścia-wyjścia lub innej techniki. Użyjemy teraz komponentu na stronie ASP. W jednym z ostatnich
przykładów ładowaliśmy do strony HTML dane XML. Ten kod XML może być wbudowany w stronę WWW. Użyjmy
teraz naszego komponentu, aby dynamicznie utworzyć wbudowany w stronę kod XML, gdy użytkownik zażąda dostępu do
strony WWW. Za pomocą VBScript można załadować DLL ze strony WWW i dynamicznie utworzyć kod XML wyko-
rzystywany w aplikacji WWW. Poniższy kod tworzy taką samą jak poprzednio stronę WWW, jednak teraz jest dynamiczna i
tworzy XML na bieżąco.
Dim strXML
Set xml = Server.Create0bject("XML Tool.Database")
strSQL="Select * from Customers "
strConnect="File Name=c:\jetweb.UDL;"
strXML= xml.CreateXML("Customer", cstr(strSOL), cstr(strConnect))
%>
<APPLET code="com.ms.xml.dso.XMLDSO.class"
MAYSCRIPT id=xmldso WIDTH="100%" HEIGHT="20">
<%=strXML%>
</APPLET>
Za pomocą prostej kwerendy przestawnej z bazy danych Northwind utworzymy niezwiązany formularz na stronie ASP.
Utworzymy plik global.asa, aby zarządzać plikami GIF (wydruk 27.18).
Sub Session_OnEnd
Dim i
For i = 0 To Session("nFiles") - 1
Session("FileSystem").DeleteFile "D:\ntstuff\WebStuff\" &
Session("szFile" & i ), True
Next
End Sub
</SCRIPT>
W pliku ASP utworzymy tablicę aHeaders, w której umieszczamy nazwy nagłówków, w tym przykładzie cztery kwartały
roku podatkowego. Następnie po otwarciu wyniku ADO opartego na zapisanej kwerendzie krzyżowej o nazwie
qryQuarterlySales, wypełniamy tablicę aValues wartościami pól wyniku. Pełny kod przedstawiony jest na wydruku 27.19.
aValues(0) = rst![Otr 1]
aValues(1) = rst!(Otr 2]
aValues(2) = rst![Otr 3]
aValues(3) = rst![Otr 4]
ChartSpacel.Border.Color = c.chColorNone
ChartSpacel.Charts.Add
ChartSpacel.Charts(0).Type = _
ChartSpacel.Constants.chChartTypeColumnClustered
ChartSpacel.Charts(0).SeriesColleCtion.Add
ChartSpacel.Charts(0).Series0ollection(0).Caption = "Sales"
ChartSpacel.Charts(0).Series0ollection(0).SetData _
498 D:\Kompakt !!!\Kompakt\Ksiazki 1 !\!done - Access 2000 - Księga eksperta\Access 2000 - Księga eksperta.doc
Rozdział 27. ♦ Publikowanie w sieci przy użyciu Accessa 2000 i Active Server Pages 499