Spis Treści
c534792409 \h
217
HYPERLINK \l "_Toc534792410"
Deklaruj zmienne w jak najwęższym zakresie PAGEREF _Toc534792410 \h
218
HYPERLINK \l "_Toc534792411"
Używaj określonych typów danych PAGEREF _Toc534792411 \h
218
HYPERLINK \l "_Toc534792412"
Niszcz zmienne obiektów PAGEREF _Toc534792412 \h
218
HYPERLINK \l "_Toc534792413"
Używaj słowa kluczowego TypeOf PAGEREF _Toc534792413 \h
218
HYPERLINK \l "_Toc534792414"
Używaj Me zamiast Screen.ActiveForm i Screen.ActiveControl PAGEREF _Toc534792414 \h
218
HYPERLINK \l "_Toc534792415"
Używaj narzędzia do obsługi błędów PAGEREF _Toc534792415 \h
218
HYPERLINK \l "_Toc534792416"
Używaj Option Explicit PAGEREF _Toc534792416 \h
218
HYPERLINK \l "_Toc534792417"
Numeracja od 0 czy od 1? PAGEREF _Toc534792417 \h
218
HYPERLINK \l "_Toc534792418"
Natychmiast naprawiaj błędy PAGEREF _Toc534792418 \h
218
HYPERLINK \l "_Toc534792419"
Używaj komentarzy PAGEREF _Toc534792419 \h
218
HYPERLINK \l "_Toc534792420"
Używaj znaku kontynuacji wiersza PAGEREF _Toc534792420 \h
219
HYPERLINK \l "_Toc534792421"
Używaj krótkich procedur PAGEREF _Toc534792421 \h
219
HYPERLINK \l "_Toc534792422"
Używaj standaryzowanych konwencji nazewnictwa PAGEREF _Toc534792422 \h
219
HYPERLINK \l "_Toc534792423"
Nigdy nie używaj Stop PAGEREF _Toc534792423 \h
219
HYPERLINK \l "_Toc534792424"
Nie usuwaj błędów przy użyciu okien komunikatu PAGEREF _Toc534792424 \h
219
HYPERLINK \l "_Toc534792425"
Testowanie aplikacji PAGEREF _Toc534792425 \h
220
HYPERLINK \l "_Toc534792426"
Ćwiczenie technik usuwania błędów PAGEREF _Toc534792426 \h
220
HYPERLINK \l "_Toc534792427"
Rozdział 13. Profesjonalna obsługa błędów PAGEREF _Toc534792427 \h
221
HYPERLINK \l "_Toc534792428"
Usuwanie błędów składni PAGEREF _Toc534792428 \h
221
HYPERLINK \l "_Toc534792429"
Usuwanie błędów logicznych PAGEREF _Toc534792429 \h
223
HYPERLINK \l "_Toc534792430"
Usuwanie błędów wykrytych w trakcie użytkowania PAGEREF _Toc534792430 \h
223
HYPERLINK \l "_Toc534792431"
Proste narzędzie do obsługi błędów PAGEREF _Toc534792431 \h
223
HYPERLINK \l "_Toc534792432"
On Error GoTo ErrorHandler PAGEREF _Toc534792432 \h
223
HYPERLINK \l "_Toc534792433"
ExitHere PAGEREF _Toc534792433 \h
223
HYPERLINK \l "_Toc534792434"
ErrorHandler PAGEREF _Toc534792434 \h
224
HYPERLINK \l "_Toc534792435"
Resume ExitHere PAGEREF _Toc534792435 \h
224
HYPERLINK \l "_Toc534792436"
Przebieg programu z narzędziem do obsługi błędów PAGEREF _Toc534792436 \h
224
HYPERLINK \l "_Toc534792437"
Obiekt Err PAGEREF _Toc534792437 \h
225
HYPERLINK \l "_Toc534792438"
Err.Clear PAGEREF _Toc534792438 \h
225
HYPERLINK \l "_Toc534792439"
Err.Raise PAGEREF _Toc534792439 \h
225
HYPERLINK \l "_Toc534792440"
Reagowanie na błędy PAGEREF _Toc534792440 \h
226
HYPERLINK \l "_Toc534792441"
Instrukcje Resume PAGEREF _Toc534792441 \h
227
HYPERLINK \l "_Toc534792442"
Resume PAGEREF _Toc534792442 \h
227
HYPERLINK \l "_Toc534792443"
Resume Next PAGEREF _Toc534792443 \h
227
HYPERLINK \l "_Toc534792444"
Uzyskiwanie dodatkowych informacji o błędzie PAGEREF _Toc534792444 \h
227
HYPERLINK \l "_Toc534792445"
Zaawansowane narzędzie do obsługi błędów PAGEREF _Toc534792445 \h
228
HYPERLINK \l "_Toc534792446"
Moduł klasowy Error (Obiekt) PAGEREF _Toc534792446 \h
229
HYPERLINK \l "_Toc534792447"
Właściwości obiektu cError PAGEREF _Toc534792447 \h
229
HYPERLINK \l "_Toc534792448"
Metody obiektu cError PAGEREF _Toc534792448 \h
230
HYPERLINK \l "_Toc534792449"
Przeglądanie obiektu cError w Object Browser PAGEREF _Toc534792449 \h
231
HYPERLINK \l "_Toc534792450"
Przetwarzanie błędu PAGEREF _Toc534792450 \h
231
HYPERLINK \l "_Toc534792451"
Doświadczenie użytkownika końcowego PAGEREF _Toc534792451 \h
232
HYPERLINK \l "_Toc534792452"
Identyfikowanie problemów sprzętowych PAGEREF _Toc534792452 \h
234
HYPERLINK \l "_Toc534792453"
Sporządzanie raportów o błędach PAGEREF _Toc534792453 \h
234
HYPERLINK \l "_Toc534792454"
Opcje obiektu cError PAGEREF _Toc534792454 \h
235
HYPERLINK \l "_Toc534792455"
Odwołania do interfejsu API systemu Windows PAGEREF _Toc534792455 \h
236
HYPERLINK \l "_Toc534792456"
Błędy w różnych aplikacjach PAGEREF _Toc534792456 \h
237
HYPERLINK \l "_Toc534792457"
Obsługa błędów w procedurach zagnieżdżonych PAGEREF _Toc534792457 \h
237
HYPERLINK \l "_Toc534792458"
Zaawansowane zagadnienia związane z błędami PAGEREF _Toc534792458 \h
237
HYPERLINK \l "_Toc534792459"
Procedury zdarzeń związane z błędami PAGEREF _Toc534792459 \h
237
HYPERLINK \l "_Toc534792460"
On Error GoTo 0 PAGEREF _Toc534792460 \h
238
HYPERLINK \l "_Toc534792461"
On Error Resume Next PAGEREF _Toc534792461 \h
238
HYPERLINK \l "_Toc534792462"
Metoda AccessError PAGEREF _Toc534792462 \h
238
HYPERLINK \l "_Toc534792463"
Inne funkcje związane z błędami PAGEREF _Toc534792463 \h
238
HYPERLINK \l "_Toc534792464"
Ustawienie opcji wyłapujących błędy PAGEREF _Toc534792464 \h
238
HYPERLINK \l "_Toc534792465"
Rozdział 14. Optymalizacja aplikacji PAGEREF _Toc534792465 \h
240
HYPERLINK \l "_Toc534792466"
Ulepszanie podstaw: optymalizacja sprzętu i systemu Windows PAGEREF _Toc534792466 \h
241
HYPERLINK \l "_Toc534792467"
Instalowanie aplikacji w celu uzyskania optymalnej wydajności PAGEREF _Toc534792467 \h
242
HYPERLINK \l "_Toc534792468"
Optymalizacja silnika bazy danych Jet PAGEREF _Toc534792468 \h
242
HYPERLINK \l "_Toc534792469"
Bezpieczne modyfikowanie ustawień silnika Jet PAGEREF _Toc534792469 \h
246
HYPERLINK \l "_Toc534792470"
Narzędzia służące do pomiaru wydajności PAGEREF _Toc534792470 \h
247
HYPERLINK \l "_Toc534792471"
Spojrzenie za kulisy PAGEREF _Toc534792471 \h
248
HYPERLINK \l "_Toc534792472"
Optymalizacja bazy danych od podstaw PAGEREF _Toc534792472 \h
249
HYPERLINK \l "_Toc534792473"
Projektowanie tabel w celu osiągnięcia poprawy wydajności PAGEREF _Toc534792473 \h
249
HYPERLINK \l "_Toc534792474"
Normalizacja danych w celu osiągnięcia poprawy wydajności PAGEREF _Toc534792474 \h
249
HYPERLINK \l "_Toc534792475"
Tworzenie indeksów w celu przyspieszenia pracy kwerend PAGEREF _Toc534792475 \h
250
HYPERLINK \l "_Toc534792476"
Wcześniejsze tworzenie relacji jako sposób na poprawę wydajności PAGEREF _Toc534792476 \h
250
HYPERLINK \l "_Toc534792477"
Poprawa wydajności kwerend PAGEREF _Toc534792477 \h
250
HYPERLINK \l "_Toc534792478"
Wybór typu zestawu wyników zapewniającego optymalną wydajność PAGEREF _Toc534792478 \h
252
HYPERLINK \l "_Toc534792479"
Zwiększenie szybkości kwerend PAGEREF _Toc534792479 \h
253
HYPERLINK \l "_Toc534792480"
Przyspieszenie funkcjonowania formularzy PAGEREF _Toc534792480 \h
255
HYPERLINK \l "_Toc534792481"
Zacznijmy od początku PAGEREF _Toc534792481 \h
255
HYPERLINK \l "_Toc534792482"
Szybsze pobieranie rysunków PAGEREF _Toc534792482 \h
255
HYPERLINK \l "_Toc534792483"
Podstawowy, szybki formularz PAGEREF _Toc534792483 \h
256
HYPERLINK \l "_Toc534792484"
Szybsze drukowanie raportów PAGEREF _Toc534792484 \h
258
HYPERLINK \l "_Toc534792485"
Pisanie szybkiego kodu PAGEREF _Toc534792485 \h
258
HYPERLINK \l "_Toc534792486"
Użycie pamięci przez kod PAGEREF _Toc534792486 \h
259
HYPERLINK \l "_Toc534792487"
Praca z modułami PAGEREF _Toc534792487 \h
259
HYPERLINK \l "_Toc534792488"
Kompilowanie kodu PAGEREF _Toc534792488 \h
259
HYPERLINK \l "_Toc534792489"
Dekompilacja PAGEREF _Toc534792489 \h
259
HYPERLINK \l "_Toc534792490"
Tworzenie pliku MDE PAGEREF _Toc534792490 \h
260
HYPERLINK \l "_Toc534792491"
Użycie Option Explicit PAGEREF _Toc534792491 \h
260
HYPERLINK \l "_Toc534792492"
Precyzyjne wybieranie rozmiaru zmiennych PAGEREF _Toc534792492 \h
260
HYPERLINK \l "_Toc534792493"
Oszczędzanie przestrzeni stosu przy użyciu zmiennych typu string PAGEREF _Toc534792493 \h
260
HYPERLINK \l "_Toc534792494"
Dokładne określanie typu obiektów PAGEREF _Toc534792494 \h
260
HYPERLINK \l "_Toc534792495"
Umieszczenie kodu we wnętrzu procedury zamiast odwoływania się do innych funkcji PAGEREF _Toc534792495 \h
261
HYPERLINK \l "_Toc534792496"
Zmiana True i False PAGEREF _Toc534792496 \h
261
HYPERLINK \l "_Toc534792497"
Użycie Len() zamiast pustego ciągu PAGEREF _Toc534792497 \h
261
HYPERLINK \l "_Toc534792498"
Użycie True i False zamiast zera PAGEREF _Toc534792498 \h
261
HYPERLINK \l "_Toc534792499"
Szybkie odwołania do obiektów PAGEREF _Toc534792499 \h
261
HYPERLINK \l "_Toc534792500"
Użycie szybkich tablic PAGEREF _Toc534792500 \h
262
HYPERLINK \l "_Toc534792501"
Używaj stałych, gdy jest to tylko możliwe PAGEREF _Toc534792501 \h
262
HYPERLINK \l "_Toc534792502"
Właściwe użycie zakładek (Bookmarks) PAGEREF _Toc534792502 \h
262
HYPERLINK \l "_Toc534792503"
Zamykaj i niszcz PAGEREF _Toc534792503 \h
263
HYPERLINK \l "_Toc534792504"
Używaj SQL zamiast DAO PAGEREF _Toc534792504 \h
263
HYPERLINK \l "_Toc534792505"
Użycie indeksowania kolekcji PAGEREF _Toc534792505 \h
263
HYPERLINK \l "_Toc534792506"
Tworzenie szybszych pętli PAGEREF _Toc534792506 \h
263
HYPERLINK \l "_Toc534792507"
Usuń z kodu IIF() PAGEREF _Toc534792507 \h
264
HYPERLINK \l "_Toc534792508"
Porządkowanie Select Case PAGEREF _Toc534792508 \h
264
HYPERLINK \l "_Toc534792509"
Używaj Execute zamiast RunSQL PAGEREF _Toc534792509 \h
264
HYPERLINK \l "_Toc534792510"
Używaj A2KU_Timer PAGEREF _Toc534792510 \h
264
HYPERLINK \l "_Toc534792511"
Testuj wydajność transakcji PAGEREF _Toc534792511 \h
264
HYPERLINK \l "_Toc534792512"
Kontroluj odświeżanie PAGEREF _Toc534792512 \h
264
HYPERLINK \l "_Toc534792513"
Używaj wczesnego wiązania i zwracaj uwagę na odniesienia ActiveX PAGEREF _Toc534792513 \h
265
HYPERLINK \l "_Toc534792514"
Przejście do architektury klient-serwer PAGEREF _Toc534792514 \h
265
HYPERLINK \l "_Toc534792515"
Chleba i igrzysk PAGEREF _Toc534792515 \h
265
HYPERLINK \l "_Toc534792516"
Część V Access i architektura klient-serwer PAGEREF _Toc534792516 \h
266
HYPERLINK \l "_Toc534792517"
Rozdział 15. Wprowadzenie do projektów programu Microsoft Access oraz narzędzi wizualnych PAGEREF _Toc534792517 \h
267
HYPERLINK \l "_Toc534792518"
Wprowadzenie do projektów programu Microsoft Access PAGEREF _Toc534792518 \h
267
HYPERLINK \l "_Toc534792519"
Wady i zalety ADP PAGEREF _Toc534792519 \h
267
HYPERLINK \l "_Toc534792520"
Użycie ADP PAGEREF _Toc534792520 \h
268
HYPERLINK \l "_Toc534792521"
Tworzenie ADP PAGEREF _Toc534792521 \h
268
HYPERLINK \l "_Toc534792522"
Nowe okno bazy danych PAGEREF _Toc534792522 \h
269
HYPERLINK \l "_Toc534792523"
Praca z ADP i istniejącymi bazami danych serwera SQL PAGEREF _Toc534792523 \h
270
HYPERLINK \l "_Toc534792524"
Praca z tabelami PAGEREF _Toc534792524 \h
270
HYPERLINK \l "_Toc534792525"
Widoki w serwerze SQL PAGEREF _Toc534792525 \h
271
HYPERLINK \l "_Toc534792526"
Procedury przechowywane PAGEREF _Toc534792526 \h
272
HYPERLINK \l "_Toc534792527"
Diagramy bazy danych PAGEREF _Toc534792527 \h
272
HYPERLINK \l "_Toc534792528"
Formularze, strony, raporty i moduły PAGEREF _Toc534792528 \h
273
HYPERLINK \l "_Toc534792529"
Zarządzanie serwerem SQL poprzez ADP PAGEREF _Toc534792529 \h
273
HYPERLINK \l "_Toc534792530"
Składowanie i odtwarzanie PAGEREF _Toc534792530 \h
273
HYPERLINK \l "_Toc534792531"
Replikacja serwera SQL PAGEREF _Toc534792531 \h
274
HYPERLINK \l "_Toc534792532"
Bezpieczeństwo PAGEREF _Toc534792532 \h
274
HYPERLINK \l "_Toc534792533"
Powtórne przyłączenie do bazy serwera SQL PAGEREF _Toc534792533 \h
275
HYPERLINK \l "_Toc534792534"
Tworzenie projektu opartego na nowej bazie danych PAGEREF _Toc534792534 \h
276
HYPERLINK \l "_Toc534792535"
Tworzenie tabel PAGEREF _Toc534792535 \h
276
HYPERLINK \l "_Toc534792536"
Ustawienie właściwości tabeli i indeksów PAGEREF _Toc534792536 \h
277
HYPERLINK \l "_Toc534792537"
Tworzenie zależności na diagramie bazy danych PAGEREF _Toc534792537 \h
277
HYPERLINK \l "_Toc534792538"
Tworzenie kaskad poprzez wyzwalacze PAGEREF _Toc534792538 \h
278
HYPERLINK \l "_Toc534792539"
Tworzenie widoków PAGEREF _Toc534792539 \h
278
HYPERLINK \l "_Toc534792540"
Tworzenie procedur przechowywanych PAGEREF _Toc534792540 \h
279
HYPERLINK \l "_Toc534792541"
Tworzenie aplikacji w Accessie PAGEREF _Toc534792541 \h
279
HYPERLINK \l "_Toc534792542"
Tworzenie plików ADE PAGEREF _Toc534792542 \h
279
HYPERLINK \l "_Toc534792543"
Zakończenie: przenoszenie bazy danych Access 97 na serwer SQL i do pliku ADP PAGEREF _Toc534792543 \h
280
HYPERLINK \l "_Toc534792544"
Rozdział 16. Tworzenie interfejsu użytkownika dla Microsoft SQL Server PAGEREF _Toc534792544 \h
281
HYPERLINK \l "_Toc534792545"
Architektura klient-serwer: OLE DB kontra ODBC PAGEREF _Toc534792545 \h
281
HYPERLINK \l "_Toc534792546"
Tworzenie połączenia z serwerem SQL PAGEREF _Toc534792546 \h
281
HYPERLINK \l "_Toc534792547"
Tworzenie źródła danych ODBC (DSN) PAGEREF _Toc534792547 \h
282
HYPERLINK \l "_Toc534792548"
Łączenie tabel PAGEREF _Toc534792548 \h
282
HYPERLINK \l "_Toc534792549"
Wady tabel połączonych PAGEREF _Toc534792549 \h
283
HYPERLINK \l "_Toc534792550"
Połączenie najlepszych metod: wypełnianie tabel podczas startu aplikacji PAGEREF _Toc534792550 \h
283
HYPERLINK \l "_Toc534792551"
Procedury przechowywane i kwerendy przekazujące PAGEREF _Toc534792551 \h
284
HYPERLINK \l "_Toc534792552"
Tworzenie raportów opartych na procedurach przechowywanych poprzez zapytania przekazujące PAGEREF _Toc534792552 \h
284
HYPERLINK \l "_Toc534792553"
Raportowanie z serwera SQL w Accessie PAGEREF _Toc534792553 \h
286
HYPERLINK \l "_Toc534792554"
Zaawansowane możliwości: przekazywanie parametrów do procedury przechowywanej w czasie działania programu PAGEREF _Toc534792554 \h
286
HYPERLINK \l "_Toc534792555"
Dodatkowe filtrowanie danych raportu PAGEREF _Toc534792555 \h
287
HYPERLINK \l "_Toc534792556"
Formularze w aplikacji PAGEREF _Toc534792556 \h
288
HYPERLINK \l "_Toc534792557"
Formularze związane PAGEREF _Toc534792557 \h
288
HYPERLINK \l "_Toc534792558"
Formularze niezwiązane PAGEREF _Toc534792558 \h
289
HYPERLINK \l "_Toc534792559"
Zaawansowane właściwości: dostawca OLE DB dla serwera SQL PAGEREF _Toc534792559 \h
290
HYPERLINK \l "_Toc534792560"
Następny zestaw wyników PAGEREF _Toc534792560 \h
290
HYPERLINK \l "_Toc534792561"
Wykonywanie poleceń z parametrami PAGEREF _Toc534792561 \h
291
HYPERLINK \l "_Toc534792562"
Długa droga PAGEREF _Toc534792562 \h
291
HYPERLINK \l "_Toc534792563"
Użycie metody CreateParameters PAGEREF _Toc534792563 \h
292
HYPERLINK \l "_Toc534792564"
Użycie Refresh PAGEREF _Toc534792564 \h
292
HYPERLINK \l "_Toc534792565"
Obsługa zwracanych wartości PAGEREF _Toc534792565 \h
293
HYPERLINK \l "_Toc534792566"
Wykonanie procedury bez obiektu Command PAGEREF _Toc534792566 \h
294
HYPERLINK \l "_Toc534792567"
Użycie klasy Connection PAGEREF _Toc534792567 \h
294
HYPERLINK \l "_Toc534792568"
Użycie klasy Connection w aplikacji PAGEREF _Toc534792568 \h
295
HYPERLINK \l "_Toc534792569"
Rozdział 17. Interfejs Accessa 2000 do Oracle'a PAGEREF _Toc534792569 \h
296
HYPERLINK \l "_Toc534792570"
Dostęp do danych Oracle'a przez Accessa PAGEREF _Toc534792570 \h
296
HYPERLINK \l "_Toc534792571"
Tabele połączone PAGEREF _Toc534792571 \h
297
HYPERLINK \l "_Toc534792572"
Tworzenie ciągu połączenia ODBC PAGEREF _Toc534792572 \h
297
HYPERLINK \l "_Toc534792573"
Tworzenia nazwy źródła danych PAGEREF _Toc534792573 \h
297
HYPERLINK \l "_Toc534792574"
Koszt połączenia z Oracle'em PAGEREF _Toc534792574 \h
298
HYPERLINK \l "_Toc534792575"
Kwerendy przekazujące (SPT) PAGEREF _Toc534792575 \h
298
HYPERLINK \l "_Toc534792576"
Określanie właściwości kwerend przekazujących PAGEREF _Toc534792576 \h
299
HYPERLINK \l "_Toc534792577"
Składnia kwerend przekazujących PAGEREF _Toc534792577 \h
299
HYPERLINK \l "_Toc534792578"
Wielkość liter PAGEREF _Toc534792578 \h
299
HYPERLINK \l "_Toc534792579"
Wyrażenie Select PAGEREF _Toc534792579 \h
300
HYPERLINK \l "_Toc534792580"
Klauzula WHERE PAGEREF _Toc534792580 \h
300
HYPERLINK \l "_Toc534792581"
Definiowanie zależności PAGEREF _Toc534792581 \h
300
HYPERLINK \l "_Toc534792582"
Użycie znaków specjalnych PAGEREF _Toc534792582 \h
300
HYPERLINK \l "_Toc534792583"
Użycie Null i Not Null PAGEREF _Toc534792583 \h
300
HYPERLINK \l "_Toc534792584"
Tworzenie wyrażeń Insert PAGEREF _Toc534792584 \h
301
HYPERLINK \l "_Toc534792585"
Tworzenie wyrażeń Update PAGEREF _Toc534792585 \h
301
HYPERLINK \l "_Toc534792586"
Użycie Group By/Having PAGEREF _Toc534792586 \h
301
HYPERLINK \l "_Toc534792587"
Funkcje w Oracle'u i Accessie PAGEREF _Toc534792587 \h
301
HYPERLINK \l "_Toc534792588"
Ciągi PAGEREF _Toc534792588 \h
302
HYPERLINK \l "_Toc534792589"
Łączenie PAGEREF _Toc534792589 \h
302
HYPERLINK \l "_Toc534792590"
Initcap, Lower, Upper PAGEREF _Toc534792590 \h
302
HYPERLINK \l "_Toc534792591"
Instr PAGEREF _Toc534792591 \h
303
HYPERLINK \l "_Toc534792592"
LTrim/RTrim PAGEREF _Toc534792592 \h
303
HYPERLINK \l "_Toc534792593"
Soundex PAGEREF _Toc534792593 \h
304
HYPERLINK \l "_Toc534792594"
Substr PAGEREF _Toc534792594 \h
304
HYPERLINK \l "_Toc534792595"
Decode PAGEREF _Toc534792595 \h
305
HYPERLINK \l "_Toc534792596"
Obliczenia w Oracle'u PAGEREF _Toc534792596 \h
305
HYPERLINK \l "_Toc534792597"
Ceil() PAGEREF _Toc534792597 \h
305
HYPERLINK \l "_Toc534792598"
Floor() PAGEREF _Toc534792598 \h
305
HYPERLINK \l "_Toc534792599"
Nvl() PAGEREF _Toc534792599 \h
306
HYPERLINK \l "_Toc534792600"
Round() PAGEREF _Toc534792600 \h
306
HYPERLINK \l "_Toc534792601"
Sign() PAGEREF _Toc534792601 \h
306
HYPERLINK \l "_Toc534792602"
Trunc() PAGEREF _Toc534792602 \h
306
HYPERLINK \l "_Toc534792603"
Greatest/Least PAGEREF _Toc534792603 \h
306
HYPERLINK \l "_Toc534792604"
Obliczenia na datach PAGEREF _Toc534792604 \h
307
HYPERLINK \l "_Toc534792605"
Arytmetyka PAGEREF _Toc534792605 \h
307
HYPERLINK \l "_Toc534792606"
Sysdate PAGEREF _Toc534792606 \h
307
HYPERLINK \l "_Toc534792607"
Add_Months PAGEREF _Toc534792607 \h
307
HYPERLINK \l "_Toc534792608"
Months_Between PAGEREF _Toc534792608 \h
307
HYPERLINK \l "_Toc534792609"
Next_Day() PAGEREF _Toc534792609 \h
308
HYPERLINK \l "_Toc534792610"
To_Date() PAGEREF _Toc534792610 \h
308
HYPERLINK \l "_Toc534792611"
Problem roku 2000 PAGEREF _Toc534792611 \h
308
HYPERLINK \l "_Toc534792612"
Poznajemy widoki i procedury przechowywane PAGEREF _Toc534792612 \h
309
HYPERLINK \l "_Toc534792613"
Tworzenie widoków PAGEREF _Toc534792613 \h
309
HYPERLINK \l "_Toc534792614"
Połączenie z Oracle'em poprzez ADO PAGEREF _Toc534792614 \h
310
HYPERLINK \l "_Toc534792615"
Parametry PAGEREF _Toc534792615 \h
311
HYPERLINK \l "_Toc534792616"
Tworzenie procedur przechowywanych PAGEREF _Toc534792616 \h
312
HYPERLINK \l "_Toc534792617"
Uruchamianie procedury PAGEREF _Toc534792617 \h
313
HYPERLINK \l "_Toc534792618"
Tworzenie niezwiązanego interfejsu do Oracle'a PAGEREF _Toc534792618 \h
313
HYPERLINK \l "_Toc534792619"
Tworzenie niezwiązanego interfejsu PAGEREF _Toc534792619 \h
314
HYPERLINK \l "_Toc534792620"
Tworzenie zmiennych globalnych PAGEREF _Toc534792620 \h
314
HYPERLINK \l "_Toc534792621"
Ładowanie danych i inicjalizacja formularza PAGEREF _Toc534792621 \h
315
HYPERLINK \l "_Toc534792622"
Programowanie przycisków sterujących PAGEREF _Toc534792622 \h
315
HYPERLINK \l "_Toc534792623"
Zmiana danych Oracle'a przy użyciu formularza PAGEREF _Toc534792623 \h
317
HYPERLINK \l "_Toc534792624"
Wstawienie danych do Oracle'a przy użyciu formularza PAGEREF _Toc534792624 \h
318
HYPERLINK \l "_Toc534792625"
Zapisywanie danych do Oracle'a przy użyciu formularza PAGEREF _Toc534792625 \h
318
HYPERLINK \l "_Toc534792626"
Usuwanie danych przy użyciu formularza PAGEREF _Toc534792626 \h
319
HYPERLINK \l "_Toc534792627"
Zamykanie połączenia z Oracle'em PAGEREF _Toc534792627 \h
319
HYPERLINK \l "_Toc534792628"
Część VI Współoperatywność PAGEREF _Toc534792628 \h
321
HYPERLINK \l "_Toc534792629"
Rozdział 18. Użycie automatyzacji ActiveX PAGEREF _Toc534792629 \h
322
HYPERLINK \l "_Toc534792630"
Co to jest automatyzacja ActiveX PAGEREF _Toc534792630 \h
322
HYPERLINK \l "_Toc534792631"
Dlaczego używamy automatyzacji PAGEREF _Toc534792631 \h
322
HYPERLINK \l "_Toc534792632"
Różnice między serwerem automatyzacji a klientem automatyzacji PAGEREF _Toc534792632 \h
323
HYPERLINK \l "_Toc534792633"
Określanie zasobów wymaganych przez automatyzację PAGEREF _Toc534792633 \h
323
HYPERLINK \l "_Toc534792634"
Wielka trójka PAGEREF _Toc534792634 \h
323
HYPERLINK \l "_Toc534792635"
Tworzenie i ustanowienie odwołania do innej aplikacji PAGEREF _Toc534792635 \h
323
HYPERLINK \l "_Toc534792636"
Ustanawianie odwołania do innej aplikacji PAGEREF _Toc534792636 \h
323
HYPERLINK \l "_Toc534792637"
Przegląd obiektów, właściwości i metod PAGEREF _Toc534792637 \h
324
HYPERLINK \l "_Toc534792638"
Poznajemy strukturę obiektów PAGEREF _Toc534792638 \h
324
HYPERLINK \l "_Toc534792639"
Użycie narzędzia Object Browser PAGEREF _Toc534792639 \h
324
HYPERLINK \l "_Toc534792640"
Tworzenie zmiennej obiektowej PAGEREF _Toc534792640 \h
326
HYPERLINK \l "_Toc534792641"
Odwołanie do pracującej aplikacji PAGEREF _Toc534792641 \h
326
HYPERLINK \l "_Toc534792642"
Przypisywanie zmiennej obiektowej do aplikacji PAGEREF _Toc534792642 \h
326
HYPERLINK \l "_Toc534792643"
Tworzenie egzemplarza aplikacji PAGEREF _Toc534792643 \h
327
HYPERLINK \l "_Toc534792644"
Jednoczesne użycie funkcji GetObject i New PAGEREF _Toc534792644 \h
327
HYPERLINK \l "_Toc534792645"
Użycie wczesnego i późnego łączenia typów PAGEREF _Toc534792645 \h
327
HYPERLINK \l "_Toc534792646"
Użycie funkcji CreateObject PAGEREF _Toc534792646 \h
328
HYPERLINK \l "_Toc534792647"
Kiedy nie można uzyskać odwołania do aplikacji PAGEREF _Toc534792647 \h
328
HYPERLINK \l "_Toc534792648"
Co wtedy, gdy użytkownik ma inną wersję aplikacji? PAGEREF _Toc534792648 \h
328
HYPERLINK \l "_Toc534792649"
Użycie metod i właściwości obiektów automatyzacji PAGEREF _Toc534792649 \h
329
HYPERLINK \l "_Toc534792650"
Ustawianie właściwości obiektu PAGEREF _Toc534792650 \h
329
HYPERLINK \l "_Toc534792651"
Wykonywanie metod obiektów PAGEREF _Toc534792651 \h
329
HYPERLINK \l "_Toc534792652"
Zwalnianie obiektów automatyzacji PAGEREF _Toc534792652 \h
329
HYPERLINK \l "_Toc534792653"
Łączymy wszystko razem PAGEREF _Toc534792653 \h
329
HYPERLINK \l "_Toc534792654"
Zamykanie aplikacji serwera automatyzacji PAGEREF _Toc534792654 \h
330
HYPERLINK \l "_Toc534792655"
Użycie właściwości UserControl do sprawdzenia, w jaki sposób została otwarta aplikacja PAGEREF _Toc534792655 \h
330
HYPERLINK \l "_Toc534792656"
Użycie WithEvents w celu udostępnienia zdarzeń serwera automatyzacji PAGEREF _Toc534792656 \h
331
HYPERLINK \l "_Toc534792657"
Uruchamiamy WithEvents PAGEREF _Toc534792657 \h
331
HYPERLINK \l "_Toc534792658"
Techniki i wskazówki do automatyzacji PAGEREF _Toc534792658 \h
332
HYPERLINK \l "_Toc534792659"
Ustanowienie odwołania, użycie wczesnego wiązania typów i słowa kluczowego New PAGEREF _Toc534792659 \h
332
HYPERLINK \l "_Toc534792660"
Użycie istniejącego egzemplarza aplikacji, jeżeli jest ona uruchomiona PAGEREF _Toc534792660 \h
333
HYPERLINK \l "_Toc534792661"
Wyłącz odświeżanie ekranu PAGEREF _Toc534792661 \h
333
HYPERLINK \l "_Toc534792662"
Informacja o przetwarzaniu PAGEREF _Toc534792662 \h
333
HYPERLINK \l "_Toc534792663"
Wykonywanie programu przez serwer automatyzacji PAGEREF _Toc534792663 \h
334
HYPERLINK \l "_Toc534792664"
Użycie konstrukcji With/End With PAGEREF _Toc534792664 \h
334
HYPERLINK \l "_Toc534792665"
Zwalnianie zmiennych obiektowych PAGEREF _Toc534792665 \h
334
HYPERLINK \l "_Toc534792666"
Nie wyświetlaj okien dialogowych i komunikatów PAGEREF _Toc534792666 \h
334
HYPERLINK \l "_Toc534792667"
Używaj obsługi błędów PAGEREF _Toc534792667 \h
334
HYPERLINK \l "_Toc534792668"
Rozdział 19. Integracja z Office 2000 PAGEREF _Toc534792668 \h
335
HYPERLINK \l "_Toc534792669"
Powody integracji z Office 2000 PAGEREF _Toc534792669 \h
336
HYPERLINK \l "_Toc534792670"
Użycie Worda PAGEREF _Toc534792670 \h
336
HYPERLINK \l "_Toc534792671"
Użycie Excela PAGEREF _Toc534792671 \h
336
HYPERLINK \l "_Toc534792672"
Użycie PowerPoint PAGEREF _Toc534792672 \h
336
HYPERLINK \l "_Toc534792673"
Użycie Outlooka PAGEREF _Toc534792673 \h
336
HYPERLINK \l "_Toc534792674"
Użycie Graph PAGEREF _Toc534792674 \h
337
HYPERLINK \l "_Toc534792675"
Użycie MapPoint PAGEREF _Toc534792675 \h
337
HYPERLINK \l "_Toc534792676"
Użycie FrontPage PAGEREF _Toc534792676 \h
337
HYPERLINK \l "_Toc534792677"
Użycie Bindera PAGEREF _Toc534792677 \h
337
HYPERLINK \l "_Toc534792678"
Wybór właściwego narzędzia PAGEREF _Toc534792678 \h
337
HYPERLINK \l "_Toc534792679"
Wszędzie VBA PAGEREF _Toc534792679 \h
337
HYPERLINK \l "_Toc534792680"
Użycie rejestratora makr do pisania kodu PAGEREF _Toc534792680 \h
338
HYPERLINK \l "_Toc534792681"
Użycie makr automatycznych PAGEREF _Toc534792681 \h
339
HYPERLINK \l "_Toc534792682"
Microsoft Forms PAGEREF _Toc534792682 \h
339
HYPERLINK \l "_Toc534792683"
Object Browser PAGEREF _Toc534792683 \h
339
HYPERLINK \l "_Toc534792684"
Nazwy klas aplikacji Office PAGEREF _Toc534792684 \h
340
HYPERLINK \l "_Toc534792685"
Przykład automatyzacji PAGEREF _Toc534792685 \h
340
HYPERLINK \l "_Toc534792686"
Automatyzacja Worda PAGEREF _Toc534792686 \h
341
HYPERLINK \l "_Toc534792687"
Model obiektów Worda PAGEREF _Toc534792687 \h
342
HYPERLINK \l "_Toc534792688"
Użycie szablonów Worda PAGEREF _Toc534792688 \h
342
HYPERLINK \l "_Toc534792689"
Wstawianie danych do dokumentu Worda PAGEREF _Toc534792689 \h
343
HYPERLINK \l "_Toc534792690"
Korespondencja seryjna PAGEREF _Toc534792690 \h
343
HYPERLINK \l "_Toc534792691"
Zakładki PAGEREF _Toc534792691 \h
345
HYPERLINK \l "_Toc534792692"
Zastępowanie PAGEREF _Toc534792692 \h
345
HYPERLINK \l "_Toc534792693"
Przykłady kodu automatyzacji Worda PAGEREF _Toc534792693 \h
345
HYPERLINK \l "_Toc534792694"
Formatowanie dokumentów PAGEREF _Toc534792694 \h
345
HYPERLINK \l "_Toc534792695"
Użycie stylów dokumentu PAGEREF _Toc534792695 \h
346
HYPERLINK \l "_Toc534792696"
Autokorekta PAGEREF _Toc534792696 \h
346
HYPERLINK \l "_Toc534792697"
Autotekst PAGEREF _Toc534792697 \h
346
HYPERLINK \l "_Toc534792698"
Autopodsumowanie PAGEREF _Toc534792698 \h
346
HYPERLINK \l "_Toc534792699"
Widoki dokumentu PAGEREF _Toc534792699 \h
347
HYPERLINK \l "_Toc534792700"
Spis treści PAGEREF _Toc534792700 \h
347
HYPERLINK \l "_Toc534792701"
Przypisy PAGEREF _Toc534792701 \h
347
HYPERLINK \l "_Toc534792702"
Nagłówki PAGEREF _Toc534792702 \h
347
HYPERLINK \l "_Toc534792703"
Stopki PAGEREF _Toc534792703 \h
347
HYPERLINK \l "_Toc534792704"
Hiperłącza PAGEREF _Toc534792704 \h
347
HYPERLINK \l "_Toc534792705"
Tworzenie tabel PAGEREF _Toc534792705 \h
348
HYPERLINK \l "_Toc534792706"
Ustawienia strony PAGEREF _Toc534792706 \h
348
HYPERLINK \l "_Toc534792707"
Podgląd wydruku PAGEREF _Toc534792707 \h
348
HYPERLINK \l "_Toc534792708"
Drukowanie dokumentów, kopert i etykiet PAGEREF _Toc534792708 \h
348
HYPERLINK \l "_Toc534792709"
Pola PAGEREF _Toc534792709 \h
348
HYPERLINK \l "_Toc534792710"
Informacje o dokumencie PAGEREF _Toc534792710 \h
349
HYPERLINK \l "_Toc534792711"
Inne możliwości Worda PAGEREF _Toc534792711 \h
350
HYPERLINK \l "_Toc534792712"
Automatyzacja Excela PAGEREF _Toc534792712 \h
350
HYPERLINK \l "_Toc534792713"
Model obiektów Excela PAGEREF _Toc534792713 \h
350
HYPERLINK \l "_Toc534792714"
Przykłady automatyzacji Excela PAGEREF _Toc534792714 \h
351
HYPERLINK \l "_Toc534792715"
Formatowanie dokumentów Excela PAGEREF _Toc534792715 \h
351
HYPERLINK \l "_Toc534792716"
Tworzenie wykresów PAGEREF _Toc534792716 \h
351
HYPERLINK \l "_Toc534792717"
Użycie właściwości Parent PAGEREF _Toc534792717 \h
352
HYPERLINK \l "_Toc534792718"
Automatyzacja PowerPoint PAGEREF _Toc534792718 \h
352
HYPERLINK \l "_Toc534792719"
Model obiektów PowerPoint PAGEREF _Toc534792719 \h
353
HYPERLINK \l "_Toc534792720"
Przykłady automatyzacji PowerPoint PAGEREF _Toc534792720 \h
353
HYPERLINK \l "_Toc534792721"
Dodanie slajdu PAGEREF _Toc534792721 \h
353
HYPERLINK \l "_Toc534792722"
Dodanie efektu przejścia PAGEREF _Toc534792722 \h
354
HYPERLINK \l "_Toc534792723"
Wstawianie danych i formatowanie slajdów PAGEREF _Toc534792723 \h
354
HYPERLINK \l "_Toc534792724"
Wstawienie rysunku do slajdu PAGEREF _Toc534792724 \h
354
HYPERLINK \l "_Toc534792725"
Uruchamianie prezentacji PAGEREF _Toc534792725 \h
354
HYPERLINK \l "_Toc534792726"
Automatyzacja Outlook PAGEREF _Toc534792726 \h
354
HYPERLINK \l "_Toc534792727"
Model obiektów Outlook PAGEREF _Toc534792727 \h
355
HYPERLINK \l "_Toc534792728"
Przykłady automatyzacji Outlook PAGEREF _Toc534792728 \h
355
HYPERLINK \l "_Toc534792729"
Dodawanie i wyświetlanie folderów PAGEREF _Toc534792729 \h
355
HYPERLINK \l "_Toc534792730"
Dodawanie nowego zadania i wyświetlenie zadań PAGEREF _Toc534792730 \h
356
HYPERLINK \l "_Toc534792731"
Tworzenie wiadomości e-mail z załącznikiem PAGEREF _Toc534792731 \h
356
HYPERLINK \l "_Toc534792732"
Tworzenie elementów Outlooka PAGEREF _Toc534792732 \h
357
HYPERLINK \l "_Toc534792733"
Wyświetlanie domyślnych folderów PAGEREF _Toc534792733 \h
357
HYPERLINK \l "_Toc534792734"
Wyświetlenie foldera publicznego PAGEREF _Toc534792734 \h
357
HYPERLINK \l "_Toc534792735"
Szukanie elementu w Outlooku PAGEREF _Toc534792735 \h
357
HYPERLINK \l "_Toc534792736"
Filtrowanie elementów w Outlooku PAGEREF _Toc534792736 \h
357
HYPERLINK \l "_Toc534792737"
Automatyzacja Graph PAGEREF _Toc534792737 \h
358
HYPERLINK \l "_Toc534792738"
Model obiektów Graph PAGEREF _Toc534792738 \h
358
HYPERLINK \l "_Toc534792739"
Tworzenie wykresu PAGEREF _Toc534792739 \h
358
HYPERLINK \l "_Toc534792740"
Przykłady automatyzacji Graph PAGEREF _Toc534792740 \h
359
HYPERLINK \l "_Toc534792741"
Automatyzacja MapPoint PAGEREF _Toc534792741 \h
359
HYPERLINK \l "_Toc534792742"
Model obiektów MapPoint PAGEREF _Toc534792742 \h
359
HYPERLINK \l "_Toc534792743"
Przykłady automatyzacji MapPoint PAGEREF _Toc534792743 \h
360
HYPERLINK \l "_Toc534792744"
Automatyzacja FrontPage PAGEREF _Toc534792744 \h
360
HYPERLINK \l "_Toc534792745"
Model obiektów FrontPage PAGEREF _Toc534792745 \h
360
HYPERLINK \l "_Toc534792746"
Przykłady automatyzacji FrontPage PAGEREF _Toc534792746 \h
361
HYPERLINK \l "_Toc534792747"
Automatyzacja Bindera PAGEREF _Toc534792747 \h
362
HYPERLINK \l "_Toc534792748"
Model obiektów Bindera PAGEREF _Toc534792748 \h
362
HYPERLINK \l "_Toc534792749"
Przykłady automatyzacji Bindera PAGEREF _Toc534792749 \h
362
HYPERLINK \l "_Toc534792750"
Zabezpieczanie dokumentów, szablonów i kodu programu PAGEREF _Toc534792750 \h
363
HYPERLINK \l "_Toc534792751"
Rozdział 20. Użycie Visual Basic z Accessem PAGEREF _Toc534792751 \h
364
HYPERLINK \l "_Toc534792752"
Tworzenie komponentów ActiveX PAGEREF _Toc534792752 \h
364
HYPERLINK \l "_Toc534792753"
Czym są komponenty ActiveX PAGEREF _Toc534792753 \h
364
HYPERLINK \l "_Toc534792754"
Różnice między ActiveX EXE i ActiveX DLL PAGEREF _Toc534792754 \h
365
HYPERLINK \l "_Toc534792755"
Tworzenie komponentu ActiveX PAGEREF _Toc534792755 \h
365
HYPERLINK \l "_Toc534792756"
Kompilowanie biblioteki DLL PAGEREF _Toc534792756 \h
367
HYPERLINK \l "_Toc534792757"
Użycie komponentu ActiveX cSound PAGEREF _Toc534792757 \h
368
HYPERLINK \l "_Toc534792758"
Użycie komponentu w innych aplikacjach PAGEREF _Toc534792758 \h
369
HYPERLINK \l "_Toc534792759"
Dystrybucja komponentów ActiveX PAGEREF _Toc534792759 \h
369
HYPERLINK \l "_Toc534792760"
Instalowanie komponentu PAGEREF _Toc534792760 \h
369
HYPERLINK \l "_Toc534792761"
Tworzenie programu instalacyjnego przy użyciu Package and Deployment Wizard PAGEREF _Toc534792761 \h
369
HYPERLINK \l "_Toc534792762"
Rozprowadzanie plików przy użyciu kreatora Package and Deployment Wizard PAGEREF _Toc534792762 \h
373
HYPERLINK \l "_Toc534792763"
Wpisy w rejestrze PAGEREF _Toc534792763 \h
375
HYPERLINK \l "_Toc534792764"
Zgodność komponentów PAGEREF _Toc534792764 \h
375
HYPERLINK \l "_Toc534792765"
Komponent obsługi błędów PAGEREF _Toc534792765 \h
376
HYPERLINK \l "_Toc534792766"
Dane modułu obsługi błędów PAGEREF _Toc534792766 \h
377
HYPERLINK \l "_Toc534792767"
Komponent cError PAGEREF _Toc534792767 \h
377
HYPERLINK \l "_Toc534792768"
Tworzenie formantów ActiveX PAGEREF _Toc534792768 \h
377
HYPERLINK \l "_Toc534792769"
Rodzaje formantów ActiveX PAGEREF _Toc534792769 \h
377
HYPERLINK \l "_Toc534792770"
Atrybuty formantów ActiveX PAGEREF _Toc534792770 \h
378
HYPERLINK \l "_Toc534792771"
Tworzenie programowych formantów ActiveX PAGEREF _Toc534792771 \h
378
HYPERLINK \l "_Toc534792772"
Utworzenie projektu dla formantu ActiveX PAGEREF _Toc534792772 \h
378
HYPERLINK \l "_Toc534792773"
Tworzenie interfejsu PAGEREF _Toc534792773 \h
379
HYPERLINK \l "_Toc534792774"
Ustawianie właściwości projektu PAGEREF _Toc534792774 \h
380
HYPERLINK \l "_Toc534792775"
Zapisywanie projektu PAGEREF _Toc534792775 \h
380
HYPERLINK \l "_Toc534792776"
Dodawanie metod i zdarzeń PAGEREF _Toc534792776 \h
380
HYPERLINK \l "_Toc534792777"
Użycie kreatora ActiveX Control Interface Wizard PAGEREF _Toc534792777 \h
380
HYPERLINK \l "_Toc534792778"
Dodajemy kod do formantu ActiveX PAGEREF _Toc534792778 \h
382
HYPERLINK \l "_Toc534792779"
Wywoływanie zdarzenia PAGEREF _Toc534792779 \h
382
HYPERLINK \l "_Toc534792780"
Użycie zdarzenia ReadProperties PAGEREF _Toc534792780 \h
383
HYPERLINK \l "_Toc534792781"
Testowanie formantu ActiveX w Visual Basicu PAGEREF _Toc534792781 \h
383
HYPERLINK \l "_Toc534792782"
Użycie formantu Timer na formularzu Accessa PAGEREF _Toc534792782 \h
385
HYPERLINK \l "_Toc534792783"
Tworzenie wielu formantów Timer PAGEREF _Toc534792783 \h
385
HYPERLINK \l "_Toc534792784"
Rozprowadzanie formantu ActiveX Timer PAGEREF _Toc534792784 \h
386
HYPERLINK \l "_Toc534792785"
Tworzenie okna właściwości PAGEREF _Toc534792785 \h
386
HYPERLINK \l "_Toc534792786"
Użycie okna właściwości PAGEREF _Toc534792786 \h
387
HYPERLINK \l "_Toc534792787"
Użycie formantu Timer w innych aplikacjach PAGEREF _Toc534792787 \h
387
HYPERLINK \l "_Toc534792788"
Tworzenie formantów ActiveX interfejsu użytkownika PAGEREF _Toc534792788 \h
387
HYPERLINK \l "_Toc534792789"
Tworzenie interfejsu użytkownika PAGEREF _Toc534792789 \h
387
HYPERLINK \l "_Toc534792790"
Ustawienie właściwości projektu PAGEREF _Toc534792790 \h
388
HYPERLINK \l "_Toc534792791"
Zapisywanie projektu PAGEREF _Toc534792791 \h
388
HYPERLINK \l "_Toc534792792"
Testowanie formantu na formularzu Visual Basica PAGEREF _Toc534792792 \h
388
HYPERLINK \l "_Toc534792793"
Użycie formantu cSlider na formularzu Accessa PAGEREF _Toc534792793 \h
388
HYPERLINK \l "_Toc534792794"
Dystrybucja formantu ActiveX cSlider PAGEREF _Toc534792794 \h
389
HYPERLINK \l "_Toc534792795"
Użycie formantu cSlider w innych aplikacjach PAGEREF _Toc534792795 \h
389
HYPERLINK \l "_Toc534792796"
Tworzenie instalacyjnego pakietu internetowego PAGEREF _Toc534792796 \h
389
HYPERLINK \l "_Toc534792797"
Użycie formantu cSlider na stronie WWW PAGEREF _Toc534792797 \h
391
HYPERLINK \l "_Toc534792798"
Część VII Zagadnienia wielodostępu PAGEREF _Toc534792798 \h
393
HYPERLINK \l "_Toc534792799"
Rozdział 21. Zagadnienia wielodostępu, serwer plików, blokowanie PAGEREF _Toc534792799 \h
394
HYPERLINK \l "_Toc534792800"
Konflikty PAGEREF _Toc534792800 \h
394
HYPERLINK \l "_Toc534792801"
Konfiguracja PAGEREF _Toc534792801 \h
395
HYPERLINK \l "_Toc534792802"
Access i blokady Jet PAGEREF _Toc534792802 \h
395
HYPERLINK \l "_Toc534792803"
Omówienie blokowania PAGEREF _Toc534792803 \h
396
HYPERLINK \l "_Toc534792804"
Blokowanie stron kontra blokowanie rekordów PAGEREF _Toc534792804 \h
396
HYPERLINK \l "_Toc534792805"
Plik LDB PAGEREF _Toc534792805 \h
397
HYPERLINK \l "_Toc534792806"
Optymistyczne i pesymistyczne blokowanie rekordów PAGEREF _Toc534792806 \h
397
HYPERLINK \l "_Toc534792807"
Blokowanie optymistyczne PAGEREF _Toc534792807 \h
397
HYPERLINK \l "_Toc534792808"
Blokowanie pesymistyczne PAGEREF _Toc534792808 \h
397
HYPERLINK \l "_Toc534792809"
Blokowanie rekordów PAGEREF _Toc534792809 \h
398
HYPERLINK \l "_Toc534792810"
Właściwość RecordLocks w interfejsie związanym PAGEREF _Toc534792810 \h
398
HYPERLINK \l "_Toc534792811"
Metody blokowania silnika Jet PAGEREF _Toc534792811 \h
398
HYPERLINK \l "_Toc534792812"
Określanie stanu blokad PAGEREF _Toc534792812 \h
398
HYPERLINK \l "_Toc534792813"
Sprawdzanie blokad PAGEREF _Toc534792813 \h
400
HYPERLINK \l "_Toc534792814"
Użycie blokowania stron PAGEREF _Toc534792814 \h
401
HYPERLINK \l "_Toc534792815"
Obsługa błędów blokowania PAGEREF _Toc534792815 \h
401
HYPERLINK \l "_Toc534792816"
Ustawienia blokowania Accessa PAGEREF _Toc534792816 \h
401
HYPERLINK \l "_Toc534792817"
Konflikty zapisu PAGEREF _Toc534792817 \h
401
HYPERLINK \l "_Toc534792818"
Zablokowany rekord PAGEREF _Toc534792818 \h
402
HYPERLINK \l "_Toc534792819"
Transakcje PAGEREF _Toc534792819 \h
402
HYPERLINK \l "_Toc534792820"
Blokady Oracle/SQL Server PAGEREF _Toc534792820 \h
403
HYPERLINK \l "_Toc534792821"
Rozdział 22. Replikacja i JRO PAGEREF _Toc534792821 \h
404
HYPERLINK \l "_Toc534792822"
Kiedy użyć replikacji PAGEREF _Toc534792822 \h
404
HYPERLINK \l "_Toc534792823"
Kiedy nie używać replikacji PAGEREF _Toc534792823 \h
405
HYPERLINK \l "_Toc534792824"
Przystosowanie bazy do replikacji PAGEREF _Toc534792824 \h
405
HYPERLINK \l "_Toc534792825"
Replikacja przy użyciu aktówki PAGEREF _Toc534792825 \h
405
HYPERLINK \l "_Toc534792826"
Użycie interfejsu użytkownika PAGEREF _Toc534792826 \h
406
HYPERLINK \l "_Toc534792827"
Wybór między obiektami lokalnymi i replikowanymi PAGEREF _Toc534792827 \h
408
HYPERLINK \l "_Toc534792828"
Planowanie topologii replikacji PAGEREF _Toc534792828 \h
409
HYPERLINK \l "_Toc534792829"
Wybór schematu sterowanego PAGEREF _Toc534792829 \h
411
HYPERLINK \l "_Toc534792830"
Synchronizacja bezpośrednia PAGEREF _Toc534792830 \h
411
HYPERLINK \l "_Toc534792831"
Synchronizacja pośrednia PAGEREF _Toc534792831 \h
411
HYPERLINK \l "_Toc534792832"
Wybór schematu niesterowanego PAGEREF _Toc534792832 \h
411
HYPERLINK \l "_Toc534792833"
Jet i model obiektowy replikacji PAGEREF _Toc534792833 \h
411
HYPERLINK \l "_Toc534792834"
Poznajemy JRO PAGEREF _Toc534792834 \h
412
HYPERLINK \l "_Toc534792835"
Opis metod i właściwości JRO PAGEREF _Toc534792835 \h
413
HYPERLINK \l "_Toc534792836"
Właściwość ActiveConnection PAGEREF _Toc534792836 \h
413
HYPERLINK \l "_Toc534792837"
Właściwość ConflictFunction PAGEREF _Toc534792837 \h
413
HYPERLINK \l "_Toc534792838"
Właściwość ConflictTables PAGEREF _Toc534792838 \h
415
HYPERLINK \l "_Toc534792839"
Właściwość DesignMasterID PAGEREF _Toc534792839 \h
416
HYPERLINK \l "_Toc534792840"
Obiekty repliki PAGEREF _Toc534792840 \h
416
HYPERLINK \l "_Toc534792841"
Właściwość ReplicaID PAGEREF _Toc534792841 \h
416
HYPERLINK \l "_Toc534792842"
Właściwość ReplicaType PAGEREF _Toc534792842 \h
416
HYPERLINK \l "_Toc534792843"
Właściwość RetentionPeriod PAGEREF _Toc534792843 \h
416
HYPERLINK \l "_Toc534792844"
Właściwość Visibility PAGEREF _Toc534792844 \h
417
HYPERLINK \l "_Toc534792845"
Metoda CreateReplica PAGEREF _Toc534792845 \h
417
HYPERLINK \l "_Toc534792846"
Metoda GetObjectReplicability PAGEREF _Toc534792846 \h
418
HYPERLINK \l "_Toc534792847"
Metoda MakeReplicable PAGEREF _Toc534792847 \h
418
HYPERLINK \l "_Toc534792848"
Metoda PopulatePartial PAGEREF _Toc534792848 \h
419
HYPERLINK \l "_Toc534792849"
Metoda SetObjectReplicability PAGEREF _Toc534792849 \h
420
HYPERLINK \l "_Toc534792850"
Metoda Synchronize PAGEREF _Toc534792850 \h
420
HYPERLINK \l "_Toc534792851"
Kolekcja Filters PAGEREF _Toc534792851 \h
421
HYPERLINK \l "_Toc534792852"
Właściwość Count PAGEREF _Toc534792852 \h
421
HYPERLINK \l "_Toc534792853"
Metoda Item PAGEREF _Toc534792853 \h
421
HYPERLINK \l "_Toc534792854"
Metoda Append PAGEREF _Toc534792854 \h
422
HYPERLINK \l "_Toc534792855"
Metoda Delete PAGEREF _Toc534792855 \h
422
HYPERLINK \l "_Toc534792856"
Metoda Refresh PAGEREF _Toc534792856 \h
422
HYPERLINK \l "_Toc534792857"
Obiekt Filter PAGEREF _Toc534792857 \h
422
HYPERLINK \l "_Toc534792858"
Właściwość FilterCriteria PAGEREF _Toc534792858 \h
422
HYPERLINK \l "_Toc534792859"
Właściwość FilterType PAGEREF _Toc534792859 \h
422
HYPERLINK \l "_Toc534792860"
Właściwość TableName PAGEREF _Toc534792860 \h
423
HYPERLINK \l "_Toc534792861"
Rozdział 23. Bezpieczeństwo PAGEREF _Toc534792861 \h
424
HYPERLINK \l "_Toc534792862"
Elementy bezpieczeństwa PAGEREF _Toc534792862 \h
424
HYPERLINK \l "_Toc534792863"
Zabezpieczenie bazy danych hasłem PAGEREF _Toc534792863 \h
424
HYPERLINK \l "_Toc534792864"
System bezpieczeństwa grupy roboczej PAGEREF _Toc534792864 \h
425
HYPERLINK \l "_Toc534792865"
Tworzenie grupy roboczej PAGEREF _Toc534792865 \h
426
HYPERLINK \l "_Toc534792866"
Użytkownicy i grupy PAGEREF _Toc534792866 \h
427
HYPERLINK \l "_Toc534792867"
Omówienie domyślnych ustawień użytkowników i grup PAGEREF _Toc534792867 \h
428
HYPERLINK \l "_Toc534792868"
Tworzenie użytkowników PAGEREF _Toc534792868 \h
428
HYPERLINK \l "_Toc534792869"
Ustawianie i zmiana hasła użytkownika PAGEREF _Toc534792869 \h
429
HYPERLINK \l "_Toc534792870"
Tworzenie grup PAGEREF _Toc534792870 \h
429
HYPERLINK \l "_Toc534792871"
Przypisywanie użytkowników do grup PAGEREF _Toc534792871 \h
430
HYPERLINK \l "_Toc534792872"
Rozróżnianie między domyślnymi i specjalnymi grupami i użytkownikami PAGEREF _Toc534792872 \h
430
HYPERLINK \l "_Toc534792873"
Poznajemy uprawnienia PAGEREF _Toc534792873 \h
430
HYPERLINK \l "_Toc534792874"
Tworzenie systemu bezpieczeństwa przy użyciu opcji startowych PAGEREF _Toc534792874 \h
432
HYPERLINK \l "_Toc534792875"
Zagadnienia bezpieczeństwa przy użyciu replikacji PAGEREF _Toc534792875 \h
432
HYPERLINK \l "_Toc534792876"
Ochrona podzielonych baz danych PAGEREF _Toc534792876 \h
433
HYPERLINK \l "_Toc534792877"
Opcja With OwnerAccess PAGEREF _Toc534792877 \h
434
HYPERLINK \l "_Toc534792878"
Bezpieczeństwo systemu klient-serwer PAGEREF _Toc534792878 \h
434
HYPERLINK \l "_Toc534792879"
Zarządzanie użytkownikami PAGEREF _Toc534792879 \h
434
HYPERLINK \l "_Toc534792880"
Wyliczanie grup i użytkowników oraz wyświetlanie przynależności PAGEREF _Toc534792880 \h
435
HYPERLINK \l "_Toc534792881"
Identyfikacja bieżących użytkowników za pomocą ADOX PAGEREF _Toc534792881 \h
436
HYPERLINK \l "_Toc534792882"
Wyszukiwanie użytkowników z pustym hasłem PAGEREF _Toc534792882 \h
437
HYPERLINK \l "_Toc534792883"
Ustawianie i usuwanie hasła PAGEREF _Toc534792883 \h
438
HYPERLINK \l "_Toc534792884"
Zarządzanie grupami PAGEREF _Toc534792884 \h
438
HYPERLINK \l "_Toc534792885"
Zarządzanie właściwością obiektów PAGEREF _Toc534792885 \h
438
HYPERLINK \l "_Toc534792886"
Zarządzanie wieloma aplikacjami PAGEREF _Toc534792886 \h
438
HYPERLINK \l "_Toc534792887"
Użycie SQL PAGEREF _Toc534792887 \h
439
HYPERLINK \l "_Toc534792888"
Create PAGEREF _Toc534792888 \h
439
HYPERLINK \l "_Toc534792889"
Add User PAGEREF _Toc534792889 \h
439
HYPERLINK \l "_Toc534792890"
Grant/Revoke PAGEREF _Toc534792890 \h
439
HYPERLINK \l "_Toc534792891"
Drop PAGEREF _Toc534792891 \h
440
HYPERLINK \l "_Toc534792892"
Zabezpieczanie bazy danych krok po kroku PAGEREF _Toc534792892 \h
440
HYPERLINK \l "_Toc534792893"
Częste błędy bezpieczeństwa PAGEREF _Toc534792893 \h
440
HYPERLINK \l "_Toc534792894"
Część VIII Publikowanie w sieci za pomocą Accessa 2000 PAGEREF _Toc534792894 \h
442
HYPERLINK \l "_Toc534792895"
Rozdział 24. Konfiguracja serwera WWW dla publikowania w sieci WWW PAGEREF _Toc534792895 \h
443
HYPERLINK \l "_Toc534792896"
Środowisko programistyczne a środowisko produkcyjne PAGEREF _Toc534792896 \h
443
HYPERLINK \l "_Toc534792897"
Wybór platformy PAGEREF _Toc534792897 \h
444
HYPERLINK \l "_Toc534792898"
Personal Web Server i Peer Web Services PAGEREF _Toc534792898 \h
444
HYPERLINK \l "_Toc534792899"
Internet Information Server PAGEREF _Toc534792899 \h
444
HYPERLINK \l "_Toc534792900"
Co to jest Option Pack PAGEREF _Toc534792900 \h
445
HYPERLINK \l "_Toc534792901"
Uruchomienie serwera WWW PAGEREF _Toc534792901 \h
446
HYPERLINK \l "_Toc534792902"
Instalacja PAGEREF _Toc534792902 \h
446
HYPERLINK \l "_Toc534792903"
NT Option Pack dla Windows 95/98 PAGEREF _Toc534792903 \h
446
HYPERLINK \l "_Toc534792904"
Dostępne komponenty instalacji PAGEREF _Toc534792904 \h
446
HYPERLINK \l "_Toc534792905"
Opcje instalacji: minimalna, typowa i niestandardowa PAGEREF _Toc534792905 \h
448
HYPERLINK \l "_Toc534792906"
Microsoft Transaction Server 2.0 PAGEREF _Toc534792906 \h
449
HYPERLINK \l "_Toc534792907"
Co to jest broker transakcji? PAGEREF _Toc534792907 \h
449
HYPERLINK \l "_Toc534792908"
Zarządzanie i konfiguracja serwera WWW PAGEREF _Toc534792908 \h
450
HYPERLINK \l "_Toc534792909"
Personal Web Manager PAGEREF _Toc534792909 \h
450
HYPERLINK \l "_Toc534792910"
Microsoft Management Console PAGEREF _Toc534792910 \h
451
HYPERLINK \l "_Toc534792911"
Konfiguracja Internet Information Server PAGEREF _Toc534792911 \h
451
HYPERLINK \l "_Toc534792912"
Zabezpieczanie aplikacji WWW PAGEREF _Toc534792912 \h
455
HYPERLINK \l "_Toc534792913"
Różnice pomiędzy witryną a katalogiem wirtualnym PAGEREF _Toc534792913 \h
456
HYPERLINK \l "_Toc534792914"
Co to jest IUSER ? PAGEREF _Toc534792914 \h
457
HYPERLINK \l "_Toc534792915"
Typ systemu plików PAGEREF _Toc534792915 \h
457
HYPERLINK \l "_Toc534792916"
Struktura katalogów i wymagane uprawnienia PAGEREF _Toc534792916 \h
458
HYPERLINK \l "_Toc534792917"
ASP/HTML - położenie i uprawnienia PAGEREF _Toc534792917 \h
458
HYPERLINK \l "_Toc534792918"
Bazy danych - położenie i uprawnienia PAGEREF _Toc534792918 \h
459
HYPERLINK \l "_Toc534792919"
Rozdział 25. Przenoszenie Accessa 2000 do sieci WWW za pomocą komponentów sieciowych Office PAGEREF _Toc534792919 \h
460
HYPERLINK \l "_Toc534792920"
Czym są komponenty sieciowe Office PAGEREF _Toc534792920 \h
460
HYPERLINK \l "_Toc534792921"
Co potrafią komponenty sieciowe Office PAGEREF _Toc534792921 \h
461
HYPERLINK \l "_Toc534792922"
Wymagane licencje na użycie komponentów sieciowych PAGEREF _Toc534792922 \h
461
HYPERLINK \l "_Toc534792923"
Użycie formantu Office Arkusz PAGEREF _Toc534792923 \h
461
HYPERLINK \l "_Toc534792924"
Rozpoczynamy PAGEREF _Toc534792924 \h
461
HYPERLINK \l "_Toc534792925"
Użycie formantu w Accessie PAGEREF _Toc534792925 \h
462
HYPERLINK \l "_Toc534792926"
Użycie formantu Office Wykres PAGEREF _Toc534792926 \h
463
HYPERLINK \l "_Toc534792927"
Rozpoczynamy PAGEREF _Toc534792927 \h
464
HYPERLINK \l "_Toc534792928"
Użycie formantu w Accessie PAGEREF _Toc534792928 \h
464
HYPERLINK \l "_Toc534792929"
Użycie formantu Office Tabela przestawna PAGEREF _Toc534792929 \h
465
HYPERLINK \l "_Toc534792930"
Rozpoczynamy PAGEREF _Toc534792930 \h
466
HYPERLINK \l "_Toc534792931"
Rozdział 26. Użycie stron dostępu do danych PAGEREF _Toc534792931 \h
467
HYPERLINK \l "_Toc534792932"
Czym są strony dostępu do danych? PAGEREF _Toc534792932 \h
467
HYPERLINK \l "_Toc534792933"
Architektura oraz wymagania stron dostępu do danych PAGEREF _Toc534792933 \h
467
HYPERLINK \l "_Toc534792934"
Tworzenie Twojej pierwszej strony dostępu do danych PAGEREF _Toc534792934 \h
468
HYPERLINK \l "_Toc534792935"
Oglądanie strony dostępu do danych PAGEREF _Toc534792935 \h
470
HYPERLINK \l "_Toc534792936"
Tworzenie interaktywnych odnośników PAGEREF _Toc534792936 \h
471
HYPERLINK \l "_Toc534792937"
Łączenie komponentów sieciowych Office z DAP PAGEREF _Toc534792937 \h
472
HYPERLINK \l "_Toc534792938"
Dodanie komponentu sieciowego Arkusz Excel PAGEREF _Toc534792938 \h
473
HYPERLINK \l "_Toc534792939"
Dodanie komponentu sieciowego Wykres PAGEREF _Toc534792939 \h
473
HYPERLINK \l "_Toc534792940"
Skrypty w stronach dostępu do danych PAGEREF _Toc534792940 \h
474
HYPERLINK \l "_Toc534792941"
Zmiana źródła danych w trakcie działania strony PAGEREF _Toc534792941 \h
475
HYPERLINK \l "_Toc534792942"
Rozdział 27. Publikowanie w sieci przy użyciu Accessa 2000 i Active Server Pages PAGEREF _Toc534792942 \h
477
HYPERLINK \l "_Toc534792943"
Użycie Active Server Pages PAGEREF _Toc534792943 \h
477
HYPERLINK \l "_Toc534792944"
Architektura Active Server Pages PAGEREF _Toc534792944 \h
478
HYPERLINK \l "_Toc534792945"
Active Server Pages kontra CGI PAGEREF _Toc534792945 \h
478
HYPERLINK \l "_Toc534792946"
Uruchomienie stron ASP PAGEREF _Toc534792946 \h
478
HYPERLINK \l "_Toc534792947"
Rozpoczynamy pracę z Active Server Pages PAGEREF _Toc534792947 \h
479
HYPERLINK \l "_Toc534792948"
Konstrukcja kodu ASP PAGEREF _Toc534792948 \h
480
HYPERLINK \l "_Toc534792949"
Ograniczenia eksportu stron ASP PAGEREF _Toc534792949 \h
481
HYPERLINK \l "_Toc534792950"
Active Server Pages PAGEREF _Toc534792950 \h
481
HYPERLINK \l "_Toc534792951"
Silnik ASP PAGEREF _Toc534792951 \h
481
HYPERLINK \l "_Toc534792952"
Skrypty wykonywane na serwerze PAGEREF _Toc534792952 \h
481
HYPERLINK \l "_Toc534792953"
Użycie VBScript na stronach ASP PAGEREF _Toc534792953 \h
484
HYPERLINK \l "_Toc534792954"
Obiekty aplikacji i sesji PAGEREF _Toc534792954 \h
486
HYPERLINK \l "_Toc534792955"
Użycie obiektu aplikacji PAGEREF _Toc534792955 \h
486
HYPERLINK \l "_Toc534792956"
Użycie obiektu sesji PAGEREF _Toc534792956 \h
486
HYPERLINK \l "_Toc534792957"
Użycie obiektów żądań i odpowiedzi PAGEREF _Toc534792957 \h
486
HYPERLINK \l "_Toc534792958"
Obiekt Response PAGEREF _Toc534792958 \h
487
HYPERLINK \l "_Toc534792959"
Response.Redirect PAGEREF _Toc534792959 \h
487
HYPERLINK \l "_Toc534792960"
Response.Write PAGEREF _Toc534792960 \h
487
HYPERLINK \l "_Toc534792961"
Obiekt Request PAGEREF _Toc534792961 \h
487
HYPERLINK \l "_Toc534792962"
Plik global.asa PAGEREF _Toc534792962 \h
487
HYPERLINK \l "_Toc534792963"
Przykłady użycia obiektów ASP PAGEREF _Toc534792963 \h
488
HYPERLINK \l "_Toc534792964"
Użycie ADO w aplikacjach ASP PAGEREF _Toc534792964 \h
489
HYPERLINK \l "_Toc534792965"
Przykład: tworzenie strony WWW dostępnej dla członków grupy PAGEREF _Toc534792965 \h
490
HYPERLINK \l "_Toc534792966"
Publikacja w sieci z Accessa 2000 przy użyciu XML PAGEREF _Toc534792966 \h
494
HYPERLINK \l "_Toc534792967"
Podstawy XML PAGEREF _Toc534792967 \h
494
HYPERLINK \l "_Toc534792968"
Programowe tworzenie pliku XML PAGEREF _Toc534792968 \h
496
HYPERLINK \l "_Toc534792969"
Tworzenie wykresów przy użyciu formantu Wykres PAGEREF _Toc534792969 \h
498
Część I
Projektowanie bazy danych
Rozdział 1.
Co nowego w Accessie 2000
W tym rozdziale:
Nowy interfejs użytkownika.
Zmiany w VBE.
Strony dostępu do danych.
Podarkusze danych.
Autokorekta nazw.
ADO jako domyślny system dostępu do danych.
Współpraca online.
Access jako interfejs użytkownika dla SQL Server.
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 producentó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.
Nowy interfejs użytkownika
Pierwszą rzeczą, jaką zauważysz po uruchomieniu Accessa 2000, jest jego nowy interfejs. Microsoft postanowił ujednolicić graficzny interfejs użytkownika we wszystkich swoich aplikacjach, włączając w to Access. Okno bazy danych posiada pasek zawierający grupy obiektów dostępnych dla programisty, co upodabnia Access do programu Microsoft Outlook. Nie jest to tylko zabieg kosmetyczny. Dzięki temu możesz tworzyć dowolne, logiczne grupy, ze skrótami do właściwych obiektów. Przykładowo, możesz utworzyć grupę „Zamówienia i Sprzedaż”, a następnie w obrębie tej grupy umieścić skróty do kwerend, formularzy, raportów, stron, makr i modułów powiązanych z zamówieniami i sprzedażą. Dzięki temu unikniesz czasochłonnych poszukiwań wśród wszystkich obiektów. Tę przydatną cechę ilustruje rysunek 1.1.
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.
W przeciwieństwie do VB wszystkie moduły utworzone w tym osobnym, zintegrowanym środowisku przechowywane są w pliku .MDB wraz ze wszystkimi obiektami bazy danych. Jednakże, możesz z łatwością importować i eksportować pliki typu *.bas, *.cls i *.frm do i z Accessa 2000.
Rysunek 1.3. Środowisko VBE jest teraz w dużym stopniu konfigurowalne |
|
Strony dostępu do danych
Możliwości, jakie Access stwarza programistom, również zostały rozszerzone o nowy obiekt - strony dostępu do danych (DAP XE "DAP" - ang. Data Access Pages). Umożliwiają one użytkownikom tworzenie stron sieci Web, powiązanych z danymi w taki sam sposób jak formularze lub raporty. Wystarczy umieścić na stronie kilka specjalnych formantów, ustawić kilka właściwości, zapisać je w intra- bądź Internecie, a inni użytkownicy będą mogli korzystać z nich za pomocą przeglądarki. Strony te mogą zawierać również pogrupowane dane (ang. Grouped Data Access Pages). Takie strony umożliwiają użytkownikom interaktywne zagłębienie się w dane przy użyciu przeglądarki. Może okazać się, że strony dostępu do danych są najszybszym sposobem na współdzielenie danych i zestawu funkcji interfejsu z użytkownikami. Strony te mogą także być alternatywnym sposobem rozpowszechniania plików typu MDE.
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 |
|
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.
ADO jako domyślny system
dostępu do danych
Gdy spojrzymy do wewnątrz, w Accessie zmieniono domyślny system dostępu do danych. Zamiast znanych, lecz pamięciochłonnych obiektów Data Access (DAO XE "DAO" ), do pobierania i zarządzania danymi Access używa obiektów Active Data (ADO XE "ADO" ). Korzyści płynące z ADO są bardzo liczne: prostszy interfejs, płaska struktura, użycie tych samych technik i interfejsów między podobnymi źródłami danych, możliwość pobierania i zarządzania danymi z innych źródeł niż tylko programy typu RDBMS, a także zapowiedź większej wydajności i rozszerzonych opcji. Mimo iż Access współpracuje z obiektami DAO, Microsoft nie będzie już rozbudowywał tego systemu. Tak więc, jeśli nie miałeś jeszcze okazji pracować z ADO, szczegółowy opis tego zagadnienia znajdziesz w rozdziale 6. „Wprowadzenie do obiektów danych ActiveX” i 7. „Zaawansowane ADO”.
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.
Access jako interfejs użytkownika dla SQL Server
Bez wątpienia najciekawszą z nowych opcji Accessa 2000 jest nowy typ projektu aplikacji: Microsoft Access Project XE "Microsoft Access Project" (*.adp). Projektom tym, będącym zapowiedzią nadchodzącej ery Accessa, poświęcimy w tej książce dużo miejsca. Access był zawsze zdalną bazą danych działającą w ramach środowiska serwera plików i był ograniczony do ilości
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:
Określenie wymagań.
Architektura.
Planowanie rozwoju.
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 |
|
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 faza wymagań jest tak ważna?
Prawidłowo zidentyfikowane i przeanalizowane wymagania pozwolą zmniejszyć liczbę nieprzewidzianych zmian, które trzeba będzie później wprowadzić. Eksperci z przemysłu software'owego stwierdzili, że koszty ponoszone na wprowadzanie zmian, rosną o mnożnik zawierający się między 5 a 10, podczas przejścia na każdy kolejny etap procesu rozwoju. Przykładowo, jeśli klient zauważy błąd w wymaganiach, który zostanie poprawiony w fazie wymagań, zmiana zajmie godzinę. Jeśli błąd zostanie zauważony dopiero po włączeniu tej opcji w projekt, wprowadzenie zmiany zajmie 10 godzin. Jeśli element ten został już zintegrowany i przetestowany z resztą aplikacji, naprawa błędu może potrwać 50 godzin. Jeśli problem wynikł dopiero po dostarczeniu aplikacji do klienta, jego rozwiązanie zajmie blisko 100 godzin.
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.
Odnalezienie rzeczywistego problemu
Określenie wymagań należy rozpocząć od ustalenia zakresu aplikacji. Nie ulega wątpliwości, że klient ma problem, który, jak sądzi, może być rozwiązany za pomocą programu komputerowego. Jednak klient nie zawsze może właściwie zdefiniować ów problem.
|
|||
|
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.
Oto kilka pomocnych wskazówek:
Gdy poszukujesz kluczowych informacji o funkcjonowaniu procesu, nigdy nie opieraj się na opiniach innych osób.
Wielokrotnie w procesach handlowych można wyróżnić oficjalny sposób, w jaki proces powinien przebiegać oraz sposób, w jaki rzeczywiście przebiega. Powinieneś poznać obydwa.
Bądź otwarty i słuchaj uważnie. Pierwsze Twoje pomysły (i klienta) na rozwiązanie problemu powinny zostać zapisane i odłożone, dopóki nie zostaną potwierdzone za pomocą obserwacji i analiz.
W tabeli 2.1 znajdziesz przykłady typowych wymagań klientów.
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ę przetwarzaniem 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 XE "diagram 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.
|
|||
|
Każdy diagram procesu powinien być tworzony na dużej kartce papieru, a nie przy użyciu komputera. Rysowanie na papierze zabiera mniej czasu i umożliwia większą interakcję. Jest także mniej uciążliwe i bardziej czytelne. Aby ograniczyć konieczne poprawki i zmiany, jako elementów procesu można używać naklejanych karteczek. Po otrzymaniu ostatecznego diagramu procesu można go przerysować przy użyciu Microsoft Worda 2000 lub Visio. |
Identyfikacja zakresu projektu
Współpracuj z klientem, aby właściwie określić zakres aplikacji. Pamiętaj, że chodzi tu o zakres długoterminowy, a nie koncentrujący się na tej fazie projektu.
W przykładzie ze sprawozdaniem o kosztach programiści i decydenci doszli do porozumienia co do zakresu aplikacji. Uzgodnili, iż aplikacja powinna zautomatyzować rozliczanie zaliczek, zgłaszanie zapotrzebowania na delegacje oraz cały proces zgłaszania kosztów począwszy od pojawienia się zapotrzebowania na delegację u pracownika, aż
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:
Czy opisuje potrzebę, czy raczej sposób jej realizacji?
Czy może być zweryfikowane po jego wprowadzeniu?
Czy jest jednoznaczne?
Czy w pełni opisuje potrzebę?
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.
|
|||
|
Utwórz bazę danych zawierającą wszystkie wymagania. Dla każdego z wymagań dołącz numer identyfikacyjny, typ, opis, datę, źródło, zysk oraz sposób weryfikacji wymagania po jego implementacji, wagę i inne. |
Tabela 2.1.
Typy wymagań
Typ wymagań |
Opis |
Przykład |
Funkcjonalne |
Wymagania te opisują żądane funkcje lub cechy oraz zasady handlowe, które ich dotyczą |
Użytkownik będzie w stanie nadać priorytet klienta na: Krytyczny, Wysoki, Średni, Niski |
Tabela 2.1.
Typy wymagań (ciąg dalszy)
Typ wymagań |
Opis |
Przykład |
Wydajność |
Wymagania dotyczące wydajności zawierają: Szybkość, Czas reakcji, Pojemność, Wielkość bazy danych |
Baza danych powinna poprzez zakładową sieć LAN obsługiwać do 20 użytkowników, ze standardowym czasem odpowiedzi wysokości 200 ms |
Bezpieczeństwo |
Wymagania dotyczące bezpieczeństwa obejmują ograniczenia w użytkowaniu i dostępie do opcji aplikacji oraz danych |
Wszyscy użytkownicy muszą się do aplikacji logować. Każdy użytkownik będzie członkiem jednej z następujących grup bezpieczeństwa: Użytkownik, Administrator, Menedżer |
Skalowalność |
Skalowalność dotyczy zdolności do powiększania ilości danych, użytkowników, witryn lub częstotliwości zbierania danych |
Aplikacja musi obsługiwać 50 aktualnych użytkowników oraz dodatkowo 50 użytkowników, którzy zostaną dołączeni na przestrzeni najbliższych dwóch lat |
Rozszerzalność |
Wymagania dotyczące rozszerzalności charakteryzują zdolność do poszerzania aplikacji o dodatkowe opcje w kolejnych wersjach. |
Aplikacja będzie tak skonstruowana i zaimplementowana, aby można było dodać obsługę faktur klientów |
Konfigurowalność |
Konfigurowalność mierzy łatwość, z jaką parametry aplikacji mogą być zmieniane przez klienta, bez konieczności ingerencji zespołu programistów |
Administrator będzie miał możliwość corocznego uaktualniania stawek ubezpieczeniowych |
Kompatybilność |
Kompatybilność to zdolność aplikacji do jej instalowania i funkcjonowania w różnych środowiskach sprzętowych i programowych, a także do interakcji z innymi aplikacjami |
Program będzie zainstalowany w systemach Win95, Win98 i Win NT 4.0 Workstation, z minimum 8MB pamięci oraz 200MB dostępnej przestrzeni dyskowej |
Dostępność |
Dostępność służy do określenia ile godzin lub jaką część czasu aplikacja jest w stanie wykonywać pracę, do której została skonstruowana |
Administrator bazy musi zarezerwować sobie czas od 22:00 do 23:00 wieczorem, aby sporządzać zapasowe kopie danych |
Łatwość w użyciu |
Wymaganie to służy określeniu stopnia, w jakim przeszkoleni użytkownicy mogą korzystać z systemu |
Aplikacja zawiera moduł Pomoc online, który obejmuje 90% jej opcji |
Łatwość w nauce |
Wymaganie to jest miarą łatwości oraz czasu, w jakim użytkownicy są w stanie poznać system |
Po jednodniowym treningu użytkownicy powinni być w wystarczającym stopniu zaznajomieni z aplikacją, aby rozpocząć z nią pracę |
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 XE "ASP" i XML XE "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 XE "SQL Server" czy Oracle XE "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 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.
|
|||
|
Programiści powinni posiadać stałą kontrolę nad czasem. Najlepszym sposobem na wykształcenie w sobie umiejętności przewidywania jest porównywanie własnych prognoz z czasem, który jest faktycznie niezbędny do wykonania danej czynności. |
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 XE "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 |
|
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:
Układ formularza (na przykład: rozmieszczenie formantów, rozmiar i proporcje formularza).
Grupowanie pól (na przykład: wklęsłe ramki czy proste linie)
Określenie dla pól i etykiet rodzaju, koloru, rozmiaru i stylu czcionki (pogrubienie/kursywa)
Nazwy oraz sposoby reagowania przycisków (na przykład: Anuluj, Zamknij czy Zakończ?)
Wskazanie użytkownikowi, czy formularze są przeznaczone tylko do odczytu, czy też można je edytować.
Sposób komunikacji z użytkownikiem (na przykład: zwięzły bądź rozwlekły).
|
|||
|
Zamiast tracić czas na pisanie oficjalnego dokumentu, utwórz po prostu bazę danych z zestawem formularzy i raportów zawierającym przykłady najczęściej używanych formantów. Plik ten może być rozwijającym się przykładem preferowanych przez Ciebie stylów interfejsu użytkownika. Jeszcze lepiej będzie, jeśli oprócz formularzy zamieścisz tam także kod opisujący poruszanie się po formularzach i inne powszechnie używane zestawy funkcji. Formularze te posłużą jako standardowe szablony dla twoich produktów. |
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ą.
|
|||
|
Nie trać czasu na spory, co jest w danym momencie najlepsze - po prostu wybierz dobrą metodę, przekonaj do niej innych i trzymaj się jej. |
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 XE "standardy nazewnictwa"
Poniższy przykład korzysta z przyrostkowego standardu nazewnictwa i czynności wykonywane przez programistę są oczywiste.
DblLodgingTotal = Double(intNights) * dblRate
Natomiast kolejny przykład nie jest już taki oczywisty.
x = Text7 * Text12
Oto kluczowe elementy większości standardów nazewnictwa:
przedrostki obiektowe (na przykład: txt, cbo, lst...);
przedrostki typów danych (na przykład: sgl, int, str...);
typowe nazwy baz (na przykład: użycie Acct lub Account);
typowe skrótowce (na przykład: stat = status).
Standardy kodowania XE "standardy kodowania"
Oto przykłady elementów, które możesz chcieć określić w standardach kodowania:
komentarze nagłówków;
komentarze w kodzie;
wcięcia;
rozmiar podprocedur i funkcji (na przykład: maksymalnie 60 wierszy);
użycie instrukcji Option Explicit.
|
|||
|
Istnieją określone standardy nazewnictwa dotyczące rozwoju aplikacji w środowiskach Access/VBA/Office/VB. Dwa najpopularniejsze to konwencje nazewnictwa Reddicka i Leszynskiego. Zaletą korzystania z tych konwencji jest to, że nowi programiści zatrudnieni przez Twoją firmę mogą już je znać. Poza tym, konwencje te są używane w fachowej prasie, książkach oraz w materiałach szkoleniowych. Wybierz jedną z nich i konsekwentnie się jej trzymaj. |
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.
Dziel i rządź XE "dziel i rządź" : działania w fazie Konstrukcja
Istnieje wiele podejść do fazy Konstrukcja XE "konstrukcja" . Możesz zacząć od wdrożenia najtrudniejszych i najbardziej niepewnych części aplikacji lub rozpocząć od tych najłatwiejszych części. Możesz także zacząć od formularzy i zakończyć na raportach. Mimo iż wszystkie te podejścia są prawidłowe, wielu programistów osiągnęło sukces, zaczynając od stworzenia solidnych podstaw i na nich budując resztę aplikacji. Podstawy najczęściej składają się z projektu tabel, nakreślenia głównych formularzy i często używanych modułów i funkcji. Działanie takie ma na celu stworzenie działającego rdzenia, stanowiącego podstawę działania każdego z programistów. Jeśli chodzi o formularze, dobrze jest poświęcić trochę czasu na stworzenie jednego lub dwóch, które później posłużą jako szablony dla następnych.
|
|||
|
Nadeszła odpowiednia chwila, by zainwestować w tworzenie komponentów, które będziesz mógł wykorzystywać wielokrotnie. Wysiłek włożony w zaprojektowanie i testowanie tych elementów zacznie zwracać się z każdym ich użyciem. |
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). |
||
|
|||
|
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 zaktualizować nazwę edycji/kompilacji wyświetlaną przez aplikację.
Rysunek 2.6. Tworzenie kompilacji |
|
|||
|
Pamiętaj o wstawieniu aktualnej nazwy edycji i kompilacji w startowym formularzu aplikacji oraz formularzu „O programie” otwieranym z poziomu menu Pomoc. To ułatwia określenie, w której wersji znaleziono błąd. Przykładowo: „Wersja 1.0 edycja 89 - 2/24/2000”. |
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 XE "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.
|
|||
|
Jeśli nie korzystasz z Visual SourceSafe, procedury archiwizacyjne stają się jeszcze ważniejsze. |
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.
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ą projektu do czasu, gdy wyjaśnione zostaną wszelkie wątpliwości.
|
|||
|
Doskonałym sposobem na opisanie niestandardowych algorytmów jest umieszczenie w procedurze lub funkcji komentarzy w pseudokodzie XE "pseudokod" . Pseudokod jest to uproszczony kod VBA, dołączony jako komentarz opisujący implementowany w danym miejscu kodu proces. Dokładna składnia nie jest ważna. Opisujesz jedynie algorytm użyty w VBA. Poniższy przykład przedstawia użycie pseudokodu w nagłówku procedury. Public Sub ProcessAllUpdates() ' Comments : Get the updated mail from MAPI Inbox, ' unattatch it and update the current database. ' Parameters : <none> ' Returns : <none> ' Created : Tuesday, July 27, 1999 11:44 PM by Joe Developer ' Pseudo Code : ' -------------------------------------------------------------- ' Sub ProcessUpdates() ' UpdateCount = 0 ' UnattatchAllUpdates() ' Open a recordset from tblDownloadReceivedResults ' For each <Update file> in Recordset ' ProcessOneUpdate() ' If succesful Then ' Delete Update file ' Increment(UpdateCount) ' Next ' -------------------------------------------------------------- |
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.
|
|||
|
Konsekwentne używanie standardów nazewnictwa i kodowania znacznie ułatwia i skraca proces kontroli kodu programu. Pozwala także uniknąć dyskusji na temat przewagi jednych stylów nad innymi. |
||
|
|||
|
Jeśli jesteś samotnym programistą (chodzi nam oczywiście o to, że nie pracujesz 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 XE "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.
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.
Oto przykłady testów, które powinieneś wykonać:
Przetestuj zachowanie aplikacji, gdy tabele są puste.
Sprawdź różne rozdzielczości ekranu.
Przetestuj oba ustawienia rozmiaru czcionki we Właściwościach ekranu systemu Windows (Małe czcionki i Duże czcionki).
Zastosuj kilka różnych zestawów kolorów we Właściwościach ekranu systemu Windows.
Sprawdź, jak wyglądają wydruki na kilku różnych drukarkach (uwzględnij zwłaszcza markę i model drukarki posiadanej przez klienta).
Przetestuj aplikację zarówno z włączoną jak i wyłączoną opcją Autoukrywanie paska Narzędzi systemu Windows.
Sprawdź, czy pomoc „Co to jest?”, etykietki narzędzi i pasek stanu odpowiadają właściwym polom.
Sprawdź kolejność klawisza Tab na każdym formularzu.
Upewnij się, że klawisze skrótu na każdym formularzu są identyczne.
Przetestuj na każdym formularzu działanie klawiszy domyślnych (Enter i Esc).
Sprawdź jednolitość stylów na każdym formularzu i raporcie.
Testowanie instalacji i konfiguracji
W rzeczywistości rzadko się zdarza, by komputery użytkowników były takie same jak komputery programistów. Używają one innego oprogramowania, ilość pamięci jest różna, często korzystają z dziwnych drukarek i jeszcze dziwniejszych kart graficznych. Innymi słowy, komputery użytkowników czynią życie programistów ciekawszym. Ta różnorodność konfiguracji ma duży wpływ na łatwość instalacji aplikacji, a także na jej późniejsze działanie. Jeśli to możliwe, postaraj się przetestować aplikację w najgorszym środowisku, jakie możesz sobie wyobrazić. W przypadku większych projektów rozważ wykorzystanie do tego celu wyspecjalizowanej firmy. Oferują one laboratoria przepełnione zarówno nowym, jak i starszym sprzętem oraz oprogramowaniem.
|
|||
|
Instalację i sprawdzenie funkcjonowania aplikacji przeprowadź zarówno na „czystym”, jak i na „brudnym” komputerze. Przez „czysty” komputer rozumiemy taki, gdzie na niedawno sformatowanym dysku zainstalowano tylko system operacyjny i niezbędne oprogramowanie (tak jak na fabrycznie nowym komputerze). „Brudny” komputer to taki, na którym w dłuższym okresie czasu instalowano wiele wersji różnych aplikacji. Testowanie aplikacji na obu rodzajach komputerów pozwoli odnaleźć nieoczekiwane problemy związane z plikami typu DLL, ustawieniami rejestru, szablonami i innymi wspomagającymi plikami. Do szybkiego odtwarzania różnych konfiguracji komputera warto użyć oprogramowania służącego do sporządzania obrazu dysku. |
||
|
|||
|
Nie oczekuj, że przeprowadzenie testów pozwoli Ci odkryć wszystkie błędy. Większość aplikacji jest zbyt skomplikowana, aby można było przetestować każdą możliwą kombinację wartości danych i ścieżek wykonywania. Dlatego właśnie tak ważne są wcześniejsze działania, czyli określenie wymagań, planowanie oraz kontrole projektu i aplikacji. Stanowią one pierwszy i jednocześnie najlepszy sposób na wyeliminowanie błędów. Dużo łatwiej jest zapobiegać usterkom przez dokładne projektowanie niż odnajdywać je i usuwać później. |
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.
Każda z poniższych czynności może ukazać istniejące usterki:
Kontrola projektu i aplikacji - usterki odkryte w fazie kontroli to zarówno niezgodność z przyjętymi standardami jak i usterki w samym projekcie.
Kontrola dokumentów - podczas kontroli dokumentów można odkryć wiele potencjalnych usterek. Może brakować dokumentu zawierającego wymagania lub mogą być one niewłaściwie zdefiniowane. Dokumentacja projektu może nie obejmować wszystkich wymagań lub po prostu zawierać błędy.
Testowanie XE "testowanie" - najczęstszymi usterkami wykrywanymi w tej fazie są błędy w kodzie programu. Można wówczas również odkryć błędy w dokumentacji, gdyż to właśnie na jej podstawie testy powinny się odbywać.
Obsługa klienta - podczas testowania wersji beta lub po dostarczeniu aplikacji do klienta błędy stwierdzone przez użytkowników zostaną przekazane bezpośrednio do programisty lub personelu zajmującego się obsługą klientów. System zbierania informacji o błędach powinien także dawać użytkownikom możliwość zgłaszania pomysłów ulepszenia aplikacji.
Obsługa błędów - jeśli używasz automatycznego zgłaszania błędów, które opisaliśmy w rozdziale 13. „Profesjonalna obsługa błędów”, informacje o błędach mogą być przesyłane pocztą elektroniczną lub zapisywane w specjalnym pliku na komputerze klienta.
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.
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.
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.
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”.
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
Pole danych |
Opis |
Unikatowy identyfikator |
Można używać kolejnych liczb. Jeśli informacje o usterkach wprowadza kilka osób, upewnij się, że liczby te się nie powtarzają |
Opis usterki |
Opisz wygląd potencjalnego błędu, łącznie z kodami błędów i sposobem działania, który do jego wystąpienia prowadzi |
Znalezione przez |
Nazwisko osoby zgłaszającej usterkę |
Kiedy znaleziono |
Data i godzina odkrycia |
Oczekiwane rezultaty |
Co miało się stać? |
Tabela 2.3.
Informacje o usterkach (ciąg dalszy)
Pole danych |
Opis |
Gdzie odnaleziono |
Sporządź listę dokumentów i elementów programu, których zgłaszane usterki mogą dotyczyć (na przykład: dokument zawierający informacje o wymaganiach, dokumentacja dotycząca architektury, nazwa formularza, nazwa raportu, nazwa modułu) |
Wersja |
Określ wersję dokumentu lub bazy danych (na przykład: Beta 2.1, kompilacja 36, dokument dotyczący wymagań z dnia 29/06/2000 i tak dalej) |
Oprogramowanie i konfiguracja komputera |
Sporządź listę istotnych informacji dotyczących konfiguracji komputera, jak rozdzielczość ekranu, ilość wyświetlanych kolorów, ilość pamięci, wolna przestrzeń dyskowa, system operacyjny, jednocześnie używane oprogramowanie i tak dalej |
Waga |
Jak poważny jest wykryty problem? Patrz tabela 2.4 |
Częstotliwość |
Jak często błąd występuje? Patrz tabela 2.5 |
Powtarzalność |
Jak łatwo doprowadzić do ponownego wystąpienia błędu? Patrz tabela 2.6 |
Ważność |
Jak ważne jest naprawienie tej usterki? Patrz tabela 2.7 |
Osoba odpowiedzialna |
Który z programistów zajmie się rozwiązaniem tego problemu? |
Status rozwiązania problemu |
Jaki jest status usterki? Patrz tabela 2.8 |
Opis rozwiązania problemu |
W jaki sposób „poprawiono”? Dlaczego „odłożono na później” lub „zignorowano”? |
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. |
Nieciągła |
Usterka zwykle występuje, ale nie zawsze. |
Raz |
Usterkę zaobserwowano raz, nie przeprowadzono dalszych testów powtarzalności. |
Niepowtarzalna |
Usterkę zaobserwowano raz i nie udało jej się powtórzyć. |
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 |
||||
|
|||||
|
Możesz usprawnić proces rozwoju, odnajdując przyczyny leżące u podstaw powstawania usterek. Określając, jak i gdzie powstała usterka, możesz znaleźć sposób na uniknięcie tego w przyszłości. Najczęstsze z takich przyczyn to: błędy w projektowaniu i kodowaniu, braki w wymaganiach lub niejednoznaczne ich zdefiniowanie, a także niewystarczające przeszkolenie programistów i klientów. |
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 zamierzonych 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 XE "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.
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.
|
|||
|
Access różni się od innych narzędzi programistycznych, gdyż zapisuje wszystkie obiekty w jednym pliku typu MDB. Wiele z dostępnych w sprzedaży narzędzi do kontroli wersji jest w stanie śledzić jedynie osobne pliki. Ograniczenie to sprawia, iż każdorazowo zachodzi konieczność pobierania i zwracania całej bazy danych. Dość nieporęczne, prawda? Upewnij się, że narzędzie, którego zakup rozważasz, wspiera Microsoft Accessa, śledząc jego pojedyncze obiekty. |
Rozdział 3.
Projekt bazy danych
i normalizacja
W tym rozdziale:
Relacyjne systemy zarządzania bazami danych.
Teoria projektowania relacyjnego.
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.
Relacyjne systemy zarządzania bazami danych (RDBMS)
W książkach i czasopismach, jakie czytasz, wielokrotnie możesz spotkać się z pojęciem - relacyjne systemy zarządzania bazami danych (ang. Relational Database Managment Systems - RDBMS XE "RDBMS" ). Możesz zapytać, co Access ma wspólnego z modelem RDBMS. Model ten został stworzony w 1970 roku przez pracownika firmy IBM, dr E.F. Codda. Celem ustalonych w modelu RDBMS zasad było uniezależnienie funkcjonowania interfejsów od zmian dokonywanych w modelu danych. Produkty RDBMS używają wspólnych elementów danych, takich jak CustomerID, aby połączyć wiersze w dwóch różnych tabelach, między którymi zachodziła relacja, a także używają tych pól w sprzężeniu. Istnieje 13 zasad, które produkt musi spełnić, aby można go było nazwać Relacyjnym Systemem Zarządzania Bazami Danych. Niektórzy z krytyków Accessa twierdzą, że nie
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.
Zasady relacyjne dr Codda
Access spełnia wszystkie z 13 zasad relacyjnych XE "zasady relacyjne" dr Codd XE "Codd dr" a. Tabela 3.1 zawiera nazwę i opis każdej z nich, a także komentarz o zastosowaniu tych zasad w Accessie.
Tabela 3.1.
Zasady relacyjne dr Codda
Zasada dr Codda |
Nazwa zasady |
Opis |
Komentarz dotyczący Accessa |
Zasada 0. |
Zasada tworzenia XE "zasada tworzenia" |
Każdy program typu RDBMS musi być w stanie zarządzać bazami danych jedynie za pomocą swoich zdolności relacyjnych. Jeśli system działa na zasadach operowania danymi rekord-po-rekordzie, nie możemy go nazywać systemem w pełni relacyjnym |
Access był pierwszą na rynku, działającą w systemie Windows bazą danych, która przestrzegała tej zasady. Access, w przeciwieństwie do niektórych systemów, nie stosuje numeracji rekordów |
Zasada 1. |
Informacja XE "informacja" |
Wszystkie dane w relacyjnej bazie przedstawiane są jako wartości w tabelach. Dane nie mogą być przechowywane w żaden inny sposób |
Access przechowuje dane jako tabele, w aparacie baz danych Jet |
Zasada 2. |
Gwarantowany dostęp XE "gwarantowany dostęp" |
Poprzez użycie kombinacji wartości klucza podstawowego, nazwy tabeli i nazwy kolumny, musi istnieć dostęp do dowolnej partii danych |
Access przestrzega tej zasady poprzez użycie kluczy głównych. Jeśli sam nie utworzysz w tabeli klucza głównego, Access zażąda, abyś to zrobił |
Zasada 3. |
Brakujące informacje XE "brakujące informacje" |
Program musi obsługiwać wartości Null. Wartości te przedstawiają brakujące lub bezużyteczne informacje |
Access obsługuje wartości Null dla brakujących informacji. Jednocześnie pozwala uniknąć wprowadzania wartości Null poprzez użycie pól wymaganych. |
Zasada 4. |
Katalog systemu XE "katalog systemu" |
Opis bazy danych lub „katalog” na poziomie logicznym jako wartości tabelaryczne. Język relacyjny (SQL) powinien móc działać na projekcie bazy danych w taki sam sposób, w jaki działa na danych przechowywanych w strukturze |
Katalog ten umieszczony jest w aparacie bazy danych Microsoft Jet. Do stworzenia zapytania dotyczącego katalogu systemu możesz użyć obiektu Active Data o nazwie OpenSchema (patrz rozdział 5. „Jet 4.0 - silnik baz danych Microsoft). SQL DDL daje Ci możliwość tworzenia tabel, indeksów itp. |
Tabela 3.1.
Zasady relacyjne dr Codda (ciąg dalszy)
Zasada dr Codda |
Nazwa zasady |
Opis |
Komentarz dotyczący Accessa |
Zasada 5. |
Kompletny język XE "kompletny język" |
Program typu RDBMS musi obsługiwać jasno określony język do operowania danymi (SQL), który w pełni obsługuje definiowanie i operowanie danymi, określanie widoku, ograniczenia integralności, ograniczenia transakcyjne i autoryzację |
Access (Jet) w pełni obsługuje SQL dla operowania danymi, określania widoków (kwerendy wybierające) i ograniczeń integralności (Okno Relacje i komenda UTWÓRZ OGRANICZENIE) |
Zasada 6. |
Uaktualnianie widoków XE "uaktualnianie widoków" |
Wszystkie widoki mogą być systemowo uaktualnione. W prawdziwym programie typu RDBMS, większość (ale nie wszystkie) widoków może być uaktualniana |
Access był pierwszą bazą danych, umożliwiającą użycie kwerend aktualizujących |
Zasada 7. |
Ustawianie poziomu uaktualnień XE "ustawianie poziomu uaktualnień" |
Program typu RDBMS musi nie tylko potrafić pobierać zestawy danych. Musi także potrafić wstawiać, aktualizować i usuwać dane jako zestaw relacyjny |
Access spełnia to wymaganie poprzez użycie kwerend funkcjonalnych |
Zasada 8. |
Fizyczna niezależność danych XE "fizyczna niezależność danych" |
Dane i aplikacja muszą być od siebie fizycznie niezależne. Odpowiedni program typu RDBMS lub „optymalizator” powinny móc śledzić fizyczne zmiany w danych. Przykładowo, aplikacje RDBMS nie powinny ulegać modyfikacji na skutek dodania bądź usunięcia z tabeli indeksu |
Access umożliwia Ci modyfikowanie obiektów bazy danych, bez konieczności dokonywania zmian w reszcie aplikacji. Jet zawiera także logiczny aparat przechowywania |
Zasada 9. |
Logiczna niezależność danych XE "logiczna niezależność danych" |
Gdy to tylko możliwe, aplikacja powinna być niezależna od zmian dokonywanych w tabelach podstawowych. Przykładowo, gdy tabele są łączone w widok, nie powinny następować zmiany w kodzie |
Gdy tworzysz w Accessie kwerendę, możesz ją z łatwością połączyć z formularzem lub raportem, jakby to była tabela |
Zasada 10. |
Niezależność integralności XE "niezależność integralności" |
Integralność danych musi być definiowalna w języku relacyjnym i przechowywana w katalogu. Ograniczenia w integralności danych mogą być wbudowane w aplikację, jednakże podejście to jest obce dla modelu relacyjnego. W modelu relacyjnym integralność powinna być naturalną cechą projektu bazy danych. |
Mimo iż Microsoft nie umieścił w dokumentacji informacji na temat przechowywania integralności przez aparat Jet, możesz tworzyć zasady integralności poprzez SQL. Jet przechowuje te informacje w projekcie bazy danych jako część katalogu. |
Tabela 3.1.
Zasady relacyjne dr Codda (ciąg dalszy)
Zasada dr Codda |
Nazwa zasady |
Opis |
Komentarz dotyczący Accessa |
Zasada 11. |
Niezależność podziału XE "niezależność podziału" |
Zdolności programu typu RDBMS nie będą ograniczone dzięki umieszczeniu jego komponentów w osobnych bazach danych. |
Ponieważ silnik Jet przechowuje swoje zasady integralności danych na poziomie aparatu, pozostałe jego komponenty nie mają wpływu na zasady integralności. |
Zasada 12. |
Brak podwersji XE "brak podwersji" |
Jeśli program RDBMS posiada język typu „jeden rekord jednocześnie”, język ten nie może być używany do omijania zasad integralności lub ograniczeń języka relacyjnego. Dlatego też nie wystarczy, by zasady relacyjne zarządzały programem typu RDBMS, ale muszą być prawami nadrzędnymi. |
Access umożliwia Ci użycie obiektów DAO i ADO, aby operować jednym rekordem jednocześnie poprzez aktualizowalne zestawy rekordów. Dzięki tym narzędziom do operowania danymi nie możesz naruszyć 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.
Teoria projektowania relacyjnego
Teoria projektowania relacyjnego, opracowana przez dr Codda w celu rozbudowania zasad relacyjnych, składa się z następujących kategorii:
Tabele i niepowtarzalność.
Klucze obce i domeny.
Relacje.
Normalizacja danych.
Zasady integralności.
Korzyści z używania modelu relacyjnego
Korzystając z teorii projektowania relacyjnego uzyskujesz zalety płynące z lat poszukiwań najlepszego sposobu zarządzania danymi. Niektóre z nich, jakie otrzymasz w wyniku normalizacji bazy danych, to:
Pewność integralności danych.
Skuteczność przechowywania danych.
Możliwość rozwoju bazy danych.
Zachowanie bazy danych jest przewidywalne, gdyż jest ona zgodna z wielokrotnie przetestowanymi zasadami.
Ponieważ przestrzegasz tych zasad, inni projektanci baz danych mogą dużo łatwiej zrozumieć Twój projekt.
Okno Relacje staje się samo w sobie dokumentem.
Zmiany w schemacie bazy danych są łatwe we wdrożeniu.
Tabele i niepowtarzalność
Kiedy tworzysz aplikacje bazy danych, każda tabela XE "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 XE "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 XE "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:
Wartości całkowite;
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. |
Klucze obce i domeny
Klucz główny staje się bardzo ważny, gdy chcesz go użyć w innej tabeli. Sytuację taką przedstawiono na rysunku 3.2.
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 XE "klucz obcy" , 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.
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 XE "relacja" . Przez relacje rozumiemy zasady obsługiwane na poziomie silnika bazy danych (patrz: Zasada 4. dr Codda). Access wyróżnia trzy różne typy relacji:
relacja jeden-do-jednego;
relacja jeden-do-wielu;
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 XE "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 |
|
Relacja jeden-do-wielu
Najpopularniejszy typ relacji, relacja jeden-do-wielu XE "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 |
|
Relacja wiele-do-wielu
O relacji wiele-do-wielu XE "relacja 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 |
|
Podarkusze danych
Jedną z nowych opcji Accessa 2000 są podarkusze danych XE "podarkusz 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 |
|
Rysunek 3.7. Właściwości podarkusza danych |
|
Tabela 3.2.
Właściwości podarkusza danych
Nazwa właściwości |
Opis |
Nazwa podarkusza danych |
Nazwa kwerendy, która posłuży do wypełnienia podarkusza danych |
Podrzędne pola łączące |
Pole w podrzędnej tabeli (lub kwerendzie), które ma być połączone z polem w aktualnej tabeli |
Nadrzędne pola łączące |
Pole w aktualnej tabeli, które ma być połączone z polem w podrzędnej tabeli lub kwerendzie |
Wysokość podarkusza danych |
Wysokość podarkusza danych (w calach) |
Rozwinięty podarkusz danych |
Wartość tak/nie, określająca, czy podczas otwierania tabeli podarkusz danych ma być domyślnie rozwinięty |
Normalizacja danych XE "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:
Pierwsza postać normalna.
Druga postać normalna.
Trzecia postać normalna.
Pierwsza postać normalna XE "pierwsza postać normalna"
W pierwszej postaci normalnej wszystkie kolumny w tabeli muszą posiadać wartości atomowe XE "wartość atomowa" . Innymi słowy, każde pole może zawierać tylko jedną wartość, a nie listę wartości lub powtarzającą się grupę danych. Wiele kartotekowych baz danych przechowuje dane w ten sposób, co znacznie utrudnia ich przeszukiwanie.
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 |
|
Rysunek 3.9. Tabela w pierwszej postaci normalnej, ale nie w drugiej postaci normalnej |
|
Druga postać normalna XE "druga postać normalna"
Mimo iż tabela przedstawiona na rysunku 3.9 jest w pierwszej postaci normalnej, nie jest jednak w drugiej postaci normalnej. Mówimy, że tabela jest w drugiej postaci normalnej, gdy jest w pierwszej postaci normalnej i jednocześnie każde z jej pól nie będących polem klucza głównego jest w pełni zależne od całego klucza głównego. Innymi słowy, część informacji może być przechowywana w innej tabeli i pobierana z niej poprzez odnośnik. Spójrz na tabelę na rysunku 3.9. Klucz główny składa się z ContactID, ContactInfoID i ContactInfo. Czy kolumna ContactName zależy od części klucza: ContactInfoID i ContactInfo? Nie, gdyż jest zależna od pola ContactID. Aby przekształcić tę tabelę do drugiej postaci normalnej, należy informacje o kliencie umieścić w osobnej tabeli odnośnika i utworzyć pomiędzy tabelami przedstawioną na rysunku 3.10 relację jeden-do-wielu. Tabele te są teraz w drugiej postaci normalnej.
Trzecia postać normalna XE "trzecia postać normalna"
Mimo iż tabele na rysunku 3.10 są w pierwszej i drugiej postaci normalnej, nie są jednak w trzeciej postaci normalnej. Z tabelą w trzeciej postaci normalnej mamy do czynienia, gdy wszystkie pola, nie będące polami klucza głównego, są wzajemnie zależne.
Rysunek 3.10. Tabela jest w drugiej postaci normalnej, ale nie w trzeciej 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.
Rysunek 3.11. Tabele w trzeciej postaci normalnej |
|
Korzyści z normalizacji XE "normalizacja:korzyści"
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.
Zasady integralności danych
Podczas normalizowania danych powinieneś również uwzględnić zasady integralności danych. Większość z zastosowanych zasad będzie zależeć od zdefiniowanych relacji XE "relacja" . Podczas określania relacji możesz dodatkowo ustawić kaskadowe aktualizowanie i usuwanie rekordów.
Ustawienie aktualizowania kaskadowego XE "aktualizacja kaskadowa" 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 XE "usuwanie kaskadowe" 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:
Kwerendy w Accesie 2000.
Tworzenie zaawansowanych kwerend.
Użycie kwerend.
Właściwości kwerendy.
Siatka QBE.
Panel tabel.
Siatka kwerendy.
Kwerendy podsumowujące.
Użycie kwerend krzyżowych.
Użycie kwerend parametrycznych.
Kwerendy przekazujące.
Kwerendy definiujące dane.
Optymalizowanie kwerend.
Kwerendy XE "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 XE "SQL" lub graficznego interfejsu użytkownika nazywanego tabelą QBE XE "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 XE "Oracle" i Microsoft SQL Server XE "SQL Server" ). Są one najszybszym i najpewniejszym sposobem efektywnej interakcji z danymi w relacyjnej bazie danych.
Rozdział ten poświęcony jest zaawansowanym odmianom tego potężnego narzędzia.
Kwerendy w Accesie 2000
Dokładna konstrukcja bazy danych w połączeniu z możliwościami, jakie dają kwerendy, umożliwiają zaspokojenie części najprostszych, codziennych potrzeb w zarządzaniu danymi. Jednocześnie mogą pomóc w rozwiązaniu najbardziej złożonych problemów, gdyż relacyjna struktura pozwala na logiczne grupowanie danych. Dzięki temu, pomiędzy powiązanymi obiektami można tworzyć użyteczne połączenia. W relacyjnej bazie danych masz wgląd w te dane, których w danym momencie potrzebujesz.
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, 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 zaawansowanych kwerend
Kwerendy, podobnie jak tabele i formularze, są obiektami bazy danych i przechowywane są w znajdującej się w głównym oknie bazy grupie Kwerendy (skróty do nich mogą być przechowywane w dowolnej, stworzonej przez programistę grupie).
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 zabezpieczeń bazy (temat ten został szczegółowo omówiony w rozdziale 23., „Bezpieczeństwo”). Na dole okna znajdują się dwa pola wyboru. Zaznaczenie pola Ukryty XE "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 XE "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”.
|
||
|
Innym sposobem na ukrycie kwerendy przed uczestnikami jest umieszczenie na początku jej nazwy liter USYS (np. USYS_myquery). Aby przeglądać takie obiekty, musisz w menu Narzędzia otworzyć okno dialogowe Opcje i zaznaczyć pole wyboru Obiekty systemowe. |
|
|
||
|
Microsoft również ukrywa różne obiekty, używając do tego celu przedrostka MSYS. Nie możesz dopuścić, by użytkownicy uzyskali dostęp do tych tabel systemowych, bo ich zmiana może doprowadzić do uszkodzenia bazy. Również programiści powinni unikać używania ich, gdyż Microsoft nie gwarantuje umieszczenia ich w kolejnej wersji. Upewnij się, że tabele systemowe są ukryte, zanim przekażesz bazę do rąk użytkowników. |
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 XE "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 XE "relacja" 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:
Opis - taka sama właściwość dostępna jest z poziomu obiektu.
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.
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.
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.
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.
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 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.
Ź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.
Ź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.
Blokowanie rekordów XE "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 rekordem, 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.
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.
Czas oczekiwania ODBC XE "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.
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.
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.
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.
Nazwa podarkusza danych XE "podarkusz 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ę.
Podrzędne pole łączące (NOWOŚĆ) - jest to pole podarkusza danych, najczęściej pole klucza, które odpowiada polu w głównej kwerendzie.
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.
Wysokość podarkusza danych (NOWOŚĆ) - wartość w calach, określająca wysokość wyświetlanego podarkusza danych.
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.
|
||
|
Mimo iż możliwym jest aktualizowanie danych poprzez podarkusz, zmiany te są uwzględniane w obliczeniach kwerendy dopiero po jej ponownym uruchomieniu. |
|
|
||
|
Czas oczekiwania ODBC jest mierzony w sekundach i domyślnie ustawiony na 60 sekund. Jednakże ustawienie tej właściwości na zero nie oznacza, iż kwerenda będzie ciągle „prosiła” o odpowiedź. Ustawienie takie powoduje wyłączenie tej opcji, co sprawia, że nie zostanie wyświetlony żaden komunikat o przekroczeniu czasu oczekiwania. |
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ę XE "relacja" . Relacje ustawione w oknie dialogowym Relacje są tu wyświetlane automatycznie. Funkcja ta nazywa się Autosprzęganie XE "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.
|
||
|
Tworzenie relacji w kwerendzie lub pozwolenie na to Accessowi odnosi skutek jedynie dla działania tej kwerendy. Dla osiągnięcia lepszych i bardziej wiarygodnych efektów ustalaj relacje między obiektami w oknie Relacje. Dzięki temu, w razie potrzeby będziesz mógł bez problemów włączyć wymuszanie więzów integralności lub kaskadowe aktualizowanie i usuwanie rekordów. |
Umieszczanie tabeli lub kwerendy w panelu tabel
Umieszczanie tabel lub kwerend w panelu tabel jest proste. Gdy po raz pierwszy tworzysz kwerendę i przechodzisz do widoku Projekt kwerendy, Access „poprosi” Cię o wybranie tabel lub kwerendy, których będziesz chciał używać. Wyświetlone okno dialogowe posiada trzy zakładki, jedną dla tabel, jedną dla kwerend i jedną dla obu typów obiektów. Jeśli musisz dodać tabelę lub kwerendę po zamknięciu tego okna dialogowego, możesz je przywrócić, wybierając z menu Kwerenda opcję Pokaż tabelę. Możesz także użyć znajdującego się na pasku narzędzi przycisku Pokaż tabelę.
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.
Tworzenie relacji w panelu tabel
Jeśli nie utworzyłeś relacji między tabelami na poziomie bazy danych poprzez okno Relacje, możesz utworzyć je ad hoc, z poziomu kwerendy. Aby to zrobić, kliknij nazwę pola w jednej tabeli i przeciągnij je na pole w drugiej tabeli. Pomiędzy tymi polami powstanie linia sprzężenia XE "linia sprzężenia" i od tego momentu będą się one zachowywać, jakby istniała między nimi relacja.
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:
Sprzężenie wewnętrzne XE "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.
Lewe sprzężenie zewnętrzne XE "sprzężenie zewnętrzne" (ang. outer join XE "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.
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ć nieprzyporzą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 XE "osierocone rekordy" . Rekordy zagubione są zazwyczaj niewidoczne 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.
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 |
|
Wydruk 4.1. Wyrażenie SQL dla kwerendy z rysunku 4.4
SELECT TOP 10 Klienci.NazwaFirmy, Count(Zamówienia.IDzamówienia) AS PoliczOfIDzamówienia
FROM Klienci INNER JOIN Zamówienia ON Klienci.IDklienta = Zamówienia.IDklienta
GROUP BY Klienci.NazwaFirmy
ORDER BY Count(Zamówienia.IDzamówienia);
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.
Porównaj te wyniki z wynikami na rysunku 4.5 i wydrukiem 4.2.
Rysunek 4.5. Dwunastu klientów z najmniejszą ilością zamówień w sprzężeniu zewnętrznym |
|
Wydruk 4.2. Wyrażenie SQL dla kwerendy z rysunku 4.5
SELECT TOP 10 Klienci.NazwaFirmy, Count(Zamówienia.IDzamówienia) AS PoliczOfIDzamówienia
FROM Klienci LEFT JOIN Zamówienia ON Klienci.IDklienta = Zamówienia.IDklienta
GROUP BY Klienci.NazwaFirmy
ORDER BY Count(Zamówienia.IDzamówienia);
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ń |
|
Wydruk 4.3. Wyrażenie SQL dla kwerendy z rysunku 4.6
SELECT Klienci.NazwaFirmy, Zamówienia.IDzamówienia
FROM Klienci LEFT JOIN Zamówienia ON Klienci.IDklienta = Zamówienia.IDklienta
WHERE (((Zamówienia.IDzamówienia) Is Null));
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 kwerend 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 |
|
Wydruk 4.4. Wyrażenie SQL dla kwerendy z rysunku 4.7
SELECT TOP 10 Klienci.NazwaFirmy, Count(Zamówienia.IDzamówienia) AS PoliczOfIDzamówienia
FROM Klienci INNER JOIN Zamówienia ON Klienci.IDklienta = Zamówienia.IDklienta
GROUP BY Klienci.NazwaFirmy
ORDER BY Count(Zamówienia.IDzamówienia);
Rysunek 4.8. Dziesięciu\ klientów z najmniejszą ilością zamówień w sprzężeniu wewnętrznym |
|
Wydruk 4.5. Wydruk SQL dla kwerendy z rysunku 4.8
SELECT TOP 10 Klienci.NazwaFirmy, Count(Zamówienia.IDzamówienia) AS PoliczOfIDzamówienia
FROM Klienci LEFT JOIN Zamówienia ON Klienci.IDklienta = Zamówienia.IDklienta
GROUP BY Klienci.NazwaFirmy
ORDER BY Count(Zamówienia.IDzamówienia);
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 XE "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.
Umieszczanie pól w siatce kwerendy
Umieszczanie pól w kwerendzie może się odbywać na kilka sposobów:
Dwukrotne kliknięcie - dwukrotne kliknięcie nazwy pola w tabeli powoduje przeniesienie go do pierwszego wolnego miejsca w siatce kwerendy.
Kliknij i przeciągnij - możesz umieszczać pola, klikając i przeciągając je do dowolnej kolumny w siatce kwerendy.
Kliknięcie z klawiszem Ctrl - kliknięcie jednego pola, przytrzymanie klawisza Ctrl i kliknięcie innych pól w tej samej tabeli umożliwi Ci przeniesienie ich wszystkich jednocześnie do siatki kwerendy.
Dwukrotne kliknięcie paska z nazwą tabeli - dwukrotne kliknięcie paska z nazwą tabeli spowoduje zaznaczenie wszystkich jej pól. Przeciągnij zaznaczone w ten sposób pola do siatki kwerendy. Możesz również użyć kliknięcia z klawiszem Ctrl, aby z usunąć niektóre z zaznaczonych pól.
Gwiazdka - pierwsza pozycja w tabeli to znak gwiazdki. Dwukrotne kliknięcie lub przeciągnięcie go do siatki kwerendy spowoduje utworzenie pojedynczego wpisu w siatce, lecz w rezultatach kwerendy widoczne będą wszystkie pola z tabeli.
Wybierz pola w siatce kwerendy - pierwszy wiersz siatki kwerendy wskazuje, które pole jest aktualnie używane. Umieszczenie punktu wprowadzania w tym wierszu umożliwi Ci wybór pola. Uważaj, aby przez przypadek nie wybrać pola z niewłaściwej tabeli. Następny wiersz siatki kwerendy, Tabela, może znacznie ułatwić korzystanie z tego sposobu.
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.
Określanie kolejności sortowania, wyświetlania rezultatów oraz wybór kryteriów kwerendy
Wiersz Sortuj XE "sortowanie" umożliwia Ci określenie sposobu, w jaki kwerenda sortuje wiersze rezultatów. Każde z pól możesz sortować Rosnąco, Malejąco lub pozostawić je bez sortowania. Gdy do sortowania wybrane jest więcej niż jedno pole, o kolejności sortowanie decyduje kolejność pól od lewej do prawej.
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.
|
||
|
Możesz wielokrotnie dodawać pola do tabeli QBE, wyłączać opcję Pokaż i kontrolować sortowanie zestawu rezultatów bez zmieniania kolejności pól. |
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 XE "kwerenda podsumowująca" .
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.
Wydruk 4.6. Wyrażenie SQL dla kwerendy z rysunku 4.9
SELECT Klienci.NazwaFirmy, Produkty.NazwaProduktu
FROM Produkty INNER JOIN ((Klienci INNER JOIN Zamówienia ON Klienci.IDklienta = Zamówienia.IDklienta) INNER JOIN [Opisy zamówień] ON Zamówienia.IDzamówienia = [Opisy zamówień].IDzamówienia) ON Produkty.IDproduktu = [Opisy zamówień].IDproduktu
ORDER BY Klienci.NazwaFirmy, Produkty.NazwaProduktu;
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 XE "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.
|
||
|
Żadna z funkcji agregujących nie uwzględnia w swoich obliczeniach wartości Null. Jeśli chcesz to zmienić, musisz przekształcić wartości Null na zera, korzystając z kwerendy aktualizującej lub polecenia IIF(IsNull([nazwapola]),0,[nazwapola]), aby kwerenda wyświetlała wartości zero. |
Funkcja agregująca Policz XE "Policz:funkcja agregująca"
Aby zobaczyć, ile zamówień złożył każdy z klientów, musisz zmodyfikować kwerendę. Zamiast pola NazwaProduktu wprowadź z tabeli Zamówienia pole IDzamówienia i w wierszu Podsumowanie wybierz wartość Policz. Usuń z panelu tabele Opisy zamówień i Produkty.
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 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 |
|
Wydruk 4.7. Wyrażenie SQL dla kwerendy z rysunku 4.10
SELECT Klienci.NazwaFirmy, Count(Zamówienia.IDzamówienia) AS PoliczOfIDzamówienia
FROM Klienci INNER JOIN Zamówienia ON Klienci.IDklienta = Zamówienia.IDklienta
GROUP BY Klienci.NazwaFirmy
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.
Funkcja agregująca Średnia XE "Średnia:funkcja agregująca"
Aby zobaczyć średnią cenę danej kategorii produktów, utwórz kwerendę opartą jedynie na tabeli Produkty. W siatce kwerendy umieść pola IDkategorii i CenaJednostkowa, dodaj wiersz Podsumowanie i ustaw opcję podsumowania w polu CenaJednostkowa na Średnia (rysunek 4.11 i wydruk 4.8).
Rysunek 4.11. Siatka QBE kwerendy obliczającej średnią |
|
Wydruk 4.8. Wyrażenie SQL dla kwerendy z rysunku 4.11
SELECT Produkty.IDkategorii, Avg(Produkty.CenaJednostkowa) AS ŚredniaOfCenaJednostkowa
FROM Produkty
GROUP BY Produkty.IDkategorii;
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.
Funkcje agregujące Minimum XE "Minimum:funkcja agregująca" i Maksimum XE "Maksimum:funkcja agregująca"
Funkcje Min/Maks mogą być przydatne, gdy chcesz uzyskać największą wartość w danym polu. Na przykład w sytuacji, gdy chcesz zobaczyć datę ostatniego zamówienia każdego z klientów. Aby tego dokonać, utwórz kwerendę z tabelami Klienci i Zamówienia, połączonymi za pomocą pola IDklienta. Umieść w siatce kwerendy pola NazwaFirmy i DataZamówienia. Dodaj wiersz Podsumowanie i ustaw opcję podsumowania pola DataZamówienia na Maksimum. Uzyskasz w ten sposób datę ostatniego zamówienia każdego z klientów. Ustawienie tej opcji na Minimum spowoduje wyświetlenie najwcześniejszego, zarejestrowanego zamówienia każdego z klientów. Możesz nawet wyświetlać je obok siebie, dodając ponownie pole DataZamówienia i wybierając Maksimum dla jednego i Minimum dla drugiego z nich.
Funkcje agregujące Pierwszy i Ostatni
Na pierwszy rzut oka, funkcje Pierwszy XE "Pierwszy:funkcja agregująca" i Ostatni XE "Ostatni:funkcja agregująca" mogą przypominać Minimum i Maksimum, w rzeczywistości jednak bardzo się od siebie różnią. Minimum i Maksimum oceniają przedstawiane dane. Pierwszy i Ostatni po prostu pobierają pierwszą lub ostatnią wartość napotkaną przez kwerendę, co czasami daje zaskakujące rezultaty. Radzimy z ostrożnością korzystać z tych funkcji, najlepiej na uprzednio posortowanych, tymczasowych tabelach. Użycie tych opcji na nieposortowanej lub posortowanej w niewłaściwy
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.
Funkcje agregujące Odchylenie standardowe i Wariancja
Odchylenie standardowe (OdchStd XE "OdchStd:funkcja agregująca" ) i Wariancja XE "Wariancja:funkcja agregująca" dokonują obliczeń na wartościach danego pola. Wystarczy utworzyć kwerendę grupującą dane w dowolny sposób. Zaznacz odpowiednie pole i ustaw opcję wiersza Podsumowanie na OdchStd lub Wariancja. Odchylenie standardowe i Wariancja wykorzystują metodę próbkowania opartą na mianowniku (n - 1), gdzie n równe jest liczbie rekordów w zestawie rezultatów. Metoda ta używana jest w analizie statystycznej.
Kolejne dwie opcje podsumowujące - Wyrażenie i Gdzie - nie są funkcjami agregującymi.
Funkcja Wyrażenie
Wyrażenie XE "Wyrażenie:funkcja" 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 |
|
Wydruk 4.9. Wyrażenie SQL dla kwerendy z rysunku 4.12
SELECT Kategorie.NazwaKategorii, Count(Produkty.NazwaProduktu) AS PoliczOfNazwaProduktu, Sum([CenaJednostkowa])*1.05 AS [Przykladowe Wyrażenie]
FROM Kategorie INNER JOIN Produkty ON Kategorie.IDkategorii = Produkty.IDkategorii
GROUP BY Kategorie.NazwaKategorii;
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 XE "Gdzie:warunek" 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 XE "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 |
|
Wydruk 4.10. Wyrażenie SQL dla kwerendy z rysunku 4.13
SELECT Kategorie.NazwaKategorii,
Count(Produkty.NazwaProduktu) AS PoliczOfNazwaProduktu,
Sum([Opisy zamówień].Ilość) AS SumaOfIlość
FROM (Kategorie
INNER JOIN Produkty ON Kategorie.IDkategorii = Produkty.IDkategorii)
INNER JOIN ((Klienci
INNER JOIN Zamówienia ON KLienci.IDklienta = Zamówienia.IDklienta)
INNER JOIN [Opisy zamówień] ON Zamówienia.IDzamówienia = [Opisy zamówień].IDzamówienia) ON Produkty.IDproduktu = [Opisy zamówień].IDproduktu
WHERE (((Zamówienia.KrajOdbiorcy)="USA"))
GROUP BY Kategorie.NazwaKategorii
HAVING (((Sum([Opisy zamówień].Ilość))>1000));
|
||
|
Łatwym sposobem na zapamiętanie kolejności wykonywania wyrażeń z fraz Where i Having jest przeglądanie wyrażeń SQL tworzonych przez każdą kwerendę. Fraza Having zawsze jest za frazą Group by. |
Użycie kwerend krzyżowych
Kwerendy krzyżowe XE "kwerenda krzyżowa" i agregujące są do siebie bardzo zbliżone. Kwerenda krzyżowa posiada wiele zdolności analitycznych. W typowej kwerendzie wybierającej pola wyświetlane są u góry zestawu rezultatów, a lista wartości poniżej, jako pojedyncze rekordy. W kwerendzie agregującej pola również znajdują się u góry zestawu rezultatów, jednakże poniżej wyświetlane są wartości będące podsumowanymi danymi. Kwerenda krzyżowa umożliwia Ci tak przekształcić podsumowania uzyskane dzięki kwerendzie agregującej, że wartości będące rezultatami jednej z grup rozmieszczone są u góry zestawu rezultatów. Utworzona przez lewą kolumnę i górny wiersz zestawu rezultatów macierz wypełniana jest żądanymi przez Ciebie obliczeniami. W wyniku tego otrzymujemy coś na kształt tabeli przestawnej.
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 wiersza, 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 |
|
Wydruk 4.11. Wyrażenie SQL dla kwerendy z rysunku 4.14
TRANSFORM Sum([Opisy zamówień].Ilość) AS SumaOfIlość
SELECT Klienci.NazwaFirmy
FROM (Kategorie INNER JOIN Produkty
ON Kategorie.IDkategorii = Produkty.IDkategorii)
INNER JOIN ((Klienci INNER JOIN Zamówienia
ON Klienci.IDklienta = Zamówienia.IDklienta)
INNER JOIN [Opisy zamówień] ON Zamówienia.IDzamówienia = [Opisy zamówień].IDzamówienia)
ON Produkty.IDproduktu = [Opisy zamówień].IDproduktu
WHERE (((Zamówienia.DataZamówienia) Between #1/1/1998# And #12/31/1998#))
GROUP BY Klienci.NazwaFirmy
PIVOT "Q" & CStr(DatePart("Q",[DataZamówienia]));
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.
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]))
Wydruk 4.12. Wyrażenie SQL dla kwerend z rysunków 4.15 i 4.16
TRANSFORM Sum([Opisy zamówień].Ilość) AS SumaOfIlość
SELECT Klienci.NazwaFirmy
FROM Kategorie INNER JOIN (Produkty
ON Kategorie.IDkategorii = Produkty.IDkategorii)
INNER JOIN ((Klienci INNER JOIN Zamówienia
ON Klienci.IDklienta = Zamówienia.IDklienta)
INNER JOIN [Opisy zamówień] ON Zamówienia.IDzamówienia = [Opisy zamówień].IDzamówienia)
ON Produkty.IDproduktu = [Opisy zamówień].IDproduktu)
WHERE (((Zamówienia.DataZamówienia) Between #1/1/1998# And #12/31/1998#))
GROUP BY Klienci.NazwaFirmy
PIVOT "Q" & CStr(DatePart("Q", [DataZamówienia]));
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 |
|
Użycie kwerend parametrycznych
Kwerendy parametryczne XE "kwerenda parametryczna" nie są osobnym typem kwerend. Wymagają one po prostu interwencji użytkownika. Wszystkie kwerendy przed ich uruchomieniem mogą żądać podania określonych informacji. Pewnie zdarzyło Ci się podczas tworzenia kwerendy wprowadzić niepoprawną nazwę pola lub wartość. Gdy próbowałeś uruchomić tę kwerendę, zostałeś poproszony o zidentyfikowanie tych informacji. Jeśli faktycznie Ci się to przydarzyło, stworzyłeś wówczas kwerendę parametryczną. Teraz również to zrobisz, jednakże będziemy kontrolować to, co się dzieje. Dobrym przykładem będzie kwerenda oparta na tabeli Klienci i zawierająca pola NazwaFirmy, Przedstawiciel i Telefon. Kwerenda ta przedstawiona jest na rysunku 4.17, a odpowiadające jej wyrażenie SQL znajduje się na wydruku 4.13.
Rysunek 4.17. Podstawa dla prostej kwerendy parametrycznej |
|
Wydruk 4.13. Wyrażenie SQL dla kwerendy z rysunku 4.17
SELECT Klienci.NazwaFirmy, Klienci.Przedstawiciel, Klienci.Telefon
FROM Klienci
ORDER BY Klienci.Przedstawiciel;
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.
Wydruk 4.14. Wyrażenie SQL dla kwerendy z rysunku 4.18
SELECT Klienci.NazwaFirmy, Klienci.Przedstawiciel, Klienci.Telefon
FROM Klienci
WHERE (((Klienci.NazwaFirmy)="Frankenversand"))
ORDER BY Klienci.Przedstawiciel;
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.
Rysunek 4.18. Kwerenda z prostym kryterium w siatce QBE |
|
Tworzenie parametrów dla kwerendy w siatce QBE
Aby utworzyć parametr XE "parametr:tworzenie" w siatce QBE, wybierz z menu Kwerenda opcję Parametry. Wyświetlone zostanie okno dialogowe, w którym możesz umieścić parametry, które chcesz ustawić. Mimo iż można tworzyć kwerendy parametryczne bez użycia okna dialogowego, umożliwia ono kontrolowanie kolejności przedstawiania parametrów oraz typów danych dla każdego z nich. Po umieszczeniu parametrów w oknie dialogowym możesz rozmieścić je na właściwych miejscach w siatce kwerendy. Parametr w siatce kwerendy musi dokładnie odpowiadać parametrowi w oknie dialogowym. Jeśli parametr będzie istniał jedynie w oknie dialogowym, kwerenda poprosi użytkownika o podanie informacji, jednakże nie będzie wiedzieć, jak ma je zastosować.
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.
Wydruk 4.15. Wyrażenie SQL dla kwerendy z rysunku 4.19
PARAMETERS [ID Klienta] Text;
SELECT Klienci.NazwaFirmy, Zamówienia.IDzamówienia, Zamówienia.DataZamówienia,
Produkty.NazwaProduktu, [Opisy zamówień].CenaJednostkowa,
[Opisy zamówień].Ilość, [Opisy zamówień].Rabat
FROM Produkty
INNER JOIN ((Klienci INNER JOIN Zamówienia
ON Klienci.IDklienta = Zamówienia.IDklienta)
Rysunek 4.19. Umieszczanie parametru w kwerendzie w siatce QBE |
|
INNER JOIN [Opisy zamówień] ON Zamówienia.IDzamówienia = [Opisy zamówień].IDzamówienia)
ON Produkty.IDproduktu = [Opisy zamówień].IDproduktu
WHERE (((Klienci.IDklienta)=[IDklienta]))
ORDER BY Zamówienia.DataZamówienia DESC, Produkty.NazwaProduktu;
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.
Teraz kwerenda, pytając klienta, użyje powyższego zdania.
Tworzenie parametrów w kwerendach korzystających z programu
Kwerendy parametryczne mogą działać w aplikacjach w inny sposób - poprzez program. Parametry tworzą w kwerendzie zbiór, do którego możesz zwracać się podczas wykonywania kwerendy w kodzie VBA. Ma to swoje dobre strony. W interfejsie użytkownika możesz pobrać wszystkie parametry poprzez formularz, jednocześnie kontrolując typ danych i ich poprawność, a następnie umieścić je wszystkie w kwerendzie parametrycznej. Umożliwia to użytkownikowi całościowe przeglądanie tego, co wpisuje, i dokonywanie
zmian przed otrzymaniem zestawu rekordów. Podczas normalnego wykonywania kwerendy parametrycznej użytkownik nie ma możliwości powrotu do poprzednich parametrów. Po wpisaniu wartości może jedynie iść dalej lub anulować kwerendę.
Tworzenie kwerend parametrycznych
- siatka QBE a program
Często programiści wykonują procedury SQL poprzez kod. W wielu przypadkach sposób ten sprawdza się doskonale, jednakże nie jest pozbawiony wad. Po pierwsze, procedury SQL mogą być niezrozumiałe lub niedostępne dla innych, mniej doświadczonych programistów, których zadaniem w przyszłości może być obsługa tej aplikacji. Może to doprowadzić do błędów w jej działaniu. Użycie kwerendy parametrycznej umożliwia innym programistom, posiadającym oczywiście odpowiednie uprawnienia, modyfikowanie kwerendy poprzez siatkę QBE, co może być uważane za wspólny mianownik użytkowników i programistów Accessa. Najważniejszy jest fakt, że w większości przypadków kwerenda parametryczna jest najszybszym i najbardziej wiarygodnym sposobem na wykonywanie kwerendy bez zmiany jej kryteriów lub właściwości. Dzieje się tak, ponieważ Access kompiluje kwerendy, więc Jet ma już gotowy ich profil wykonywania. Krótko mówiąc, ciąg SQL w kodzie nie jest zoptymalizowany, a kwerenda parametryczna może być optymalizowana. Kiedy kwerenda parametryczna jest we właściwy sposób wykonywana poprzez program, użytkownik nie jest proszony o podawanie żadnych informacji.
Wykonywanie kwerendy parametrycznej
poprzez program
Teraz pokażemy, w jaki sposób kwerenda parametryczna XE "kwerenda parametryczna:wykonywanie" może być wykonywana poprzez kod. Wydruk 4.16 akceptuje nazwę kwerendy i jeden parametr, a następnie używa tych argumentów, aby otworzyć daną kwerendę i policzyć jej rekordy. Zwracana wartość to ilość rekordów w zestawie rekordów. Możesz uruchamiać tę funkcję z okna Analiza programu lub poprzez zdarzenie na formularzu.
Wydruk 4.16. Funkcja wykonująca kwerendę parametryczną poprzez kod
Function RunParameterQuery (QryName As String, CustID As String)
'Funkcja ta uruchomi kwerendę parametryczną, która
'pobiera ID klienta jako argument
'Argumenty:
' QryName - Nazwa kwerendy parametrycznej
' CustID - Ciąg identyfikujący klienta
'Z "Access 2000 - Księga eksperta" (Helion)
'Autorzy: Forte, Howe, Ralston
Dim db As Database
Dim qrydef As QueryDef
Dim rs As Recordset
Set db = CurrentDb()
Set qrydef = db.QueryDefs (QryName)
'Tutaj parametrowi nadajemy nazwę.
Qrydef ("ID klienta") = CustID
Set rs = qrydef.OpenRecordset()
RunParamQuery = rs.RecordCount
Rs.Close
End Function
Wykonywanie kwerendy poprzez zbiór parametrów
Wydruk 4.17 wykorzystuje w kwerendzie zbiór parametrów. Umieszczając w argumentach funkcji słowo kluczowe ParamArray, możesz używać jej z różnymi kwerendami parametrycznymi, niezależnie od ilości wymaganych przez nie parametrów. Funkcja wykonuje pętlę poprzez tablicę ParamArgs() i przyznaje parametry w kolejności ich podawania. Aby użyć tej funkcji, uruchom ją z okna Analiza programu. Otrzymany rezultat to ilość rekordów. Kilkukrotne uruchomienie tej funkcji zaowocuje przyspieszeniem pracy kwerend parametrycznych.
Wydruk 4.17. Funkcja uruchamiająca kwerendy parametryczne ze zmienną ilością parametrów
Function OpenParamQuery (QryName, _
ParamArray ParamArgs() As Variant) As Long
'Z "Access 2000 - Księga eksperta" (Helion)
'Autorzy: Forte, Howe, Ralston
'Argumenty
' QryName - Nazwa kwerendy prametrycznej
' ParamArgs - Zmienna lista wartości wprowadzanych do
' parametrów kwerendy. Muszą być
' ułożone w takiej kolejności, w jakiej spodziewa się ich kwerenda.
Dim db As Database
Dim qrydef As QueryDef
Dim i As Integer
Dim rs As Recordset
Dim rscount As Long
On Erro GoTo OpenParameterQuery_Error
Setdb = CurrentDb()
Set qry = db.QueryDefs(QueryName)
'Przejdź przez wszystkie parametry I przyznawaj je według indeksów
For i = 0 To Ubound(ParamArgs())
qry.Parameters(i) = ParamArgs(i)
Next
Set rs = qry.OpenRecordset(dbOpenSnapshot)
OpenParameterQuery = rs.RecordCount
OpenParamQuery_Exit:
Set qry = Nothing
rs.Close
Exit Function
OpenParamQuery_Error:
OpenParamQuery = 0
GoTo OpenParamQuery_Exit
End Function
|
||
|
Jeśli dokonasz parametryzacji zagnieżdżonej kwerendy, wciąż będzie istniał tylko jeden zbiór parametrów. |
Kwerendy przekazujące XE "kwerenda przekazująca"
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ą.
Tworzenie kwerendy przekazującej
Kwerenda przekazująca XE "kwerenda przekazująca:tworzenie" tworzona jest tak jak każda inna kwerenda, z tą różnicą, że nie dodaje się do niej żadnych tabel. Po jej utworzeniu z menu Kwerenda wybierz opcję Wyłącznie SQL, a następnie Przekazująca. Spowoduje to zamianę okna Kwerenda w okno SQL. Istnieją tylko dwie właściwości, ważne dla uruchamiania kwerendy przekazującej: sama procedura SQL i ciąg połączenia. Procedura SQL zawiera polecenia dla serwera we właściwej, zrozumiałej dla niego składni SQL. Ciąg połączenia zawiera informacje niezbędne, by kwerenda mogła skontaktować się z serwerem.
Oto przykład możliwego ciągu połączenia:
ODBC;
DRIVER=SQL SERVER;
SERVER=Access2000UnleashedServer;
UID=sa;
DATABASE=PUBS;
TRUSTED_CONNECTION=YES
ODBC (Open Database Connectivity) to przedrostek ciągu połączenia. Poprzedza on zawsze ciągi połączenia XE "Open Database Connectivity" 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 XE "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
Poza umiejętnością manipulowania danym zawartymi w tabelach kwerendy Accessa mogą również tworzyć, modyfikować i usuwać tabele w Accessie w taki sposób, by nadać aplikacji umiejętność inteligentnej pracy z danymi.
Kwerendy definiujące dane XE "kwerenda definiująca 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 XE "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 dokonują ciągłych modyfikacji w liczbie, strukturze i właściwościach tabel, indeksów i relacji. Zanim zaczniesz z nimi pracować, sporządź kopię zapasową swojej bazy i uruchom je w kopii swojego projektu. |
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. Warunek ograniczający jest opcjonalny.
Tworzenie nowej tabeli
Logicznym początkiem pracy z kwerendami definiującymi dane jest procedura Create Table XE "Create Table" . Jak sama nazwa wskazuje, będzie ona tworzyła tabelę XE "tabela:tworzenie" , jednakże jej zdolności do tego się nie ograniczają. Korzystając z kwerendy tworzącej tabele, możesz utworzyć tabele z poziomu siatki QBE, jednakże ten sposób nie umożliwia określenia rozmiaru i ograniczeń pola, indeksów oraz relacji.
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.
Składnia prostej procedury Create Table wygląda następująco:
Create Table nazwatabeli (pole1 typdanych (rozmiar), pole2 typdanych (rozmiar),...,);
|
||
|
Budować kwerendy można jedynie w oparciu o zamknięte w danym momencie tabele. |
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 XE "tabela:modyfikowanie" możliwe jest modyfikowanie jej zawartości przy użyciu kwerend definiujących dane. Polecenie Alter Table XE "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.
Alter Table TestTable drop Phone;
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 XE "indeks:tworzenie" . Umożliwia to polecenie Create Index XE "Create Index" .
Podstawowa składnia tego polecenia jest następująca:
CREATE [UNIQUE] INDEX nazwaindeksu
ON nazwatabeli (nazwapola1 ASC/DESC nazwapola2 ASC/DESC...)
[WITH Primary/Disallow Null/Ignore Null]
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.
Poniższe wyrażenie utworzy indeks w nowej tabeli:
Create Index Nazwisko on TabelaTestowa(Nazwisko) with primary;
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.
|
||
|
Możliwe jest tworzenie indeksów w tabelach połączonych ze źródłem danych ODBC, jeśli tabele te nie posiadają jeszcze indeksu. W tym przypadku, indeksy nie znajdują się na serwerze. Rezydują w Accessie jako dynamiczne odnośniki do pól z danymi. Serwer nie zauważa tych pseudoindeksów i nie są wymagane specjalne pozwolenia, aby je tworzyć. Aby tego dokonać, użyj tej samej składni jak dla tabel źródłowych. Pseudoindeksów używaj w przypadkach, gdy źródło ODBC nie posiada własnego indeksu, a użytkownicy muszą aktualizować dane. |
Usuwanie tabeli
Aby usunąć tabelę XE "tabela:usuwanie" z bazy danych lub usunąć indeks z tabeli, użyj polecenia DROP TABLE XE "DROP TABLE" lub DROP INDEX XE "DROP INDEX" .
DROP TABLE nazwatabeli/[nazwaindeksu ON nazwatabeli]
Poniższe wyrażenie usunie z bazy tabelę i wszystkie zawarte w niej dane:
DROP TABEL TabelaTestowa
Określanie właściwości pól
Warunki ograniczające pozwalają na określenie pozostałych właściwości pól. Właściwości te można podzielić na dwie grupy: klucze i relacje. Warunki ograniczające umieszczane są w po definicji pola w wyrażeniu definiującym dane. W warunku nie jest stosowana interpunkcja, tak więc ważna jest kolejność.
Gdy określamy klucze, składnia jest następująca:
CONSTRAINT nazwawarunku PRIMARY KEY/UNIQUE/NOT NULL
Gdy określamy relacje dla tabeli lub pola, składnia warunku ograniczającego jest nieco inna:
CONSTRAINT nazwarelacji REFERENCES nazwainnejtabeli (nazwapowiązanegopola)
Gdy tworzysz relacje między dwoma polami, za pomocą warunku CONSTRAINT XE "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.
Wydruk 4.18. Użycie warunków podczas tworzenia pól
CREATE TABLE TabelaTestowa
(IDpracownika Long CONSTRAINT myFieldConstraint
PRIMARY KEY Constraint myRelations references Pracownicy (IDpracownika),
Imię TEXT,
Nazwisko TEXT,
Telefon TEXT)
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 XE "optymalizowanie kwerend"
Oto kilka czynności, które może wykonać programista, aby zapewnić odpowiednią wydajność kwerendy:
Indeksuj sprzężone pola po obu stronach relacji. Dotyczy to również tabel nie tworzonych przez mechanizm Jet.
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.
Utwórz indeks dla pól, których będziesz używał do sortowania. Nieindeksowane pola sortuj tylko w ostateczności.
Upewnij się, że dla wszystkich pól wybrałeś właściwy typ danych i rozmiar. Rozmiar pól powinien być możliwie najmniejszy.
Nie przeciążaj siatki QBE. Używaj tylko pól niezbędnych dla zestawu rezultatów.
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.
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.
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.
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.
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.
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ż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.
Gdy tylko to możliwe, korzystaj z techniki Accessa 2000 klient-serwer.
Rozdział 5.
Jet 4.0 - silnik baz danych Microsoft
W tym rozdziale:
Historia Microsoft Jet.
Praktyczne zastosowanie nowych opcji silnika Jet 4.0.
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.
Historia Microsoft Jet
Dzisiaj Microsoft Jet XE "Jet" używany jest jako aparat bazy danych w ponad 30 produktach firmy Microsoft. Można wśród nich wymienić (oprócz, rzecz jasna, Accessa) takie programy, jak Project, Money, Team Manager, a nawet edukacyjne gry dla dzieci. Jet całkowicie zdominował rynek domowych baz danych, gdyż każda jego edycja zawiera coraz nowocześniejsze technologie. Cofnijmy się teraz odrobinę, aby prześledzić historię Microsoft Jet.
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 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:
nowy wbudowany dostawca baz danych OLE;
blokowanie na poziomie rekordów;
pełna obsługa Unicode;
ulepszone typy danych;
poprawione funkcje Autonumerowania;
przeszukiwalne pola typu Memo;
poprawki trybu przeznaczonego dla wielu użytkowników;
ulepszenia w replikacji;
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.
Przyszłe wersje Microsoft Jet
Na początku 1998 roku pojawiły się plotki, że era Jet ma się ku końcowi. Wraz z pakietem Office 2000 Microsoft wydał „domową” wersję SQL Server 7.0 i typ projektów Accessa, który był alternatywą dla Jet (ADP XE "ADP" - patrz rozdział 15. „Wprowadzenie do projektów programu Microsoft Access oraz narzędzi wizualnych”). Wraz z obiektami ADO 2.0 i Universal Data Access, Microsoft wypuścił bazy danych OLE jako metodę dostępu do danych w architekturze klient-serwer (więcej informacji o bazach danych OLE i obiektach ADO w rozdziale 6. „Wprowadzenie do obiektów danych ActiveX” i 7. „Zaawansowane ADO”). ADO 2.0 i bazy danych OLE porozumiewają się ze źródłem danych bezpośrednio poprzez OLE. Ponieważ Microsoft chciał korzystać z baz OLE dla architektury klient-serwer poprzez ADP, klienci uznali, że to już koniec Jet. Microsoft zaprzeczył tym plotkom na wielu konferencjach prasowych i zapewnił, że silnik Jet będzie nadal umieszczany w produktach tej firmy.
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.
Wbudowany dostawca baz danych OLE
Jeśli jeszcze tego nie wiesz, strategia dostępu do danych Microsoftu opiera się aktualnie na obiektach ActiveX Data Objects (ADO) (więcej informacji o obiektach ADO w rozdziale 6. „Wprowadzenie do obiektów danych ActiveX” i 7. „Zaawansowane ADO”). Działanie obiektów ADO oparte jest na koncepcji powszechnego dostępu do danych, wykorzystującego do komunikowania się ze źródłami danych wbudowanych dostawców.
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.
Blokowanie na poziomie rekordu
Tak, nie pomyliłeś się! Jet 4.0 obsługuje blokowanie na poziomie rekordu! Teraz możesz poprawić współbieżność aplikacji, blokując jeden wiersz, a nie jak to miało miejsce wcześniej - całą stronę. Blokowanie na poziomie rekordu może wpłynąć na znaczne zwiększenie wydajności obszernych, transakcyjnych baz danych. W niektórych testach, blokowanie na poziomie rekordu umożliwiło sześciokrotną poprawę wydajności w stosunku do blokowania na poziomie strony. Programowa obsługa blokowania na poziomie rekordu będzie dostępna w ADO i Accessie, ale nie w DAO. Bezpośrednią korzyścią z blokowania na poziomie rekordu jest koniec konfliktów z blokowaniem stron. Więcej na temat blokowania na poziomie wiersza w rozdziale 21. „Zagadnienia wielodostępu, serwer plików, blokowanie”.
Pełna obsługa Unicode XE "Unicode"
Jet 4.0 przechowuje wszystkie dane o znakach (wszystkie pola typu Tekst i Memo) w kodzie Unicode. Umożliwia to łatwe przełączanie się pomiędzy językami i zestawami znaków w aplikacji. Teraz, gdy konwertujesz coś na inny język lub alfabet, masz 100% gwarancji zgodności danych po konwersji.
Czym jest Unicode?
Dzisiaj na świecie istnieje wiele nakładających się na siebie standardów kodowania znaków tekstowych. W przypadku istnienia tak wielu różnych zestawów znaków dla stron kodowych proces tworzenia jednego, międzynarodowego kodu podstawowego jest wyjątkowo trudny. Mniej więcej dziesięć lat temu firmy Apple i Xerox zaczęły wspólnie opracowywać nowy standard zestawu znaków. W 1991 roku firmy te założyły konsorcjum Unicode. Obecnie jego członkami są między innymi: Microsoft, Apple, AT&T, Compaq, Digital, Ecological Linguistics, Hewlett-Packard, IBM, Lotus, NeXT, Novell, Reuters oraz wiele innych firm.
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.
Obsługa Unicode 1.1 w silniku Jet 4.0
Aby umieścić kod Unicode w silniku Jet 4.0, rozmiar strony danych został zwiększony do 4 KB. Umożliwiło to zmianę ograniczenia wielkości pliku typu MDB z 1,07 GB do 2,14 GB. Ponieważ Unicode przechowuje dane w większych stronach, rozmiar niektórych baz (z dużą ilością danych tekstowych) może się zwiększyć. Jednakże Jet umożliwia kompresję kodu Unicode. Opcja Kompresja Unicode jest również dostępna podczas projektowania tabel w Accessie (rysunek 5.1).
Rysunek 5.1. Opcja Kompresja Unicode w tabeli w widoku Projekt |
|
||||
|
|||||
|
Kompresja indeksu jest domyślnie włączona i jeśli konwertujesz aplikację z poprzedniego formatu pliku, wszystkie typy znaków będą miały włączoną opcję Kompresja Unicode. Jeśli jednak baza danych jest już w formacie pliku Jet 4.0, aby włączyć kompresję Unicode, właściwość ta musi zostać ustawiona. Kompresja Unicode nie działa na polach typu Memo o rozmiarze przekraczającym 4 kB, posiadających na stronie inne wiersze. |
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).
Wydruk 5.1. Tworzenie skompresowanego pola Unicode w VBA
Private Sub cmdUnicode_Click()
'Procedura ta spowoduje utworzenie tabeli MyTable i
'skompresowanego pola w standardzie Unicode o nazwie MyCoolCounter
'Kod ten może być uruchamiany jedynie poprzez ADO w VBA
'i nie jest obsługiwany przez DAO
'Z książki "Access 2000 Księga Eksperta" (Helion)
'Autorzy: Forte, Howe, Ralston
Dim strSQL As String
On Error GoTo Proc_Err
'Utwórz procedurę SQL
strSQL = "CREATE TABLE MyTable (MyCompressedField CHARACTER(255) WITH COMPRESSION)"
'Wykonaj procedurę SQL na
'aktualnym połączeniu ADO
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 samego zestawu funkcji, czego rezultatem jest jednolitość między produktami. |
Typy danych Jet
Tabela 5.1 zawiera przegląd typów danych Jet. Typy danych w silniku Jet 4.0 zostały poprawione, aby lepiej współpracować z SQL Server XE "SQL Server" . Aby ułatwić przenoszenie i replikowanie baz danych Jet do SQL Server, typy danych zostały do siebie upodobnione. Nazwy typów danych Jet nie zawsze są takie same jak w Accessie. Access tłumaczy je za Ciebie.
Tabela 5.1.
Przegląd typów danych Jet 4.0
Typ danych Jet |
Nazwa w Accessie |
Uwagi |
Character |
Tekst |
Maksymalna długość to 255 znaków. Dzięki obsłudze Unicode długość ta dotyczy wszystkich języków. Dopuszczalne synonimy: Char, Varchar, Character Varying, Nchar, National Character, National Char, Nvarchar, National Character Varying i National Char Varying. |
Tabela 5.1.
Przegląd typów danych Jet 4.0 (ciąg dalszy)
Typ danych Jet |
Nazwa w Accessie |
Uwagi |
|
|
Użycie słowa Tekst bez określenia długości ma teraz inne znaczenie. Jest synonimem dla Memo. To przybliża znaczenie słowa Tekst silnika Jet do jego znaczenia w Microsoft SQL Server. Możesz wciąż używać słowa Tekst z określeniem długości, na przykład TEKST (100), aby określić stałą ilość znaków w kolumnie. Poniższy przykład ilustruje użycie TEKST do określania typu danych: CREATE TABLE t1 (c1 TEXT) oznacza to samo, co CREATE TABLE t1 (c1 MEMO) i zbliżone jest do definicji i składni słowa TEXT w SQL Server. CREATE TABLE t1 (c1 TEXT (100)) oznacza to samo co CREATE TABLE t1 (c1 CHAR (100)) i zapewnia kompatybilność z większością już istniejących aplikacji Microsoft Jet. |
LongText |
Memo |
Maksymalna długość (w bajtach) wynosi teraz około 2.14 GB, czyli w przybliżeniu 1.07 miliarda znaków. Dopuszczalne synonimy to Text, Ntext, Memo, LongChar i Note. |
Binary |
Obiekt OLE |
Maksymalna długość to 255 znaków. Dopuszczalne synonimy: Varbinary, Binary, Varying oraz Bir Varying. |
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)
Typ danych Jet |
Nazwa w Accessie |
Uwagi |
Currency |
Walutowy |
Dopuszczalny synonim to Money. Dane otrzymywane poprzez ODBC w formacie SQL_DECIMAL lub SQL_NUMERIC (na przykład: SQL Server Decimal lub Numeric) są kojarzone z typem danych Walutowy aparatu Jet. |
Boolean |
Tak/Nie --> [Author:RG] |
Dopuszczalne synonimy: Bit, Logical, Logical1 oraz YesNo. |
GUID |
IDreplikacji |
Jedyny dopuszczalny synonim to UniqueIdentifier. |
Decimal |
Dziesiętne |
Typ danych Dziesiętne jest nowością w aparacie Microsoft Jet 4.0.
Jest to dokładny typ danych, przyjmujący wartości z zakresu 1028-1 do -1028-1. Możesz zdefiniować zarówno precyzję Dopuszczalne synonimy to Dec i Numeric. |
|
|
Dane otrzymywane poprzez ODBC w formacie SQL_DECIMAL lub SQL_NUMERIC będą teraz kojarzone z typem danych Dziesiętne aparatu Jet, a nie Walutowy. Zauważ, że ten typ danych obsługiwany jest jedynie przez ADO. |
Ulepszenia opcji Autonumerowanie
Jet 4.0 daje pełną kontrolę nad polem typu Autonumerowanie XE "autonumerowanie" . Masz teraz możliwość określenia punktu początkowego i przedziału licznika. Możesz sprawić, by pole Autonumerowanie zaczynało się od 1000 i przyrastało o 100. Te funkcje dostępne są jedynie poprzez SQL DDL do ADO/JOLT. Korzyścią, jaką dzięki temu otrzymujemy, jest większa kontrola 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.
Przeszukiwalne pola Memo
W poprzednich wersjach Accessa i Jet pola typu Memo nie mogły być indeksowane. W silniku Jet 4.0 indeksowaniu podlega pierwszych 255 znaków. Podczas przeszukiwania z użyciem znaków zastępczych (*) używany jest jedynie indeks. Mimo iż funkcja ta działa poprawnie, ogranicza przeszukiwanie do pierwszych 255 znaków. Bierz to pod uwagę podczas przeszukiwania pól Memo, bo jeśli kryterium, według którego przeszukujesz, nie mieści się w tym zakresie, przeszukiwanie nie da właściwych rezultatów.
Kontrola połączeń i zamknięcie bierne
Wśród innych opcji związanych z obsługa wielu użytkowników należy wymienić nową Listę użytkowników, wyliczającą wszystkich użytkowników bazy poprzez ADO, jak miało to miejsce w przypadku narzędzia LDBView. Opcja Kontrola połączeń umożliwi Ci odmówienie dostępu do bazy. Mimo iż nie możesz „wyrzucić” innego użytkownika, możesz zabezpieczyć się przed podłączaniem się do bazy nowych użytkowników. Opcja ta, wraz z zestawem funkcji Listy użytkowników, pozwala biernie zamknąć bazę danych, a następnie, gdy wszyscy inni użytkownicy są odłączeni, otworzyć bazę z wyłącznością. Znajdujący się na wydruku 5.2 kod programu przedstawia użycie Listy użytkowników z biernym zamknięciem.
Wydruk 5.2. Użycie Listy użytkowników w ADO
Sub UserRoster(strPath As String)
Dim conn As ADODB.Connection
Dim rst As ADODB.Recordset
Set conn = New ADODB.Connection
With conn
.Provider = "Microsoft.Jet.OLEDB.4.0"
.ConnectionString = "data source=" & strPath
.Open
End With
Set rst = conn.OpenSchema(adSchemaProviderSpecific, , _
"{947bb102-5d43-11d1-bdbf-00c04fb92675}")
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ą komputera, 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.
Nowa składnia SQL
Do Jet 4.0 dodano wiele rozszerzeń SQL, aby mógł on obsługiwać nowy zestaw funkcji i był bardziej zgodny z ANSI 92 SQL. Dodatkową korzyścią jest fakt, iż większość z tych rozszerzeń ułatwia pisanie wyrażeń SQL funkcjonujących między Jet a SQL Server. Ulepszenia SQL obejmują:
Zabezpieczenia.
Definiowanie widoków i procedur.
Wywoływanie parametrów.
Transakcje.
Tworzenie i modyfikację tabel DDL.
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.
Wydruk 5.3. Ustawianie zabezpieczeń w Jet 4.0
Private Sub cmdSecurity_Click()
'Procedura ta spowoduje otwarcie pliku MDB z określonym plikiem 'zabezpieczeń,
a następnie dodanie użytkowników i grup
'Kod ten może być uruchamiany jedynie poprzez ADO w VBA
'i nie jest obsługiwany przez DAO
'Z książki "Access 2000 Księga eksperta" (Helion)
'Autorzy: Forte, Howe, Ralston
Dim conn As ADODB.Connection
On Error GoTo Proc_Err
Set conn = New ADODB.Connection
'Ustaw połączenie do bazy danych
'używając ADO i określając w ciągu połączenia bazę systemową
With conn
.Provider = "Microsoft.Jet.OLEDB.4.0"
.ConnectionString = "data source=" & strPath & _
";Jet OLEDB:System database=" & strMDWPath
.Open
End With
'Wykonaj procedury SQL
conn.Execute "CREATE GROUP SuperGroup"
conn.Execute "GRANT SELECT, DELETE, INSERT, UPDATE ON tblCustomers TO SuperGroup"
conn.Execute "REVOKE DELETE ON tblCustomers From SuperGroup"
conn.Execute "CREATE USER Steve Batman"
conn.Execute "ADD USER Steve to 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:
ALTER DATABASE PASSWORD NewPass OldPass
Definiowanie widoków i procedur
Jet 4.0 umożliwia zdefiniowanie zapisanej kwerendy jako widok lub procedurę. Widok może być zdefiniowany jako nieparametryczna, zwracająca wiersze kwerenda. Procedurami nazywamy wszystkie nie korzystające z DDL i UNION czynności oraz kwerendy parametryczne. Widoki i procedury możesz tworzyć zarówno poprzez ADO, jak i nową składnię SQL Jet: CREATE VIEW i CREATE PROCEDURE. Nowa składnia jest bardziej kompatybilna z ANSI 92 i umożliwia łatwiejsze przenoszenie widoków i Jet do innych baz ANSI 92 SQL, jak na przykład SQL Server. Poniższy kod SQL tworzy widok i procedur.
CREATE VIEW qryAllCustomers AS SELECT * FROM tblCustomers
CREATE PROCEDURE qryAllCustomers_DEL AS DELETE * FROM tblCustomers
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.
Wydruk 5.4. Otwieranie kwerendy parametrycznej w ADO
Private Sub cmdPramQuery_Click()
'Procedura ta spowoduje otwarcie kwerendy parametrycznej
'przy użyciu nowej składni EXEC
'Kod ten może być uruchamiany jedynie poprzez ADO w VBA
'i nie jest obsługiwany przez DAO
'Z książki "Access 2000 Księga eksperta" (Helion)
'Autorzy: Forte, Howe, Ralston
Dim rst As ADODB.Recordset
On Error GoTo Proc_Err
Set rst = New ADODB.Recordset
'Otwórz zestaw rekordów oparty na
'wykonywanej kwerendzie parametrycznej
rst.Open "Exec qryParameterQuery 1", CurrentProject.Connection
'Display the results
MsgBox rst![FirstName]
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description, vbCritical
Resume Proc_Exit
End Sub
Transakcje
SQL Jet 4.0 obsługuje teraz transakcje XE "transakcja" . Transakcja musi obowiązkowo rozpoczynać się w następujący sposób:
BEGIN TRANSACTION
Aby utworzyć lub cofnąć transakcję, użyj odpowiednio poniższych poleceń:
ROLLBACK
ROLLBACK 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.
Wydruk 5.5. Transakcje w SQL Jet 4.0
Sub Jet40Transaction()
Dim conn As ADODB.Connection
Set conn = CurrentProject.Connection
With conn
.Provider = "Microsoft.Jet.OLEDB.4.0"
.ConnectionString= "data source=" & Application.CurrentProject.Path & "employee_2k.mdb"
.Open
End With
'Execute the SQL Statements
conn.Execute "BEGIN TRANSACTION"
conn.Execute "UPDATE Employees SET Employees.HomePhone = " & _
Chr(39) & "2129560615" & Chr(39) & _
"WHERE (((Employees.EmployeeID)=1))"
conn.Execute "DELETE" &vbNewLine & _
"From tasks" & vbNewLine & _
"WHERE (((Tasks.[Emp ID])=1)); "
Conn.Execute "COMMIT TRANSACTION"
End Sub
Tworzenie tabel DDL
W Microsoft Jet 4.0 polecenie CREATE TABLE jest znacznie potężniejsze. Najbardziej interesującą opcją nowych rozszerzeń SQL w silniku Jet 4.0 jest opcja CHECK CONSTRAINTS. Umożliwia ona rozszerzenie reguł biznesowych na więcej niż jedną tabelę. Możesz użyć SQL do odnalezienia informacji w kilku tabelach, a następnie użyć tych informacji do wymuszenia określonych warunków na nowo wstawianych rekordach. Załóżmy, że mamy tabele Customers (Klienci) i Credit Limit (Limit kredytu). Możesz nakazać silnikowi Jet wymuszenie reguły biznesowej, która spowoduje, że nowo wstawiany rekord może być zaakceptowany jedynie w sytuacji, gdy przyjmuje wartości niższe od przyjętego limitu kredytowego. Ograniczenie to zdefiniowałbyś poprzez SQL w następujący sposób:
CHECK (<SQL Condition>)
Poniższy kod tworzy tabelę z ograniczeniem w polu CREDITLIMIT:
CREATE TABLE Customers (CustId IDENTITY (100,10),
CFrstNm VARCHAR(10), CLstNm VARCHAR(15), CustomerLimit DOUBLE,
CHECK (CustomerLimit <= (SELECT SUM (CreditLimit) FROM CreditLimit)));
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.
Wydruk 5.6. Użycie ograniczeń
Private Sub cmdCreateConstraint_Click()
'Procedura ta spowoduje utworzenie 2 tabel, z których jedna
'będzie zawierać ograniczenie oparte na drugiej tabeli
'Kod ten może być uruchamiany jedynie poprzez ADO w VBA
'i nie jest obsługiwany przez DAO
'Z książki "Access 2000 Księga eksperta" (Helion)
'Autorzy: Forte, Howe, Ralston
Dim conn As ADODB.Connection
On Error GoTo Proc_Err
Set conn = CurrentProject.Connection
'Utwórz tabelę sprawdzającą limit kredytu
conn.Execute "CREATE TABLE CreditLimit (CreditLimit DOUBLE);"
'Wprowadź limit kredytu
conn.Execute "INSERT INTO CreditLimit VALUES (100);"
'Utwórz tabelę Customers (Klienci) z ograniczeniem
conn.Execute "CREATE TABLE Customers_Con (CustId IDENTITY (100,"&_
" 10), CFrstNm VARCHAR(10), CLstNm VARCHAR(15), " & _
"CustomerLimit DOUBLE, CHECK (CustomerLimit <= " & _
"(SELECT SUM (CreditLimit) FROM CreditLimit)));"
'Dokonaj wprowadzenia
conn.Execute "INSERT INTO Customers_Con (CLstNm, CFrstNm, CustomerLimit)" & _
"VALUES ('Collins', 'Kevin', 100);"
'Przejdzie do tej linii, gdy limit kredytu złamie regułę
conn.Execute "INSERT INTO Customers_Con (CLstNm, CFrstNm, CustomerLimit)" & _
"VALUES ('Forte', 'Stephen', 101);"
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:
Historia dostępu do danych.
Universal Data Access.
Obiekty ActiveX Data (ADO).
Model obiektowy ActiveX Data.
Obiekty ADO: Recordset.
Obiekty ADO: Error.
Przejście z obiektów DAO do ADO.
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 XE "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.
Historia dostępu do danych
Teraz pokażemy, jak wyglądała droga do obiektów ADO XE "ADO" . Spoglądając na nią, będziesz mógł docenić korzyści płynące z ich używania.
Firmowe interfejsy API
Zanim Microsoft wprowadził na rynek swoje pierwsze produkty, jedyna droga na uzyskanie programowego dostępu do danych prowadziła przez interfejsy API poszczególnych firm. Zmuszało to programistów do poznawania różnych API dla każdego z systemów baz danych, dla których tworzyli aplikacje. Nie trzeba chyba dodawać, że rozwiązanie to było bardzo niewygodne.
Open Database Connectivity (ODBC)
Kilka lat temu Microsoft wprowadził na rynek specyfikację Open Database Connectivity (ODBC XE "ODBC" ). Był to ogólny, programowy interfejs API, umożliwiający programistom tworzenie aplikacji dla każdej bazy danych, posiadającej sterownik ODBC. Wymagało to wprawdzie znajomości API ODBC, ale nie trzeba już było poznawać interfejsu każdej bazy, dla której tworzono aplikacje. API ODBC nie był łatwy w użyciu, jednakże był pierwszym krokiem na drodze do rozwiązania problemu istnienia tak wielu API. Jak wiecie, ODBC szybko stał się standardową metodą dostępu do danych.
Microsoft Jet/Obiekty Data Access (DAO)
Gdy wraz z Accessem 1.0 do rąk użytkowników trafił Microsoft Jet i obiekty Data Access (DAO), dostęp do danych został znacznie ułatwiony. Obiekty DAO dostarczały standardowego sposobu dostępu do danych dla Jet. Dodatkowo Jet mógł poprzez ODBC komunikować się z wieloma źródłami danych zgodnymi z ODBC, oraz z innymi bazami danych. Z silnika Microsoft Jet korzystały miliony użytkowników, aby dzięki jednemu modelowi obiektu dostępu danych uzyskać dostęp do różnych baz.
Zdalne obiekty danych (RDO) i ODBCDirect
Wydając Visual Basic 4.0 Enterprise Edition, Microsoft wprowadził nowy model obiektowy dla źródeł ODBC, zdalne obiekty danych (RDO - ang. Remote Database Objects). Obiekty RDO umożliwiały dostęp do danych ODBC z pominięciem Jet. Uzyskano dzięki temu wzrost szybkości działania aplikacji. Mimo iż obiekty RDO były krokiem naprzód, programiści (w tym również autorzy tej książki) nie byli zadowoleni z konieczności uczenia się dwóch modeli obiektowych dostępu do danych. Większość z nich pracowała już z obiektami DAO i nigdy nie nauczyła się obsługiwać RDO. Odpowiedzią Microsoftu było ODBCDirect, rozszerzenie modelu obiektowego DAO, które wykorzystywało obiekty RDO jako metody dostępu do zewnętrznych danych bez użycia Jet. Istniały już wówczas cztery metody dostępu do danych: API ODBC, DAO, RDO oraz ODBCDirect. Pomnażanie modeli obiektu osiągnęło punkt krytyczny i jasnym było, że coś należy z tym zrobić. Stąd inicjatywa Microsoftu o nazwie Universal Data Access.
Universal Data Access
Gdy istniało tak wiele metod dostępu do danych, Microsoft postanowił, poprzez inicjatywę Universal Data Access, stworzyć nowy standard. Pierwszym etapem jej wprowadzania były bazy danych OLE - otwarta specyfikacja zaprojektowana jako kontynuacja sukcesu ODBC. Bazy danych OLE to otwarty standard, umożliwiający dostęp do każdego rodzaju danych. ODBC stworzono jako metodę dostępu do danych w bazach relacyjnych, podczas gdy bazy danych OLE zaprojektowano z myślą zarówno o relacyjnych jak i nierelacyjnych źródłach danych (skrzynki pocztowe, tekstowe i graficzne dane w sieci WWW, usługi katalogowe oraz przechowywane na komputerach klasy mainframe dane IMS i VSAM). ODBC używa sterowników ODBC do komunikowania się ze źródłami danych, natomiast bazy danych OLE wykorzystują do tego celu dostawców danych. Bazy danych OLE umożliwiają nauczenie się tylko jednego modelu obiektowego dla wszystkich baz a nawet używanie tego modelu podczas pracy z nierelacyjnymi źródłami danych. Technologia OLE to znaczny postęp w porównaniu z ODBC, ponieważ potrafi porozumiewać się z wieloma różnymi źródłami danych. Aby zapewnić kompatybilność z poprzednimi wersjami, do baz danych OLE dołączono dostawcę dla ODBC. Dzisiaj istnieją również dostawcy dla Jet, SQL Server, Oracle, NT 5 Active Directory i wielu innych programów.
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 |
|
Obiekty ActiveX Data (ADO)
Obiekty ActiveX Data (ADO) to model obiektowy, którego możesz używać w celu pobierania danych z baz OLE. Technologia ta istniała już od pewnego czasu, a od wersji 2.0 stała się preferowaną przez Microsoft metodą dostępu do danych. Przyjrzyjmy się historii obiektów ADO.
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:
Microsoft Data Links.
Stałe zestawy rekordów.
Zestawy rekordów tworzone przez użytkownika.
Zestawy rekordów OLAP.
Wszystkie te technologie opisane są w rozdziale 7., „Zaawansowane ADO”.
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:
ADO - dla operacji DDL i zabezpieczeń (ADOX);
JRO XE "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ć wersji 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 Microsoft wydaje nowe wersje obiektów ADO niezależnie od pakietu Office i naszej książki, więcej informacji i najnowsze szczegóły znajdziesz na stronie WWW poświęconej tym zagadnieniom. Umieszczono na niej mnóstwo próbek kodu i dokumentacji technicznej. Strona ta przedstawiona jest na rysunku 6.2 i znajduje się pod adresem http:// www.microsoft.com/data. |
|||
Rysunek 6.2. Strona WWW dotycząca obiektów ADO i baz OLE |
|
Model obiektowy ADO
Model obiektu ADO jest bardzo prosty i płaski. W przeciwieństwie do modeli DAO i RDO model ADO nie jest hierarchiczny. Znajduje się on na rysunku 6.3.
Rysunek 6.3. Model obiektowy ADO |
|
Model obiektowy ADO składa się z siedmiu obiektów:
Connection.
Recordset.
Command.
Parameter.
Field.
Property.
Error.
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
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 XE "Connection:obiekt" 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
Dim conn As ADODB.Connection
On Error GoTo Proc_Err
'Utwórz obiekt połączenia
Set conn = New ADODB.Connection
With conn
'Ustaw właściwość dostarczyciela
'W ten sposób nakazujemy Ado użycie JOLT
.Provider = "Microsoft.Jet.OLEDB.4.0"
'W ciągu połączenia określ ścieżkę
'W tym miejscu możesz określić informacje
'dotyczące zabezpieczeń (co opisaliśmy w kolejnych rozdziałach)
.ConnectionString = "data source=C:\northwind.mdb"
'W ten sposób określamy tryb otwarcia bazy
'Możesz teraz dokonać wyboru między trybem "z wyłącznością"
'a "tylko do odczytu"
.Mode = adModeReadWrite
'Use the open method
.Open
End With
MsgBox "Połączony poprzez " & conn.Provider & _
" dostawcę OLE DB!", vbInformation
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description, vbCritical
Resume Proc_Exit
End Sub
Na wydruku tym wykorzystaliśmy następujące właściwości obiektu Connection:
Provider.
ConnectionString.
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.
Otwarcie połączenia w Accessie 2000
Gdy używasz ADO w aplikacji działającej w Accessie 2000, określenie ciągu połączeniowego do tej samej bazy jest krótsze. Ponieważ Access sam korzysta z globalnego obiektu Connection (jak CurrentDB w starszych wersjach DAO), możesz określić właściwość Connection, używając obiektu CurrentProject.Connection:
Dim conn As ADODB.Connection
Set conn = CurrentProject.Connection
Wykonywanie wyrażeń SQL w obiekcie Connection
W aktualnym obiekcie Connection możesz wykonywać instrukcje SQL. Przypomina to wykonywanie metod z obiektu bazy danych w DAO.
Wydruk 6.2 przedstawia, jak wykonywać wyrażenie SQL w obiekcie Connection.
Wydruk 6.2. Wykonywanie wyrażenia SQL w obiekcie Connection
Sub ConnExecute()
'Procedura ta spowoduje utworzenie połączenia z bazą
'danych Accessa przy użyciu dostawcy OLE DB dla Jeta,
'a następnie wykona polecenie
'Z książki "Access 2000 Księga eksperta" (Helion)
'Autorzy: Forte, Howe, Ralston
Dim conn As ADODB.Connection
Dim strSQL As String
Dim lngRecordsAffected As Long
On Error GoTo Proc_Err
'Utwórz obiekt połączenia
Set conn = New ADODB.Connection
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) & "));"
conn.Execute strSQL, lngRecordsAffected
MsgBox lngRecordsAffected & " rekordy zaktualizowane!", vbInformation
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.
Obiekty ADO: Recordset
Obiekt Recordset XE "Recordset:obiekt" jest programowym zbiorem danych pochodzących z tabeli, kwerendy lub procedury SQL. Posiada on pola, w których znajdują się dane z wierszy tabeli lub kwerendy, na której jest oparty. Aby otworzyć ten obiekt, musisz użyć następującej składni:
Recordsetobject.Open "Statement", _
ActiveConnection, CursorType, LockType, Options
W tabeli 6.1 znajdują się opisy każdego z parametrów.
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.
Wydruk 6.3. Otwarcie obiektu Recordset
Sub OpenRecordset()
'Procedura ta spowoduje otwarcie w aktualnej bazie
'zestawu rekordów opartego na tabeli Customers,
'a następnie wydrukuje te rekordy
'Z książki "Access 2000 Księga eksperta" (Helion)
'Autorzy: Forte, Howe, Ralston
Dim conn As ADODB.Connection
Dim rst As ADODB.Recordset
On Error GoTo Proc_Err
'Utwórz połączenie
Set conn = CurrentProject.Connection
'Utwórz nowy zestaw rekordów
Set rst = New ADODB.Recordset
'Otwórz zestaw rekordów
rst.Open "Customers", _
conn, adOpenForwardOnly, adLockReadOnly, adCmdTableDirect
'Utwórz pętlę w zestawie rekordów
Do Until rst.EOF
Debug.Print rst!CompanyName
rst.MoveNext
Loop
'Zamknij i usuń zestaw rekordów
rst.Close
Set rst = Nothing
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description, vbCritical
Resume Proc_Exit
End Sub
Tabela 6.1.
Parametry otwarcia obiektu Recordset
Argument |
Wymagany |
Uwagi |
Domyślnie |
Statement |
Tak |
Nazwa tabeli, kwerendy bądź prawidłowe wyrażenie SQL |
- |
ActiveConnection |
Tak |
Prawidłowy obiekt Connection bądź prawidłowy ciąg połączenia |
- |
Cursor Type |
Nie |
adOpenDynamic - Możliwość przeglądania zmian w zestawie rekordów, nawet tych dokonanych przez innych użytkowników adOpenForwardOnly - Przekazywanie dalej jedynie nieprzewijalnych zestawów rekordów adOpenKeyset - Brak możliwości przeglądania zmian dokonanych przez innych użytkowników; możliwość przeglądania zmian dokonanych przez aktualnego użytkownika adOpenStatic - Brak możliwości przeglądania zmian w zestawie rekordów |
adOpenForwardOnly |
Lock Type |
Nie |
adLockBatchOptimistic - Blokuje rekordy w programie wsadowym adLockOptimistic - Blokowanie optymistyczne adLockPessimistic - Blokowanie pesymistyczne adLockReadOnly - Tylko do odczytu |
adLockReadOnly |
Options |
Nie |
adCmdFile - otwarcie przechowywanego na dysku zestawu rekordów adCmdStoredProc - Przechowywana procedura SQL Server lub kwerenda 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 |
adCmdUnknown |
Na wydruku 6.3 użyliśmy obiektu Connection, bazującego na aktualnym połączeniu:
'Otwórz zestaw rekordów
rst.Open "Customers", _
conn, adOpenForwardOnly, adLockReadOnly, adCmdTableDirect
W Accessie 2000 możesz użyć wyrażenia CurrentProject.Connection:
'Otwórz zestaw rekordów
rst.Open "Customers", _
CurrentProject.Connection, _
adOpenForwardOnly, adLockReadOnly, adCmdTableDirect
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
Użycie Recordset z obiektami Command i Parameter
Obiekt Command XE "Command:obiekt" przedstawia dość specyficzne polecenie, które będziesz wykonywał na źródle danych poprzez jego dostawcę. Przykładem polecenia jest kwerenda funkcjonalna. Możesz również użyć Command w połączeniu z obiektem Parameter XE "Parameter:obiekt" , w celu wykona-
nia kwerend parametrycznych w Accessie lub procedur przechowywanych serwera SQL. Obiekt Parameter odnosi się do parametru lub argumentu związanego z obiektem Command.
|
Przyjrzyjmy się teraz, w jaki sposób wykonać zapisaną kwerendę parametryczną Accessa. Kwerenda ta znajduje się na płycie CD-ROM, w pliku Rozdz06.mdb, pod nazwą qryCustOrders_Prm. Oto jej treść w SQL: |
PARAMETERS OrderID Long;
SELECT Orders.*
FROM Orders AS Orders
WHERE (((Orders.OrderID)=[OrderID]));
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 |
|
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.
|
||
|
Gdy używasz obiektów Command, Jet obsługuje jedynie parametry wejściowe. SQL Server oraz inne serwery baz danych potrafią obsługiwać parametry wyjściowe w zapisanych procedurach, tak więc nie próbuj wprowadzać parametrów wyjściowych. |
With prm
.Name = "OrderID"
.Value = 10248
.Type = adInteger
.Direction = adParamInput
End With
cmd.Parameters.Append prm
Teraz korzystamy z metody Execute XE "Execute:metoda" 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 polecenia, 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.
Wydruk 6.4. Wykonywanie polecenia
Sub OpenRecordsetviaCommand()
'Procedura ta spowoduje otwarcie w aktualnej bazie
'zestawu rekordów opartego na obiekcie Command,
'Obiekt ten będzie odwoływał się do znajdującej się w bazie
'kwerendy qryCustOrders_Prm
'Z książki "Access 2000 Księga eksperta" (Helion)
'Autorzy: Forte, Howe, Ralston
Dim conn As ADODB.Connection
Dim rst As ADODB.Recordset
Dim cmd As ADODB.Command
Dim prm As ADODB.Parameter
On Error GoTo Proc_Err
'Utwórz połączenie
Set conn = CurrentProject.Connection
Set cmd = New ADODB.Command
With cmd
.ActiveConnection = conn
.CommandText = "qryCustOrders_Prm"
.CommandType = adCmdTable
End With
Set prm = New ADODB.Parameter
With prm
.Name = "OrderID"
.Value = 10248
.Type = adInteger
.Direction = adParamInput
End With
cmd.Parameters.Append prm
Set rst = cmd.Execute
'Utwórz pętlę w zestawie rekordów
Do Until rst.EOF
Debug.Print rst!OrderDate
rst.MoveNext
Loop
'Zamknij i usuń zestaw rekordów
rst.Close
Set rst = Nothing
Set cmd = Nothing
Set prm = Nothing
Set conn = Nothing
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description, vbCritical
Resume Proc_Exit
End Sub
Wykonywanie kwerendy funkcjonalnej
poprzez obiekt Command
|
Możesz wykonywać zapisane kwerendy funkcjonalne Accessa poprzez obiekt Command. W pliku Rozdz06.mdb znajduje się kwerenda qryUpdateTitle, aktualizująca stanowisko każdego z pracowników w tabeli Customers, od Account Manager do Account Executive. Oto ta kwerenda w języku SQL: |
UPDATE Customers SET Customers.ContactTitle = "Account Executive"
WHERE (((Customers.ContactTitle)="Account Manager"));
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ć.
Wydruk 6.5. Wykonywanie kwerendy funkcjonalnej Accessa poprzez ADO
Sub ActionQueryCmd()
'Procedura ta spowoduje uruchomienie kwerendy funkcjonalnej
'poprzez obiekt Command, a następnie wydrukuje właściwości
'zestawu rekordów
'Z książki "Access 2000 Księga eksperta" (Helion)
'Autorzy: Forte, Howe, Ralston
Dim cmd As ADODB.Command
Dim lngRecordsAffected As Long
On Error GoTo Proc_Err
Set cmd = New ADODB.Command
Dim rst As ADODB.Recordset
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
MsgBox lngRecordsAffected & " rekordy zaktualizowane!", _
vbInformation
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Obiekty Field i Property
Obiekty Field XE "Field:obiekt" i Property XE "Property:obiekt" świetnie nadają się do odnajdywania informacji o tabeli lub zestawie rekordów. Obiekt Field przedstawia każdą kolumnę pól w zestawie rekordów. Obiekt Property przedstawia każdą właściwość, niezależnie od tego, jakiego obiektu dotyczy kwerenda. Możesz przechodzić przez każde pole w zestawie rekordów lub właściwość zmiennej obiektu poprzez składnię For...Each - patrz wydruk 6.6.
Wydruk 6.6. Wykorzystanie obiektów Field i Property poprzez ADO
Sub FieldandProperty()
'Procedura ta spowoduje wydrukowanie wszystkich pól
'zestawu rekordów wraz z ich wartościami oraz właściwości
'zestawu rekordów
'Z książki "Access 2000 Księga eksperta" (Helion)
'Autorzy: Forte, Howe, Ralston
Dim rst As ADODB.Recordset
Dim fld As ADODB.Field
Dim prp As ADODB.Property
On Error GoTo Proc_Err
Set rst = New ADODB.Recordset
'Otwórz zestaw rekordów oparty na tabeli klienci
rst.Open "Customers", CurrentProject.Connection
'Wydrukuj nazwę i wartość każdego pola
Debug.Print "Table Fields:"
For Each fld In rst.Fields
Debug.Print fld.Name & ": " & fld.Value
Next fld
'Wydrukuj właściwości tabeli
Debug.Print
Debug.Print "Table Properites:"
For Each prp In rst.Properties
Debug.Print prp.Name
Next prp
rst.Close
Set rst = Nothing
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Obiekty ADO: Error
Podczas pisania kodu zdarza się popełnić błąd lub umożliwić dokonywanie zmian poza kontrolą użytkownika (jak na przykład umożliwić administratorowi sieci LAN przeniesienie bazy danych bez poinformowania Cię o tym). Obiekt Connection posiada zbiór obiektów Error, które przedstawiają każdy z występujących błędów. Obiekt Error XE "Error:obiekt" posiada kilka istotnych właściwości. Umieściliśmy je w tabeli 6.2.
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.
Wydruk 6.7. Użycie obiektu Error
Sub ConnErrHandle()
'Procedura ta wymusi powstanie błędu, a następnie
'użyje obiektu Error w celu uzyskania informacji o tym błędzie
'Z książki "Access 2000 Księga eksperta" (Helion)
'Autorzy: Forte, Howe, Ralston Dim conn As ADODB.Connection
Dim rst As ADODB.Recordset
On Error GoTo Proc_Err
Set conn = CurrentProject.Connection
Set rst = New ADODB.Recordset
Rysunek 6.5. Komunikat o błędzie wykorzystujący obiekt Error |
|
'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
'Dla każdego z błędów wyświetl komunikat
MsgBox "Błąd ADO: " & adoErr.Description & _
vbNewLine & "Błąd wewnętrzny: " & _
adoErr.NativeError & _
vbNewLine & "Procedura SQL: " & _
adoErr.SQLState & _
vbNewLine & "Źródło: " & _
adoErr.Source, vbCritical, _
"Kod błędu: " & adoErr.Number
Next adoErr
Resume Proc_Exit
End Sub
Przejście z obiektów DAO do ADO
Wstęp do obiektów ADO wykazał, że istnieje wiele podobieństw między nimi a obiektami DAO. Przez całą tę książkę będziemy pokazywać, w jaki sposób możesz korzystać z obiektów ADO, porównując je do DAO. Ta część stanowi wstęp do procesu konwersji oraz porównanie tych dwóch modeli obiektu.
Konwersja z poprzednich wersji Accessa
Podczas przeprowadzania konwersji z poprzedniej wersji bazy danych Accessa do Accessa 2000 powinieneś wziąć pod uwagę, że ADO jest nową, domyślną metodą dostępu do danych. Może to powodować zamieszanie podczas tworzenia obiektu o tej samej nazwie w ADO jak i w DAO (na przykład „recordset”). Jeśli w Accessie użyjesz następującego kodu:
Dim db As Database
Dim rst as Recordset
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 XE "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
Pozwoli to wyeliminować możliwość pomyłki w zmiennych obiektu DAO podczas konwersji.
Czy warto przejść na obiekty ADO?
W wypadku tworzenia nowej aplikacji w Accessie 2000 odpowiedź jest jedna: używać ADO. Lecz co w sytuacji, gdy konwertujemy do Accessa 2000 już istniejąca aplikację? Wówczas przejście na obiekty ADO również powinno być brane pod uwagę. Z pewnością zechcesz przejść na obiekty ADO jak najszybciej, by móc korzystać z opcji niedostępnych w DAO. Poza tym, Microsoft zapowiedział odejście od technologii DAO, więc w kolejnych wersjach Accessa obiekty DAO nie będą bezpośrednio obsługiwane. Ponieważ przyszłość należy do technologii ADO, powinieneś poważnie rozważyć jej wprowadzenie. Czy masz na to czas? Pieniądze? Elementami, które powinieneś brać w tych rozważaniach pod uwagę, powinny być poziom Twoich umiejętności oraz wysokość budżetu.
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!
Uruchom Accessa 97. Jeśli aplikacja jest w starszej wersji niż Access 97, najpierw musisz ją skonwertować do Accessa 97.
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.
Ze strony WWW Microsoftu pobierz i zainstaluj ADO 2.1.
Rozpocznij konwersję od procedur, które nie komunikują się z innymi. Gdy skończysz konwersję jednej procedury, dwukrotnie ją przetestuj. Dopiero wtedy przejdź do kolejnej. W zależności od wielkości bazy danych, operacja ta może trwać dni lub nawet tygodnie.
Nie usuwaj starych procedur. Zmieniaj ich nazwy na NazwaProcedury_DAO, dodając na końcu _DAO, aby móc szybko zmienić nazwę procedury ADO (używającej końcówki _ADO) i podmienić procedurę DAO podczas testowania.
Po skonwertowaniu kodu w osobnych procedurach zacznij oględziny kodu tych większych i bardziej złożonych. Nie trać czasu na poprawianie innych rzeczy w tych procedurach. Na dokonanie poprawek przyjdzie czas później. Zmień tylko kod DAO. Użyj tej samej metodologii testowania, co w punkcie 5.
Po skonwertowaniu całego kodu przetestuj jednocześnie obie wersje aplikacji. Później przekaż nową aplikację do testów innemu programiście.
Utwórz metody, które umożliwią użytkownikom łatwe wycofywanie dokonanych zmian. Dzięki temu, jeśli aplikacja powoduje błędy w danych, użytkownicy będą mogli powrócić do poprzedniego stanu.
Oddaj do rąk użytkowników wersję beta, by mogli przetestować ją w codziennym użyciu. Do testowania wersji ADO wybierz kilku wiarygodnych użytkowników. Nie usuwaj poprzedniej, działającej wersji DAO. Utwórz skrót do niej, na wypadek wystąpienia błędów zakłócających pracę użytkowników.
Gdy jesteś już pewien, że użytkownicy w wystarczający sposób przetestowali aplikację, przeprowadź konwersję do Accessa 2000 i powtórz kroki 7-9.
|
||
|
Upewnij się, że użytkownicy faktycznie testują aplikację! Aby sprawdzić, czy użytkownicy faktycznie testują aplikację w wystarczający sposób, możesz dołączyć do niej technikę, której używamy my. Nie chcemy być obarczani odpowiedzialnością za błędy, które użytkownik mógł znaleźć podczas testowania, więc w wersjach beta umieszczamy bardzo szczegółowe oprogramowanie monitorujące. Podczas uruchamiania każdej procedury, nawet tak prostej jak przycisk Zamknij, zapisujemy w bazie wszelkie informacje. Dzięki temu wiemy, jak często dany użytkownik uruchamiał określoną procedurę, a nawet jak często tworzył dany raport. Później analizujemy te dane i w zależności od wyników tej analizy prosimy użytkowników o przetestowanie określonych części aplikacji. Procedura ta daje nam pewność, że użytkownicy przetestowali wszystkie elementy, zanim przekształcimy wersję beta w wersję końcową. |
Kiedy nie dokonywać konwersji?
Niewielkie projekty, z małym budżetem, nie powinny być konwertowane do technologii ADO. Jak widzisz, procedura testowania składa się z wielu etapów. Jeśli użytkownicy nie są w stanie pokryć kosztów testowania, zaniechaj konwersji. Technologia DAO działa zadowalająco w Accessie 2000. Co więcej, w DAO 3.6 poprawiono kilka błędów, tak więc kod napisany w tej technologii powinien bez żadnych modyfikacji działać lepiej w Accessie 2000 niż 97.
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.
Porównanie modelu obiektowego
ADO i DAO
DAO posiada olbrzymi model obiektowy, składający się z ponad 50 elementów. Model obiektowy w technologii ADO jest dużo mniejszy i zawiera ich jedynie 7. Gdzie podziała się reszta? W tej części zobaczysz, jak wygląda porównanie dostępu do danych
w obu tych technologiach. Temat ten został omówiony w rozdziałach 22. „Replikacja i JRO” i 7. „Zaawansowane ADO”. 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
Obiekt DAO |
Obiekt ADO |
DBEngine |
Brak |
Workspace |
Brak |
Database |
Connection |
Recordset |
Recordset |
Field |
Field |
QueryDef |
Command |
Parameter |
Parameter |
Error |
Error |
Rozdział 7.
Zaawansowane ADO
W tym rozdziale:
Użycie dostawcy OLE DB dla Accessa.
Uzyskanie poprzez ADO dostępu do danych w bazach nierelacyjnych.
Zaawansowana obróbka danych przy użyciu ADO.
Definiowanie danych przy użyciu ADOX.
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.
Użycie dostawcy OLE DB dla Jet w Accessie 2000
Gdy używasz ADO XE "ADO" w aplikacjach Accessa, najprawdopodobniej będziesz korzystał z dostawcy OLE DB XE "OLE DB" dla Jet (użycie dostawcy OLE DB dla SQL Server jest omówione w rozdziale 15). Dostawca ten pozwala na bezpośredni dostęp do plików typu MDB. Zdolność bezpośredniej komunikacji ze źródłem danych to wielki krok naprzód dla ADO. Aby użyć dostawcy OLE DB dla Jet, musisz podać jego nazwę i pełną ścieżkę dostępu do bazy danych jako część ciągu połączeniowego. Aby zachować przejrzystość, umieszczono w ADO właściwość Provider XE "Provider:właściwość" , której odpowiednie ustawienie umożliwi użycie dostawcy dla Jet. Jego unikatowym CLASSID w ciągu połączenia jest: Microsoft.Jet.OLEDB.4.0. Poniższy przykład przedstawia, jak tworzyć połączenie do bazy Microsoft Accessa przy użyciu dostawcy OLE DB dla Jet:
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"
.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. |
Jet OLEDB:System database |
Lokalizacja systemowej bazy Jet, która ma być używana przez określonych użytkowników. Powoduje to unieważnienie wartości ustalonej w rejestrze lub klucza rejestru systemdb używanego wraz z Jet OLEDB:Registry Path. Właściwość ta może zawierać ścieżkę dostępu do pliku. |
Jet OLEDB:Database Password |
Hasło używane do otwarcia bazy danych. Od hasła użytkownika różni się tym, że hasło bazy danych dotyczy pliku a nie konkretnego użytkownika. Więcej informacji znajdziesz w rozdziale 21. „Zagadnienia wielodostępu, serwer plików, blokowanie”. |
Jet OLEDB:Engine Type |
Określenie silnika, który aktualnie jest wykorzystywany w celu uzyskania dostępu do danych. |
Jet OLEDB:Database Locking Mode |
Tryb używany podczas blokowania bazy danych. Więcej informacji w rozdziale 21., dotyczącym obsługi wielu użytkowników. Zauważ, że baza może być otwarta tylko w jednym trybie jednocześnie. Użytkownik, który jako pierwszy otwiera bazę, określa jej tryb blokowania. |
Jet OLEDB:Global Partial Bulk Ops |
Właściwość ta określa zachowanie Jet w przypadku błędu w masowych operacjach SQL DML. Może zostać unieważniona przez ustawienie właściwości Jet na OLEDB:Partial Bulk Ops. |
Jet OLEDB:Global Bulk Transactions |
Określa, czy masowe operacje SQL są wykonywane. Właściwość ta wskazuje ustawienie domyślne dla wszystkich operacji w aktualnym połączeniu. |
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
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 XE "Connection:obiekt"
- 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 XE "Open:metoda" :
Dim rst As ADODB.Recordset
Set rst = New ADODB.Recordset
rst.Open "Customers", CurrentProject.Connection
|
||
|
Zalecamy ostrożność podczas korzystania z CurrentProject.Connection. Pamiętaj, że polecenie to nie może być używane w innym środowisku niż Access 2000. Jeśli zamierzasz wykorzystać swój kod w innej aplikacji niż Access (np. Visual Basic), do utworzenia połączenia musisz użyć dłuższej składni. |
Rola Microsoft Data Links
w podłączaniu się do bazy danych
Teraz, gdy obiekty ADO są podstawowym sposobem uzyskiwania dostępu do danych, twórcy Accessa uznali że programiści potrzebują standardowego sposobu obsługiwania, ładowania, otwierania i zarządzania informacjami o połączeniu OLE DB, przypominającego dawne narzędzie do zarządzania i administrowania sterownikami ODBC. Możliwość tę dają Microsoft Universal Data Links XE "Universal Data Links" (UDL). Mechanizm UDL XE "UDL" umożliwia zapisywanie informacji o połączeniu w pliku UDL, a następnie otwarcie obiektu Connection w ADO, na podstawie informacji zapisanych w tym pliku. Możliwość ta będzie bardzo przydatna, gdy chcesz przetestować podłączenie bazy danych do różnych komputerów bez zmiany kodu.
Mechanizm Microsoft Universal Data Links składa się z:
graficznego interfejsu użytkownika, służącego do tworzenia połączeń OLE DB;
interfejsu automatyzacji.
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.
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;"
|
Fragment kodu na wydruku 7.1 znajduje się w umieszczonym na dołączonej do książki płycie CD. Przedstawia on, jak utworzyć obiekt Connection oparty na pliku UDL, umieszczonym w folderze bazy danych Northwind. Łączysz się z bazą i wypełniasz okno za wartością tabeli Customers. Bardzo przydatną cechą tego kodu jest to, że jeśli będziesz chciał użyć bazy Northwind w wersji SQL, wystarczy zmienić właściwości pliku UDL i uruchomić kod ponownie. |
Wydruk 7.1. Użycie UDL w kodzie VBA
Private Sub OpenViaLink()
' Procedura używa połączenia ADO, pobierając informacje
' o połączeniu z pliku Microsoft UDL
' Następnie otwierany jest recordset
' Z książki "Access 2000 Księga eksperta" (Helion)
' Autorzy: Forte, Howe, Ralston
Dim conn As ADODB.Connection
Dim rst As ADODB.Recordset
On Error GoTo Proc_Err
Set conn = New ADODB.Connection
' Otwarcie połączenia poprzez plik UDL
' Pozwala to dynamicznie zmienić bazę danych, zmieniając
' plik UDL
conn.Open "File Name=c:\chapter7.udl;"
Set rst = New ADODB.Recordset
' Otwarcie wyniku wyrażenia SQL
rst.Open "Select * From Customers", conn
' Przeglądamy wynik i wypisujemy wartości
Do Until rst.EOF
Debug.Print rst!CompanyName
rst.MoveNext
Loop
' Porządki
rst.Close
conn.Close
Set rst = Nothing
Set conn = Nothing
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Zarządzanie plikami UDL
Istnieją dwa sposoby zarządzania plikami UDL. Pierwszy - poprzez ich interfejs użytkownika. W Panelu sterowania systemu Windows znajduje się ikona Microsoft Data Links, która umożliwia wyświetlenie listy wszystkich plików UDL we wskazanym folderze (rysunek 7.4). Łatwiej jest jednak użyć Eksploratora Windows i bezpośrednio otworzyć żądany plik.
Rysunek 7.4.
Zarządzanie |
|
Programowe zarządzanie plikami UDL
Ponieważ pliki UDL posiadają swój własny interfejs automatyzacji, możesz nimi zarządzać i kontrolować je programowo. Aby użyć UDL w kodzie VBA, ustaw odwołanie na typ biblioteki o nazwie Microsoft OLE DB Service Component 1.0 Type Library XE "type library" (rysunek 7.5).
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 XE "PromptNew:metoda" obiektu DataLinks XE "DataLinks:obiekt" . 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.
Wydruk 7.2. Programowe UDL
Private Sub OpenUDLDialog()
' Procedura używa interfejsu automatyzacji
' UDL do utworzenia połączenia
' Z książki "Access 2000 Księga eksperta" (Helion)
' Autorzy: Forte, Howe, Ralston
Dim strConnect As String
Dim rst As ADODB.Recordset
' Odwołanie do Microsoft UDL
Dim udl As MSDASC.DataLinks
On Error GoTo Proc Err
' Tworzenie obiektu Data Link
Set udl = New MSDASC.DataLinks
' Ustawienie obiektu connection na podstawie
' okna dialogowego nowego Data Link
strConnect = udl.PromptNew
Set rst = New ADODB.Recordset
' Otwarcie wyniku na podstawie
' danych wprowadzonych przez użytkownika
' do okna Data Link
rst.Open "Select * From Customers", strConnect
' Wyświetl pierwszy rekord
MsgBox rst!CompanyName
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Uzyskanie poprzez ADO dostępu do danych w bazach nierelacyjnych
Nawiązując do omówionego w rozdziale 6. wykorzystania Accessa do komunikowania się z danymi nierelacyjnymi XE "dane nierelacyjne" (jak np. Excel), ADO posiada kilka zaawansowanych opcji, które ułatwią Ci pracę z tym typem danych. Teraz przyjrzymy się opcjom:
Lista użytkowników Jet.
Tworzenie zestawów rekordów.
Kształtowanie danych.
Lista użytkowników Jet
Dostawca OLE DB dla Jet umożliwi Ci otwarcie zestawu rekordów zawierającego nazwy użytkowników aktualnie zalogowanych do bazy, której nazwę określisz w połączeniu. Dzięki temu nie będziesz już musiał korzystać z dostarczanego z poprzednimi wersjami Jet narzędzia LDBView. Kod na wydruku 7.3 przedstawia sposób utworzenia zestawów rekordów z aktualnymi użytkownikami bazy danych. W listingu tym użyliśmy metody OpenSchema obiektu Connection XE "Connection:obiekt" z parametrem charakterystycznym dla aparatu JET/JOLT. Zauważ, że ADO nie podpowiada Ci żadnych stałych. Będziesz musiał ręcznie wprowadzić wartość GUID: ({947bb102-5d43-11d1-bdbf-00c04fb92675}). Pozostaje nam mieć nadzieję, że niedogodność ta zostanie poprawiona w kolejnej wersji obiektów ADO.
Wydruk 7.3. Użycie listy użytkowników
Sub UserRoster()
' Procedura używa listy użytkowników
' do sprawdzenia, kto jest zalogowany do bazy danych
' Z książki "Access 2000 Księga eksperta" (Helion)
' Autorzy: Forte, Howe, Ralston
Dim conn As ADODB.Connection
Dim rst As ADODB.Recordset
On Error GoTo Proc Err
Set conn = New ADODB.Connection
' Otwarcie bazy danych
With conn
.Provider = "Microsoft.Jet.OLEDB.4.O"
.ConnectionString = "data source=f:\employee.mdb"
.Open
End With
' Tworzenie wyniku opartego na ilości użytkowników
' bazy danych
Set rst = conn.OpenSchema(adSchemaProviderSpecific, , _
"{947bb102-5d43-iidl-bdbf-00c04fb92675}")
' Dla każdego użytkownika wypisz nazwę jego komputera i
' inne informacje
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
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Tworzone zestawy rekordów
Obiekty ADO stwarzają Ci możliwość tworzenia zestawów rekordów „z niczego”. Możesz teraz korzystać z metod Fields.Append XE "Append:metoda" i AddNew XE "AddNew:metoda" , aby dodawać pola i dane do zestawu rekordów. Technika ta nadaje się świetnie do tworzenia 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.
Wydruk 7.4. Tworzenie zestawu rekordów z nierelacyjnych danych
Sub CreatableRst_Files(strPath As String)
'Oto przykład tworzenia zestawu rekordów
'z danych nierelacyjnych
'Tworzy zestaw rekordów składający się z nazw i rozszerzeń plików
'Z książki "Access 2000 Księga eksperta" (Helion)
'Autorzy: Forte, Howe, Ralston
Dim rst As ADODB.Recordset
On Error GoTo Proc_Err
Set rst = New ADODB.Recordset
With rst
'Wykonaj operacje lokalne
.CursorLocation = adUseClient
'Teraz dodaj pole
.Fields.Append "FileName", adVarChar, 255, adFldRowID
.Fields.Append "Extention", adChar, 3, adFldFixed
'Otwórz rst
.Open , , adOpenStatic, adLockBatchOptimistic
'Upewnij się, że w ścieżce dostępu znajduje się znak \
If Right(strPath, 1) <> "\" Then strPath = strPath & "\"
'Pobierz listę wszystkich plików w folderze, a następnie
'dodaj je do zestawu rekordów
strPath = Dir(strPath & "*.*", vbNormal)
' Nie umieszczaj wpisów . i ..
Do While strPath > ""
'Teraz dodaj do rst nowy rekord
.AddNew Array("FileName", "Extention"), _
Array(strPath, Right(strPath, 3))
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 XE "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 XE "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.
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 |
|
Wydruk 7.5. Tworzenie rekordu z ukształtowanymi danymi i wypełnianie siatki MSHFlexGrid w VB
Sub CubeGroupHierarchy()
'Wypełnij formant MSFLEXGRID
'Z książki "Access 2000 Księga eksperta" (Helion)
'Autorzy: Forte, Howe, Ralston
'Kod do wypełnienia zestawu rekordów
Dim rst As ADODB.Recordset
Dim strConnect As String
Set rst = New ADODB.Recordset
'Ustaw właściwości połączenia
'Każ ADO użyć dostarczyciela OLE DB dla Data Shaping
'Następnie podłącz wbudowanego dostarczyciela OLE DB do
'wybranego źródła danych
strConnect = "Provider=MSDataShape" & _
";data provider=Microsoft.Jet.OLEDB.4.0" & _
";data source=" & App.path & "\sample.mdb"
'Wprowadź SQL Data Shape
rst.Source = "shape {Select customerid, " & _
"Region from Customers} rst1 " & _
"COMPUTE COUNT (rst1.customerid) AS CustCount, rst1 By Region "
rst.ActiveConnection = strConnect
rst.Open , , adOpenStatic, adLockBatchOptimistic
'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 HYPERLINK "http://www.microsoft.com/data"
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.
Wydruk 7.6. Użycie Data Shaping w programie Microsoft Excel
Sub CUBRelation()
'Użycie OLAP z Microsoft Excel
'Z książki "Access 2000 Księga eksperta" (Helion)
'Autorzy: Forte, Howe, Ralston
Dim rst As ADODB.Recordset
Dim strConnect As String
Set rst = New ADODB.Recordset
'Ustaw właściwości połączenia
'Nakaż ADO użycie dostarczyciela OLE DB dla Data Shaping
'Następnie podłącz wbudowanego dostarczyciela OLE DB do
'wybranego źródła danych
strConnect = "Provider=MSDataShape;" & _
";data provider=Microsoft.Jet.OLEDB.4.0" & _
";data source=C:\sample.mdb"
'Wprowadź SQL Data Shape
rst.Source = "shape {Select * from customers where Customerid='ALFKI'}"&_
" Append " & _
"({Select * From Orders} As rsOrders " & _
"RELATE customerid to customerid)"
rst.ActiveConnection = strConnect
rst.Open , , adOpenStatic, adLockBatchOptimistic
'Pokaż RST
ShowRSTinExcel rst
End Sub
Sub ShowRSTinExcel(rst As ADODB.Recordset, _
Optional blnSKipClear As Boolean = False)
Dim rstChild As ADODB.Recordset
Dim col As ADODB.Field
Dim intCurrentColumn As Integer
Dim intCurrentRow As Integer
If Not blnSKipClear Then
'Clear out the cells
Cells.Select
Selection.ClearContents
End If
Do Until rst.EOF
intCurrentColumn = intCurrentColumn + 1
If Not blnSKipClear Then
intCurrentRow = 1
Else
intCurrentRow = 2
End If
For Each col In rst.Fields
If col.Type <> adChapter Then
Cells(intCurrentColumn, intCurrentRow) = _
col.Name & ": " & col.Value
Else
Set rstChild = col.Value
ShowRSTinExcel rstChild, True
End If
intCurrentRow = intCurrentRow + 1
Next
rst.MoveNext
Loop
Cells(1, 1).Select
End Sub
Zaawansowana obróbka danych przy użyciu ADO
W ostatnim rozdziale pokazaliśmy, jak tworzyć zestawy rekordów zawierające dane i jak korzystać z obiektów Command XE "Command:obiekt" . W tej części pokażemy kilka dodatkowych możliwości obiektów ADO. Przyjrzymy się:
Modyfikowaniu danych w zestawie rekordów.
Trwałym zestawom rekordów.
Modyfikowanie danych w zestawie rekordów
Aby modyfikować dane w zestawie rekordów, musisz jedynie przejść do niego i rozpocząć edycję. Po przejściu do kolejnego rekordu lub użyciu metody Call XE "Call:metoda" dokonane przez Ciebie zmiany zostaną zapisane. Jest to duży krok naprzód w porównaniu z obiektami DAO, gdzie musiałeś najpierw użyć polecenia Edit, a następnie obowiązkowo użyć polecenia Update. Kod na wydruku 7.7 przedstawia, w jaki sposób można dokonać edycji danych.
Wydruk 7.7. Edycja rekordu
Sub Editrecords()
'Procedura edycji danych
'Z książki "Access 2000 Księga eksperta" (Helion)
'Autorzy: Forte, Howe, Ralston
Dim rst As ADODB.Recordset
Dim strSQL As String
On Error GoTo Proc Err
' Tworzenie obiektu recordset
Set rst = New ADODB.Recordset
' Wpisz tu wyrażenie SQL zwracające potrzebne dane
strSQL = "Select * From Customers Where CustomerID='Anton'"
' Otwarcie wyniku za pomocą kursora keyset
rst.Open strSQL, CurrentProject.Connection, _
adOpenKeyset, adLockOptimistic
' Zmiana wiersza
rst!CompanyName = "Nowa nazwa"
' Użycie metody Update lub MoveNext
rst.Update
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
|
||
|
Szybciej jest otworzyć zestaw rekordów bazujący na wyrażeniu SQL wymagającym klucza podstawowego niż otwierać całą tabelę i w niej szukać żądanego rekordu. |
|
|
||
|
Ponieważ zmiany dokonywane w zestawie rekordów uwzględniane są bez użycia polecenia Update, jedynie przez przejście do kolejnego rekordu, zalecamy ostrożność podczas edycji danych. |
Dodawanie rekordu
Dodawanie rekordu przebiega w prawie identyczny sposób jak edycja. Musisz otworzyć zestaw rekordów i użyć metody AddNew XE "AddNew:metoda" . 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.
Wydruk 7.8. Dodawanie rekordu do tabeli
Sub Addrecords()
' Procedura dodaje nowy rekord do tabeli
'Z książki "Access 2000 Księga eksperta" (Helion)
'Autorzy: Forte, Howe, Ralston
Dim rst As ADODB.Recordset
On Error GoTo Proc_Err
' Tworzenie obiektu recordset
Set rst = New ADODB.Recordset
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
Być może zauważyłeś, że otwarłeś tabelę ze stałą adCmdTableDirect XE "adCmdTableDirect:stała" . Jeśli użyjesz tej stałej z typem kursora adOpenDynaset XE "adOpenDynaset:stała" 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
Typ kursora |
Opcje i typy blokowania |
Odpowiednik w DAO |
adOpenForwardOnly |
adLockReadOnly |
dbOpenSnapShot |
AdOpenKeySet |
adLockReadOnly |
Brak odpowiednika |
AdOpenKeySet |
adLockPessimistic |
dnOpenDynaset |
Tabela 7.3.
Kombinacje obiektów ADO dla Accessa (ciąg dalszy)
Typ kursora |
Opcje i typy blokowania |
Odpowiednik w DAO |
AdOpenKeySet |
adLockOptimistic |
dnOpenDynaset |
AdOpenKeySet |
adLockBatchOptimistic |
dnOpenDynaset |
AdOpenStatic |
adLockReadOnly |
dnOpenDynaset |
adOpenDynamic |
adLockOptimistic |
dbOpenTable |
Trwałe zestawy rekordów
Dla tych z was, którzy muszą również zadbać o obsługę użytkowników nie podłączonych do sieci, pojęcie trwałości rekordów to fantastyczny podarunek od firmy z Redmond. Teraz masz bowiem możliwość zapisania zestawu rekordów na dysku i jego obróbkę w aplikacji VB lub VBA. Później możesz ten zestaw ponownie włączyć do bazy. Aby tego dokonać, otwórz zestaw rekordów ADO z typem blokowania adLockBatchOptimistic XE "adLockBatchOptimistic:stała" i używając kursora client. Następnie użyj polecenia Save obiektu Recordset XE "Recordset:obiekt" . Musisz określić nazwę pliku i format, w jakim ma być zapisany. ADO oddaje do Twojej dyspozycji następujące możliwości:
adPersistADTG;
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
Dim strSOL As String
Dim strMsg As String
Dim strNewValue As String
Dim conn As ADODB.Connection
Dim rst As ADODB.Recordset
On Error GoTo Proc Err
strSQL = "Select * From Customers Where CustomerID='ALFKI'"
Set conn = New ADODB.Connection
With conn
.Provider = "Microsoft.Jet.OLEDB.4.O"
.ConnectionString = "data source=c:\sample.mdb"
.Open
End With
Set rst = New ADODB.Recordset
' Należy użyć kursora po stronie klienta
rst.CursorLocation = adUseClient
rst.Open strSQL, conn, adOpenStatic, adLockBatchOptimistic
' Pozwól użytkownikowi zmienić dane, pokazując dane bieżące
strMsg = "Proszę wprowadzić nową nazwę firmy dla: " & _
rst!CompanyName & vbNewLine & _
"ID klienta=" & rst!CustomerID
' Pobierz nową nazwę
strNewValue = InputBox(strMsg)
' Zmień rekord na komputerze klienta i zapisz na dysku
' Nie zmienia to danych w bazie danych
rst.Update "CompanyName", strNewValue
' Zmiana została wprowadzona do recordsetu klienta
On Error Resume Next
' Usuń istniejący plik
Kill "c:\hcado.dat"
On Error GoTo Proc_Err
' Zapisz recordset na dysku
rst.Save "c:\hcado.dat", adPersistADTG
rst.Close
Set rst = Nothing
MsgBox "Zapisane do: c:\hcado.dat", vbInformation
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Sub RstPersiStence Open()
' Przykład pobrania wyniku, odłączenia od bazy danych
' zapisu na dysk a następnie synchronizacji z bazą
' Zapis był wykonany w RstPersistence_Save
' Tu wykonywana jest synchronizacja
' Z książki "Access 2000 Księga eksperta" (Helion)
' Autorzy: Forte, Howe, Ralston
Dim conn As ADODB.Connection
Dim rst As ADODB.Recordset
Dim strSQL As String
Dim strMsg As String
On Error GoTo Proc Err
strSQL = "Select * From Customers Where CustomerID='ALFKI'"
' Pobranie nowego recordset z dysku
Set rst = New ADODB.Recordset
rst.Open "c:\hcado.dat", , adOpenStatic, adLockBatchOptimistic, _
adCmdFile
' Pokazanie danych z bazy danych i z dysku
strMsg = "Wartości w bazie danych: " & _
rst!CompanyName.OriginalValue
strMsg = strMsg & vbNewLine & _
"Wartości na dysku: " & rst!CompanyName
' Wyświetl wartości
MsgBox strMsg, vbInformation, "Wartości z bazy i z dysku"
' Teraz uaktualnimy bazę danych wartościami z dysku
' Trzeba ponownie podłączyć się do bazy
Set conn = New ADODB.Connection
With conn
.Provider = "Microsoft.Jet.OLEDB.4.O"
.ConnectionString = "data source=c:\sample.mdb"
.Open
End With
' Powtórne przyłączenie recordsetu do bazy danych i synchronizacja
rst.Active0onnection = conn
rst.UpdateBatch
MsgBox "Baza danych zsynchronizowana !", vbInformation
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Definiowanie danych przy użyciu ADOX
Korzystając z obiektów ADO, możesz z łatwością dokonywać definiowania danych. Aby tworzyć i modyfikować tabele, kwerendy i inne obiekty związane z danymi, jak na przykład indeksy, musisz skorzystać ze specjalnej biblioteki ADO o nazwie ADOX XE "ADOX" . Aby użyć ADOX, musisz ustawić odnośnik na Microsoft ADO Ext. 2.1 For DDL and Security, wybierając z menu Tools pozycję References (rysunek 7.8).
Rysunek 7.8. Microsoft ADO Ext. 2.1 For DDL and Security |
|
Gdy ustawiłeś już odnośnik, jesteś gotów do korzystania z ADOX.
Obiekt Catalog
Gdy korzystasz z ADOX, wszystko co robisz związane jest z obiektem Catalog XE "Catalog:obiekt" . Catalog oznacza bazę danych. Pracując w Accessie, musisz jedynie ustawić właściwość tego obiektu, ActiveConnection XE "ActiveConnection:właściwość" , 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
Tworzenie bazy danych
Aby utworzyć nową, pustą bazę danych przy użyciu ADOX, musisz użyć polecenia Create obiektu Catalog i podać ścieżkę dostępu do nowej bazy (wydruk 7.10).
Wydruk 7.10. Tworzenie bazy danych przy użyciu ADOX
Sub CreateOataBase()
' Procedura tworzy nową bazę danych przy użyciu ADOX
'Z książki "Access 2000 Księga eksperta" (Helion)
'Autorzy: Forte, Howe, Ralston
' Obiekt catalog w ADOX
Dim cat As ADOx.Catalog
On Error GoTo Proc_Err
Set cat = New ADOx.Catalog
cat.Create "provider=Microsoft.JET.OLEDB.4.0;" & _
"data source=C:\newdb.mdb"
MsgBox "Baza danyh utworzona!", vbInformation
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Tworzenie tabel i pól
Aby utworzyć tabelę i jej pola, możesz utworzyć obiekt ADOX o nazwie table i dołączyć do niego kolumny (wydruk 7.11).
Wydruk 7.11. Tworzenie tabel i pól
Sub CreateTable_JOLT4O()
' Przykład tworzy tabelę i jej pola w bieżącej bazie danych
'Z książki "Access 2000 Księga eksperta" (Helion)
'Autorzy: Forte, Howe, Ralston
' Obiekty ADOX
Dim cat As ADOx.Catalog
Dim tbl As ADOx.Table
On Error GoTo Proc_Err
Set cat = New ADOx.Catalog
' Wskazanie na obiekt Catalog bieżącej bazy danych
cat.ActiveConnection = CurrentProject.Connection
Set tbl = New ADOx.Table
' Tworzy tabelę
With tbl
.Name = "Customer_ADO"
.Columns.Append "CustomerID", adInteger
.Columns.Append "Name_Prefix", adWChar, 25.
.Columns.Append "Name_First", adWChar, 2
.Columns.Append "Name_Last", adWChar, 50
End With
cat.Tables.Append tbl
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Tworzenie dołączonej tabeli
Aby utworzyć w Accessie dołączoną tabelę, musisz utworzyć tabelę i nie dołączać do niej żadnych pól, a następnie ustawić dwie właściwości:
Jet OLE DB:Link Datasource;
JET OLE DB:Remote Table Name.
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.
Wydruk 7.12. Tworzenie dołączonej tabeli
Sub CreateAttachedJetTable()
' Tworzy tabelę dołączoną
' Z książki "Access 2000 Księga eksperta" (Helion)
' Autorzy: Forte, Howe, Ralston
Dim cat As ADOx.Catalog
Dim tbl As ADOx.Table
Set cat = New ADOx.Catalog
' Otwarcie katalogu
cat.Active0onnection = CurrentProject.Connection
Set tbl = New ADOx.Table
' Tworzenie nowej tabeli
tbl.Name = "Customers_Połączona"
' Skrót dla tworzenia tabel
Set tbl.ParentCatalog = cat
' Ustawienie właściwości połączenia
tbl.Properties("Jet OLEDB:Link Datasource") = _
"F:\backend\datafile.mdb"
tbl.Properties("Jet OLEDB:Remote Table Name") = "Customers"
' Dołącz tabelę do kolekcji tabel
cat.Tables.Append tbl
Set cat = Nothing
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Ustawianie właściwości pola
W ADOX, po utworzeniu pola, możesz użyć obiektu Column, aby ustawić właściwości charakterystyczne dla tego pola. Przykładowo, możesz ustawić typ pola na Autonumerowanie, nadając właściwości AutoIncrement wartość True:
Dim col As ADOX.Column
'Wskaż obiektowi Column
'pole CustomerID
Set col = tbl.Columns("CustomerID")
'Ustaw Column na pole typu Autonumerowanie
col.Properties("Autincrement") = True
Istnieją inne właściwości, które możesz ustawić dla obiektu Column XE "Column:obiekt" . Umieściliśmy je w tabeli 7.4 wraz z ich odpowiednikami w DAO.
Tabela 7.4.
Właściwości obiektu Field
Pole DAO |
Obiekt Column w ADOX |
||
Właściwość |
Wartość |
Właściwość |
Wartość |
Attributes |
dbAutoIncrField |
AutoIncrement |
True |
Attributes |
dbFixedField |
ColumnAttributes |
adColFixed |
Attributes |
dbHyperlinkField |
Jet OLEDB:Hyperlink |
True |
Attributes |
dbSystemField |
|
|
Attributes |
dbVariableField |
ColumnAttributes |
Not adColFixed |
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 XE "IndexNulls:właściwość" 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
DAO |
ADOX |
Opis |
|
|
Wymagane |
Ignore Nulls |
Index Nulls |
True |
False |
AdIndexNullsDisallow |
Wartość Null nie jest akceptowana w polu indeks; wpis do indeksu nie zostanie dokonany |
False |
True |
AdIndexNullsIgnore |
Wartość Null dopuszczona w polu indeks; wpis do indeksu nie zostanie dokonany |
False |
False |
AdIndexNullsIgnoreAny |
Wartość Null dopuszczona w polu indeks; wpis do indeksu zostanie dokonany |
Kod na wydruku 7.13 łączy te wszystkie przykłady, tworząc tabelę pola Autonumerowanie i indeks klucza głównego w tej tabeli.
Wydruk 7.13. Tworzenie tabeli z polem Autonumerowanie i indeksem klucza głównego
Sub CreateCreateAutoNumberrPK()
'Przykład ten tworzy tabelę
'i pola w aktualnej bazie danych
'Z książki "Access 2000 Księga eksperta" (Helion)
'Autorzy: Forte, Howe, Ralston
'Obiekty ADOX
Dim cat As ADOX.Catalog
Dim tbl As New ADOX.Table
Dim idx As ADOX.Index
On Error GoTo Proc_Err
Set cat = New ADOX.Catalog
'Wskaż obiektowi Catalog
'aktualną bazę danych
cat.ActiveConnection = CurrentProject.Connection
Set tbl = New ADOX.Table
'Teraz tworzymy tabelę
With tbl
.Name = "Customer_ADO"
.ParentCatalog = cat
.Columns.Append "CustomerID", adInteger
'Ustaw pole Autonumerowanie
.Columns("CustomerID").Properties("Autoincrement") = True
.Columns.Append "Name_Prefix", adWChar, 25
.Columns.Append "Name_First", adWChar, 25
.Columns.Append "Name_Last", adWChar, 50
End With
'Dołącz tabelę do obiektu catalog
cat.Tables.Append tbl
'Teraz tworzymy obiekt index
Set idx = New ADOX.Index
'Teraz ustawiamy klucz
'jako klucz podstawowy i
'sortujemy go w porządku malejącym
With idx
.Name = "PrimaryKey"
.Columns.Append "CustomerID"
.Columns("CustomerID").SortOrder = adSortDescending
.IndexNulls = adIndexNullsDisallow
.PrimaryKey = True
End With
'Dołączamy indeks do tabeli
tbl.Indexes.Append idx
'Sprzątamy
Set cat = Nothing
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Tworzenie relacji w ADOX
Aby utworzyć relację w ADOX, musisz utworzyć obiekt klucza, określić jego właściwości, a następnie dołączyć ten klucz do obiektu Table.
Użyj następującej składni:
Cat.Tables("Products").Keys.Append key
Kod na wydruku 7.14 wykonuje wszystkie te czynności oraz tworzy relacje.
Wydruk 7.14. Tworzenie relacji
Sub CreateForeignKey()
'Tworzenie relacji między tabelami
'Products i Categories w bazie Northwind
'Z książki "Access 2000 Księga eksperta" (Helion)
'Autorzy: Forte, Howe, Ralston
Dim cat As ADOX.Catalog
Dim key As ADOX.key
On Error GoTo Proc_Err
'Tworzenie obiektów ADOx
Set cat = New ADOX.Catalog
Set key = New ADOX.key
'Otwarcie obiektu katalog na aktualną bazę danych
cat.ActiveConnection = CurrentProject.Connection
'Ustawienie właściwości nowego obiektu Key
With key
'Nazwa obiektu Key w bazie
'musi być unikatowa
.Name = "CategoriesProducts"
'Określenie rodzaju klucza
.Type = adKeyForeign
'Określenie strony JEDEN relacji jeden-do-wielu
.RelatedTable = "Categories"
'Określenie strony WIELU
.Columns.Append "CategoryID"
'Pole "jeden" w tabeli po stronie "jeden"
.Columns("CategoryID").RelatedColumn = "CategoryID"
'Określenie aktualizowania kaskadowego
.UpdateRule = adRICascade
End With
'Teraz określ tabele po stronie "wielu"
'i dołącz do niej nowy obiekt Key
cat.Tables("Products").Keys.Append key
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Tworzenie kwerend w ADOX
Aby utworzyć kwerendę w ADOX, musisz użyć pustego obiektu Command i ustawić jego właściwość CommandText XE "CommandText:właściwość" , a następnie dołączyć go do aktualnego obiektu catalog:
cmd.CommandText = "Select * FROM Categories"
"Dołącz kwerendę do zbioru
cat.Views.Append "qryCategories", cmd
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:
widoki;
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).
Wydruk 7.15. Tworzenie widoku w ADOX
Sub CreateView()
' Tworzenie nowej kwerendy (widoku)
' Z książki "Access 2000 Księga eksperta" (Helion)
' Autorzy: Forte, Howe, Ralston
Dim cat As ADOx.Catalog
Dim cmd As ApODB.Command
Set cat = New ADOx.Catalog
Set cmd = New ADODB.Command
' Otwarcie katalogu
cat.ActiveConnection = CurrentProject.Connection
' Tworzenie kwerendy
cmd.CommandText = "Select * FROM Categories"
' Dołączenie kwerendy do kolekcji
cat.Views.Append "qryCategories", cmd
Set cat = Nothing
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Tworzenie procedury
Tworzenie procedury jest równie proste jak tworzenie widoku. Wystarczy zdefiniować właściwość Commandtext XE "Commandtext:właściwość" i dołączyć go do obiektu catalog (wydruk 7.16).
Wydruk 7.16. Tworzenie procedury
Sub CreateProcedure()
' Tworzenie kwerendy (procedury)
' Z książki "Access 2000 Księga eksperta" (Helion)
' Autorzy: Forte, Howe, Ralston
Dim cat As ADOx.Catalog
Dim cmd As ADODB.Command
Set cat = New ADOx.Catalog
Set cmd = New ADODB.Command
' Otwarcie katalogu
cat.ActiveConnection = CurrentProject.Connection
'Create the komendy
cmd.CommandText = "Parameters [@Region] Text;" & _
"Select * from Employees where Region = [@Region]"
' Tworzenie procedury
cat.Procedures.Append "qryEmployeesRegion", cmd
Set cat = Nothing
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Modyfikowanie wyrażenia SQL kwerendy
Aby zmodyfikować wyrażenie SQL kwerendy, musisz najpierw utworzyć obiekt command oparty na aktualnej kwerendzie w bazie danych, a następnie zmodyfikować właściwość commandtext i zresetować obiekt command (wydruk 7.17).
Wydruk 7.17. Zmiana wyrażenia SQL
Sub Modify0uerySQL()
' Zmiana wyrażenia SQL kwerendy
' Z książki "Access 2000 Księga eksperta" (Helion)
' Autorzy: Forte, Howe, Ralston
Dim cat As ADOx.Catalog
Dim cmd As ADODB.Command
On Error GoTo Proc Err
Set cat = New ADOx.Catalog
Set cmd = New ADODB.Command
' Otwarcie katalogu
cat.ActiveConnection = CurrentProject.Connection
' Pobranie kwerendy z bazy danych
Set cmd = cat.Procedures("qryEmployeesRegion").Command
' Zmiana wyrażenia SQL
cmd.CommandText = "Parameters [forms]![frmOrder]![txtRegion] Text;" &_
"Select * from Employees " & _
"Where Region = [forms]![frmOrder]![txtRegion] "
' Zapis zmienionej kwerendy
Set cat.Procedures("qryEmployeesRegion").Command = cmd
Set cat = Nothing
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:
Projektowanie formularza.
Rozbudowa formularzy przy użyciu formantów ActiveX.
Raporty.
Rozdział 8.
Projektowanie formularza
W tym rozdziale:
Właściwości formularza.
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 formularzy 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 |
|
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 przedstawiać i współpracować z danymi.
Źródło rekordów XE "Ź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.
|
||
|
Jeśli nie określisz źródła rekordów podczas projektowania, nie będziesz mógł z nim powiązać pojedynczych pól formularza. |
Edycja dozwolona XE "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 XE "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 XE "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 XE "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.
Filtry dozwolone XE "Filtry dozwolone" , Filtr XE "Filtr" , Uporządkuj według XE "Uporządkuj według"
Właściwości te umożliwiają zastrzeżenie określonego zestawu rekordów w danym formularzu poprzez użycie warunku WHERE we właściwości Filtr lub kolejności sortowania we właściwości Uporządkuj według. Właściwość Filtry dozwolone nakazuje (bądź nie) Accessowi czytanie tych wartości podczas otwierania formularza.
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 XE "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:
Formularz pojedynczy - wyświetla rekordy pojedynczo.
Formularze ciągłe - wyświetla, wiele rekordów, każdy z nich we własnej kopii formularza w części szczegółowej.
Arkusz danych - podobnie jak arkusz kalkulacyjny wyświetla dane w wierszach i kolumnach.
Dostępne widoki XE "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:
Formularz.
Arkusz danych.
Oba.
Paski przewijania XE "Paski przewijania"
Właściwość ta umożliwia Ci wyłączenie lub włączenie pionowego i poziomego paska przewijania w formularzu.
Selektory rekordów XE "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 XE "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 XE "Styl obramowania"
Formularze w Accessie, w zależności od ich przeznaczenia, mogą być wyświetlane w różnych rodzajach obramowań:
Zmienny - umożliwia użytkownikom zmianę rozmiaru formularza. Na oknie umieszczone są przyciski Minimalizuj i Maksymalizuj.
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.
Cienki - powoduje określenie stałego rozmiaru formularza. Przyciski Minimalizuj i Maksymalizuj są włączone.
Brak - brak jakiegokolwiek obramowania. Ustawienie to sprawdza się w przypadku ekranów tytułowych.
Pole menu sterowania XE "Pole menu sterowania"
Właściwość ta określa, czy wyświetlane są przyciski Minimalizuj, Maksymalizuj i Zamknij.
Przyciski Min Max XE "Przyciski Min Max"
Gdy ustawisz tę właściwość na Tak, użytkownicy będą mogli minimalizować i maksymalizować formularze na pulpicie.
Przycisk Zamknij XE "Przycisk Zamknij"
Gdy ustawisz tę właściwość na Tak, użytkownicy będą mogli używać menu kontrolnego do zamykania formularza.
|
||
|
Jeśli ustawisz tę właściwość na Nie, musisz umożliwić użytkownikom zamknięcie formularza w inny sposób. W innym razie, będą go mogli zamknąć jedynie poprzez kombinacje klawiszy Ctrl+F4 bądź Alt+F4 albo przez zamknięcie Accessa. |
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 XE "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 XE "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.
Pasek menu XE "Pasek menu" , pasek narzędzi XE "Pasek narzędzi"
Jeśli stworzyłeś własne menu lub paski narzędzi, które chcesz połączyć z określonym formularzem, ustawienie tej właściwości spowoduje, że to menu lub pasek zostaną wyświetlone po uruchomieniu formularza.
Menu podręczne XE "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.
Pasek menu podręcznego XE "Pasek menu podręcznego"
Jeśli stworzyłeś dla formularza menu podręczne, wybranie go w tym miejscu i ustawienie właściwości Menu podręczne na Tak nakaże Accessowi wyświetlenie tego menu za każdym razem, gdy użytkownik użyje na formularzu prawego klawisza myszy.
Metka XE "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.
|
||
|
Jeśli formularz oparty jest na kodzie i ustawisz właściwość Ma moduł na Nie, cały kod zostanie usunięty. Access powiadomi Cię o tym fakcie. |
Ma moduł XE "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).
Rysunek 8.2. Okno dialogowe Wstaw hiperłącze |
|
Zezwolenie na zmiany projektu XE "Zezwolenie na zmiany projektu"
Ustawienie tej właściwości na Wszystkie widoki pozostawia po uruchomieniu formularza otwarte okno dialogowe Format, co umożliwia dokonywanie zmian i oglądanie ich „na żywo” w aplikacji. Nie zapomnij ustawić tej właściwości na Tylko widok projektu po dokonaniu zmian.
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.
Argumenty otwarcia (OpenArgs) XE "OpenArgs"
Właściwość ta jest dostępna jedynie wtedy, gdy formularz działa. Dzięki niej po wprowadzeniu ciągu wartości w jednym formularzu zostanie on automatycznie wprowadzony do drugiego formularza.
'Składnia dla formularza wysyłającego:
Docmd.OpenForm "MyForm", "jakiś ciąg wartości"
'Składnia dla formularza odbierającego:
Dim x as string
If not isnull (OpenArgs) then
X = Me.OpenArgs
'wykonaj specjalne formatowanie
end if
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 XE "Property Get" i Property Let. XE "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
' odpowiada założonym kryteriom
Public Property Let MyAge(byval intAge as Integer)
If intAge < 16 then
Msgbox "Wiek kierowcy nie może być mniejszy niż 16 lat"
Else
IntMyAge=intAge
End if
End Property
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 XE "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 przeciwnym 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ń uruchamianych 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.
Otwórz (z opcją Anuluj).
Załaduj.
Zmień rozmiar.
Aktywuj.
Aktualny.
Wejście do pierwszego formantu.
Uzyskanie fokusu przez pierwszy formant.
|
||
|
Jeśli na formularzu nie ma formantów, sam formularz uzyska fokus. |
Jeśli w formularzu umieszczony jest podformularz, następujące zdarzenia wykonywane są PRZED zdarzeniem otwarcia głównego formularza:
Otwórz (z opcją Anuluj).
Załaduj.
Zmień rozmiar.
Aktualny.
Wejście do pierwszego formantu.
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.
Wyładuj (z opcją anuluj).
Dezaktywuj.
Zamknij.
Zmiana rozmiaru formularza
Gdy zmieniany jest rozmiar formularza, określone zdarzenia uruchamiane są w przedstawionej poniżej kolejności.
Zmień rozmiar.
Dezaktywuj.
Maksymalizowanie formularza
Gdy formularz jest maksymalizowany, określone zdarzenia uruchamiane są w przedstawionej poniżej kolejności.
Zmień rozmiar.
Przywrócenie zminimalizowanego formularza
Gdy formularz jest przywracany, określone zdarzenia uruchamiane są w przedstawionej poniżej kolejności.
Aktywuj.
Zmień rozmiar.
Formanty formularza w Accessie
Aby pomóc Ci w tworzeniu aplikacji, Access 2000 zawiera wiele wbudowanych formatów. Niektóre z nich, jak na przykład pole tekstowe, nie zmieniły się zbytnio od czasów Accessa 1.0. W niektórych, jak pole listy, zaszły znaczące zmiany. W tej części scharakteryzujemy najciekawsze z formantów Accessa.
Formant Lista rozwijana XE "Lista rozwijana:formant"
Listy rozwijane zawierają zestaw uprzednio zdefiniowanych wartości, co ułatwia użytkownikom wprowadzanie danych poprzez wybieranie z list żądanych wartości. Większość list rozwijanych bazuje na kwerendach lub wyrażeniach SQL i zwykle zawiera jedną lub dwie kolumny i pole związane. Mimo iż dużej części programistów to wystarcza, istnieją interesujące właściwości list rozwijanych Accessa 2000, które mogą znacznie zwiększyć ich funkcjonalność.
Użycie zdarzenia Not In List
Zdarzenie Not In List XE "Not In List:zdarzenie" uruchamia się automatycznie, gdy wprowadzana jest wartość, która nie znajduje się na liście. Umożliwia to programiście zbadanie tej wartości i podjęcie decyzji, co z nią zrobić.
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
'Ta procedura uruchamia się tylko wtedy, gdy wykryty zostanie
'obiekt nie znajdujący się na liście
Msg = "Klient "& Newdata &" nie został odnaleziony, _
Czy chcesz dodać do listy klientów?"
'Poinformuj użytkownika o nowej wartości.
MyResponse = MsgBox(Msg, vbInformation + vbYesNo, _
"Klient nie został odnaleziony")
'Jeśli tak, dodaj kod, by zająć się nową wartością.
If MyResponse = vbYes Then
MsgBox "Tu wpisz kod", vbInformation _
+ vbOKOnly, "Gotowy do dodawania"
Me.cboUser = ""
Else
'Jeśli nie, wprowadź kod, aby zapytać użytkownika o poprawną wartość.
MsgBox "Wybierz z listy innego _
Klienta", vbInformation + vbOKOnly, "Wybierz _
innego Klienta"
End If
'Każ Accessowi kontynuować. Opis stałych procedury zdarzenia
'znajdziesz w internetowym pliku pomocy.
Response = acDataErrContinue
Tworzenie automatycznie rozwijającej się listy rozwijanej
Ile razy chciałeś po prostu przejść do pola listy tak, by rozwinęła się automatycznie bez użycia polecenia SendKeys? W Accessie 97, jedyne co musisz zrobić to wpisać poniższą linijkę kodu do zdarzenia Enter:
ActiveControl.DropDown
To wszystko!
Tworzenie własnych list rozwijanych
Zazwyczaj wartości w rozwijanych polach pochodzą z tabeli lub kwerendy. Ale to nie jest jedyna możliwość. Ustawiając właściwość Typ źródła wierszy na Lista pól, możesz wybrać przeglądanie pól w bazowej tabeli lub kwerendzie. Możesz również wybrać w tej właściwości nazwę dowolnej funkcji, która będzie wyświetlać dowolną listę. Nawet, jeśli nie zauważysz od razu korzyści płynących z takiego rozwiązania, przydaje się ono, gdy chcesz dodać do listy specjalną wartość jak na przykład Wszystkie. Opcja ta przyda się również, gdy będziesz chciał wyświetlić przydatną dla księgowych, wyrównaną do prawej listę wartości walutowych. To ostatnie rozwiązanie możliwe jest poprzez umieszczenie spacji po lewej stronie wartości i wyświetlenie za pomocą czcionki o stałej szerokości (np. Courier).
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
' Dodaje u góry listy wartość specjalną "Wszystkie"
' Można dodać "Wszystkie" do różnych kolumn listy
Static dbs As Database, rst As Recordset
Static lngDisplayID As Long
Static intDisplayCol As Integer
Static strDisplayText As String
Dim intSemiColon As Integer
On Error GoTo Err_AddAllToList
Select Case intCode
Case acLBInitialize
' See if function is already in use.
If lngDisplayID <> 0 Then
MsgBox "AddAllToList Jest już używane przez inny formant !"
AddAllToList = False
Exit Function
End If
' Wyłuskanie kolumny do wyświetlenia i wyświetlenie tekstu z
' własności Tag
intDisplayCol = 1.
strDisplayText = "(Wszystkie)"
If Not IsNull(ctl.Tag) Then
intSemiColon = InStr(ctl.Tag, ";")
If intSemiColon = 0 Then
intDisplayCol = Val(ctl.Tag)
Else
intDisplayCol = Val(Left(ctl.Tag, intSemiColon - 1))
strDisplayText = Mid(ctl.Tag, intSemiColon + 1)
End If
End If
' Otwórz recordset zdefiniowany przez własność RowSource
Set dbs = CurrentDb
Set rst = dbs.OpenRecordset(ctl.RowSource, dbOpenSnapshot)
' Zapamiętaj i zwróć lngId
lngDisplayID = Timer
AddAllToList = lngDisplayID
Case acLBOpen
AddAllToList = lngDisplayID
Case acLBGetRowCount
' Zwróć ilość wierszy w wyniku
On Error Resume Next
rst.MoveLast
AddAllToList = rst.RecordCount + 1.
Case acLBGetColumnCount
' Zwróć ilość kolumn w wyniku
AddAllToList = rst.Fields.Count
Case acLBGetColumnWidth
AddAllToList = -1.
Case acLBGetValue
If lngRow = 0 Then
If lngCol = int0isplayCol - 1 Then
AddAllToList = strDisplayText
Else
AddAllToList = Null
End If
Else
rst.MoveFirst
rst.Move lngRow - 1
AddAllToList = rst(lngCol)
End If
Case acLBEnd
lngDisplayID = 0
rst.Close
End Select
Bye_AddAllToList:
Exit Function
Err_AddAllToList:
MsgBox Err.Description, vbOKOnly + vbCritical, "AddAllToList"
AddAllToList = False
Resume Bye_AddAllToList
End Function
Pobieranie więcej niż jednej wartości z pola listy i listy rozwijanej
Korzystając z właściwości Column, możesz pobrać wartość z dowolnej kolumny w polu listy lub listy rozwijanej. W właściwości Column XE "Column:właściwość" pierwsza kolumna ma numer 0, druga 1, i tak dalej.
Przykładowo, aby odczytać wartość z czwartej kolumny listy rozwijanej, wpisałbyś:
MyVariantValue = Me!MyComboBox.Column(3)
Pole listy
Pole listy XE "Pole listy:formant" 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.
Pole listy wielokrotnego wyboru
W Accessie 2 istniały sztuczki pozwalające na umożliwienie użytkownikom wybieranie kilku wartości z listy. Począwszy od Accessa 2000, wybieranie kilku wartości naraz stało się łatwe dzięki polu listy wielokrotnego wyboru. Jednakże pobieranie wybranych wartości nie zawsze jest tak intuicyjne.
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 XE "Wybór wielokrotny:właściwość" . 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
'Utwórz ciąg przechowujący wiadomość.
strMsg = "Wybrano następujących pracowników: " _
& vbCr & vbCr
For i = 1 To Me.lstMulti.ListCount
'Sprawdź, czy użytkownik zaznaczył ten wiersz.
If Me.lstMulti.Selected(i) Then
'Jeśli tak, dodaj pierwszą kolumnę zaznaczonego wiersza
' do ciągu wiadomości.
StrName = Me.lstMulti.Column(0, i)
'Pobierz wartość obiektu (pola związanego) i dodaj ją
'do ciągu. Spowoduje to utworzenie wyświetlanego
'imienia i nazwiska.
StrName = strName & Chr(32) & _ Me.lstMulti.ItemData(i)
strMsg = strMsg & strName & vbCr
End If
Next
MsgBox Msg
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 XE "podformularz" 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 XE "Obiekt źródłowy:właściwość" , 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:
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.
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żyj dołączonego do Accessa kreatora podformularzy.
|
||
|
W Accessie 97 Kreator formantów był domyślnie włączony. W Accessie 2000 jest inaczej. Aby użyć tego kreatora, upewnij się, czy znajdujący się w Przyborniku przycisk Kreatorzy formantów jest wciśnięty (rysunek 8.4). Gdy tworzysz nowy podformularz w widoku Projekt formularza, Kreator podformularzy zostanie uruchomiony automatycznie. |
Tworzenie odniesienia dla podformularza
Istnieje kilka sposobów tworzenia odniesień dla formantów na podformularzu. Typowa składnia wygląda następująco:
Forms!MyForm!SubFormControlName.Form!ControlName
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
W obu przypadkach efekt będzie ten sam.
Aby mieć pewność co do składni, skorzystaj z kreatora wyrażeń (Ctrl+F2).
Rysunek. 8.4. Przybornik z wciśniętym przyciskiem Kreatora formantów |
|
Wbudowany formant Karta
Innym sposobem na łączenie formantów jest zastosowanie formantu Karta. Jest on jednym z wbudowanych obiektów Accessa 2000.
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 XE "Grupa opcji:formant" , 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.
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.
Na zakładce Paski narzędzi kliknij Nowy...
W polu Nazwa paska narzędzi wpisz dowolną nazwę i kliknij OK.
Na zakładce Paski narzędzi kliknij Właściwości.
Z listy Typ wybierz Podręczny.
Ustaw właściwość Zezwalaj na dostosowanie w żądany sposób i kliknij Zamknij. Nie martw się, nie stracisz tego paska.
W oknie Paski narzędzi kliknij Menu podręczne.
Na pasku narzędzi Menu podręczne kliknij kategorię Niestandardowe. Tam znajdziesz swoje nowe menu podręczne.
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 XE "Hiperłącze:formant" 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:
Jak korzystać z formantów ActiveX.
Użycie formantów ActiveX.
21 formantów ActiveX.
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.
Jak korzystać z formantów ActiveX
Miałeś już okazję zapoznać się z wbudowanymi formantami, które można umieszczać na formularzach Accessa (np. pola tekstowe czy przyciski poleceń). Formanty ActiveX działają w bardzo podobny sposób, z tą różnicą, że kod obsługujący zestaw funkcji formantu ActiveX przechowywany jest w osobnym pliku, który przed użyciem musi zostać zainstalowany.
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 XE "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.
|
||
|
Nie każdy formant ActiveX będzie działał we wszystkich aplikacjach. Formant świetnie działający w Visual Basicu może nie działać w Accessie i na odwrót. Aby się przekonać, czy dany formant ActiveX będzie działał w Accessie, przejrzyj jego dokumentację lub sam przeprowadź odpowiednie testy. |
Typy formantów ActiveX
Istnieją dwa typy formantów ActiveX: formanty związane z procesem projektowania i formanty wykorzystywane podczas użytkowania aplikacji.
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 XE "Image:formant" oraz Common Dialog XE "Common Dialog:formant" .
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 XE "Toolbar:formant" , MonthView XE "MonthView:formant" , ListView XE "ListView:formant" , 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.
Gdzie znaleźć formanty ActiveX?
Bez wątpliwości wiele formantów ActiveX znajduje się już na Twoim komputerze. Być może nawet nie uda Ci się ustalić pochodzenia części z nich. Oto kilka możliwych źródeł:
Windows.
Aplikacje Microsoft Office.
Visual Basic.
Internet Explorer.
Inne aplikacje.
Inni producenci.
Pliki pobrane ze stron sieci WWW.
Formanty ActiveX, które utworzyłeś za pomocą C++ XE "C++" , Java XE "Java" czy Visual Basica. Więcej informacji o tworzeniu własnych formantów ActiveX znajdziesz w rozdziale 20., „Użycie Visual Basic z Accessem”.
|
||
|
Doradzamy testowanie formantów ActiveX przed ich użyciem. Wiele formantów można znaleźć w Internecie. Sprawdź, czy dany formant odpowiada Twoim potrzebom, zanim go zakupisz. |
Czy formanty ActiveX są bezpieczne?
Niekoniecznie. Formanty ActiveX zawierają kod. Złośliwy programista mógłby bez trudu utworzyć formant, który dokona poważnych uszkodzeń systemu operacyjnego Twojego komputera. Doradzamy korzystanie jedynie z formantów pochodzących ze sprawdzonych źródeł.
Czy mogę korzystać z formantów ActiveX
i rozpowszechniać je w moich aplikacjach?
To, że dany formant znajduje się na Twoim komputerze, nie oznacza wcale, że możesz z niego korzystać i umieszczać go w swoich aplikacjach. Powinieneś zadać sobie pytanie: „Czy mam prawo korzystać z danego formantu ActiveX?”
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.
Użycie formantów ActiveX
Użycie formantów ActiveX w Accessie wymaga wykonania następujących kroków:
Zainstalowania formantu na komputerze.
Zarejestrowania formantu.
Dodania formantu do formularza.
Ustawienia właściwości formantu.
Dodania kodu, który umożliwi wykonanie metod i reagowanie na zdarzenia.
Instalowanie formantu ActiveX
Formant ActiveX XE "formanty ActiveX:instalowanie" musi zostać zainstalowany na komputerze, w innym bowiem przypadku, gdy aplikacja będzie chciała go użyć, wyświetlony zostanie komunikat o błędzie. Oznacza to, że za każdym razem, gdy rozpowszechniasz aplikację, musisz upewnić się, że dołączyłeś do niej również wymagane formanty ActiveX. O tym jednak w dalszej części tego rozdziału.
|
||
|
Jeśli rozpowszechniasz aplikację korzystającą z formantów ActiveX, powinieneś się upewnić, czy wymagane formanty są zainstalowane na każdym z komputerów, na których aplikacja będzie uruchamiana. I tak, przykładowe aplikacje dla tego rozdziału nie będą działać na Twoim komputerze, jeśli nie zainstalujesz odpowiednich formantów ActiveX. |
Rejestrowanie formantów ActiveX
Zanim formant ActiveX zostanie dodany do formularza Accessa, musi zostać zarejestrowany. Aby określić, czy formant został zarejestrowany, spróbuj dołączyć go do formularza (opis tej czynności znajdziesz w następnym rozdziale). Jeśli Ci się to uda, znaczy to, że formant został już zarejestrowany. W przeciwnym wypadku musisz zarejestrować go przy użyciu Accessa.
Niektóre formanty ActiveX XE "formanty ActiveX:rejestrowanie" 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 |
|
Dodawanie formantu ActiveX do formularza
Jeśli formant ActiveX jest już zarejestrowany, możesz dodać go do formularza. Aby tego dokonać, otwórz formularz w widoku Projekt i z menu Wstaw wybierz Formant ActiveX lub kliknij znajdujący się w prawym dolnym rogu Przybornika przycisk Więcej formantów (rysunek 9.2).
Znajdujący się w Przyborniku przycisk Więcej formantów |
|
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 |
|
Ustawianie właściwości formantu ActiveX
Formanty ActiveX posiadają arkusz właściwości identyczny jak wbudowane formanty Accessa. Mają również stronę z właściwościami przypominającą arkusz właściwości formularza, co znacznie ułatwia ustawianie właściwości. Aby otworzyć stronę z właściwościami formantu ActiveX, kliknij go prawym klawiszem myszy i z menu kontekstowego wybierz pozycję Obiekt, a następnie Properties (rysunek 9.5).
Rysunek 9.5.
Strona z właściwościami formantu |
|
Pisanie kodu umożliwiającego wykonywanie metod
i reagowanie na zdarzenia
W przypadku formantów ActiveX pisanie kodu umożliwiającego wykonywanie metod i reagowanie na zdarzenia nie różni się niczym od pisania kodu dla wbudowanych formantów Accessa.
Aby uzyskać informacje o właściwościach, metodach i zdarzeniach związanych z formantem, skorzystaj z narzędzia Object Browser XE "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.
|
|||
|
|
W znajdującej się na dołączonym do książki CD-ROM-ie aplikacji znajdziesz przykłady kodu użyte we wszystkich z 21 formantów ActiveX. |
Tabela 9.1 zawiera nazwę formantu, nazwę jego pliku i opis.
Tabela 9.1.
Przegląd formantów ActiveX
Formant ActiveX |
Nazwa pliku |
Opis |
Animation |
MSCOMCT2.OCX |
Odtwarza w formularzu pliki video (AVI) |
Calendar |
|
Wyświetla w formularzu kalendarz |
Common Dialog |
COMDLG32.OCX |
Wyświetla okna dialogowe Otwórz, Zapisz jako, Kolor, Czcionka, Drukuj i Pomoc |
DateTimePicker |
MSCOMCT2.OCX |
Rozwijany kalendarz, który umożliwia użytkownikom wprowadzanie dat |
FlatScrollBar |
MSCOMCT2.OCX |
Płaski pasek przewijania |
Tabela 9.1.
Przegląd formantów ActiveX (ciąg dalszy)
Formant ActiveX |
Nazwa pliku |
Opis |
|||||
ImageCombo |
MSCOMCTL.OCX |
Pole kombi zawierające rysunki związane z obiektami na liście |
|||||
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 |
|||||
|
|||||||
|
|
Znajdujący się na płycie CD-ROM kod dla tego rozdziału zawiera przykłady każdego z tych formantów. |
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 XE "Animation:formant" .
Rysunek 9.7. Przykład formantu Animation |
|
||||
|
|||||
|
Formant Animation nie obsługuje wszystkich plików typu AVI. Przykładowo, formant ten nie współpracuje z plikami AVI zawierającymi dźwięk. Ponadto plik AVI nie powinien być kompresowany. Jedynym wyjątkiem są pliki kompresowane przy użyciu kompresji Run-Length. |
Tabela 9.2.
Właściwości i metody dla formantu Animation
Obiekt |
Opis |
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 XE "Calendar:formant" 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.
Formant Common Dialog
Dzięki użyciu formantu Common Dialog XE "Common Dialog:formant" można z łatwością wyświetlać typowe okna dialogowe systemu Windows - Otwórz, Zapisz jako, Kolor, Czcionka, Drukuj i Pomoc (rysunek 9.9).
Rysunek 9.8. Przykład 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ę |
|
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 XE "DateTimePicker:formant" 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ć.
|
||
|
Wygląd rozwijanego kalendarza może być zmieniany przy użyciu różnych zestawów kolorów (patrz właściwości w tabeli 9.5). |
Tabela 9.5 zawiera najczęściej używane właściwości dla formantu DateTimePicker.
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 XE "FlatScrollBar:formant"
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 zawiera najczęściej używane właściwości 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.
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.
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.
|
||
|
Po usunięciu obiektów z formantu ImageList wartości indeksu ulegają zmianie, więc nie możesz się na nich opierać. Zawsze korzystaj z unikatowych wartości klucza i używaj ich przy tworzeniu odniesień do rysunków w kodzie. |
|
|
||
|
Nie przesadzaj z użyciem rysunków w aplikacjach. Formant ImageList pochłania dużą część pamięci komputera i użycie większej ilości rysunków może spowodować zmniejszenie wydajności aplikacji. Po otwarciu formularza zawierającego ten formant wszystkie rysunki przechowywane są w pamięci. |
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.
|
||
|
Po związaniu formantu ImageList z innym formantem nie możesz do niego dodawać nowych rysunków. Przed umieszczeniem formantu na formularzu upewnij się, że dodałeś wszystkie zaplanowane rysunki. Jeśli będziesz chciał dodać rysunki do formantu ImageList po związaniu go z innym formantem, najpierw będziesz musiał je rozłączyć. |
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.
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 zawiera najczęściej używane obiekty i właściwości 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 |
||||
Właściwość SortOrder |
Sortowanie rosnąco i malejąco |
||||
Właściwość SubItems |
Tablica ciągów wyświetlana w widoku Szczegóły |
||||
Właściwość View |
Ustawia wygląd obiektów: Duże ikony, Małe ikony, Lista i Szczegóły |
||||
|
|||||
|
Użycie formantu ListView w połączeniu z formantem TreeView znacznie zwiększa funkcjonalność interfejsu Eksploratora Windows. Jest to bardzo dobry sposób na przeglądanie danych, gdyż większość użytkowników miała już okazję poznać ten interfejs. |
Formant MAPISession
Interfejs MAPI (ang. Messaging Application Programming Interface) nadzoruje korzystające z poczty aplikacje Accessa. Formant MAPISession XE "MAPISession:formant" umożliwia rozpoczęcie i zamknięcie sesji MAPI (rysunek 9.15).
Rysunek 9.15. Przykład formantu MAPISession |
|
||||
|
|||||
|
Aby formanty MAPI funkcjonowały poprawnie, konieczne jest zainstalowanie na komputerze usługi MAPI oraz zgodnego z nią systemu poczty elektronicznej (na przykład Microsoft Exchange). |
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 XE "MAPIMessages:formant" . 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 |
Właściwość MsgDateReceived |
Data otrzymania wiadomości |
Właściwość MsgID |
Identyfikator wiadomości |
Właściwość MsgNoteText |
Tekst wiadomości |
Właściwość MsgRead |
Określa, czy wiadomość została przeczytana |
Właściwość MsgSent |
Określa, czy wiadomość została wysłana |
Właściwość MsgSubject |
Temat wiadomości |
Właściwość RecipAdress |
E-mailowy adres odbiorcy |
Metoda Compose |
Pisanie wiadomości |
Metoda Copy |
Kopiowanie wiadomości |
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 XE "MonthView:formant"
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.
Właściwości i zdarzenia dla formantu MonthView (ciąg dalszy)
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 XE "ProgressBar:formant"
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 |
|
|||
|
||||
|
Wizualne informowanie użytkownika o przebiegu dłuższego procesu sprawia, iż wydaje się on być krótszy niż jest w rzeczywistości. |
|||
|
W przypadku długich procesów powinieneś już na początku w części wypełnić formant. Nie jest to być może zbyt uczciwe, bo nie odzwierciedla rzeczywistego postępu procesu. Jednakże w sytuacji, w której mija dłuższy czas, zanim wypełni się choćby pierwsza część paska postępu, może się zdarzyć, że użytkownik wyłączy komputer myśląc, że się zawiesił. |
Tabela 9.13 zawiera najczęściej używane właściwości 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 w formancie wzrasta |
Formant RichText
Formant RichText XE "RichText:formant" 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 |
|
Możliwości formantu RichText są następujące:
Łączenie czcionek, stylów, rozmiarów i kolorów.
Indeksy dolne i górne.
Formatowanie akapitów.
Możliwość pracy z dużymi plikami tekstowymi.
Zdolność dołączania do pola typu memo w Accessie.
Możliwość dołączania plików graficznych, ikon i dokumentów.
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 |
Właściwość SelColor |
Określa kolor zaznaczonego tekstu |
Metoda Find |
Przegląda formant w poszukiwaniu określonego tekstu |
Metoda LoadFile |
Ładuje do formantu plik tekstowy lub plik .RTF |
Metoda SaveFile |
Zapisuje plik zawarty w formancie |
Metoda SelPrint |
Drukuje zaznaczony tekst |
Metode SelChange |
Występuje, gdy zmianie ulegnie zaznaczenie tekstu lub pozycja znaku wprowadzania |
Formant Slider
Formant Slider XE "Slider:formant" 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).
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 XE "StatusBar:formant"
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 |
|
||||
|
|||||
|
Korzystając z właściwości Align, możesz umieścić formant StatusBar w różnych miejscach formularza (u góry, u dołu, po lewej bądź prawej stronie). Aby być w zgodzie z innymi aplikacjami systemu Windows, należałoby umieścić pasek stanu u dołu formularza. |
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 |
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 XE "SysInfo:formant"
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:
System operacyjny, jego wersja i numer edycji.
Zdarzenia na pulpicie, wielkość monitora i zmiany rozdzielczości.
Zdarzenia związane z Plug and Play.
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 |
Formant TabStrip
Formant TabStrip XE "TabStrip:formant" 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, ClientWidth, ClientLeft, ClientRight |
Zwraca współrzędne obszaru wyświetlania formantu |
Właściwość ImageList |
Przyporządkowuje formant ImageList |
Właściwość MultiSelect |
Umożliwia wybór kilku obiektów jednocześnie |
Właściwość Placement |
Umieszcza zakładki u góry, u dołu, po lewej lub po prawej stronie |
Właściwość SelectedItem |
Określa wybraną zakładkę |
Właściwość Style |
Modyfikuje wygląd zakładek (przyciski zwykłe bądź płaskie) |
Metoda DeselectAll |
Usuwa zaznaczenie zakładek |
Obiekt Click |
Występuje po kliknięciu zakładki |
Formant Toolbar XE "Toolbar:formant"
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.
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, ButtonWidth |
Wysokość i szerokość znajdujących się na pasku narzędzi 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 XE "TreeView:formant" 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
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 |
||||
|
|||||
|
Obiekt Node posiada własny zestaw przydatnych właściwości (Child, FirstSibling, LastSibling, Previous, Parent, Next i Root). |
Formant UpDown
Formant UpDown XE "UpDown:formant" 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 XE "BuddyControl:właściwość" . 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 |
Właściwość Increment |
Określa wielkość zmiany formantu |
Właściwość Min/Max |
Minimalna i maksymalna wartość formantu |
Właściwość Orientation |
Określa położenie formantu (poziome lub pionowe) |
Właściwość SyncBuddy |
Określa, czy występuje synchronizacja właściwości Value formantu UpDown z formantem związanym |
Właściwość Value |
Aktualna pozycja wartości przewijanej |
Zdarzenie Change |
Występuje przy zmianie właściwości Value |
Zdarzenie DownClick |
Występuje po naciśnięciu strzałki w dół lub w lewo |
Zdarzenie UpClick |
Występuje po naciśnięciu strzałki w górę lub w prawo |
Formant WebBrowser XE "WebBrowser:formant"
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?
Przeglądarka ta jest udostępniana użytkownikom bez konieczności opuszczania Accessa.
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.
|
||
|
Jeśli na Twoim komputerze zainstalowany jest Internet Explorer (w wersji 3 lub wyższej), zainstalowany jest również formant WebBrowser. Formant ten nie może być rozpowszechniany osobno w aplikacjach. Musisz więc sprawdzić, czy użytkownicy posiadają taką przeglądarkę lub przekazać im całego Internet Explorer'a. |
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 |
Zdarzenie DownloadBegin |
Występuje po rozpoczęciu otwierania strony |
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 |
Dystrybucja formantów ActiveX
Gdy przekazujesz użytkownikom aplikację Accessa, musisz do niej dołączyć wszystkie formanty ActiveX. W przeciwnym razie aplikacja nie będzie działać prawidłowo. Każdy użyty formant ActiveX musi być poprawnie zainstalowany i zarejestrowany przez użytkownika. Najłatwiejszym sposobem na udostępnianie formantów jest użycie narzędzia VBA Package and Deployment Wizard XE "VBA Package and Deployment Wizard" .
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:
Czym są raporty?
Struktura raportów w Accessie.
Tworzenie prostych raportów przy użyciu kreatora.
Dostosowywanie raportów.
Praca z podraportami.
Tworzenie prostych etykiet adresowych.
Publikowanie raportu.
Modyfikowanie raportu podczas jego działania.
Programowe tworzenie raportów.
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 XE "raport" 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 XE "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.
Struktura raportów w Accessie
Raporty w Accessie podzielone są na cztery główne części (sekcje): Nagłówek/Stopka raportu, Nagłówek XE "Nagłówek" /Stopka XE "Stopka" strony, Nagłówek/Stopka sekcji i szczegóły. Sekcje te porządkują dane w raporcie. Pierwszym w kolejności wydruku elementem raportu jest Nagłówek/Stopka raportu. Jest tylko jeden taki element. Stopka raportu drukowana jest po wszystkich danych, lecz przed stopką strony (mimo, iż w widoku Projekt wygląda to inaczej). Każda strona w raporcie może mieć Nagłówek/Stopkę strony. Mimo iż masz dostęp tylko do jednej sekcji Strona w widoku Projekt, sekcja ta drukowana jest na każdej stronie raportu. Później pokażemy jak modyfikować Nagłówek/Stopkę strony, by wyglądała inaczej na każdej stronie. Nagłówki/Stopki sekcji pojawiają się, gdy umieszczasz w raporcie elementy grupowane. W raporcie może być maksymalnie dziesięć takich sekcji. Niejednokrotnie sprawiają one wiele trudności projektantom raportów. Pokażemy, jak można nimi zarządzać, by uzyskiwać przydatne informacje. Ostatnia z omawianych sekcji - Szczegóły - wyświetla najbardziej szczegółowe informacje w raporcie. Istnieje tylko jedna sekcja Szczegóły i umieszczona jest między wszystkimi nagłówkami i stopkami sekcji, pośrodku widoku Projekt. Rysunek 10.1 przedstawia sekcje raportu w widoku Projekt.
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 |
|
Tworzenie prostych raportów
przy użyciu kreatora
Kreator raportów XE "kreator raportów" jest chyba najbardziej przydatnym z kreatorów Accessa i mimo iż mało prawdopodobne jest, że da Ci raport idealnie odpowiadający Twoim potrzebom, to prawdopodobnie zaoszczędzi Ci 90% pracy w 90% raportów. Co więcej, zadania, które wykona, to najbardziej pracochłonne i nużące z czynności związanych z tworzeniem raportów.
|
||
|
Kreator Raportów może jedynie tworzyć nowe raporty. Po utworzeniu raportu modyfikacji możesz dokonywać wyłącznie ręcznie |
Aby utworzyć raport przy użyciu Kreatora raportów wystarczy z okna dialogowego Nowy raport wybrać pozycję Kreator raportów (rysunek 10.2).
Wybierz źródło danych (w naszym przykładzie używamy tabeli Kategorie) i kliknij przycisk OK.
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.
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.
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.
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.
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).
Rysunek 10.4. Wybieranie pól w Kreatorze raportów |
|
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 |
|
Przejdź przez okna dialogowe i ustaw sortowanie na pole NazwaProduktu.
Nazwij raport „Kategorie i Produkty” i zobacz, jak wygląda.
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.
Zmiana źródła rekordów w raporcie
Pierwszym krokiem w modyfikowaniu raportu jest zmiana jego źródła rekordów ( rysunek 10.6). Trudno byłoby dokonać znaczących zmian w raporcie, nie uzyskując właściwych rekordów i pól.
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 XE "Źródło rekordów:właściwość" i kliknij przycisk z wielokropkiem (...), aby uruchomić Konstruktora kwerend XE "Konstruktor 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 |
|
Zmiana struktury grupowania w raporcie
Najbardziej znaczącą ze zmian, jakich musisz dokonać, jest zmiana struktury grupowania w raporcie. Gdy dokonujesz grupowania, każesz raportowi zebrać razem wskazane dane i przedstawić je w blokach. Bloki te nazywane są również pasmami. Możesz tworzyć je i modyfikować poprzez okno dialogowe Sortowanie i grupowanie XE "Sortowanie i grupowanie" . Po utworzeniu pasma grupującego masz do dyspozycji kilka opcji:
Pole/Wyrażenie - pole lub wyrażenie, które decyduje o grupowaniu raportu.
Porządek sortowania - sposób prezentowania grupowania. Do wyboru masz Rosnąco lub Malejąco.
Nagłówek grupy - po umieszczeniu grupy w raporcie możesz zdecydować, czy przed danymi ma znajdować się wolna przestrzeń, w której zazwyczaj umieszcza się informacje o grupowanych wartościach.
Stopka grupy - sekcja ta znajduje się po grupie danych. Zazwyczaj zawiera obliczenia i podsumowania danych w grupie.
Grupuj według XE "Grupuj według:właściwość" - właściwość ta określa, co będzie decydowało o grupowaniu. Przy ustawieniu Każda wartość dane będą grupowane według wartości całych elementów, podczas gdy ustawienie Pierwsze znaki spowoduje grupowanie tylko według pierwszych znaków elementów. Właściwość ta działa łącznie z właściwością Przedział grupowania.
Przedział grupowania - gdy właściwość Grupuj według ustawiona jest na Interwał, przedział grupowania określa ilość znaków, która zostanie użyta. Tabela 10.1 zawiera dostępne wartości oraz sytuacje, w których można je wykorzystać.
Tabela 10.1.
Wartości przedziału grupowania i ograniczenia w ich stosowaniu
Ustawienie |
Wartość |
Ograniczenie |
Każda wartość |
0 |
Dowolny typ danych |
Znaki przedrostka |
1 |
Tylko dla pól tekstowych |
Rok |
2 |
Tylko dla pól daty |
Kwartał |
3 |
Tylko dla pól daty |
Tabela 10.1.
Wartości przedziału grupowania i ograniczenia w ich stosowaniu (ciąg dalszy)
Ustawienie |
Wartość |
Ograniczenie |
||||
Miesiąc |
4 |
Tylko dla pól daty |
||||
Tydzień |
5 |
Tylko dla pól daty |
||||
Dzień |
6 |
Tylko dla pól daty |
||||
Godzina |
7 |
Tylko dla pól daty |
||||
Minuta |
8 |
Tylko dla pól daty |
||||
Interwał |
9 |
Tylko dla pól liczbowych |
||||
|
||||||
|
Gdy decydujesz się na grupowanie wyrażenia, Access nie będzie w stanie określić jego wyniku, gdy raport będzie w widoku Projekt. W takim przypadku, Access przedstawi wszystkie możliwe opcje właściwości Grupuj według i Przedział grupowania. Upewnij się, że wybrałeś opcję, która będzie odpowiednia dla tego wyrażenia. |
Trzymaj razem XE "Trzymaj razem:właściwość" - 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
Ustawienie |
Wartość |
Opis |
Nie |
0 |
Podział strony występuje w zależności od umiejscowienia nagłówków, stopek i danych. |
Całą grupę |
1 |
Access próbuje umieścić nagłówki, stopki i dane na jednej stronie. |
Z pierwszym szczegółem |
2 |
Access próbuje wydrukować nagłówek grupy na tej samej stronie, co pierwszy rekord szczegółowy. |
Umieszczenie grupowania w raporcie
Aby aktywować Grupowanie XE "grupowanie" , wystarczy ustawić nagłówek, stopkę lub oba te elementy. Po wykonaniu tej czynności, w oknie Sortowanie i grupowanie obok nazwy pola pojawi się mała ikona, a w raporcie w widoku Projekt wyświetlona zostanie nowa sekcja. Każdy formant umieszczony w tej sekcji będzie tworzył grupę opartą na jego wartościach, zależną od wybranych ustawień dodatkowych.
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.
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.
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.
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.
Użycie funkcji w raporcie
Aby otrzymywać w raporcie właściwe i pełne informacje, będziesz czasami zmuszony do pisania funkcji, które będą w raporcie wykonywać obliczenia lub inne czynności. Umieszczenie w raporcie obliczeń może również wpłynąć na poprawę jego funkcjonowania. Jeśli masz do wyboru umieszczanie funkcji w raporcie lub w podlegającej mu kwerendzie, powinieneś rozważyć to pierwsze rozwiązanie. Umożliwi to zmniejszenie ilości wykonywanych obliczeń. Teraz opiszemy użycie funkcji w raporcie.
Użycie funkcji obliczeniowych
Obliczenia w raporcie nie różnią się od obliczeń wykonywanych w innych obiektach Accessa. Jedyna różnica polega na tym, że w raporcie to samo wyrażenie, w zależności od sekcji, w której znajduje się formant, może dać inne wyniki. Przyczyna tego faktu jest prosta. Gdy Access przetwarza dane, by utworzyć żądane grupowania, w rzeczywistości przetwarza różne dane. Więc wyrażenie
Suma XE "Suma:funkcja" ([IlośćJednostkowa])
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 XE "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ę |
|
Użycie Funkcji Immediate IF
Inną, bardzo użyteczną funkcją, którą można wykorzystać w raporcie, jest funkcja Immediate IF (IIF XE "IIF" ()). Funkcja ta umożliwia wykonanie testu If...Then...Else bez konieczności pisania kodu. Sprawdza się ona, gdy należy podsumować dane bądź podkreślić znaczenie poszczególnych rekordów w raporcie. Zawiera trzy argumenty: warunek, czynność wykonywaną, gdy warunek jest spełniony oraz czynność wykonywaną, gdy warunek nie jest spełniony. Argumenty oddzielane są przecinkiem. Aby użyć tej funkcji, napisz warunek, który może być spełniony lub nie (przykładowo, [suma of ilośćjednostkowa]>=500). Drugim argumentem jest zazwyczaj wartość, jaka jest wyświetlana, gdy warunek został spełniony (np. „Powyżej”), a trzecim argumentem jest wartość, jaka jest wyświetlana, gdy warunek nie jest spełniony (np. „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", "")
Użycie własnych funkcji w module raportu
Zdarza się, że wyrażenie staje się zbyt złożone, by umieścić je w zwykłej funkcji IIF(). Gdy taka sytuacja ma miejsce, możesz utworzyć funkcję, która będzie dokładnie odpowiadać Twoim potrzebom, i odwołać się do niej w raporcie. Przykład na wydruku 10.1 przedstawia, jak można taką funkcję napisać w module raportu i odwołać się do niej z umieszczonego w raporcie formantu.
Wydruk 10.1. Funkcja w module raportu
' Jak zamienić wartość na ciąg
Function HiLowTest(dblQuantity As Double) As String
If dblQuantity >= 500 Then
HiLowTest = "Powyżej"
Else
HiLowTest = "Poniżej"
End If
End Function
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.
Teraz możesz zamienić funkcję IIF() na:
=HiLowTest ([Suma of Ilośćjednostkowa])
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życie własnych funkcji w osobnym module
Zdarza się również, że obliczenia wykonywane w raporcie wykorzystywane są również w formularzu i w kwerendach. W takich przypadkach dobrze jest napisać funkcję w osobnym module tak, by kwerendy, formularze i raporty danej aplikacji mogły zawsze otrzymywać zbieżne wyniki. Poniższy przykład przedstawia podstawową funkcję, która poprawia pisownię danego ciągu znaków. Do tego rodzaju funkcji można odwoływać się z różnych miejsc w aplikacji.
Użyjemy tu nowej funkcji VBA Accessa - Split XE "Split:funkcja" (). 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 XE "UCase:funkcja " (), zamienia pierwszą literę każdego słowa na dużą. Aby zwrócić słowa z zamienionymi literami, funkcja korzysta z funkcji Left XE "Left:funkcja " i Right XE "Right:funkcja " , 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
On Error GoTo MakeProper_Err
Dim vararray As Variant
Dim i As Integer
Dim strTemp As String
If Len(str) = 0 Then
Resume MakeProper_Exit
End If
' Najpierw zamień wszystkie litery na małe
str = LCase(str)
' Split() wypełnia tablicę częściami ciągu
' Split() używa spacji jako domyślnego ogranicznika
vararray = Split(str)
' Przejdź przez tablicę I zamieniaj każdą z pierwszych liter na
' na dużą oraz utwórz strTemp
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 XE "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 XE "Immediate Window" lub naciśnij klawisze Ctrl+G.
W oknie wpisz
?MakeProper XE "MakeProper:funkcja" ("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:
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.
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.
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.
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 XE "podraport" . 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 |
|
Tworzenie prostego podraportu
W typowym podraporcie istnieje relacja jeden-do-wielu między rekordami podrzędnymi a nadrzędnymi. Zapisz, które z pól uczestniczą w relacji między dwiema tabelami lub kwerendami.
Utwórz raport dla rekordów nadrzędnych. Będzie to raport główny.
Utwórz następny raport dla rekordów podrzędnych. Będzie to podraport.
W widoku Projekt głównego raportu wyłącz kreator (odpowiedni przycisk znajduje się w przyborniku) i użyj narzędzia Podraport. W miejscu, gdzie chcesz go umieścić, rozciągnij prostokąt.
Jako właściwość podraportu Obiekt źródłowy XE "Obiekt źródłowy:właściwość" ustaw nazwę podraportu utworzonego w punkcie 3.
Jeśli połączone pola, które wcześniej zapisałeś, mają takie same nazwy, Access automatycznie wypełni właściwości Nadrzędne pole łączące XE "Nadrzędne pole łączące:właściwość" i Podrzędne pole łączące XE "Podrzędne pole łączące:właściwość" . Jeśli nazwy ich są różne, nazwa powiązanego pola głównego raportu powinna być wpisana we właściwości Nadrzędne pole łączące, a we właściwości Podrzędne pole łączące powinna zostać wpisana nazwa odpowiadającego mu pola podraportu. Jeśli łącze wymaga więcej niż jednego pola, oddziel je przecinkiem.
|
||
|
We właściwości Podrzędne pole łączące należy umieścić nazwę związanego pola, a nie nazwę formantu wyświetlającego to pole. Natomiast we właściwości Nadrzędne pole łączące można się posłużyć nazwą odpowiedniego formantu. |
|
|
||
|
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 |
|
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.
Tworzenie prostych etykiet adresowych
Mimo iż być może jeszcze nigdy nie miałeś potrzeby tworzenia etykiet adresowych, ta sama technika może być wykorzystana do tworzenia innych rzeczy, na przykład plakietek z nazwiskami, etykiet na dokumentację techniczną, identyfikatorów wyposażenia itp. Access posiada Kreatora etykiet XE "Kreator etykiet" , który potrafi drukować etykiety w setkach różnych formatów. Formaty te mogą być wybierane podczas działania kreatora lub też później.
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.
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ł |
|
||||
|
|||||
|
Jeśli znajdziesz się w sytuacji, w której nie będzie etykiety odpowiadającej Twoim potrzebom, klikając przycisk Dostosuj, możesz utworzyć własny format etykiety. |
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.
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 |
|
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”.
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 |
|
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 XE "Trim:funkcja" (). 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 XE "Trzymaj grupę razem:właściwość" 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.
Metody publikowania raportów
W tej części omówimy sposoby, na jakie można rozpowszechniać raporty Accessa poprzez programy Word, Excel i pocztę elektroniczną. Istnieje kilka różnych formatów, które mogą pomóc dopasować raporty do potrzeb użytkowników. Nowym sposobem na rozpowszechnianie raportów w sieci są strony dostępu do danych. Ponieważ są to jednak osobne obiekty, omówione zostały w rozdziale 26., „Użycie stron dostępu do danych”.
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.
Użycie wbudowanych metod Accessa do eksportowania raportów XE "eksport raportów"
Access posiada siedem opcji umożliwiających eksportowanie lub publikowanie raportów (rysunek 10.15). Każda z tych opcji to inny format pliku, do którego zapisywane są informacje o raporcie i jego układzie. Zostały one opisane w poniższej tabeli.
Tabela 10.3.
Opcje eksportowania raportów w Accessie
Format pliku |
Rozszerzenie pliku |
Opis |
|
Access |
*.mdb, *.adp, *.mdw |
Eksportuje cały raport do innej bazy danych w Accessie |
|
Excel |
*.xls |
Zapisuje rezultaty raportu w arkuszu danych Excela (wersja 5 i 7) |
|
Excel |
*.xls |
Zapisuje rezultaty raportu w arkuszu danych Excela (wersja 97 i 2000) |
|
HTML XE "HTML" |
*.html, *.htm |
Tworzy wersję raportu w języku HTML. Każda ze stron raportu to osobny plik HTML, indeksowany według numerów stron (na przykład SprzedażWedługKategorii, SprzedażWedługKategorii2...) Do poruszania się między stronami służą automatycznie tworzone hiperłącza |
|
Text |
*.txt, *.csv, *.tab, *.asc |
Powszechnie akceptowany format pliku, rozpoznawany przez prawie każdą aplikację. Wszelkie informacje o sposobie formatowania zostaną utracone |
|
Rich Text Format XE "Rich Text Format" |
*.rtf |
Format ten zatrzymuje podstawowe informacje o sposobie formatowania. Rozpoznawany jest przez większość edytorów tekstu |
|
SnapShot XE "SnapShot" Format |
*snp |
Format charakterystyczny dla Accessa. Umożliwia on przesłanie raportu do osób nie posiadających Accessa. Wymaga przeglądarki Microsoft Snapshot Viewer |
|
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.
Użycie łączy pakietu Office do publikowania raportów
Innym sposobem na publikowanie raportów są łącza pakietu Office. Przeglądając raport w widoku Podgląd wydruku, możesz nacisnąć znajdujący się na pasku narzędzi przycisk Łącza Office, a wybrany raport zostanie wysłany do Worda lub Excela. Wówczas możesz zapisać go w dowolnym miejscu.
Problemy związane z publikacją
Gdy używasz formatów Excel i Text jako wyjściowych, istnieje ryzyko utraty części informacji o sposobach formatowania raportu, tak więc przed udostępnieniem go użytkownikom sprawdź, czy nadaje się do użytku.
Użycie poczty elektronicznej do publikowania raportów
Wysyłanie raportów pocztą elektroniczną może się odbywać z poziomu Accessa poprzez zgodny z MAPI XE "MAPI" system pocztowy (na przykład Microsoft Exchange). Gdy otwarłeś raport w widoku Podgląd wydruku lub po zaznaczeniu go w oknie bazy danych z menu Plik wybierz Wyślij do. Możesz wysłać raport jako załącznik w formatach HTML, Excel, DOS Text, RTF lub SnapShot.
Aby przeglądać raport w formacie SnapShot, należy posiadać przeglądarkę SnapShot Viewer XE "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”.
|
||
|
Gdy eksportujesz lub przesyłasz raport oparty na kwerendzie parametrycznej, raport może nie funkcjonować poprawnie. Zastanów się, czy nie będzie lepiej oprzeć eksportowaną wersję na statycznej tabeli z tym samym ustawieniem parametrów. |
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 rozwią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 XE "Filtr:właściwość" , 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:
Otwórz raport Katalog w widoku Projekt.
Zmień właściwość Filtr włączony na Tak.
We właściwości Filtr wprowadź następujące wyrażenie:
[NazwaKategorii] = "Napoje"
Przejdź do widoku Podgląd wydruku. Wyświetlone powinny zostać jedynie napoje.
Powróć do widoku Projekt i ustaw właściwość Filtr włączony na Nie.
Przejdź do widoku Podgląd wydruku. Wyświetlone zostaną wszystkie kategorie.
Aby użyć tych właściwości w kodzie, mógłbyś utworzyć następujące procedury:
Reports![Katalog].FilterOn=True
lub
Reports![Katalog].Filter=[NazwaKategorii]= "Napoje"
Trzymaj grupę razem XE "Trzymaj grupę razem:właściwość"
Przy tworzeniu raportów wielokolumnowych może zaistnieć konieczność zachowania grup w kolumnie lub na stronie w całości. Oto dwie dostępne opcje:
Na kolumnę - gdy właściwość ta jest użyta łącznie z umieszczoną w oknie dialogowym Sortowanie i grupowanie właściwością Trzymaj razem, Access spróbuje zmieścić całą grupę w tej samej kolumnie.
Na stronę - gdy właściwość ta jest użyta łącznie z umieszczoną w oknie dialogowym Sortowanie i grupowanie właściwością Trzymaj razem, Access spróbuje zmieścić całą grupę na tej samej stronie.
HasData XE "HasData:właściwość"
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 |
Do sprawdzenia, czy obliczenia powinny być wykonywane, wystarczy prosta formuła:
="Category has " & if ([CategorySubRpt].[Report].[HasData] = -1, _
[CategorySubRpt].[Report]![CatCount],0) & " products."
Zdarzenia raportu (podczas jego działania)
Poniższe zdarzenia to niektóre ze zdarzeń uruchamianych podczas działania raportu. Oznacza to, że uruchamiane są, gdy raport jest drukowany, zaznaczany itd. Są to zdarzenia, których będziesz używał do kontroli zachowań związanych z interakcją z użytkownikami lub danymi raportu.
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 aktywowaniu XE "Przy aktywowaniu:zdarzenie" , przy dezaktywowaniu XE "Przy dezaktywowaniu:zdarzenie"
Zdarzenia te uruchamiane są, gdy raport staje się aktywnym oknem (w przypadku Przy dezaktywowaniu przestaje nim być) lub gdy rozpoczyna się drukowanie raportu.
Przy braku danych XE "Przy braku danych:zdarzenie"
Dawniej, gdy po otwarciu raport nie zawierał żadnych rekordów lub jego filtr nie zwrócił żadnych wierszy, Access wyświetlał komunikat o błędzie. Na szczęście problem ten został rozwiązany i teraz formanty związane z pustym źródłem rekordów są po prostu puste. Jednakże zdarzenie Przy braku danych będzie w takim przypadku uruchamiane. Może być użyte do grzecznego poinformowania użytkowników o braku rekordów i anulowania raportu. Gdyby raport miał wyświetlać zamówienia według klientów, kod na wydruku 10.3 anuluje raport, gdyby dany klient nie posiadał żadnych zamówień.
Wydruk 10.3. Anulowanie raportu przy braku danych
Private Sub Report_NoData(Cancel As Integer)
' Ostrzeż użytkownika
MsgBox "Ten klient nie składał zamówień"
' Anuluj otwieranie raportu
Cancel = True
End Sub
Przy błędzie XE "Przy błędzie:zdarzenie"
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 XE "AccessError:metoda" obiektu Application XE "Application:obiekt" , 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 XE "Przy stronie:zdarzenie"
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 XE "Przy zamknięciu:zdarzenie"
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 XE "Sekcja:właściwość"
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 XE "Nazwa:właściwość" , 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
Sekcja |
Indeks |
Nazwa/Stała |
Szczegóły |
0 |
acDetail |
Nagłówek |
1 |
acHeader |
Stopka |
2 |
acFooter |
Nagłówek Strony |
3 |
acPageHeader |
Stopka Strony |
4 |
acPageFooter |
Nagłówek Grupy - poziom 1 |
5 |
Nazwa pola grupy |
Stopka Grupy - poziom 1 |
6 |
Nazwa pola grupy |
Nagłówek Grupy - poziom 2 |
7 |
Nazwa pola grupy |
Stopka Grupy - poziom 2 |
8 |
Nazwa pola grupy |
Nagłówek Grupy - poziom 3 ...itd. |
9...itd. |
Nazwa pola grupy |
Wysokość XE "Wysokość:właściwość"
Właściwość ta umożliwia określenie wysokości sekcji.
Widoczny XE "Widoczny:właściwość"
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.
Można powiększać, można zmniejszać XE "Można zmniejszać:właściwość"
Są to dwie, różne właściwości, umożliwiające określenie, czy sekcja może zmieniać swój rozmiar, w celu reagowania na zmiany wielkości formantów. Jeśli w sekcji z właściwością Można powiększać ustawioną na Tak umieścisz formant zawierający więcej rekordów, dzięki właśnie tej właściwości dane zostaną wyświetlone poprawnie.
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.
Nowy wiersz XE "Nowy wiersz:właściwość" lub kolumna
Przy tworzeniu raportów kolumnowych ustawienia właściwości Nowy wiersz lub kolumna dają Ci dużą kontrolę nad wyglądem raportu. Ustawienia te opisane są w tabeli 10.6.
Tabela 10.6.
Ustawienia właściwości Nowy wiersz lub kolumna
Nazwa |
Wartość |
Opis |
Nie |
0 |
Kontrolę nad układem wierszy i kolumn sprawują wartości z okna dialogowego Ustawienia strony. Są to wartości domyślne. |
Przed sekcją |
1 |
Każda sekcja zaczyna się od nowego wiersza lub kolumny. Jeśli wystarczy miejsca, nowa sekcja może współdzielić kolumnę lub wiersz. |
Po sekcji |
2 |
Po wydrukowaniu sekcji tworzony jest nowy wiersz lub kolumna. |
Przed i po |
3 |
Każda sekcja zaczyna się od nowego wiersza lub kolumny. |
Powtórz sekcję XE "Powtórz sekcję:właściwość"
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.
Właściwości sekcji (podczas działania raportu)
Do opisanych poniżej właściwości programista ma dostęp po uruchomieniu raportu. Może dzięki nim modyfikować zachowanie i wygląd raportów, reagując w ten sposób na zachowanie danych i inne warunki.
Wymuszaj nową stronę XE "Wymuszaj nową stronę:właściwość"
Właściwość ta jest krokiem naprzód w nadzorowaniu podziału strony. Może być ona użyta podczas drukowania raportu. Ustawiając tę właściwość (opartą na danych ze źródła rekordów), możesz kontrolować podział strony w odniesieniu do układu sekcji. Tabela 10.7 zawiera ustawienia tej właściwości.
Tabela 10.7.
Ustawienia właściwości Wymuszaj nową stronę
Nazwa |
Wartość |
Opis |
Nie |
0 |
Ustawienie domyślne. Bieżąca sekcja drukowana jest na bieżącej stronie |
Tak |
1 |
Nowa sekcja zaczyna się od nowej strony |
Trzymaj razem XE "Trzymaj razem:właściwość"
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.
PrzenieśUkład, NastępnyRekord i DrukujSekcję
Właściwości te umożliwiają kontrolowanie tego, co i w jaki sposób jest drukowane.
PrzenieśUkład XE "PrzenieśUkład:właściwość" - ustawienie True (Prawda) umożliwi Accessowi przejście do drukowania następnego elementu strony. Ustawienie False (Fałsz) sprawia, że raport nie przechodzi do drukowania następnego elementu strony.
NastępnyRekord XE "NastępnyRekord:właściwość" - gdy właściwość ta ustawiona jest na True, raport przejdzie do następnego rekordu ze źródła rekordów (co nie nastąpi w przypadku ustawienia False).
DrukujSekcję XE "DrukujSekcję:właściwość" - ustawienie True - sekcja będzie drukowana, False - nie.
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
Oczekiwany rezultat |
MoveLayout |
NextRecord |
PrintSection |
Drukuj każdy wiersz, jeden po drugim |
True |
True |
True |
Zostaw puste miejsce |
True |
True |
False |
Powtórz wiersz |
True |
False |
True |
Zostaw puste miejsce, pozostań przy tym samym wierszu danych |
True |
False |
False |
Drukuj różne wiersze w tej samej linii |
False |
True |
True |
Pozostań w tej samej linii, lecz opuść wiersz danych |
False |
True |
False |
LiczbaFormatowań XE "LiczbaFormatowań:właściwość"
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ść LiczbaFormatowań 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ń XE "LiczbaDrukowań:właściwość"
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 XE "ByłKontynuowany:właściwość" , BędzieKontynuowany XE "BędzieKontynuowany:właściwość"
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 ustawiona 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 XE "Przy formatowaniu:zdarzenie" . 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.
Programowe tworzenie raportów
Prawdopodobnie największym wyzwaniem dla programisty jest stworzenie raportu dla danych, które ulegają ciągłym zmianom. Wyobraźmy sobie okresowy raport o sprzedaży produktów według regionów. Załóżmy też, że musi mieć on postać tabeli. Jeśli raport oparty jest na kwerendzie krzyżowej, nazwy kolumn użyte jako ich nagłówki będą się prawdopodobnie zmieniać co miesiąc. Będzie to problem dla związanych formantów w raporcie. Jednym z możliwych rozwiązań jest programowe tworzenie raportu za każdym razem, gdy jest to konieczne. Można tego dokonać przy użyciu modułu VBA.
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.
Tworzenie źródła rekordów
Pierwszym krokiem jest stworzenie źródła rekordów. Przedstawiona w listingu 10.4 funkcja o nazwie MakeCrosstabQuery posiada dwa argumenty danych: datFrom i datTo. Określają one okres, jakiego raport dotyczy. Jeśli definicja kwerendy nie istnieje, zostanie utworzona przez funkcję. W przeciwnym wypadku po prostu zaktualizowana zostanie właściwość SQL definicji kwerendy. Do funkcji tej będziemy się odwoływać z funkcji tworzącej raport, jednakże mogłaby być wykorzystywana przez samą siebie do innych celów.
Wydruk 10.4. Programowe tworzenie kwerendy krzyżowej
Function MakeCrosstabQuery(datFrom As Date, datTo As Date) As Boolean
' Obsługa błędów w kodzie
On Error Resume Next
Dim db As Database
Dim qrydef As querydef
Dim strSQL As String
Set db = CurrentDb
' Upewnij się, że znasz wszystkie obiekty w pojemniku, używając
' procedury Refresh (odśwież)
db.QueryDefs.Refresh
' Pobierz kwerendę
Set qrydef = db.QueryDefs("Ilość dostarczona według regionów")
' 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
Set qrydef = db.CreateQueryDef( _
"Ilość dostarczona według regionów")
' Jako, że utworzyłeś nowy obiekt, odśwież pojemnik
db.QueryDefs.Refresh
' Zanim przejdziesz dalej, wyzeruj obiekt Err
Err = 0
End If
' Dla skrócenia procedury załóż, że daty są poprawne
datFrom = CStr(datFrom)
datTo = CStr(datTo)
' Utwórz procedurę SQL
strSQL = strSQL & "TRANSFORM Sum([Order Details].Quantity) "
strSQL = strSQL & "AS SumOfQuantity "
strSQL = strSQL & "SELECT Products.ProductName "
strSQL = strSQL & "FROM Products INNER JOIN "
strSQL = strSQL & "(Orders INNER JOIN [Order Details] ON _
Orders.OrderID = "
strSQL = strSQL & "[Order Details].OrderID) ON Products.ProductID _
= [Order Details].ProductID "
strSQL = strSQL & "WHERE (((Orders.OrderDate) Between #" & datFrom _
& "# And #" & datTo & "#) AND "
strSQL = strSQL & "((Orders.ShipRegion) Is Not Null)) "
strSQL = strSQL & "GROUP BY Products.ProductName "
strSQL = strSQL & "ORDER BY Orders.ShipRegion "
strSQL = strSQL & "PIVOT Orders.ShipRegion; "
' Skoro obiekt został już utworzony, wystarczy zmienić
' procedurę SQL zmieniając właściwość SQL
qrydef.SQL = strSQL
If (Err) Then
' W tym miejscu przekaż błąd do twojego modułu zajmującego
' się ich poprawianiem
Exit Function
End If
' Zamknij obiekt Kwerenda
qrydef.Close
db.QueryDefs.Refresh
End Function
Po utworzeniu kwerendy możesz przejść do tworz,enia raportu.
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.
Tworzenie obiektu Raport
Funkcja PrepareCrosstabReport() utworzy nową kwerendę, uruchomi ją, a następnie utworzy nowy obiekt Raport, który będzie zgodny z właściwościami nowej kwerendy. Po utworzeniu obiektu Raport funkcja przejdzie do umieszczenia w sekcjach raportu formantów oraz związaniu ich ze źródłem danych. Ponieważ Access numeruje formanty w kolejności ich tworzenia, sprawowanie kontroli nad tym, czy formanty następują po sobie w tej samej kolejności co etykiety, wydaje się być ułatwione. Aby to osiągnąć, funkcja tworzy etykiety i wiąże formanty w osobnych pętlach. Stopka raportu tworzona jest przy użyciu procedury RunCommand XE "RunCommand:metoda" obiektu DoCmd XE "DoCmd:obiekt" , a następnie jej właściwość Widoczny (Visible) zmieniana jest na 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.
Wydruk 10.5. Tworzenie raportu przy użyciu kodu
Public Function PrepareCrosstabReport(datFrom As Date, datTo As Date) As Boolean
On Error GoTo PrepareCrosstabReport_Err
Dim db As Database
Dim DocName As String
Dim rs As Recordset
Dim rpt As Report
Dim i As Integer
Dim x As Integer
Set db = CurrentDb()
'Wyzeruj kwerendę, by używać nowych danych i otwórz ją
MakeCrosstabQuery datFrom, datTo
Set rs = db.OpenRecordset("Ilość dostarczona według regionów")
' Utwórz obiekt Raport
Set rpt = CreateReport("", "")
rpt.Caption = " Ilość dostarczona według regionów Between " & _
datFrom & " and " & datTo
' Teraz musisz utworzyć formanty
Dim ctlNew As Control
' Do wypełnienia jest dziewięć formantów, więc...
If rs.Fields.Count - 1 > 9 Then
x = 9
Else
x = rs.Fields.Count - 1
End If
' Utwórz, rozmieść, zwiąż i sformatuj formanty
For i = 0 To x
Set ctlNew = CreateReportControl(rpt.Name, acTextBox, acDetail)
With ctlNew
.Height = 270
.Width = 1080
.Top = 0
.Left = (60 + .Width) * i
rpt("text" & i).ControlSource = rs.Fields(i).Name
End With
Next
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
rpt.RecordSource = " Ilość dostarczona według regionów"
DoCmd.OpenReport rpt.Name, acViewPreview
'Normalnie, to zostałoby wydrukowane
PrepareCrosstabReport = True
PrepareCrosstabReport_Exit:
Set rpt = Nothing
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 XE "CreateGroupLevel:funkcja" . 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.
Funkcja CreategroupLevel posiada cztery argumenty:
StrReport - ciąg identyfikujący raport, który chcesz modyfikować.
StrExpr - wyrażenie poziomu grupy, zazwyczaj nazwa pola, rodzaj obiektu lub data.
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.
Tworzenie grupowania dwutygodniowego
Jeśli grupujesz dane na dany dzień i chcesz uzyskać grupowanie dwutygodniowe (na przykład podczas tworzenia listy płac), w oknie dialogowym Sortowanie i grupowanie XE "Sortowanie i grupowanie" ustaw właściwość Grupuj według XE "Grupuj według:właściwość" na Interwał, a właściwość Przedział grupowania XE "Przedział grupowania:właściwość" na 2.
Ukryj powtarzające się dane
Może zdarzyć się, że w prostym raporcie tabelarycznym informacja powtarza się w kolejnych wierszach. Aby tego uniknąć, ustaw właściwość Ukryj Duplikaty XE "Ukryj Duplikaty:właściwość" danego formantu na Tak. Umożliwi Ci to uzyskanie wyglądu przypominającego grupowanie, jednak bez użycia sekcji oraz drukowanie danych określających grupę i pierwszej linii szczegółów w tym samym wierszu.
Alfabetyczne grupowanie danych
W raporcie wyświetlającym listę klientów według pola NazwiskoKlienta możesz, wykonując poniższe kroki, alfabetycznie podzielić klientów na grupy:
W oknie dialogowym Sortowanie i grupowanie ustaw właściwość Grupuj według na Pierwsze znaki.
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 |
|
Ustaw źródło formantu z nazwiskiem klienta na:
=Left([NazwiskoKlienta]], 1)
Tworzenie numerowanych list
Użycie właściwości Suma bieżąca w połączeniu ze źródłem formantu umożliwi raportowi numerowanie obiektów na liście. Na rysunku 10.17 znajduje się przykład raportu z ponumerowanymi obiektami. Numerowanie może zaczynać się od nowa dla każdej grupy lub być kontynuowane przez cały raport.
Rysunek 10.17. Rezultat numerowania |
|
Umieść w raporcie formant, który będzie zawierał numer pozycji.
Ustaw źródło formantu na =1. Będzie to początek schematu numerowania.
Ustaw właściwość Suma bieżąca formantu na Wszędzie lub W grupie.
Tworzenie pustych linii co n znaków
W rozdziale tym opisaliśmy, jak przy użyciu właściwości PrzenieśUkład, NastępnyRekord i DrukujSekcję tworzyć puste linie. Wydruk 10.6 jest przykładem takiego kodu. Można go umieścić w większości raportów. By zmienić częstotliwość tworzenia pustych linii, wystarczy zmodyfikować stałą intSkipLine.
Wydruk 10.6. Tworzenie pustych linii co n znaków
Option Compare Database
Dim intCurrLine As Integer
Const intSkipLine = 3
Private Sub Detail_Format(Cancel) As Integer, FormatCount As Integer)
If intCurrLine Mod (intSkipLine + 1) = 0 Then
Me.NextRecord = False
Me.PrintSection = False
End If
intCurrLine = intCurrLine + 1
End Sub
Private Sub Report_Open(Cancel As Integer)
cLines = 0
End Sub
Zerowanie numeru strony dla nowych grup
Ponieważ właściwość Page (strona) sekcji jest zapisywana lub odczytywana podczas uruchamiania raportu, można ją zmieniać przy każdym formatowaniu nagłówka grupy. Właściwość ta nie powinna być mylona z właściwością Strony, która nie może być zapisywana podczas działania raportu. Poniższy kod zeruje liczbę stron. Przydaje się on, gdy grupy zajmują więcej niż jedną stronę.
Sub GroupHeader_Format
Page=1
End Sub
Rysowanie pionowych linii
Tworzenie w raporcie pionowych linii może być dokonane z pomocą zaledwie kilku linijek kodu. Aby rysować linie w zdarzeniu Przy formatowaniu, ustaw pozycje i wywołaj metodę Line. Używaną tutaj miarą są twipy (1,440 cala).
Wydruk 10.7 zawiera przykład procedury rysującej linię.
Wydruk 10.7. Rysowanie poziomych linii przy użyciu kodu
Private Sub Detail_Format(Cancel As Integer, FormatCount As Integer)
Dim x1 As Single
'Pozycja pozioma przeliczona z cali na twipy
x1 = 3 * 1440
' Użyj procedury raportu Line, gdzie
' x1, y1 to współrzędne początkowe, a
' x2, y2 to współrzędne końcowe
Me.Line (x1, 1) - (x1, 32000)
End Sub
Przesuwanie numerów parzystych i nieparzystych stron
Jeśli zajdzie potrzeba umieszczenia numerów stron parzystych po prawej, a nieparzystych po lewej stronie, pomocna będzie poniższa funkcja. Możesz chcieć jej również użyć przy tworzeniu marginesu do oprawy.
Wydruk 10.8 zawiera przykład takiej techniki.
Wydruk 10.8. Zmiana pozycji numerów parzystych i nieparzystych stron
Private Sub Detail_Print(Cancel As Integer, PrintCount As Integer)
If (Me!txtpagenumber Mod 2 = 0) Then
txtpagenumber.TextAlign = 3 'Lewy
Else
txtpagenumber.TextAlign = 1 'Prawy
End If
End Sub
Identyfikacja użytkownika drukującego raport
Jeśli Twoja baza danych Accessa jest zabezpieczona, możesz określić identyfikator użytkownika drukującego raport oraz użyć tego identyfikatora do uzyskania nazwiska tego użytkownika. Wpisz poniższe wyrażenie jako źródło niezwiązanego formantu:
=ObecnyUżytkownik()
lub
=dlookup("TabelaUżytkowników" , "[Nazwisko]", "[IDUżytkownika]= " & ObecnyUżytkownik() & ")
Wyrównanie stron do oprawy
Gdy strony mają być oprawione jak książka, musi być na nich miejsce na umieszczenie oprawy. Oznacza to, iż zawartość stron nieparzystych musi być przesunięta w prawo, a parzystych w lewo. Czynność taką wykonuje kod z wydruku 10.9.
Wydruk 10.9. Wyrównywanie stron do oprawy
Private Sub PageFooterSection_Format(Cancel As Integer, _
FormatCount As Integer)
Dim ctl As Control
If (Me.Page Mod 2 = 0) 'Strona jest parzysta
For Each ctl In Me.Controls
.Left = .Left + 1440 'przesuwa wszystko o jeden cal w lewo
Next
Else 'strona jest nieparzysta
For Each ctl In Me.Controls
.Left = .Left - 1440 'przesuwa wszystko o jeden cal w prawo
Next
End If
End Sub
Obliczanie podsumowań strony
Access wyświetli komunikat o błędzie, jeśli będziesz próbował umieścić funkcję podsumowującą (np. Suma()) w formancie znajdującym się w nagłówku lub stopce strony. Ponieważ często pojawia się konieczność podsumowania strony, jest to dość niewygodne. Z pomocą prostego kodu można wykonać obliczenia podsumowujące wartości na stronie, a następnie wyświetlić je poprzez niezwiązany formant w stopce strony. Aby skorzystać z kodu użytego w przykładzie, konieczne jest wykonanie następujących czynności:
W oparciu o tabelę Faktury utwórz prosty raport. W części Szczegóły umieść pola NazwaOdbiorcy i CenaJednostkowa.
W części Szczegóły umieść ponownie pole CenaJednostkowa i zmień jego nazwę na SumaBieżąca. Ustaw właściwość Widoczny na Nie i Suma bieżąca na Wszędzie.
W stopce strony umieść niezwiązane pole tekstowe i nazwij je txtPageSubtot.
Kod z listingu 10.10 wprowadź do zdarzenia stopki strony Przy wydruku.
Wydruk 10.10. Obliczanie podsumowania strony
Option Compare Database
Dim x As Double
Private Sub PageFooterSection_Print(Cancel As Integer, _
PrintCount As Integer)
txtpagesubtot = RunningSum - x
x = RunningSum
End Sub
'Teraz raport będzie zawierał podsumowania stron
Precyzyjne przesuwanie formantów
Aby zminimalizować ryzyko przesunięcia formantów, do ich zaznaczania możesz używać następujących technik:
Kliknij linijkę, by zaznaczyć formanty znajdujące się w określonym miejscu.
Kliknij tło raportu i przeciągnij zaznaczenie na odpowiednie formanty bez poruszania ich.
Do przechodzenia między formantami używaj klawisza Tab.
Kombinacja klawisza Ctrl i strzałek umożliwia precyzyjne przesuwanie formantu oraz przemieszczanie formantów między sekcjami.
Kombinacja klawisza Shift i strzałek umożliwia zmianę rozmiaru formantów bez przesuwania ich.
Część IV
Tajniki VBA
W tej części:
Tworzenie obiektów przy użyciu modułów klasowych.
Usuwanie błędów w aplikacjach Accessa.
Profesjonalna obsługa błędów.
Optymalizacja aplikacji.
Rozdział 11.
Tworzenie obiektów przy użyciu modułów klas
W tym rozdziale:
Korzyści z używania obiektów.
Przegląd obiektów, własności i metod.
Tworzenie klas.
Tworzenie właściwości.
Tworzenie metod.
Tworzenie zdarzeń.
Użycie obiektów.
Tworzenie kopii obiektów.
Przegląd innych obiektów.
Implementacja obiektu do obsługi błędów.
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 XE "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 |
|
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 XE "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.
|
||
|
Rozdział ten poświęcony jest tworzeniu obiektów przy użyciu modułów klasowych. Pamiętaj, że moduły formularza są modułami klasowymi. W taki sam sposób, jak dodajesz właściwości i metody do własnych obiektów, możesz też dodawać właściwości i metody do formularzy. |
Korzyści z używania obiektów
Z tworzenia i używania obiektów płynie wiele korzyści, w tym: ukrywanie złożonego zestawu funkcji kodu, użycie IntelliSense XE "IntelliSense" , prostsze tworzenie i utrzymanie kodu oraz wiele innych.
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 zrozumienia kodu, dzięki któremu obiekty te działają.
Użycie technologii Microsoft IntelliSense
|
Aby używać obiektu, programista musi jedynie określić jego właściwość lub metodę przy użyciu technologii IntelliSense (rysunek 11.2). Przykładowo, jeden ze znajdujących się na naszej płycie CD obiektów to obiekt służący do obsługi błędów w aplikacjach Accessa. Ponieważ cały kod tego obiektu zawarty jest w obiekcie cError, programista musi tylko określić cechy swojego obiektu oraz właściwość lub metodę, której chce użyć. Przykładowo, gdyby programista chciał, by konsekwencją wystąpienia błędu w aplikacji było wysłanie e-maila, wystarczyłoby odwołanie do metody „e-mail”: |
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ą XE "hermetyzacja" .
Dopuszczenie przeglądania obiektów w Object Browser
Umieszczenie kodu w klasach umożliwia programistom użycie narzędzia Object Browser XE "Object Browser" w celu przeglądania właściwości, metod i innych informacji o obiekcie. W dalszej części tego rozdziału przyjrzymy się jednemu z obiektów własnych w tym narzędziu.
Tworzenie wielu egzemplarzy obiektów
Wyobraź sobie, że istnieje fragment kodu, którego używasz wielokrotnie w różnych miejscach aplikacji. W rzeczywistości, kod ten może być używany niezliczoną ilość razy jednocześnie. Przykładem tego może być kod łączenia do danych. Za każdym razem, gdy użytkownik poszukuje nowego klienta, otwiera formularz lub używa listy wyboru, z serwera pobierane są dane. Zamiast tworzyć duplikat kodu w każdej z tych procedur lepiej jest utworzyć obiekt Data Connection, zawierający kod, który będzie służył do pobierania danych z serwera.
Tworzenie kodu łatwego do aktualizacji i utrzymania
Używając klas, możesz w aplikacji wielokrotnie użyć jednostki kodu bez powtarzania go. Jeśli, przykładowo, w wielu procedurach powtarzasz kod dostępu do danych, w przypadku gdy zajdzie potrzeba wprowadzenia zmian, każde miejsce, w którym znajduje się ten kod, musi zostać odnalezione i zmodyfikowane. Postępowanie takie jest bardzo czasochłonne i mało wydajne. Gdyby w tej sytuacji użyć obiektu Data Connection, aktualizacja i wszystkie zmiany w kodzie dostępu do danych byłyby dokonywane w jednym miejscu - module klasy.
Ograniczenie dostępu do kodu
Klasy umożliwiają Ci sprawowanie kontroli nad tym, kto i w jakich okolicznościach używa kodu. Dzięki klasom możesz zabezpieczać właściwości i metody, kontrolując ich pojawianie się na zewnątrz klasy.
Tworzenie przenośnego kodu
Ponieważ moduł klasy jest odrębną jednostką kodu, może być z łatwością przenoszony z jednej aplikacji Accessa do innych.
Przegląd obiektów, właściwości i metod
Zanim przejdziemy do tworzenia obiektów, zatrzymajmy się przy podstawowych wiadomościach. Jeśli nie będziemy mieli jasności co do terminów: obiekt, właściwości i metody, przejście do dalszej części rozdziału nie będzie miało sensu.
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ść XE "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.
Wstawianie modułu klasowego
Tworzenie klasy jest bardzo proste. Trochę więcej wysiłku wymaga dodawanie do obiektu właściwości i metod.
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 XE "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 |
|
||||
|
|||||
|
Zwracaj uwagę na nazewnictwo modułów klasy, gdyż będą to nazwy Twoich obiektów. W ten sposób programiści, przy użyciu technologii IntelliSense, będą uzyskiwali dostęp do napisanego przez Ciebie kodu. Warto również poprzedzić nazwę obiektu inicjałami firmy, aby móc później bez trudu stwierdzić, który z obiektów został stworzony przez Twoją firmę. |
Tworzenie właściwości
Istnieją dwa sposoby tworzenia właściwości klasy: zmienne jawne i procedury właściwości.
|
||
|
Kod znajdujący się na dołączonej płycie CD zawiera wiele obiektów. Najprostszy z nich, obiekt cUser, wykorzystamy jako przykład na następnych stronach. Obiekt cUser przechowuje informacje o aktualnie zalogowanym użytkowniku, w tym jego lub jej imieniu. Obiekt ten może być użyty, gdy aplikacja wymaga imienia użytkownika, na przykład przy obsłudze błędów czy przy zapisywaniu autora notatek czy dokumentów. W naszym przykładzie wykorzystamy obiekt cUser do zapisywania dat i czasów logowania użytkowników, a jedno ze zdarzeń tego obiektu wykorzystamy do wyświetlenia wiadomości witającej użytkownika po zalogowaniu. |
Użycie zmiennych publicznych
Właściwość może zostać utworzona przez zadeklarowanie zmiennej publicznej w części deklaracyjnej modułu klasowego.
Poniższy przykład tworzy właściwości Imię i TypUżytkownika obiektu cUser:
Public Imię as String
Public TypUżytkownika as String
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"
Aby pobrać tę właściwość, wystarczy użyć następującego kodu (rysunek 11.4):
MsgBox cUser.Imię
Rysunek 11.4. Ustawianie i pobieranie właściwości obiektów jest proste dzięki technologii IntelliSense |
|
Użycie procedur właściwości
Właściwości mogą być dodawane do obiektów za pomocą specjalnego typu procedur VBA - procedur właściwości. Istnieją trzy rodzaje procedur właściwości: Property Let XE "Property Let" dla pobierania wartości właściwości, Property Get XE "Property Get" dla ustawiania wartości właściwości oraz Property Set XE "Property Set" , która umożliwia traktowanie obiektów jak właściwości.
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.
|
||
|
Procedury właściwości, podobnie jak wszystkie inne procedury, mogą być ustawiane jako jawne i niejawne. Jawne procedury właściwości dostępne są dla wszystkich innych procedur we wszystkich modułach. Niejawne procedury właściwości dostępne są jedynie dla procedur w module, w którym zostały zadeklarowane. |
Tworzenie w module zmiennych prywatnych
Gdy używamy procedur właściwości, wartość właściwości ukryta jest w zmiennej prywatnej modułu. Osoba tworząca klasę określa, czy właściwość ma być dostępna na zewnątrz, czy nie.
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. Przykładowo, instrukcja Property Let dla właściwości Imię akceptuje argument typu string (ciąg). W takim przypadku, procedura Property Get musi również zwracać dane typu string. |
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
Public Property Set Form(FormObject)
' Pobierz przekazany obiekt (FormObject) i zapisz go
' w zmiennej prywatnej(mobjForm)
Set mobjForm = FormObject
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
Private Sub cmdPropertySet_Click()
MsgBox "Obiekt formularz (we właściwości 'Form') nazywa się: " _
& mobjForm.Form.Name, vbInformation, "Przykład Property Set"
End Sub
Private Sub Form_Load()
Set mobjForm = New cForm
Set mobjForm.Form = Forms!frmPropertySet
End Sub
Private Sub Form_Unload(Cancel As Integer)
Set mobjForm = Nothing
End Sub
Zmienna publiczna czy procedury właściwości
Najprostszym sposobem tworzenia właściwości klasy jest użycie zmiennych publicznych. Jednakże rozwiązanie to ma swoje wady. Zmienne publiczne zawsze są dostępne na zewnątrz. Oznacza to, że nie masz kontroli nad tym, kto ustawia i pobiera wartości właściwości. Może to doprowadzić do sytuacji, w której inni zmieniają wartość właściwości, na której Ty się opierasz.
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 jednocześ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.
Tworzenie wyliczeniowych typów danych
Wyliczeniowy typ XE "typ wyliczeniowy" danych to wartość właściwości, jaką możesz dostarczyć programistom używającym Twoich obiektów. Przykładowo, być może zauważyłeś, że gdy podczas ustawiania właściwości Widoczny formularza wpiszesz znak równości, będziesz mógł z rozwijanej listy wybrać wartości True lub False (rysunek 11.5).
Rysunek 11.5 Z rozwijanej listy wybierz True lub False |
|
Możesz dostarczać takie wartości właściwości, tworząc typy wyliczeniowe.
W części deklaracyjnej modułu klasowego do określenia wartości właściwości użyj słowa kluczowego Enum XE "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:
Przykład 1. Właściwość zadeklarowana jako zmienna string
Public TypUżytkownika as String
Przykład 2. Właściwość zadeklarowana jako wyliczający typ danych
Public TypUżytkownika as ListaUżytkowników
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).
|
||
|
Wprowadzone wartości właściwości nie są ograniczone do wyliczeniowych typów danych. W poprzednim przykładzie, wyliczeniowy typ danych zawierał trzy elementy: Menedżer, Administracja i Nieznany. VBA nie uniemożliwia programiście zignorowania wartości z listy i wpisania innych (na przykład Produkcja). Aby ograniczyć możliwość wyboru do |
|
listy, użyj wartości liczbowych elementów z listy. Przykładowo, jeśli na liście są trzy elementy (i numerowanie rozpoczyna się od zera), możesz uniemożliwić wprowadzanie elementów mniejszych niż zero i większych niż dwa. |
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 XE "Przy załadowaniu:zdarzenie" , a przycisk polecenia zdarzenie Przy kliknięciu XE "Przy kliknięciu:zdarzenie" .
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 XE "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:
Event PrzyPowitaniu ()
Aby użyć zdarzenia, umieść je w metodzie obiektu. Służy do tego polecenie Raise XE "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
|
||
|
Słowo kluczowe WithEvents może być używane jedynie w modułach klasowych (takim właśnie są moduły formularza). Nie można go jednak używać w standardowych modułach. |
Po zadeklarowaniu używającej słowa kluczowego WithEvents XE "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).
Rysunek 11.8. Ekran powitalny |
|
Uruchamianie zdarzeń „Przy inicjacji”
i „Przy zakończeniu”
Moduły klasy zawsze posiadają zdarzenia Przy inicjacji i Przy zakończeniu. Aby użyć tych zdarzeń, wybierz je ze znajdującej się u góry okna kodu listy wyboru.
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 XE "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.
Tworzenie zmiennej obiektu
Zmienna jest to fragment pamięci, zarezerwowany w celu przechowywania bądź pobierania informacji. Z pewnością miałeś już do czynienia ze zmiennymi „prostymi” np. string (ciąg znaków) czy integer (liczba całkowita). Poniżej znajdziesz przykłady deklarowania i użycia dwóch prostych zmiennych:
Dim strImię as String
Dim I as Integer
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
Przypisywanie zmiennej obiektu do obiektu
Do tworzenia odniesienia między zmienną obiektu a obiektem używamy słowa kluczowego Set XE "Set" . Na przykład:
Set objUser = New 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 momencie 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ść
|
||
|
Jeśli, próbując użyć obiektu, zauważysz, że IntelliSense nie pokazuje żadnych właściwości i metod, może to oznaczać, że nie utworzyłeś bądź nie ustawiłeś zmiennej obiektu. Zdarza się jednak, że IntelliSense nie pokazuje właściwości ani metod, mimo iż kod jest poprawny. Załóż, że napisany przez Ciebie kod jest poprawny i przetestuj go. Microsoft nie dostarczył technologii IntelliSense dla każdego elementu kodu. |
Zwalnianie obiektu
Gdy zakończyłeś już pracę ze zmienną obiektu, zwolnij go, ustawiając obiekt na Nothing XE "Nothing" . W ten sposób odzyskasz zarezerwowane zasoby. Prawidłowa składnia wygląda następująco:
' Zwolnij zmienną obiektu
Set objUser = Nothing
|
||
|
Gdy opisujesz zmienną obiektu, przejdź od razu na koniec procedury i ustaw zmienną na równą Nothing. Dzięki temu nie zapomnisz jej zwolnić po napisaniu długiej procedury. |
Tworzenie wielu egzemplarzy obiektów
Klasa posiada zdefiniowany zestaw właściwości i metod. To jak szablon lub schemat. Wyobraź sobie, że otwierasz nowy dokument w Wordzie. Masz wówczas możliwość użycia szablonu, na przykład List elegancki. Po wybraniu szablonu dostosowujesz go do własnych potrzeb. Lecz zmian dokonujesz już na nowym dokumencie, nie na szablonie. Dokładnie tak samo funkcjonują klasy.
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
Set objUser1 = New cUser
Set objUser2 = New cUser
ObjUser1.Imię = "Mariusz"
ObjUser2.Imię = "Beata"
Msgbox "Aktualni użytkownicy to: " & objUser1.Imię & " i "_
objUser2.Imię
Set objUser1 = Nothing
Set objUser2 = Nothing
End Sub
Przegląd innych obiektów
|
Przykłady z tego rozdziału zawierają wiele klas, które możesz używać dla swoich potrzeb („tworzenie obiektów przy użyciu modułów klasy.mdb” na dołączonej do książki płycie CD). Teraz omówimy pokrótce każdy z tych obiektów. |
Obiekt TextFile XE "TextFile:obiekt"
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 |
|
Moduł klasowy zawiera następujący kod:
Private pintFreeFile As Integer
Private pvarInfo As Variant
Public Function ReadLineText(strFileName As String) As String
pintFreeFile = FreeFile
Open strFileName For Input As pintFreeFile
Line Input #pintFreeFile, pvarInfo
ReadLineText = pvarInfo
Close #pintFreeFile
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
Public Sub WriteLineText(strFileName As String, strText As String)
pintFreeFile = FreeFile
Open strFileName For Append As pintFreeFile
Write #pintFreeFile, strText
Close #pintFreeFile
End Sub
Obiekt Timer XE "Timer:obiekt"
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.
Kod w module klasy cTimer jest następujący:
Option Explicit
Private msngStart As Single
Public Sub Wait(lngSeconds As Long)
Do Until Timer > msngStart + lngSeconds
DoEvents
Loop
End Sub
Public Sub StartTimer()
msngStart = Timer
End Sub
Public Function ElapsedTime() As Long
Dim sngTimerStop As Single
sngTimerStop = Timer
ElapsedTime = sngTimerStop - msngStart
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 |
|
Obiekt Sound XE "Sound:obiekt"
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
Public Sub PlaySound(SoundFile As String)
' Odtwarzanie pliku dźwiękowego
sndPlaySound SoundFile, 1
End Sub
Poniższy kod korzysta z obiektu objSound (rysunek 11.11):
Dim objSound As cSound
Set objSound = New Sound
' Jeśli używasz Windows NT, wpisz ścieżkę "C:\WINNT"
objSound.PlaySound "C:\Windows\chimes.wav"
Set objSound = Nothing
Rysunek 11.11. Przykład obiektu Sound |
|
Obiekt Letter XE "Letter:obiekt"
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.
Oto kod modułu klasy cLetter:
Option Explicit
Private objWord As Word.Application
' Zmienne lokalne, do przechowywania wartości właściwości
Private mvarTemplate As String ' lokalna kopia
Private mvarSQLStatement As String 'lokalna kopia
Public Property Let SQLStatement(ByVal vData As String)
mvarSQLStatement = vData
End Property
Public Property Get SQLStatement() As String
SQLStatement = mvarSQLStatement
End Property
Public Property Let Template(ByVal vData As String)
mvarTemplate = vData
End Property
Public Property Get Template() As String
Template = mvarTemplate
End Property
Public Sub CreateLetter(DatabasePath As String, ShowWord As Boolean)
' Zapisywanie danych o klientach do pliku tymczasowego,
' który zostanie użyty do korespondencji seryjnej.
' Rozwiązanie to jest szybsze niż
' pobieranie danych bezpośrednio z Accessa.
DoCmd.OutputTo acOutputQuery, "qryCustomers", _
acFormatRTF, "C:\Temp.RTF", False
objWord.Documents.Add (Me.Template)
' Uruchomienie korespondencji seryjnej
With objWord.ActiveDocument.MailMerge
.MainDocumentType = wdFormLetters
.OpenDataSource Name:="C:\Temp.rtf"
.Destination = wdSendToNewDocument
.Execute
End With
If ShowWord Then
Me.ShowWord
End If
End Sub
Friend Sub ShowWord()
' Word widoczny dla użytkownika
objWord.Visible = True
End Sub
Private Sub Class_Initialize()
' Przejście do linii występującej po błędzie
On Error Resume Next
' Próba odwołania do Worda, który już jest otwarty
Set objWord = GetObject(, "Word.Application")
' Jeśli PRAWDA, Word nie jest uruchomiony
If objWord Is Nothing Then
' Utwórz nowy egzemplarz aplikacji Word
Set objWord = New Word.Application
' Jeśli PRAWDA, MS Word nie jest zainstalowany
If objWord Is Nothing Then
MsgBox "MS Word nie jest zainstalowany na tym komputerze"
End If
End If
End Sub
Private Sub Class_Terminate()
Set objWord = Nothing
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
' Przydziel zmienne obiektu do obiektu cLetter
Set objLetter = New cLetter
' Szablon Word'a, który będzie użyty w dokumencie
objLetter.Template = strPath & "\Business Services Letter.Dot"
' Instrukcja SQL użyta do pobrania danych dla formularza
objLetter.SQLStatement = "SELECT * FROM tblCustomers"
' Odwołanie do metody "CreateLetter" w celu stworzenia listu
objLetter.CreateLetter strPath & "\Objects.mdb", True
" Zniszczenie zmiennej obiektu
Set objLetter = Nothing
Obiekt Outlook XE "Outlook:obiekt"
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.
Oto kod zawarty w module klasy cOutlook:
Option Explicit
Private mobjOutlook As Outlook.Application
Private mMyItem As Object
Public Sub NewEmailMessage(EmailAddress As String)
' Tworzenie nowej wiadomości programu Outlook
Set mMyItem = mobjOutlook.CreateItem(olMailItem)
Rysunek 11.12. Wyświetlanie formularza Nowa wiadomość programu Outlook w aplikacjach Accessa |
|
mMyItem.To = EmailAddress
mMyItem.Display
End Sub
Private Sub Class_Initialize()
' Nie zachodzi konieczność użycia instrukcji "GetObject"
' Outlook zawsze otwiera tylko jedną kopię aplikacji
' Użyj słowa kluczowego "New"
' Ustaw zmienną obiektu na aplikację Outlook
Set mobjOutlook = New Outlook.Application
' Jeśli PRAWDA, Outlook nie jest zainstalowany
If mobjOutlook Is Nothing Then
MsgBox "MS Outlook nie jest zainstalowany na tym komputerze"
End If
End Sub
Private Sub Class_Terminate()
' Zwolnij zmienną obiektu
Set mobjOutlook = Nothing
End Sub
Poniższy kod odwołuje się do metody NewEMailMessage:
' Deklaracja zmiennej obiektu
Dim objOutlook As Outlook
' Przydziel zmienne obiektu do obiektu cOutlook
Set objOutlook = New Outlook
' Odwołanie do metody "NewEMailMessage"
objOutlook.NewEMailMessage "redakcja@helion.com.pl"
' Zniszczenie zmiennej obiektu
Set objOutlook = Nothing
Implementacja obiektu obsługi błędów
W przykładowym kodzie dla rozdziału 13. „Profesjonalna obsługa błędów” znajdziesz obszerny moduł klasowy zajmujący się obsługą błędów i obejmujący:
Zapisywanie błędów w tabeli Accessa.
Zapisywanie błędów w pliku tekstowym.
Obsługę błędów związanych z pocztą elektroniczną.
Obsługę błędów zapisu w kalendarzu programu Outlook.
Używając narzędzia Object Browser, przyjrzyj się obiektowi cError XE "cError:obiekt" (rysunek 11.13).
Rysunek 11.13.
Obiekt cError w narzędziu |
|
Użycie obiektów
w połączeniu z kolekcjami VBA
Kolekcje XE "kolekcja" 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.
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:
Jest obiektem posiadającym własne metody i właściwości.
Do kolekcji można dodawać różne typy obiektów.
Jego rozmiar się zmienia. Rośnie wraz z dodawaniem i zmniejsza się wraz z usuwaniem obiektów.
Elementy kolekcji nie podlegają sortowaniu.
Elementy kolekcji są indeksowane. Indeksowanie rozpoczyna się od wartości 1.
Tworzenie kolekcji VBA
Ponieważ kolekcje są obiektami, tworzy się je w taki sam sposób jak obiekty. Najpierw deklaruje się zmienną obiektu, która służy jako odniesienie do kolekcji. Później za pomocą słowa kluczowego Set tworzy się odniesienie zmiennej obiektu do kolekcji. Poniższy kod tworzy kolekcję użytkowników:
Dim Users as Collection
Set Users = New Collection
|
||
|
Wygodnie jest nazywać zbiory liczbą mnogą nazwy obiektów, które zawierają. Obiekt, który będzie dodawany do zbioru w naszym przykładzie, to użytkownik (User). Stąd nazwa zbioru - Użytkownicy. |
Właściwości i metody kolekcji VBA
Obiekt collection XE "collection:obiekt" ma bardzo prostą strukturę, na którą składa się jedna właściwość i trzy metody (tabela 11.1).
Tabela 11.1.
Właściwości i metody obiektu collection
Nazwa |
Typ |
Opis |
Count |
Właściwość |
Wskazuje ilość obiektów w zbiorze |
Add |
Metoda |
Używana do dodawania obiektów do zbioru |
Remove |
Metoda |
Używana do usuwania obiektów ze zbioru |
Item |
Metoda |
Używana do tworzenia odniesień do obiektów zbioru. Jest to metoda domyślna |
Dodawanie obiektów do kolekcji
Aby dodawać obiekty do zbioru, użyj metody Add.
Collection XE "Collection:Add" .Add Item [, Key][, Before][, After]
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 prostsze, 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. |
W poniższym przykładzie dodamy dwóch użytkowników do kolekcji Użytkownicy:
Dim User1 as cUser
Dim User2 as cUser
Dim Użytkownicy as Collection
Set User1 = New User
Set User2 = New User
Set Użytkownicy = New Collection
User1.Imię = "Mariusz"
User2.Imię = "Beata"
Użytkownicy.Add User1 = User1.Imię
Użytkownicy.Add User2 = User2.Imię
Set User1 = Nothing
Set User2 = Nothing
Set Użytkownicy = Nothing
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.
Odnoszenie się do określonych obiektów
Do obiektów w kolekcji można odnosić się za pomocą numeru lub wartości klucza. Gdy odnosisz się do obiektu w kolekcji za pomocą numeru, pamiętaj, że indeksowanie tych obiektów rozpoczyna się od wartości 1. Najprostszym sposobem na odnoszenie się do obiektów kolekcji jest użycie jako klucza ich nazwy. Poniższy kod przedstawia, jak odnosić się do określonego obiektu User2, korzystając z obu tych metod. Mimo iż metoda Item nie musi być określona (gdyż jest metodą domyślną), ułatwia przeglądanie i obsługę kodu.
' Odniesienie do obiektu w kolekcji za pomocą numeru indeksu
MsgBox Użytkownicy.Item(2).Type
' Odniesienie do obiektu w kolekcji za pomocą wartości klucza
MsgBox Użytkownicy.Item ("Mariusz").Type
Tworzenie pętli po obiektach kolekcji
Najłatwiejszym i najefektywniejszym sposobem na tworzenie pętli po obiektach kolekcji jest użycie pętli For Each XE "For Each" . Pętla For Next XE "For Next" może być również użyta, jednakże jest wolniejsza.
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
For Each User in Users
MsgBox User.Type
Next User
|
||
|
Przykład ten sprawdza każdego użytkownika w zbiorze. Zauważ, że pojedynczy użytkownicy posiadają zmienne obiektu o nazwach User1 i User2. Aby użyć pętli For Each, określ ogólną zmienną obiektu o nazwie User. Taka zmienna obiektu nie musi być przydzielona do obiektu za pomocą słowa kluczowego Set. Jest to możliwe jedynie w przypadku pętli For Each. |
Usuwanie pojedynczych obiektów
Aby usunąć z kolekcji określone obiekty, użyj numeru indeksu lub wartości klucza.
' Usuwanie obiektu za pomocą numeru indeksu
Użytkownicy.Remove 2
' Usuwanie obiektu za pomocą wartości klucza
Użytkownicy.Remove "Mariusz"
Usuwanie wszystkich obiektów
Aby usunąć wszystkie elementy kolekcji, nie musisz tworzyć pętli po wszystkich obiektach, a następnie wywoływać metody Remove. Dużo szybciej jest przydzielić obiekt zbiór do nowego zbioru.
' Usuwanie wszystkich elementów zbioru
Set Użytkownicy = New Collection XE "Collection:Remove"
Zwalnianie zmiennej obiektu
Kolekcje są obiektami, więc tak samo, jak w przypadku wszystkich obiektów, pamiętaj o zwolnieniu zmiennej obiektu przez ustawienie jej na Nothing.
' Usuwanie zmiennej obiektu kolekcja
Set Użytkownicy = Nothing
Rozdział 12.
Usuwanie błędów w aplikacjach Accessa
W tym rozdziale:
Usuwanie błędów logicznych.
Praca z Visual Basic Development Environment (IDE).
Obiekt debug.
Użycie okna Immediate.
Użycie programu uruchomieniowego.
Użycie kompilacji warunkowej.
Testowanie aplikacji.
Ćwiczenie technik usuwania błędów.
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.
Usuwanie błędów logicznych
Błędy logiczne XE "błąd logiczny" występują, gdy wykonywany kod nie przynosi oczekiwanych rezultatów. Naruszona może być logika lub wykonywanie programu przebiega nieprawidłowo. Gdy kod jest wykonywany, lecz nie daje oczekiwanych rezultatów, spodziewaj się błędu logicznego.
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.
Oto kilka przykładów błędów logicznych:
Procedura próbuje użyć pola bazy danych, które nie posiada danych (wartość null).
Błąd w obliczeniach.
Przetwarzanie operacji w kodzie odbywa się w nieprawidłowej kolejności.
Praca z Visual Basic Development Environment (IDE)
W środowisku projektowania Accessa nastąpiła radykalna zmiana. Podobnie jak inne Visual Basic 5 i 6, Word 97 i inne programy pakietów Office 97 i 2000, Access posiada teraz Visual Basic Development Environment (IDE). Jest to środowisko projektowania zawierające standardowe środki, umożliwiające projektowanie aplikacji w różnych produktach. Opisane w tym rozdziale techniki usuwania błędów mogą być użyte zarówno podczas tworzenia aplikacji w Accessie, jak i w Visual Basic i programach pakietu Office. Aby otworzyć IDE, w widoku Projekt formularza, z menu Widok wybierz pozycję Kod programu. Na IDE składają się różne okna, które mogą być dowolnie zamykane i otwierane (np. Project, Properties, Immediate i inne). Aby otworzyć w IDE określone okno, wybierz je z menu View. Zamykanie okien odbywa się poprzez kliknięcie znajdującego się w prawym górnym rogu okna przycisku zamykającego. Gdy otwierasz IDE, układ okien jest identyczny jak wtedy, gdy po raz ostatni go używałeś. Gdy formularz otwarty jest w widoku Projekt, możesz pracować z formantami i właściwościami tak jak we wcześniejszych wersjach Accessa. Jednakże, by przeglądać kod formularza, musisz otworzyć Visual Basic IDE (rysunek 12.1). W rzeczywistości, jest to odrębna aplikacja.
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.
Teraz omówimy okna Visual Basic IDE.
Rysunek 12.1. Visual Basic Integrated Development Environment (IDE) |
|
Project Explorer
Project Explorer XE "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 XE "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.
Rysunek 12.3. Okno Code |
|
Okno Properties XE "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 XE "Okno Immediate" może być używane do oceny i ustawiania zmiennych, uruchamiania procedur oraz wykonywania instrukcji Debug XE "Debug" .Print XE "Print" . Aby je otworzyć, z menu View wybierz Immediate window XE "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 XE "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 XE "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.
Object Browser
Aby otworzyć Object Browser XE "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 |
|
Okno Call Stack
Okno Call Stack XE "Okno Call Stack" przedstawia procedury, do których nastąpiło odwołanie. Aby je otworzyć, z menu View wybierz Call Stack lub naciśnij klawisze Ctrl+L. Szczegóły związane z funkcjonowaniem tego okna omówimy w dalszej części tego rozdziału.
|
||
|
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 XE "Debug:obiekt" posiada dwie metody, które są bardzo pomocne w usuwaniu błędów aplikacji - Debug XE "Debug:Print" .Print i Debug XE "Debug:Assert" .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.
|
||
|
Aby wyświetlać informacje w oknie Immediate, używaj instrukcji Debug.Print w kodzie. Gdy testujesz wyrażenia lub uruchamiasz funkcje w oknie Immediate, nie musisz wpisywać Debug.Print. Zamiast tego wpisz znak zapytania ?, dzięki czemu uzyskasz ten sam rezultat. |
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 XE "Len:funkcja" :
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 XE "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 XE "Stop" . Jeśli bowiem zapomnisz 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. |
Użycie okna Immediate
Aby otworzyć okno Immediate, przejdź do edytora Visual Basic i z menu View wybierz Immediate Window lub naciśnij klawisze Ctrl+G. Okno to może być używane do podglądania i ustawiania zmiennych, uruchamiania funkcji i procedur oraz wyświetlania rezultatów działania instrukcji Debug.Print.
Podglądanie zmiennych
Aby podejrzeć wartość zmiennej w oknie Immediate, wprowadź znak zapytania, a po nim nazwę zmiennej (np. ? XE "?" strName). Pamiętaj, że możesz określić wartość zmiennej, ustawiając na niej kursor myszy w trybie pauzy.
Zmiana wartości zmiennych
Aby zmienić wartość zmiennej w oknie Immediate, wprowadź jej nazwę, a po niej znak równości i nową wartość (np. intI = 10).
Wyświetlanie wartości funkcji wbudowanych
Aby wyświetlić wartość funkcji wbudowanej w oknie Immediate, wprowadź znak zapytania, a po nim nazwę funkcji (np. ? Now).
Uruchamianie funkcji własnych
Aby uruchamiać funkcje własne w oknie Immediate, wprowadź znak zapytania, a po nim nazwę funkcji i jej parametry (np. ? MyFunction).
Uruchamianie własnych procedur
Aby uruchamiać własne procedury w oknie Immediate, wystarczy wprowadzić nazwę procedury i jej parametry (np. MySubProcedure). Przed nazwą procedury nie wstawiaj znaku zapytania.
|
||
|
Uruchamiając w oknie Immediate procedurę lub funkcję, wpisz jej nazwę bez znaku zapytania. Jeśli procedura lub funkcja jest modułem formularza, wprowadź przed jej nazwą nazwę tego formularza (np. frmTest.MySubProcedure). |
Wskazówki pomocne w korzystaniu z okna Immediate
Ponieważ spędzisz duża część pracy odbywa się w oknie Immediate, poniższe wskazówki mogą okazać się bardzo pomocne.
Uruchamianie instrukcji w oknie Immediate
Aby w oknie Immediate uruchomić instrukcję kodu, umieść kursor w dowolnym miejscu tej instrukcji (nie musi to być początek ani koniec).
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.
Poruszanie się po oknie Immediate
Do przesuwania punktu wprowadzania używaj myszy oraz klawiszy strzałek. Naciśnięcie klawisza Home powoduje przeniesienie punktu wprowadzania na początek aktualnej linii kodu, a klawisza End na jej koniec.
Klawisze PageUp i PageDown służą do poruszania się po kodzie strona po stronie.
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.
Usuwanie kodu w oknie Immediate
Aby zaznaczyć cały kod w oknie Immediate celem jego usunięcia, będąc na końcu kodu naciśnij klawisze Shift+Ctrl+Home. Gdy cały kod zostanie zaznaczony, wciśnij klawisz Delete. Jeśli punkt wprowadzania znajduje się na początku kodu, naciśnij klawisze Shift+Ctrl+End. Gdy kod zostanie zaznaczony, naciśnij klawisz Delete.
Użycie programu uruchomieniowego
Usuwanie błędów w aplikacjach Accessa 2000 nie jest trudne. Wystarczy zatrzymać wykonywanie kodu w określonych miejscach i przeglądając kod, obserwować jak program jest wykonywany.
Ustawianie punktów zatrzymania
Punkt zatrzymania XE "Punkt zatrzymania" zatrzymuje wykonywanie kodu. Aby ustawić punkt zatrzymania, umieść kursor w instrukcji i z menu Run Edytora Visual Basic wybierz Toggle Breakpoint XE "Breakpoint" lub naciśnij klawisz F9. Pamiętaj, że punktów zatrzymania nie można ustawiać w pustych liniach, komentarzu oraz częściach kodu zawierających instrukcję Dim. Innym sposobem na ustawienie punktu zatrzymania jest kliknięcie szarego, lewego marginesu okna kodu na wysokości danej instrukcji. Spowoduje to umieszczenie na lewym marginesie dużej, czerwonej kropki, oznaczającej obecność punktu zatrzymania.
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 XE "Clear All Breakpoints" lub naciśnij klawisze Ctrl+Shift+F9.
Rysunek 12.7. Wykonywanie kodu zatrzymane w punkcie zatrzymania |
|
Przechodzenie przez kod
Gdy wykonywanie kodu jest wstrzymane w punkcie zatrzymania, podświetlona na żółto instrukcja nie została jeszcze wykonana. Możesz wówczas na kilka sposobów wykonywać kod.
Krokowe wykonywanie kodu XE "Krokowe wykonywanie kodu"
Aby wykonywać instrukcje kodu pojedynczo, z menu Debug Edytora Visual Basic wybierz Step Into XE "Step Into" lub naciśnij klawisz F8. Krokowe przechodzenie przez kod jest najbardziej wydajnym sposobem obserwowania, jak program jest wykonywany, oraz przeglądania wartości zmiennych w kodzie.
|
||
|
Niektórzy programiści uważają za bardzo pomocny pasek narzędzi Debug. Aby go otworzyć, z menu View wybierz Toolbars, a następnie Debug. |
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 XE "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.
Wykonywanie kodu do końca procedury
Przyjmijmy, że przechodzisz przez procedurę, która zawiera odwołania do innych procedur. Gdy znajdziesz się w procedurze, do której nastąpiło odwołanie, możesz szybko wykonać resztę tej procedury i powrócić do pierwotnej, wybierając z menu Debug pozycję Step Out XE "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.
Wykonanie do pozycji kursora
Gdy przechodzisz przez kod, możesz spowodować wykonanie kodu na pełnej prędkości do miejsca, w którym znajduje się kursor. Przydaje się to w sytuacji, gdy przechodzisz przez jedną instrukcję kodu i chcesz szybko znaleźć się w innej instrukcji (np. pętle). Gdy kilkukrotnie przechodzisz przez pętlę, aby sprawdzić, czy działa poprawnie, umieść kursor na jej końcu i z menu Debug wybierz Run to Cursor XE "Run to Cursor" lub naciśnij klawisze Ctrl+F8.
Wybór kolejnej instrukcji
Gdy przechodzisz przez kod, możesz ustawić, którą z instrukcji chcesz wykonywać jako następną. Aby tego dokonać, kliknij prawym klawiszem myszy wybraną linię kodu, a następnie z menu kontekstowego wybierz Set Next Statement XE "Set Next Statement" .
Kontynuacja wykonywania kodu
Po przejściu przez kod i sprawdzeniu, czy działa poprawnie, możesz chcieć kontynuować jego wykonywanie z pełną prędkością. Aby tego dokonać, z menu Run wybierz Continue lub naciśnij klawisz F5.
Ponowne uruchamianie kodu
Po znalezieniu i poprawieniu błędów możesz uruchomić żądany fragment kodu ponownie bez zatrzymywania i ponownego uruchamiania aplikacji. Żółta strzałka na lewej krawędzi okna wskazuje, która instrukcja będzie wykonywana jako następna. Możesz kliknąć i przeciągnąć tę strzałkę do poprzedniej linii kodu i ponownie uruchomić kod, przez który uprzednio przechodziłeś.
Podglądanie wartości zmiennych
Podczas usuwania błędów w aplikacji możesz z łatwością określić, jaka jest wartość danej zmiennej. Wystarczy, że w trybie pauzy przesuniesz nad tą zmienną kursor myszy (rysunek 12.8).
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 |
|
Użycie podczas usuwania błędów
technologii Microsoft IntelliSense
Gdy pojawia się błąd programu i odnalazłeś właściwą linię, sprawdź jej składnię przy użyciu IntelliSense. Technologia ta pozwala przyspieszyć Twoją pracę, podając Ci podczas pisania kodu sugerowane właściwości i metody obiektów. Przykładowo, po wpisaniu nazwy obiektu (np. Recordset XE "Recordset:obiekt" lub Application XE "Application:obiekt" ) 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.
Użycie okna Locals
Okno Locals XE "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.
Rysunek 12.9.
Okno Locals przedstawia aktualnie analizowane |
|
||||
|
|||||
|
Okno Locals może być wykorzystane do zmiany wartości zmiennych. Kliknij dwukrotnie wartość zmiennej i wprowadź nową wartość. |
Użycie okna Watch
Okno Watch XE "Okno Watch" może być użyte do wyliczania wartości wyrażeń podczas działania aplikacji. Przykładowo, jeśli chcesz zobaczyć, w których miejscach aplikacji zmienna strName ulega zmianie, możesz do tego wykorzystać okno Watch. Pierwszy krok to wybranie z menu Debug pozycji Add Watch. W oknie dialogowym AddWatch wpisz żądane wyrażenie (np. strName = "Kowalski"). W oknie tym możesz również wybrać, czy chcesz wyliczać wartość wyrażenia w określonych procedurach, modułach czy w całej aplikacji (rysunek 12.10). Wybierz w oknie jedną z opcji Watch Type:
Rysunek 12.10. Aby tworzyć wyrażenie Watch, użyj okna dialogowego Add Watch |
|
Watch Expression - monitoruje żądane wyrażenie.
Break When the Value is True - zatrzymuje kod w trybie pauzy, gdy żądane wyrażenie nie jest spełnione.
Break When Value Changes - zatrzymuje kod w trybie pauzy, gdy wartość wyrażenia ulega zmianie.
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 |
|
Użycie okna Call Stack
Aplikacja może zawierać procedury, które odwołują się do innych procedur, które z kolei odwołują się do innych procedur itd. Gdy usuwasz błędy w aplikacji, możesz się w pewnym momencie pogubić albo nie być pewnym, które procedury już były wykonywane. Pokaże Ci to okno Call Stack XE "Okno Call Stack" .
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 |
|
||||
|
|||||
|
Aby przejść do żądanej procedury, wybierz ją w oknie Call Stack i kliknij przycisk Show (lub po prostu kliknij dwukrotnie procedurę). |
Użycie kompilacji warunkowej XE "kompilacja warunkowa"
Obsługa pojedynczej aplikacji jest dużo łatwiejsza niż tworzenie wielu wersji. Załóżmy, że Twoja aplikacja jest używana w wielu biurach. Większa część aplikacji jest ogólna i może być używana powszechnie, lecz istnieje niewielka część kodu, która musi być zindywidualizowana dla potrzeb każdego z biur. Jeśli zdecydujesz się utworzyć wiele wersji aplikacji, ich obsługa i aktualizacja będzie bardzo trudnym i męczącym zadaniem. Każdy nowy kod ogólny będzie musiał być dodany do każdej wersji. Ponadto duża ilość wersji znacznie komplikuje obsługę i rozprowadzanie aplikacji.
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
Pisanie solidnego kodu
Nie ma sposobu na całkowite wyeliminowanie potrzeby usuwania błędów w aplikacjach. Jeśli jednak będziesz stosował się do poniższych wskazówek, prawdopodobieństwo, że kod będzie działał poprawnie i nie będzie zawierał błędów, jest większe.
Deklaruj zmienne w osobnych liniach programu
Dużo łatwiej jest sprawdzić, czy zmienna została zadeklarowana, jeśli zmienne umieszczane są w osobnych liniach, a nie długich ciągach znaków. Co więcej, technika ta nie powoduje spowolnienia działania skompilowanych aplikacji.
|
||
|
Możesz również zauważyć, że dużo łatwiej jest odnajdywać zmienne, które są pogrupowane ze względu na typ danych. |
Deklaruj zmienne w jak najwęższym zakresie
Używaj tak wielu zmiennych lokalnych, jak tylko to możliwe. To nie tylko pomoże zapobiec problemom związanym z ich zakresem, ale również poprawi wydajność.
Używaj określonych typów danych
Zawsze deklaruj typ danych i używaj najmniejszych, jak tylko to możliwe. Jeśli nie deklarujesz typu danych, używany jest wariantowy typ danych. Jest to nie tylko rozwiązanie mniej wydajne, gdyż wymaga zaangażowania dodatkowych zasobów, ale przede wszystkim, w zmiennej o wariantowym typie danych można umieścić dowolne dane. Często prowadzi to do błędów w programie. Przykładowo, jeśli zmienna powinna przechowywać liczby, a użyto wariantowego typu danych, mogą zostać użyte inne dane niż liczby lub obiekty, czego konsekwencją będzie błąd.
Niszcz zmienne obiektów
Unikaj błędów zasobów, niszcząc zmienne obiektów. Jeśli istnieje zmienna obiektu o nazwie objWord, zniszcz ją na końcu procedury, pisząc:
Set objWord = Nothing
Używaj słowa kluczowego TypeOf XE "TypeOf"
Często do procedury ogólnej możesz dołączyć formanty. Przykładowo, przekazujesz formanty pole listy i pole listy rozwijalnej do ogólnej procedury, która ładuje wartości przy użyciu metody AddItem XE "AddItem:metoda" . Jeśli przekazujesz formant inny niż wyżej wymienione pola (np. przycisk poleceń), wystąpi błąd, gdyż formant ten nie posiada metody AddItem. W procedurze użyj słowa kluczowego TypeOf, aby sprawdzić, jaki był typ przekazanego formantu. Umożliwi to uniknięcie błędu.
Używaj Me zamiast Screen.ActiveForm i Screen.ActiveControl
Gdy usuwasz błędy w aplikacji, aktywne jest okno Immediate. Stąd Screen.ActiveForm XE "Screen.ActiveForm" i Screen.ActiveControl XE "Screen.ActiveControl" nie będą działać. Zamiast nich użyj słowa kluczowego Me XE "Me" .
Używaj narzędzia do obsługi błędów
W przypadku wystąpienia błędu, dzięki narzędziu do obsługi błędów będziesz mógł zaoszczędzić dużo czasu, gdyż ułatwi Ci ono odnalezienie wadliwej instrukcji, informacji o typie błędu, numeru linii i itp. Więcej informacji na ten temat znajdziesz w rozdziale 13., „Profesjonalna obsługa błędów”.
Używaj Option Explicit
Wymuszaj deklarowanie wszystkich zmiennych, umieszczając Option Explicit XE "Option Explicit" u góry każdego modułu kodu. Możesz ustawić to domyślnie, zaznaczając opcję Require Variable Declaration w opcjach programu. Dzięki deklarowaniu wszystkich zmiennych unikniesz błędów związanych z błędami w pisowni ich nazw.
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.
Natychmiast naprawiaj błędy
Podczas tworzenia aplikacji będzie Cię kusiło, aby ignorować znalezione błędy. Przykładowo, tworząc nową opcję aplikacji, stwierdzasz błąd w innej części aplikacji. Najlepiej jest się zatrzymać i naprawić ten błąd. Jest to jednak trudne, bo jesteś skupiony na tym, co właśnie tworzyłeś. Pamiętaj jednak, ze później może być dużo trudniej odnaleźć i poprawić ten błąd. Najlepiej od razu poprawiać odnalezione błędy.
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ą kodu, ponieważ są pomijane przez kompilator. Aby utworzyć komentarz, przed tekstem umieść pojedynczy cudzysłów. W oknie kodu komentarze wyświetlane są na zielono.
|
||
|
Do zamiany tekstu w komentarz i przywrócenia stanu poprzedniego używaj znajdujących się na pasku narzędzi Edit opcji Comment Block i Uncomment Block. |
Używaj znaku kontynuacji wiersza XE "znak kontynuacji wiersza"
Konieczność przewijania ekranu, aby zobaczyć kod, który nie mieści się na ekranie, znacznie utrudnia przeglądanie kodu. Upewnij się, że cały kod widoczny jest w oknie kodu, używając znaku (_) jako znaku kontynuacji linii. Dzięki temu linie rozdzielone tym znakiem będą traktowane jak jedna całość. Typowym przykładem może być następująca instrukcja SQL:
Dim strSQL as String
strSQL = "SELECT * FROM tblErrorLog" & _
"ORDER BY tblErrorLog.ErrorLogID;"
Używaj krótkich procedur
Długie procedury trudniej zrozumieć i usunąć z nich błędy. Dziel procedury na mniejsze części. Przyjmij, że jeśli nie jesteś w stanie wydrukować procedury na jednej stronie, powinieneś rozważyć podzielenie jej na mniejsze części.
Używaj standaryzowanych konwencji nazewnictwa
Użycie konwencji nazewnictwa umożliwi Tobie i innym programistom łatwiejsze zrozumienie kodu i usunięcie z niego błędów. Bardzo często zdarza się, że programista przejmujący aplikację od innego, skarży się na trudności ze zrozumieniem kodu. Użycie konwencji nazewnictwa w celu nazywania obiektów i zmiennych znacznie ułatwia proces usuwania błędów.
Nigdy nie używaj Stop
Nigdy nie używaj Stop, aby przejść do trybu pauzy. Jak już wspomnieliśmy wcześniej, zamiast tego używaj Debug.Assert. Poprawna składnia to Debug.Assert False.
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.
Nie usuwaj błędów przy użyciu okien komunikatu
W przeszłości używanie okien komunikatu było powszechnie stosowaną techniką usuwania błędów w kodzie. Polegała ona na umieszczaniu w całym kodzie okien komunikatu i na ich podstawie odnajdywaniu wadliwych instrukcji:
Sub Demo()
MsgBox 1
Select Case rst.States
MsgBox 2
Case "Washington"
MsgBox 3
MsgBox "Washington"
MsgBox 4
Case "Oregon"
MsgBox 5
MsgBox "Oregon"
MsgBox 6
Case "California"
MsgBox 7
MsgBox "California"
MsgBox 8
End Select
MsgBox 9
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ż:
Jest szybsze niż wpisywanie dużej ilości okien komunikatu.
Okna komunikatu są modalne, więc nie możesz przejść do okna kodu, aby przejrzeć kod.
Przechodząc przez kod przy użyciu programu uruchomieniowego, możesz sprawdzać i zmieniać wartość zmiennych itp.
Po naprawieniu błędu nie musisz usuwać wszystkich wstawionych okien komunikatu.
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”.
Ćwiczenie technik usuwania błędów
Kod znajdujący się na dołączonej do książki płycie CD daje Ci możliwość przećwiczenia omówionych w tym rozdziale technik usuwania błędów (rysunek 12.13).
Rysunek 12.13. Przećwicz techniki usuwania błędów dzięki znajdującym się na płycie CD przykładom kodu |
|
Rozdział 13.
Profesjonalna obsługa błędów
W tym rozdziale:
Usuwanie błędów składni.
Usuwanie błędów logicznych.
Usuwanie błędów wykrytych w trakcie użytkowania.
Błędy w różnych aplikacjach.
Obsługa błędów w procedurach zagnieżdżonych.
Zaawansowane zagadnienia związane z błędami.
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 |
|
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.
Usuwanie błędów składni
Zacznijmy od najprostszego rodzaju błędów programu - błędów składni XE "błędy składniowe" . Błędy te występują w sytuacji, gdy kod jest napisany nieprawidłowo. Na przykład, gdy nastąpił błąd w nazwie zmiennej albo słowa kluczowego lub gdy brakuje fragmentu kodu:
Dim strName as
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:
Dim strName as String
Jednym ze sposobów na wyeliminowanie błędów składni jest umieszczenie Option Explicit XE "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ą.
W poniższym przykładzie, zmienna BankBalance w drugiej linii napisana jest z błędem:
BankBalance = 4,576.98
RS!BankBalance = BankBalence
VBA nie rozpozna BankBalence jako słowa kluczowego, więc przyjmie, że chcesz zadeklarować nową zmienną typu Variant XE "Variant:typ" z domyślną wartością Empty XE "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:
Dim bytNumber as Byte (1 bajt);
Niezadeklarowana zmienna (tylko dane liczbowe) (16 bajtów);
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 |
|
Można również spotkać inne błędy składni:
Msggbox "Hi"
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 edytorze VBA wybierz z menu głównego Tools, Options. Na zakładce Editor wyłącz opcję Auto Syntax Check. Nie wyłączy to kontroli składni, a tylko usunie irytujące okna dialogowe, które pokazują się przy każdym błędzie składniowym. Błąd będzie zaznaczany poprzez zmianę koloru czcionki na czerwony. |
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 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.
Usuwanie błędów logicznych
Z błędem logicznym XE "błąd logiczny" mamy do czynienia, gdy wykonanie kodu nie przynosi oczekiwanych rezultatów. Może to być błąd w rozumowaniu lub program jest wykonywany nieprawidłowo. Gdy kod jest wykonywany, lecz nie przynosi oczekiwanych rezultatów, spodziewaj się błędu logicznego.
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.
Proste narzędzie do obsługi błędów
Przed omówieniem zaawansowanych narzędzi do obsługi błędów zacznijmy od prostego przykładu:
Sub Demo()
Dim I as Integer
On Error GoTo ErrorHandler
' Błąd programu w tej linii
ExitHere:
Exit Sub
ErrorHandler:
MsgBox "Wystąpił błąd"
Resume ExitHere
End Sub
To proste narzędzie stosuje się do standardowych konwencji programowych, które omówione są w następnej części.
On Error GoTo ErrorHandler XE "On Error GoTo ErrorHandler"
Zgodnie z konwencją, instrukcja ta znajduje się u góry procedury, po instrukcjach Dim. Znajduje się tam dlatego, by każdy kod, w którym może wystąpić błąd, znajdował się za nią. Jeśli w kodzie pojawi się błąd, instrukcja GoTo przekaże kontrolę nad programem do narzędzia do obsługi błędów. Narzędzie to znajduje się przy etykiecie ErrorHandler. ErrorHandler nie jest słowem zarezerwowanym, lecz nazwą procedury (możesz użyć dowolnej nazwy).
|
||
|
Etykiety są łatwe do odnalezienia, gdyż znajdują się na lewym krańcu procedury i występuje po nich dwukropek. |
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ęś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 XE "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.
|
||
|
Jeśli jest to wolna procedura, na jej początku włączasz klepsydrę i wyłączasz ją na końcu, musisz uważać, by nie „zacięła się” gdzieś pośrodku, gdy wystąpi błąd. DoCmd.Hourglass False jest przykładem kodu porządkującego, który powinieneś umieścić w kodzie ExitHere, aby był wykonywany przed procedurą wyjścia, niezależnie od tego, czy błąd wystąpił, czy nie. |
|
|
||
|
W kodzie ExitHere przywróć domyślne ustawienie klepsydry. Możesz włączyć ją na początku procedury. Jeśli błąd wystąpi, zanim wyłączysz klepsydrę na końcu procedury, wykonywany kod przejdzie do narzędzia do obsługi błędów, a klepsydra nie zostanie wyłączona. Jeśli w punkcie wyjścia klepsydra powraca do ustawień domyślnych, zawsze będzie wyzerowana. |
Poniższy fragment kodu to przykład procedury wyjścia zawierającej kod porządkujący:
ExitHere:
On Error Resume Next
DoCmd.Hourglass False
DoCmd.EchoTrue
DoCmd.SetWarnings False
Set rst = Nothing
Set db = Nothing
Exit Sub
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.
Przebieg programu z narzędziem do obsługi błędów
Zauważ, jak zmienia się przebieg programu, w którym umieszczono narzędzie do obsługi błędów. Jeśli kod nie ma błędów, program wykonywany jest w następujący sposób:
Sub Demo()
On Error GoTo ErrorHandler
Prawidłowy kod
ExitHere:
Exit Sub
ErrorHandler:
MsgBox "Wystąpił błąd"
Resume ExitHere
End Sub
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 XE "Err:obiekt" , 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.
Oto właściwości obiektu Err:
Err.Number - numer aktualnego błędu. Numer ten może by wykorzystany do reagowania na różne typy występujących błędów.
Err.Description - opis błędu.
Err.Source - Obiekt lub aplikacja, które wywołały błąd.
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.
Err.HelpContext - identyfikator kontekstu dla tematu w pliku pomocy.
Err.Last DLL Error - systemowy kod błędu uzyskany przez odwołanie do biblioteki DLL.
Obiekt Err posiada również dwie metody:
Err XE "Err:Clear" .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:
Odwołanie do metody Clear obiektu Err (Err.Clear).
Użycie dowolnej instrukcji Resume.
Wyjście z procedury.
Użycie instrukcji On Error.
Err XE "Err:Raise" .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
A oto przykład użycia metody Raise:
Sub Demo (intNumber)
If intNumber = 110 Then
'Wywołaj błąd
Err.Raise vbObjectError + 50, "Moja Aplikacja"
"Liczba nie może być większa niż 100", _
"c:\MyApp\MyApp.Hlp", MyContextID
End If
End Sub
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"
|
||
|
W poznaniu właściwości i metod obiektu Err pomoże Ci Object Browser. W dowolnym module kodu naciśnij klawisz F2, wybierz bibliotekę VBA i kliknij znajdujący się poniżej klas Err Object. Będziesz mógł przejrzeć jego wszystkie właściwości i metody. Zaznacz dowolną z nich i naciśnij klawisz F1, a wyświetlona zostanie pomoc na ten temat. |
Reagowanie na błędy
Duża część kodu narzędzia do obsługi błędów powinna używać instrukcji Select Case XE "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.
Z przewidywanym błędem można sobie radzić na kilka sposobów:
Okna komunikatu przedstawiające użytkownikom informacje o błędzie.
Okna komunikatu przedstawiające użytkownikom informacje o sposobach naprawienia błędu (np. Brak dysku w napędzie a: ).
Zignorować błąd i kontynuować wykonywanie programu.
Zignorować błąd i wyjść z procedury.
Poprawić kod, by jego wykonywanie mogło być kontynuowane.
Przejść do innego miejsca w kodzie.
Sytuację tę ilustruje poniższy kod:
ErrorHandler:
Select Case Err.Number
Case 11
If MsgBox ("Wykonałeś dzielenie przez zero, wprowadź " & _
" inną liczbę. Chcesz spróbować ponownie? ", _
vbQuestion + vbYesNo) = vbYes Then
Resume
Else
Resume ExitHere
End If
Case Else
MsgBox "Wystąpił nieoczekiwany błąd. Numer błędu: " & _
Err.Number & "Opis błędu: " & Err.Description
Resume ExitHere
End Select
End Sub
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
Instrukcje Resume
Poniższe instrukcje Resume XE "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 miejsca w kodzie, w którym wystąpił błąd.
Resume Next
Resume Next XE "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 |
|
Uzyskiwanie dodatkowych informacji o błędzie
Narzędzie do obsługi błędów powinno automatycznie zapisywać wszelkie informacje o błędzie, które mogą okazać się przydatne dla programisty. Im więcej tych informacji zbierze, tym łatwiej będzie programiście odnaleźć i naprawić błąd.
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:
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.
|
|||
|
|
Obiekt Err nie posiada opcji numerowania linii. Aby numerować linie, użyj funkcji Erl. Przykład jej zastosowania znajdziesz w kodzie na dołączonej do książki płycie CD. |
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.
Nazwa procedury - przedstawia nazwę procedury, w której wystąpił błąd.
Nazwa aktywnego formantu - przedstawia nazwę formantu, który był aktywny w momencie wystąpienia błędu.
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.
|
||
|
Aktywny formant zostanie przekazany do narzędzia zajmującego się obsługą błędów. Niektóre formanty posiadają wartości, inne nie. Narzędzie do obsługi błędów powinno przekazać ActiveControl (informację o aktywnym formancie) do procedury, która oceni jego wartość, używając do tego celu wbudowanej funkcji TypeOf. Jeśli formant jest polem tekstowym, otrzymasz wartość pola tekstowego. Jeśli jednak jest to przycisk poleceń, nie próbuj uzyskiwać jego wartości, bo spowoduje to powstanie błędu. |
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.
Nazwa programu - przedstawia nazwę aplikacji, w której wystąpił błąd.
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.
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.
|
||
|
Przykład użycia odwołania do interfejsu API systemu Windows w celu otrzymania nazwy zalogowanego użytkownika w narzędziach do obsługi błędów znajduje się na dołączonej do książki płycie CD (właściwość UserName i funkcja GetUserName). |
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ą.
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.
Zaawansowane narzędzie do obsługi błędów
Teraz, gdy wiesz już jak zbudować narzędzie do obsługi błędów na poziomie procedury i jak pobierać informacje o błędzie, nadszedł czas na stworzenie zaawansowanego narzędzia do obsługi błędów.
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.
|
||
|
Przyjrzyj się umieszczonym na płycie CD narzędziom do obsługi błędów na poziomie procedury. Mimo iż użycie ogólnego narzędzia jest bardziej wydajne, jeśli nie masz doświadczenia z takimi narzędziami, powinieneś zapoznać się również z najbardziej podstawowymi przykładami. |
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.
|
||
|
Idąc jeszcze dalej, możesz użyć Visual Basica do stworzenia narzędzia do obsługi błędów, które będzie mogło być używane w każdej aplikacji zgodnej z modelem COM (Compliant Object Model). Narzędzie takie mogłoby być wykorzystywane do wychwytywania błędów w Accessie, Wordzie, Excelu i wielu innych aplikacjach. Więcej informacji na ten temat znajdziesz w rozdziale 19., „Integracja z Office 2000”. |
Moduł klasowy Error (Obiekt)
Znajdujący się w kodzie tego rozdziału moduł klasowy cError XE "cError:obiekt" zawiera właściwości i metody niezbędne do stworzenia skutecznego narzędzia do obsługi błędów. Obiekt cError zawiera w module klasy całość kodu, który będziesz mógł teraz wykorzystać. Dzięki technologii IntelliSense XE "IntelliSense" , użycie tego obiektu jest dość łatwe.
|
||
|
Jeśli nie miałeś okazji pracować jeszcze z modułami klasy, zajrzyj do rozdziału 11., Tworzenie obiektów przy użyciu modułów klasowych”. |
Właściwości obiektu cError
Obiekt cError posiada właściwości umożliwiające przechwycenie żądanych wartości przez narzędzie do obsługi błędów. Właściwości te zostały opisane w tabeli 13.1.
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)
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.
Metody obiektu cError
Metody obiektu cError dostarczają programiście użytecznych informacji o błędach. Przykładowo, informacje o błędach mogą być przesyłane do programisty pocztą elektroniczną lub zapisywane w bazie danych. Metody obiektu cError opisane są w tabeli 13.2.
Tabela 13.2.
Metody obiektu cError
Metoda |
Opis |
AddToErrorHandlerOutlook |
Dodaj informacje o błędzie do kalendarza programu Outlook, o nazwie ErrorHandler |
Clear |
Czyści obiekt cError |
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 |
WaitState |
Przechodzi w stan oczekiwania i wstrzymuje wykonywanie kodu |
WriteErrorToTable |
Zapisuje informacje o błędzie do odpowiedniej tabeli w bazie danych |
WriteErrorToTextFile |
Zapisuje informacje o błędzie do pliku tekstowego |
Przeglądanie obiektu cError w Object Browser
Jak pewnie zauważyłeś, obiekt cError posiada wiele właściwości i metod. Aby je przejrzeć, otwórz Object Browser XE "Object Browser" i wybierz moduł klasy cError (rysunek 13.4).
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
strSQL = "SELECT * FROM tblErrorOptions"
' Utwórz zestaw rekordów ADO
Set rst = New ADODB.Recordset
' Otwórz zestaw rekordów ADO
rst.Open strSQL, CurrentProject.Connection, adOpenKeyset, _
adLockOptimistic
Me.ErrorTextFile = rst!ErrorTextFileName
Me.UserEnterNoteFlag = rst!UserEnterNoteAboutError
Me.AVIFileLocation = CurrentProject.Path & rst!AVIFileLocation
Me.SoundFile = CurrentProject.Path & rst!SoundFile
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
CError.ShowAVIForm
' Wstrzymaj wykonywanie kodu do zamknięcia formularza
Me.WaitState (True)
'Zamknij formularz AVI
DoCmd.Close acForm, "frmErrorAVI", acSaveNo
End If
' Otwórz formularz, w którym użytkownik będzie mógł
' sporządzić notatkę
If Me.UserEnterNoteFlag Then
DoCmd.OpenForm "frmErrorNote", acNormal
' Wstrzymaj wykonywanie kodu do zamknięcia formularza
Me.WaitState (True)
' Zamknij formularz z notatką
DoCmd.Close acForm, "frmErrorNote", acSaveNo
End If
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
' Wyświetl formularz z informacją, że użytkownik
' może kontynuować pracę. Formularz zostanie automatycznie
' zamknięty
' po upływie określonego czasu.
DoCmd.OpenForm "frmErrorDone", acNormal
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.
Doświadczenie użytkownika końcowego
Jak powinna wyglądać obsługa błędów z punktu widzenia użytkownika końcowego? Po pierwsze, należy przyciągnąć jego uwagę tak, by przestał pracować. Pamiętaj, że błąd może być bardzo poważny i spowodować, na przykład, wprowadzenie do bazy niewłaściwych danych.
|
Dzięki odwołaniu do metod obiektu cError wyświetlony zostanie Asystent Pakietu Office oraz formularz z plikiem AVI, odtworzony zostanie również sygnał dźwiękowy, informujący o wystąpieniu błędu (rysunek 13.5). Znajdujący się na płycie CD przykład kodu zawiera również formularz AVI, powiadamiający użytkownika o błędzie (rysunek 13.6). Wywołanie takich zdarzeń przy użyciu modułu klasy cError jest bardzo proste: |
cError.OfficeAssistant
cError.AVIForm
cError.Sound
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 |
|
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 |
|
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 |
|
Rysunek 13.9.
Poinformuj użytkownika, że |
|
Identyfikowanie problemów sprzętowych
Czy zdarzyło Ci się kiedyś zauważyć, że niektóre komputery w biurze ciągle generują błędy? Jest to chyba najtrudniejszy problem do rozwiązania. Problem może być związany ze sprzętem, jego konfiguracją, konfliktem z innymi aplikacjami itp.
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.
Sporządzanie raportów o błędach
Gdy już wiesz, jak narzędzie do obsługi błędów odbierane jest przez użytkowników, zobaczmy, co daje programiście, czyli Tobie. Dzięki obiektowi cError możesz kompilować i analizować błędy programowe na kilka sposobów:
Raport o błędach - raport o błędach to raport Accessa zawierający informacje z tabeli, w której są zapisane wszystkie błędy (rysunek 13.10).
Wysyłanie e-maili o pojedynczych błędach - za każdym razem gdy występuje błąd, związane z nim szczegóły przesyłane są do Ciebie pocztą elektroniczną przy użyciu metody E-mail (rysunek 13.11).
Rysunek 13.10.
Raport Accessa zawierający informacje |
|
|
Rysunek 13.11. E-mail zawierający informację o pojedynczym błędzie |
|
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.
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.
Zapisywanie informacji o błędzie w pliku tekstowym - dzięki użyciu metody WriteErrorToTextFile wszystkie błędy będą zapisywane w wybranym pliku tekstowym.
Zapisywanie informacji o błędzie w kalendarzu programu Outlook - informacje o błędach mogą być zapisywane w kalendarzu programu Outlook i przeglądane
w różnych, zarówno wbudowanych jak i własnych, widokach. Dzięki użyciu metody AddToErrorHandlerOutlookCalendar informacje o błędach przesyłane są do odpowiedniego kalendarza (rysunek 13.12).
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ą.
Opcje obiektu cError
Jak widzisz, rozbudowane narzędzie do obsługi błędów zawiera wiele opcji i możliwości. Niektórzy Twoi klienci będą chcieli wykorzystać je wszystkie, inni nie.
Wszystkie opcje tego narzędzia znajdują się w tabeli tblErrorOptions.
Tabela 13.3.
Możliwości dostępne w module obsługi błędów
Opcja |
Opis |
Typ danych |
AccessErrorTableName |
Nazwa tabeli Accessa zawierającej informacje o błędzie |
Tak/Nie |
AddToErrorHandlerCalendar |
Dodawanie błędu do kalendarza programu Outlook |
Tak/Nie |
AVIFileLocation |
Pełna ścieżka dostępu do pliku AVI odtwarzanego w formularzu AVI |
Tekst |
DatabaseName |
Nazwa bazy danych, w której znajduje się tabela z informacjami o błędach |
Tekst |
DatabasePath |
Pełna ścieżka dostępu do wspomnianej bazy danych |
Tekst |
EmailAdress |
Adres e-mail, na który mają być wysyłane informacje o błędach |
Tekst |
Tabela 13.3.
Możliwości dostępne w module obsługi błędów (ciąg dalszy)
Opcja |
Opis |
Typ danych |
EmailErrors |
Powiadamianie o błędach za pomocą poczty elektronicznej |
Tak/Nie |
ErrorsToAccessTable |
Zapisywanie informacji o błędzie w tabeli Accessa |
Tekst |
ErrorsToTextFile |
Zapisywanie informacji o błędzie w pliku tekstowym |
Tekst |
PlaySound |
Odtwarzanie dźwięku w przypadku wystąpienia błędu |
Tak/Nie |
ShowAVIForm |
Otwieranie formularza z plikiem AVI w przypadku wystąpienia błędu |
Tak/Nie |
ShowMsgBoxerrors |
Wyświetlanie okna komunikatu z informacją o błędzie |
Tak/Nie |
ShowOfficeAssistant |
Uruchamianie Asystenta Pakietu Office w przypadku wystąpienia błędu |
Tak/Nie |
SoundFile |
Pełna ścieżka dostępu do pliku dźwiękowego |
Tekst |
UserEnterNoteAboutError |
Umożliwienie użytkownikowi sporządzenia notatki o błędzie |
Tak/Nie |
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.
Odwołania do interfejsu API systemu Windows
Pełen zestaw funkcji, jakie powinno posiadać zaawansowane narzędzie do obsługi błędów, nie byłby możliwy do osiągnięcia bez kilku odwołań do interfejsu API systemu Windows.
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 XE "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.
Błędy w różnych aplikacjach
Współczesne aplikacje Accessa zawierają w sobie inne aplikacje i komponenty. Stąd też, błędy mogą pochodzić z wielu źródeł. W typowej aplikacji Accessa mogą występować błędy związane z samym Accessem, VBA, DAO, ADO lub innymi aplikacjami (np. Word). Każda aplikacja posiada własne kody błędów, które mogą być zapisywane przez narzędzie do obsługi błędów.
|
|||
|
|
Przejrzyj znajdującą się na płycie CD bazę danych Access and Jet database Errors.mdb. Zawiera ona numer i opisy błędów baz danych Accessa i Jet. |
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.
|
||
|
Zwróć uwagę na zagrożenia związane z następującym scenariuszem: obsługą błędu zajmuje się niewłaściwe narzędzie. Przeznaczone było do obsługi zupełnie innej instrukcji kodu, w zupełnie innej procedurze niż ta, w której wystąpił błąd. Stąd też rzeczą podstawową jest umieszczanie narzędzia do obsługi błędów w każdej procedurze. |
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.
Procedury zdarzeń związane z błędami
Formularze i raporty w Accessie posiadają zdarzenia Przy błędzie XE "Przy błędzie:zdarzenie" , które można wykorzystać do wyświetlenia dowolnej wiadomości w razie wystąpienia błędu. Procedura tego zdarzenia posiada dwa argumenty:
DataErr - numer błędu zwracany przez obiekt Err. Używając tego argumentu, możesz reagować na określone typy błędów. Jeśli, przykładowo, DataErr jest równe 11, wystąpił błąd dzielenia przez zero.
Response - określa, czy komunikat o błędzie jest wyświetlany. Argument ten możesz wykorzystać do określenia sposobu powiadomienia o błędzie. Aby zignorować błąd i wyświetlić własny komunikat o błędzie, użyj stałej acDataErrContinue. Aby wyświetlić standardowy komunikat Accessa, użyj stałej acDataErrDisplay.
Typowy fragment kodu wyglądałby następująco:
Private Sub Form_error(DataErr As Integer, Response As Integer)
Dim strMessage As String
If DataErr = 11 Then
Response = acDataErrContinue
StrMessage = "Sprawdź wartość, wykonałeś dzielenie przez zero"
MsgBox strMessage
End If
End Sub
On Error GoTo 0
Powyższa instrukcja wyłącza obsługę błędów w procedurze. Powoduje to również wyzerowanie obiektu Err XE "Err:Clear" (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.
On Error Resume Next
|
||
|
Nie używaj instrukcji On Error Resume Next, gdy nie posiadasz żadnego 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 XE "AccessError:metoda"
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 |
|
Inne funkcje związane z błędami
Poniższe dwie funkcje mogą być bardzo użyteczne:
IsError XE "IsError" - funkcja służąca do określenie, czy zmienna związana z błędem ma wariantowy typ danych (Variant). Funkcja ta zwraca wartość logiczną.
CVError XE "CVError" - konwertuje wartość zmiennej związanej z błędem na zmienną wariantową.
Ustawienie opcji wyłapujących błędy
W Edytorze Visual Basic, z menu Tools wybierz Options. Na zakładce General znajdziesz opcje regulujące obsługę błędów przez Access (rysunek 13.16):
Rysunek 13.16. Ustawienia opcji wyłapujących błędy |
|
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.
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.
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.
|
||
|
Możesz wyłączyć ustawienie Break on All Errors w procedurze, umieszczając u jej góry następujący kod: Application.SetOption "Break On All Errors", False |
Rozdział 14.
Optymalizacja aplikacji
W tym rozdziale:
Ulepszanie podstaw: optymalizacja sprzętu i systemu Windows.
Instalowanie aplikacji w celu uzyskania optymalnej wydajności.
Optymalizacja silnika bazy danych Jet.
Narzędzia do pomiaru wydajności.
Spojrzenie za kulisy.
Optymalizacja bazy danych od podstaw.
Poprawa wydajności kwerend.
Zwiększenie szybkości kwerend.
Przyspieszenie funkcjonowania formularzy.
Pisanie szybkiego kodu.
Optymalizacja aplikacji XE "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 życiu 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 serwisowanie 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.
Ulepszanie podstaw: optymalizacja sprzętu i systemu Windows
Każdy element Accessa posiada wiele możliwości poprawienia wydajności aplikacji, lecz żaden z nich nie zda się na zbyt wiele, jeśli aplikacja będzie działać na przestarzałym komputerze, ze zbyt mała ilością pamięci. Zazwyczaj tańszym rozwiązaniem jest zakup sprzętu niż zapłacenie firmie programistycznej za osiągnięcie tego samego rezultatu. Sprzęt jest tańszy niż oprogramowanie, a modyfikacje sprzętowe poprawiają funkcjonowanie wszystkich aplikacji uruchamianych na danym komputerze.
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:
Procesor Pentium 133 MHz.
32 MB RAM (szczególnie w przypadku systemu Windows NT).
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.
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.
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ł.
Nie używaj RAM-dysków. W nowoczesnych, 32-bitowych systemach nie ma na nie miejsca.
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.
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.
Unikaj kompresji dysków (również kompresji NTFS XE "NTFS" ). Uruchamianie bazy danych na skompresowanym dysku będzie miało znaczny, negatywny wpływ na wydajność aplikacji.
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.
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.
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.
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.
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 odczytywanie informacji z dysku jest znacznie wolniejsze niż korzystanie z pamięci RAM. Zwiększenie pliku wymiany ma sens tylko wtedy, gdy dysk jest zdefragmentowany.
|
||
|
Upewnij się, ze plik wymiany nie znajduje się na skompresowanym dysku lub partycji. Kompresja znacznie spowolni odczytywanie i zapisywanie na dysku tymczasowych plików, które muszą być w tym miejscu zapisywane. |
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.
|
||
|
Wielu programistów używa komputerów dużo szybszych niż te, na których będzie działać aplikacja. Pamiętaj, by przetestować aplikację na komputerach podobnych do tych, jakich używają przyszli użytkownicy. Jeśli konfiguracje sprzętowe komputerów użytkowników są różne, pisz aplikację pod kątem najsłabszego z nich. |
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.
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ż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ść.
Zmniejszaj bazę danych regularnie. Powinieneś kompaktować bazę za każdym razem, gdy importujesz, usuwasz lub aktualizujesz większe ilości danych. Kompaktowanie bazy danych XE "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.
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ą.
|
||
|
Przed zainstalowaniem MDE upewnij się, że użytkownicy wiedzą, iż żaden z nich nie będzie w stanie modyfikować aplikacji w tej formie. Ze względu na dużą popularność Accessa wielu użytkowników chce mieć możliwość dokonywania późniejszych modyfikacji w aplikacji. Powinieneś również bardzo dokładnie przetestować taką aplikację, gdyż komunikaty o błędach MDE są bardzo trudno zrozumiałe. |
Optymalizacja silnika bazy danych Jet
Dobrze skonfigurowany komputer i zoptymalizowana instalacja nie dadzą zbyt dużych rezultatów, jeśli nie zoptymalizujesz samej aplikacji. Aplikacja bazy danych składa się z kilku elementów. Najważniejszym z nich jest silnik baz danych Jet. Jet znajduje się w centrum prawie wszystkich procesów zachodzących w aplikacjach Accessa i można go 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
Klucz |
Opis |
Wartość Domyślna |
Miejsce Klucza |
Stała dla metody SetOption |
ExclusiveAsyncDelay |
Liczba milisekund, jakie Jet musi odczekać przed wykonaniem ukrytej transakcji w środowisku z wyłącznością |
2000 |
\HKEY_LOCAL_MACHINES |
dbExclusive AsyncDelay |
FlushTransactionTimeout |
Gdy w tym miejscu wprowadzona jest wartość, wyłączone są SharedAsyncDelay i ExclusiveAsyncDelay.Wartość ta określa liczbę milisekund do rozpoczęcia zapisywania asynchronicznego, bez dodawania stron do bufora |
500 |
\HKEY_LOCAL_MACHINES |
dbFlush Transaction Timeout |
ImplicitCommitSync |
Określa, czy system ma czekać na zakończenie transakcji ukrytych przed kontynuacją innych procesów. Jeśli wybrano wartość No, Jet będzie przetwarzał transakcje ukryte asynchronicznie |
No (Nie) |
\HKEY_LOCAL_MACHINES |
dbImplicit CommitSync |
Tabela 14.1
Ustawienia rejestru dla silnika Jet 4.0 (ciąg dalszy)
Klucz |
Opis |
Wartość Domyślna |
Miejsce Klucza |
Stała dla metody SetOption |
LockDlay |
Liczba milisekund zanim Jet podejmie następną próbę blokowania |
100 |
\HKEY_LOCAL_MACHINES |
dbLockDelay |
LockRetry |
Ilość prób, jakie Jet podejmie w celu zablokowania strony |
20 |
\HKEY_LOCAL_MACHINES |
dbLockRetry |
MaxBufferSize |
Rozmiar bufora silnika Jet w kilobajtach |
0 |
\HKEY_LOCAL_MACHINES |
dbMaxBuffer Size |
MaxLocksPerFile |
Maksymalna liczba blokowań dla jednej transakcji. Jeśli transakcja wymaga więcej blokowań, zostanie ona podzielona na kilka innych, które będą wykonywane osobno. Ustawienie to może stwarzać problemy w przypadku Novell NetWare 3.1 |
9500 |
\HKEY_LOCAL_MACHINES |
dbMaxLocksPer File |
PagesLockedToTableLock |
(Nowość w Accessie 2000). Nadaje wyłączny dostęp do tabel w celu dokonywania aktualizacji poprzez programową kontrolę nad liczbą blokowań strony, zanim Jet spróbuje zablokować całą tabelę. Ustawienie 50 sprawi, że Jet spróbuje zablokować tabelę za 51 razem. Jeśli to się nie uda, Jet spróbuje kolejny raz za 101 razem. Wartość zero wyłącza tę opcję |
0 |
\HKEY_LOCAL_MACHINES |
|
Tabela 14.1
Ustawienia rejestru dla silnika Jet 4.0 (ciąg dalszy)
Klucz |
Opis |
Wartość Domyślna |
Miejsce Klucza |
Stała dla metody SetOption |
PageTimeout |
Ilość czasu, przez jaki niezablokowana przed odczytem strona jest przechowywana w buforze, zanim zostanie odświeżona. Czas mierzony jest w milisekundach |
5000 |
\HKEY_LOCAL_MACHINES |
dbPageTimeout |
RecycleLVs |
Określa, czy Jet będzie odzyskiwał obiekty OLE, memo i strony binarne |
0 (wyłączony) |
\HKEY_LOCAL_MACHINES |
dbRecycleLVs |
SharedAsyncDelay |
Liczba milisekund, jakie Jet musi odczekać przed wykonaniem ukrytej transakcji w środowisku ogólnym |
50 |
\HKEY_LOCAL_MACHINES |
dbSharedAsync Delay |
Threads |
Ilość wątków używanych w tle przez Jet |
3 |
\HKEY_LOCAL_MACHINES |
Brak |
UserCommitSync |
Określa, czy system czeka na zakończenie operacji zapisu przed kontynuowaniem innych procesów. Jeśli wybrano wartość No, Jet będzie przetwarzał transakcje jawne asynchronicznie |
Yes (Tak) |
\HKEY_LOCAL_MACHINES |
dbUserCommit Sync |
CompactByPKey |
Określa kolejność sortowania kluczy podstawowych. Jeśli wybrano wartość 1, Jet będzie ustawiał rekordy według wartości klucza podstawowego. W przypadku ustawienia 0, rekordy pozostaną w kolejności ich wprowadzania (kolejność naturalna) |
1 |
\HKEY_LOCAL_MACHINES |
Brak |
Tabela 14.1
Ustawienia rejestru dla silnika Jet 4.0 (ciąg dalszy)
Klucz |
Opis |
Wartość Domyślna |
Miejsce Klucza |
Stała dla metody SetOption |
SystemDB |
Nazwa i pełna ścieżka dostępu do pliku grupy roboczej |
acces_path\ system.md |
\HKEY_LOCAL_MACHINES |
Brak |
PrevFormatCompactWith UNICODECompression |
(Nowość w Accessie 2000). Umożliwia lub blokuje kompresję pól tekstowych i memo. Domyślnie kompresja jest dozwolona. |
1 |
\HKEY_LOCAL_MACHINES |
|
JetShowPlan |
Opcja ta jest domyślnie zainstalowana. Gdy zostanie utworzona przez programistę i ustawiona na On (uwaga na dużą literę), Jet tworzy i umieszcza w bieżącym katalogu plik tekstowy o nazwie showplan.out. Gdy kwerendy są wykonywane, informacje o tym zapisywane są w tym pliku. Pamiętaj o wyłączeniu tej opcji po zakończeniu tworzenia aplikacji. |
Domyślnie nie zainstalowano |
\HKEY_LOCAL_MACHINES |
Brak |
Bezpieczne modyfikowanie ustawień silnika Jet
Istnieją trzy sposoby modyfikowania ustawień rejestru silnika Jet:
Bezpośrednie edytowanie wartości przez Regedit.exe.
Tworzenie profilu użytkownika w celu pominięcia ustawień domyślnych i odwoływanie się do tego profilu przy użyciu wiersza poleceń profilu.
Umożliwienie aplikacjom tymczasowego pomijania ustawień domyślnych poprzez użycie metody SetOption XE "SetOption:metoda" obiektu bazy danych.
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.
|
||
|
Jeśli Twoja aplikacja używa źródła danych ODBC, przejrzyj ustawienia rejestru w \HKEY_LOCAL_MACHINES\SOFTWARE\MICROSOFT\JET\4.0 \ENGINES\ODBC. |
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 XE "Timer:funkcja" (), 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 XE "GetTickCount:funkcja" . 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 XE "timeGetTime:funkcja" () 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
Wydruk 14.1 ilustruje wykorzystanie tych funkcji do oceny wydajności kwerendy.
Wydruk 14.1. Obliczanie czasu wykonywania kwerendy
Sub QueryTimer(strQueryName As String)
Dim db As Database
Dim qry As QueryDef
Dim rs As Recordset
Set db = CurrentDb()
Set qry = db.QueryDefs(strQueryName)
'Uruchom zegar
a2kuStartClock
Set rs = qry.OpenRecordset()
'Zatrzymaj zegar i wyświetl rezultat w oknie Debug
Debug.Print strQueryName & " Wykonano w: " & a2kuEndClock &_
" milisekund"
rs.Close
End Sub
|
||
|
Aby otrzymać jak najdokładniejsze wyniki, umieść odwołania a2kuStartClock i a2kuEndClock jak najbliżej analizowanej procedury. |
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 XE "ISAMStats:funkcja" . 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])
Oto sześć możliwości argumentu Opcja:
|
|||
Argument dla Opcja |
Opis |
||
0 |
Zapis na dysku |
||
1 |
Odczyt z dysku |
||
2 |
Odczyt z bufora |
||
3 |
Odczyt z bufora (odczyty z wyprzedzeniem) |
||
4 |
Ustanowienie blokowania |
||
5 |
Zdjęcie blokowania |
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:
Wydruk 14.2. Sposób użycia funkcji ISAMStats do pomiaru wydajności
Sub PrintStats()
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.
Optymalizacja bazy danych od podstaw
Relacyjne bazy danych, do których również zaliczamy Accessa opierają się na tabelach, w których zawarte są informacje. Sposób, w jaki te tabele oraz relacje między nimi są zaprojektowane, ma duży wpływ na wydajność aplikacji. Jeśli tabele nie są znormalizowane, zindeksowane, a relacje między nimi ustanowione są w niewłaściwy sposób, wykonanie każdej kwerendy i procedury będzie zabierać dużo więcej czasu. Najlepsza rzecz, jaką możesz uczynić dla poprawy wydajności bazy danych, to prawidłowo zaprojektować tabele.
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:
Gdy pracujesz z połączonymi tabelami, spraw, by łącza między nimi miały charakter stały.
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ę.
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.
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 XE "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:
Znormalizowana baza danych pozwala zaoszczędzić przestrzeń dyskową, gdyż nie powtarza bez potrzeby danych.
Znormalizowana baza danych używa mniejszej ilości stron danych i stron indeksów, co skraca czas wyszukiwania danych.
W znormalizowanej bazie danych prawdopodobieństwo wystąpienia konfliktu lub pomyłki w danych jest mniejsze, gdyż powtarzają się one rzadziej.
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ą.
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.).
Ł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.
Tworzenie indeksów
w celu przyspieszenia pracy kwerend
Indeksy mogą dziesięciokrotnie przyspieszyć pobieranie danych.
Indeksy mogą również spowolnić aktualizowanie i wprowadzanie danych, więc unikaj tworzenia zbędnych indeksów.
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.
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.
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 wykorzystany 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.
Poprawa wydajności kwerend
Mimo iż użytkownicy mogą nigdy nie zobaczyć, jak wyglądają kwerendy, to one właśnie wykonują większość pracy w aplikacji. Relacyjna baza danych byłaby bezużyteczna, gdyby nie można było tworzyć w niej kwerend. Jednak nie wszystkie kwerendy tworzone są w ten sam sposób. Nawet gdy wykonałeś wszystkie czynności niezbędne do znormalizowania danych oraz utworzyłeś wszystkie wymagane indeksy, może się okazać, że kwerendy nie będą działać tak szybko jak powinny. Może się nawet zdarzyć, że dwie kwerendy zwracające ten sam zestaw wyników będą miały różną wydajność.
Aby zrozumieć, jak działa optymalizacja kwerend XE "optymalizacja kwerend" , musisz poznać sposób, w jaki obchodzi się z nimi Jet. Każda kwerenda przechodzi cztery etapy:
Definicja - przy użyciu jednego z kilku narzędzi tworzona jest instrukcja SQL.
Kompilacja - ciąg SQL jest dzielony na części.
Optymalizacja - używając działającego w oparciu o koszt algorytmu, Jet tworzy i testuje różne sposoby otrzymania żądanego zestawu wyników.
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 elementem 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.
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.
Jet pobiera wiersze z tabel na trzy sposoby:
Skanowanie XE "skanowanie" - jest to najdroższe rozwiązanie. Jet przeszukuje każdy wiersz bez użycia indeksu. Kwerenda wymusi na aparacie Jet skanowanie tabeli jeśli:
Jej ograniczenie dotyczy nieindeksowanego pola.
Duża część wierszy tabeli spełnia kryteria kwerendy.
Indeksowanie XE "indeksowanie" - Jet używa do przeszukiwania wierszy tabeli jej indeksu. Mimo, iż może się zdarzyć, że Jet będzie odczytywał stronę z danymi więcej niż raz, rozwiązanie to jest dużo szybsze niż skanowanie.
Optymalizacja Rushmore XE "Rushmore" XE "optymalizacja Rushmore" - opcja ta dostępna jest tylko w sytuacji, w której ustanowione w kwerendzie ograniczenia dotyczą więcej niż jednego indeksu. Rushmore umożliwia silnikowi Jet znaczne zmniejszenie (w niektórych przypadkach nawet do zera) ilości odczytywanych stron z danymi. Dzięki użyciu optymalizacji Rushmore Jet odczytuje jedynie indeksowane strony, co jest rozwiązaniem niezwykle wydajnym.
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:
Kwerenda musi posiadać kilka indeksów.
Kryteria kwerendy muszą dotyczyć pól z indeksami.
Instrukcje kryteriów muszą używać tych indeksów na jeden z trzech sposobów:
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'
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'
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ć
Typ sprzężenia |
Sposób działania |
Cechy charakterystyczne |
Użycie |
Indeks-Połączenie |
Większość pracy wykonują indeksy |
Indeksy użyte są po obu stronach relacji. Co najmniej jeden z indeksów nie dopuszcza wartości null (klucz podstawowy). Wszystkie tabele muszą być w rodzimym formacie aparatu Jet |
Gdy tylko to możliwe |
Tabela 14.2.
Typy złączeń: jak działają i jak je rozpoznać
Typ sprzężenia |
Sposób działania |
Cechy charakterystyczne |
Użycie |
Indeks |
Pierwsza tabela jest skanowana, a następnie, przy użyciu indeksów, odnajdywane są wiersze w drugiej tabeli |
Indeks użyty jest w polu (polach) relacji drugiej tabeli. W indeksach tych możliwe są wartości null. Ograniczenia nie używają indeksów |
Jeśli w drugiej tabeli jest niewiele rekordów, jeśli jej rekordy nie są wyświetlane w zestawie wyników lub jeśli ograniczenie w kryterium pierwszej tabeli jest bardzo wąskie |
Połączenie |
Obie tabele skanowane są jednocześnie |
Dwie tabele sortowane według sprzężonych pól. Dane z obu tabel wyświetlane są w zestawie wyników |
Obie tabele są duże i sortowane według pól w relacji |
Odnośnik |
Druga tabela jest sortowana i skanowana przed sprzężeniem |
Brak indeksów w polach sprzężonych obu tabel |
Gdy druga tabela jest mała i nie ma indeksu w polu relacji tej tabeli |
Iteracja zagnieżdżona |
Iteracja wiersz po wierszu przez każdą tabelę w relacji |
Brak indeksów po obu stronach sprzężenia |
Tylko na bardzo małych tabelach i gdy nie ma innego rozwiązania |
Wybór typu zestawu wyników
zapewniającego optymalną wydajność
Jet bierze również pod uwagę żądany zestaw wyników. Przykładowo, aby przedstawić dynamiczny zestaw rekordów (dynaset), użyje on planu, który umożliwi efektywne zaprezentowanie pierwszej strony danych nawet, jeśli plan ten będzie wolniejszy przy prezentowaniu pozostałych rekordów. Do stworzenia dynasetu Jet użyje zestawu unikalnych wartości klucza, które wskażą wiersze w podległych tabelach podstawowych. Dzięki temu, wystarczy, że Jet zaprezentuje tylko wartości klucza, a dalsza część rekordów może zostać odsłonięta dopiero, gdy zażyczy sobie tego użytkownik. Natomiast w przypadku zdjęcia, Jet zbiera wszystkie rekordy i kolumny, zanim zaprezentuje wyniki. Jeśli całe zdjęcie nie mieści się w pamięci, zostanie przerzucony do pliku wymiany, co będzie miało negatywny wpływ na wydajność. Większą wydajność uzyskałbyś więc z dużego dynasetu niż dużego zdjęcia.
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 wynikó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 XE "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.
Wydruk 14.3. Plan wykonywania kwerendy, korzystający z optymalizacji Rushmore
--- Quarterly Orders ---
-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-
Restrict rows of table Orders
using rushmore
for expression "Orders.OrderDate Between #1/1/98# And
#12/31/98#"
Outer Join result of "01)" to table "Customers"
using index "Customers!PrimaryKey"
join expression "Orders.CustomerID=Customers.CustomerID"
Sort Distinct result of "02)"
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 XE "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 przedstawia słabo zoptymalizowaną kwerendę.
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-
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.
Zwiększenie szybkości kwerend
Optymalizacja kwerend w Jet jest dość rozbudowana, co nie oznacza, że nie możesz zrobić nic w tym kierunku samemu. Oto kilka wskazówek, które pomogą Ci przyspieszyć pracę kwerend:
Twórz indeksy dla wszystkich pól, których zamierzasz użyć w kryteriach.
Twórz indeksy po obu stronach sprzężeń w kwerendzie.
Używaj kluczy podstawowych zamiast unikalnych indeksów. Ponieważ klucze podstawowe nie dopuszczają wartości null, kwerendy będą mogły korzystać z większej ilości typów sprzężeń.
Nie umieszczaj w zestawie wyników zbędnych kolumn. Przetworzenie i wyświetlenie każdej kolumny zabiera dużo czasu.
Unikaj używania złożonych wyrażeń w kwerendach.
Unikaj używania funkcji IIF() (Immediate IF). IIF() przed podaniem wyniku, ponieważ musi sprawdzić zarówno prawdziwe jak i fałszywe konsekwencje. Wykonywanie tej operacji dla każdego rekordu znacznie obniża wydajność.
Gdy używasz kwerend zagnieżdżonych, umieść obliczenia w ostatniej z nich.
Używaj Count(*) zamiast Count([IDklienta]), poniważ Rushmore szybciej przetwarza Count(*) - nie musi szukać wartości null przed zliczaniem.
Jeśli to możliwe, zamiast operatorów Greater than (więcej niż) i Less than (mniej niż) używaj operatora Between (między).
Zazwyczaj (lecz nie zawsze) umieszczenie ograniczenia po stronie „jeden” relacji jest bardziej efektywne. Spróbuj przesunąć ograniczenia na stronę „wielu” i sprawdzić, jaki to miało wpływ na wydajność. Pamiętaj, by po każdej modyfikacji kryteriów sprawdzić zestaw wyników.
Znormalizowane tabele mogą przechowywać dane na mniejszej ilości stron danych i stron indeksowanych. Traktuj normalizację jako regułę i odstępuj od niej tylko w sytuacjach, gdy nie ma innej alternatywy.
Gdy to możliwe, zamiast sprzężeń lub złożonych kryteriów OR spróbuj używać podkwerend. Optymalny wybór zależy od wielu ukrytych czynników i tylko próba może pomóc Ci zdecydować, co wybrać.
Sprzężeń zewnętrznych używaj tylko wtedy, gdy jest to konieczne, gdyż wymagają one automatycznie skanowania tabeli nadrzędnej w sprzężeniu.
Używaj zapisanych kwerend parametrycznych zamiast instrukcji SQL w kodzie. Jet już skompilował kwerendy parametryczne i przygotował dla nich plan wykonywania (mimo iż nie pokazuje go funkcja SHOWPLAN.OUT). Użycie skompilowanych i zapisanych kwerend pozwoli uniknąć koniecznej w przypadku ciągu SQL oceny i optymalizacji silnika Jet. Access kompiluje ciągi SQL użyte jako źródło rekordów lub źródło wierszy w formularzach, raportach i formantach, więc pozostają one niezmienione.
Zawsze dostarczaj skompilowane kwerendy.
Jeśli to tylko możliwe, do obróbki danych zamiast DAO używaj kwerend. Kwerendy (SQL) są w tych zadaniach prawie zawsze szybsze niż DAO.
Z uwagą wybieraj typ zestawu wyników. Dynaset będzie potrzebny, gdy będziesz chciał dodawać lub edytować dane. Zdjęcie lub Zdjęcie do przekazywania będą odpowiednie, jeśli chcesz jedynie odczytywać dane. Zdjęcia otwierają się dłużej, jednak szybciej się przewijają.
Jeśli otwierasz zestaw rekordów po to, by tylko dodawać dane, otwórz go z opcją dbAppendOnly. To pozwoli Ci zapobiec usuwaniu wierszy.
Testuj kwerendy przekazujące, gdy używasz architektury klient-serwer. Przyjrzyj się również nowym opcjom tej architektury w Accessie 2000. Kwerendy przekazujące nie zawsze są szybsze niż kwerendy wykonywane bezpośrednio na tabelach znajdujących się na serwerze, lecz zazwyczaj obciążają sieć w mniejszym stopniu.
Duże kwerendy mogą być wykonywane lepiej, jeśli ustawisz właściwość UseTransaction XE "UseTransaction:właściwość" (Użyj transakcji) na False (Nie). W przeciwnym wypadku, Access tworzy tabele tymczasowe. Czasami są one na tyle duże, że mają negatywny wpływ na wydajność kwerendy.
Gdy przeprowadzasz kwerendę na danych z serwera, do obsługi tych danych użyj metod CacheStart XE "CacheStart:metoda" , FillCache XE "FillCache:metoda" i EndCache XE "EndCache:metoda" .
Gdy masz do czynienia z danymi z serwera, unikaj lokalnego przetwarzania. Przez przetwarzanie lokalne rozumiemy na przykład: złożone polecenie Group by (Grupuj według), w którym użyto słowa kluczowego Distinct, użycie operatora LIKE w polach tekstowych lub memo, wielokrotne funkcje podsumowujące w kwerendzie krzyżowej lub kwerendy krzyżowe z warunkiem ORDER. Unikaj także użycia złożonych połączeń zewnętrznych i wewnętrznych sprzężeń. Użycie takich konstrukcji spowoduje przesłanie dużych ilości danych z serwera na lokalny komputer i w rezultacie znaczne obniżenie wydajności.
Kompaktuj bazę regularnie i sprawdzaj, czy statystyki używane przez aparat Jet do optymalizowania kwerend są poprawne.
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.
Indeksuj pola, które będą sortowane.
Jeśli operujesz na statycznych danych, rozważ utworzenie tabeli na podstawie kwerendy, zamiast ciągle uruchamiać kwerendę w bazie danych.
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ł XE "MaModuł:właściwość" 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.
Szybsze pobieranie rysunków
Użycie rysunków w interfejsie aplikacji to wykorzystanie graficznych możliwości Accessa. Jednakże nie wystarczy po prostu wstawić rysunki do aplikacji i oczekiwać, że będzie działać tak, jak ta część bazy Northwind, która zawiera zdjęcia pracowników. W tej części zajmiemy się użyciem elementów graficznych w bazie danych.
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 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.
Podstawowy, szybki formularz
Największy wpływ na szybkość pracy formularza ma ilość i typ umieszczonych na nim formantów. Każdy formant pochłania pamięć i zasoby, lecz niektóre więcej niż inne. Dla porównania, związana ramka obiektu pochłania około 40 razy więcej niż linia. Jeszcze gorzej może być w przypadku formantów ActiveX, w zależności od tego z czego się składają i jakie jest ich zadanie.
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
Typ formantu |
Względna waga |
Prostokąt |
1 |
Linia |
1 |
Podział strony |
1 |
Formant karta (bez formantów) |
4 |
Obraz (bez rysunku) |
6 |
Formant karta |
6 |
Podformularz (co najmniej) |
6 |
Etykieta |
8 |
Przycisk opcji |
8 |
Przycisk polecenia |
8 |
Pole wyboru |
8 |
Tabela 14.3.
Względne wagi formantów formularza (ciąg dalszy)
Typ formantu |
Względna waga |
Grupa opcji (bez formantów) |
8 |
Przycisk przełącznika |
9 |
Pole tekstowe |
10 |
Pole listy (co najmniej) |
10 |
Pole listy rozwijalnej (co najmniej) |
10 |
Formanty ActiveX |
20 |
Niezwiązana ramka obiektu (bez rysunku) |
>=20 |
Związana ramka obiektu |
30 |
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.
Istnieje kilka innych technik, które poprawią wydajność formantów:
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.
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.
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.
Podczas odświeżania formularzy lub wszystkich formantów zawierających dane, które mogły ulec zmianie, używaj metody Requery XE "Requery:metoda" , 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.
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 wojewó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.
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.
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.
Kiedy piszesz kod formularza (CBF), używaj słowa kluczowego Me XE "Me" . Stała ta zawsze odnosi się do aktywnego formularz, i działa szybciej niż inne odniesienia.
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.
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.
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.
Czy dynamiczny zestaw rekordów jest konieczny? Może wystarczyłoby zdjęcie?
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
Gdy użytkownik będzie chciał wyświetlić formularz, możesz go wyświetlić przy użyciu następującego polecenia:
Forms("NazwaFormularza").setfocus
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
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.
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.
Szybsze drukowanie raportów
Jaki jest pożytek z dobrej bazy danych, jeśli drukowanie raportu zajmuje cały dzień?
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.
Oto kilka wskazówek, które mogą wpłynąć na przyspieszenie tworzenia raportów:
Staraj się, by kwerenda, na której oparty jest formularz, była tak prosta jak tylko to możliwe.
Obliczenia umieszczaj w raporcie. Gdy obliczenia umieszczone są w kwerendzie, muszą być wykonywane dla każdego wiersza. Jeśli jednak umieścisz je w raporcie, użytkownik zobaczy wyniki w momencie, gdy Access wykona obliczenia dla jednej strony raportu.
Spróbuj oprzeć kwerendę na jak najmniejszej ilości tabel. Ponieważ raport będzie uruchamiał kwerendę więcej niż raz, możesz utworzyć tabelę z zestawem rezultatów. Raport będzie szybciej przeszukiwał tabelę niż ponownie wykonywał kwerendę. Rozwiązanie to może być szczególnie efektywne, gdy masz do czynienia z kwerendą zawierającą podkwerendę.
Unikaj podkwerend w źródle raportu. Raport potrzebuje dużo pamięci, a kwerenda z podkwerendą może pochłaniać więcej pamięci niż to konieczne.
Czy naprawdę potrzebujesz podraportów? Podraporty nie tylko utrudniają formatowanie danych w taki sposób, w jaki byś sobie tego życzył, ale również pochłaniają pamięć i pogarszają wydajność raportu. Zdarzają się jednak sytuacje, w których warto skorzystać z podraportów. Gdy używasz wielu funkcji, użycie podraportu może okazać się szybszym rozwiązaniem niż kilka odwołań do tych funkcji.
Unikaj wyrażeń sortujących i grupujących. Aby prawidłowo wyświetlić sortowanie i grupowanie, raport będzie musiał przeliczyć każde wyrażenie kilkakrotnie. Wykonaj obliczenia tych wartości przed przekazaniem ich do raportu.
Indeksuj wszystkie pola używane do sortowania i grupowania. Ponieważ indeksy same sortują rekordy, łatwiej jest raportowi porządkować i grupować dane wprost z indeksowanych pól.
Źródło rekordów nie powinno zawierać funkcji podsumowujących (DLookup). Takie rozwiązanie również wymusi na raporcie wielokrotne przeglądanie danych, co spowolni wyświetlanie raportu.
Nie ma sensu wyświetlanie raportu wypełnionego komunikatami #Error#. Jeśli raport nie zawiera danych, poinformuj o tym użytkownika za pomocą komunikatu i zamknij raport. Możesz określić, czy raport zawiera dane za pomocą właściwości Brak danych i Ma dane.
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.
Pisanie szybkiego kodu
Co się tyczy kodu, istnieje kilka rzeczy, które mogą poprawić szybkość wykonywanych funkcji i procedur. Mimo iż różnice między jedną techniką a drugą mogą być mierzone w znaczących ułamkach sekundy, wybór najszybszej opcji może ograniczyć przyszłą rozbudowę aplikacji. Należy być przygotowanym na to, że po pewnym czasie użytkownicy 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.
Użycie pamięci przez kod
Access używając metody „call-tree loading” przenosi do pamięci wszystkie moduły oraz wszystkie zawarte w nich procedury i funkcje. Oznacza to, że jeśli funkcja A pierwszego modułu odwołuje się do funkcji B tego samego modułu, która z kolei odwołuje się do funkcji C drugiego modułu, to Access załaduje do pamięci całą zawartość obu modułów.
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.
Tworzenie pliku MDE
Najpewniejszym sposobem na to, by aplikacja była stale skompilowana, jest przekazanie jej użytkownikom w postaci pliku MDE XE "plik MDE" . Plik taki nie zawiera kodu źródłowego i nigdy nie jest kompilowany.
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.
Użycie Option Explicit
Zawsze używaj Option Explicit XE "Option Explicit" , gdyż zmusi cię to do określania typów danych. Jeśli nie określisz typu danych zmiennej, VBA użyje największego i najbardziej obszernego typu danych. Jak zwykle, największy i najbardziej obszerny oznacza jednocześnie najwolniejszy. Określanie typu danych zmiennej jest również przydatne ze względu na przejrzystość i integralność danych.
Precyzyjne wybieranie rozmiaru zmiennych
Podczas określania zmiennej wybieraj zawsze możliwie jak najmniejszy rozmiar. Nie używaj double tam, gdzie wystarczy integer. Gdy tylko jest to możliwe, używaj ciągów o stałej zamiast o zmiennej długości.
Oszczędzanie przestrzeni stosu
przy użyciu zmiennych typu string
Zmienne typu string należą do najczęściej używanych. Można je podzielić na trzy podtypy:
Lokalne o stałej długości (nie więcej niż 64 znaki) - zmienne te używają dwóch bajtów na znak i nie korzystają z obszaru dynamicznego pamięci.
Lokalne o stałej długości (więcej niż 65 znaków) - zmienne te również używają dwóch bajtów na znak, lecz w obszarze dynamicznym pamięci. Wymagają również czterech bajtów w stosie, aby wskazywać zmienną w obszarze dynamicznym pamięci.
Długość zmienna (długość nie ma znaczenia) - wielkość użytej pamięci dynamicznej zależy od długości zmiennej. Cztery bajty pamięci stosu użyte są w celu wskazania zmiennej w obszarze dynamicznym.
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
|
||
|
Do określenia rozmiaru pól tekstowych o stałym rozmiarze używaj rozmiaru pola w tabeli. |
Dokładne określanie typu obiektów
Gdy deklarujesz typ obiektu, bądź dokładny. Jeśli kod ma przechodzić przez pola tekstowe formularza, zadeklaruj zmienną obiektu jako pole tekstowe, nie tylko jako formant. W ten sposób nie wystąpi konieczność używania VBA do sprawdzenia, o jaki rodzaj formantu chodzi.
Aby zaoszczędzić czas, zamiast
Sub CycleControls(cntl as control)
użyj
Sub CycleControls(cntl as TextBox)
Umieszczenie kodu we wnętrzu procedury
zamiast odwoływania się do innych funkcji
W momencie gdy funkcja lub procedura odwołuje się do innej funkcji lub procedury, występuje klasyczny konflikt między łatwością w obsłudze a szybkością. Technika ta bardzo ułatwia obsługę, lecz jest mniej wydajna niż umieszczenie kodu w jednej procedurze. Mogą zdarzyć się sytuacje, w których będziesz zmuszony wybierać między szybkością a łatwością obsługi, lecz nie rób tego tylko dla zyskania kilku milisekund.
Zmiana True i False
Podczas zmiany znacznika z True na False, nie zachodzi konieczność sprawdzania znacznika wartości w konstrukcji If...Then...Else. Możesz zaoszczędzić czas i linie kodu, odwracając tę wartość przy użyciu operatora NOT. Ustawiając zmienną logiczną na to, czym ona nie jest, odwracasz ja.
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ę.
Użycie Len() zamiast pustego ciągu
Aby przetestować zmienną typu string w celu sprawdzenia, czy zawiera jakiekolwiek znaki, zamiast porównywania jej do pustego ciągu (""), użyj funkcji Len XE "Len:funkcja" (). Funkcja ta dokona oceny szybciej niż porównanie z ciągiem o zerowej długości.
Sub CheckString(strString as string)
If Len(strString) then
MsgBox „Oto ciąg: ” & strString
End If
End Sub
Użycie True i False zamiast zera
Ponieważ True i False są binarne, łatwiejsze jest ich wyliczanie niż liczby zero. Użyj True i False w następujący sposób:
Function ShowNumber(dblNumber as Double) as string
If dblNumber then
ShowNumber = "Numer to " & dblNumber
EndIf
End Function
Szybkie odwołania do obiektów
W przypadku powtarzających się odwołań do rekordów używaj zmiennych. Dużo szybciej jest odwoływać się do istniejącej zmiennej formularza, formantu, raportu czy kwerendy niż ponownie odwoływać się do obiektów.
Zamiast ponownie odwoływać się do formularza
Forms![frmMyForm].Height=500
Forms![frmMyForm].Width=500
spróbuj zadeklarować zmienną i odwołać się do niej w ten sposób:
Dim frm as Form
Set frm=Forms![frmMyForm]
frm.Height=500
frm.Width=500
W przypadku większej ilości właściwości obiektu, możesz zmniejszyć ilość odwołań przy użyciu konstrukcji With...End With XE "With...End With" . Przydaje się to szczególnie wtedy, gdy ścieżka odwołania jest długa.
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
Użycie szybkich tablic
Używaj tablic. Są one przechowywane w pamięci i ładowane są bardzo szybko. Ich powiększenie zajmuje bardzo mało czasu. Tablice zajmują tyle miejsca, ile w danym momencie potrzebują. Jeśli nie wiesz, ile elementów będziesz musiał umieścić w tablicy, zamiast tworzyć dużą tablicę z pustymi miejscami, utwórz tablicę dynamiczną.
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.
Używaj stałych, gdy jest to tylko możliwe
Za każdym razem, gdy VBA ma pobrać bieżącą wartość zmiennej, musi się do niej odwoływać. Inaczej jest w przypadku stałych. Stałe poprawiają również czytelność kodu. Zamiast wpisywać wszędzie 12 jako 12 miesięcy, utwórz stałą (na przykład o nazwie WszystkieMiesiące) i ustaw ją na 12. VBA będzie odczytywać stałą dużo szybciej, a inni programiści będą wiedzieli, co miałeś na myśli ustawiając stałą. Wadą takiego rozwiązania jest to, że stałe mogą być ustawiane tylko raz i nie mogą być później zmieniane. Można ich używać do przedstawiania wartości wewnętrznych aplikacji lub wartości zewnętrznych, które nigdy nie ulegają zmianie.
Właściwe użycie zakładek (Bookmarks)
Zakładki XE "zakładka" są bardzo szybkim sposobem poruszania się po rekordach w interfejsie. Pamiętaj, że istnieją dwa rodzaje zakładek: zakładki dla formularzy i zakładki dla zestawów rekordów. Zakładka formularza jest to tablica zmiennych wariantowych, dynamicznie przyznawanych do każdego rekordu w podległym zestawie. Zakładka DAO jest to bajtowa tablica, która definiuje każdy z rekordów w zestawie. Ułatwiające poruszanie się po rekordach zakładki są niszczone i tworzone ponownie wraz z zestawami rekordów. Nie polegaj na nich, chyba że możesz je kontrolować lub gdy nie będzie to miało negatywnych konsekwencji. Nie przedstawiają one rekordów i nie mają nic wspólnego z kluczem podstawowym. Reprezentują one jedynie tymczasową pozycję rekordu w serii wierszy. Jakakolwiek obróbka danych powinna być dokonywana w oparciu o techniki odnoszące się do projektu bazy danych, a nie jedynie pozycji w zestawie rekordów. Używając kwerendy po każdej operacji aktualizacji i usuwania danych, będziesz każdorazowo niszczył zakładki i tworzył je na nowo. Jeśli Twój interfejs używa w takich sytuacjach zakładek, będziesz musiał dokładnie kontrolować aktualizację i usuwanie rekordów.
Poniższy kod ilustruje użycie zakładki w formularzu w celu przejścia do poprzedniego rekordu po dokonaniu aktualizacji.
Private Sub Findit_AfterUpdate()
Dim rsclone As Recordset
Dim recordID As Variant
Dim IDValue As Long
Set rsclone = Me.RecordsetClone
IDValue = Me![Findit]
recordID = "ID = " & Value
rsclone.FindFirst recordID
bm = rsclone.Bookmark
Me.Bookmark = bm
End Sub
Użycie zakładki w celu przejścia do poprzedniego rekordu jest o 1300% szybsze niż wykonanie instrukcji FindFirst XE "FindFirst:metoda" 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
Używaj SQL zamiast DAO
Przechodź przez zestawy rekordów tylko wtedy, gdy nie ma innego rozwiązania. Bazy danych Jet są optymalizowane pod kątem wykorzystania SQL do obróbki danych i ich struktury. Używaj kwerend zamiast DAO w każdej możliwej sytuacji. Niewiele jest sytuacji, w których obiekty DAO są szybsze niż dobrze zaprojektowana kwerenda. W przeciwieństwie do obiektów DAO kwerendy posiadają plany wykonywania i mogą korzystać z indeksów.
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”.
Użycie indeksowania kolekcji
Gdy masz do czynienia z kolekcjami, jeśli to tylko możliwe używaj ich numerów indeksów. Numery te są wewnętrznymi identyfikatorami kolekcji. Ich użycie jest dużo szybsze niż innych właściwości (np. nazw). Poniższy przykład ilustruje dwa sposoby tworzenia
odniesień do aktualnej bazy danych. Użycie Currentdb XE "Currentdb:funkcja" () 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)
jest szybszym rozwiązaniem niż
Set db=Currentdb()
Set cntl=Forms!frmMyForm(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.
Tworzenie szybszych pętli
Tworząc pętlę w kolekcji, zamiast For...Next używaj For...Each. Podczas tworzenia pętli w formantach formularza
For Each cntl on frm
...
Next
będzie działać szybciej niż zwykła pętla For...Next.
Podczas tworzenia pętli w obiektach Collection XE "Collection:obiekt" 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.
Usuń z kodu IIF()
Nie używaj w kodzie funkcji IIF XE "IIF" (). Zanim poda ona swoje wyniki, musi dokonać oceny wszystkich wyrażeń w niej zawartych. Szybszym rozwiązaniem jest standardowa struktura If...Then...Else.
Porządkowanie Select Case
Używając konstrukcji Select Case, pamiętaj o uporządkowaniu jej w taki sposób, by najczęściej występujące przypadki znajdowały się u góry. Ponieważ przejście przez Selections związane jest z testowaniem przypadków w kolejności ich ułożenia, umieszczenie najczęściej występujących u góry umożliwi jak najszybsze opuszczenie struktury.
Używaj Execute zamiast RunSQL
Unikaj pisania kodu w oparciu o polecenie DoCmd. DoCmd znajduje się na najwyższym poziomie kodu VBA. Gdy tylko istnieje inne rozwiązanie - wybierz je.
DoCmd RunSQL „...”
będzie wolniejszym rozwiązaniem od
Querydef.Execute
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.
Testuj wydajność transakcji
Transakcje nie zawsze umożliwiają zaoszczędzenie czasu. Kiedyś mogłeś być pewien, że użycie transakcji spowoduje przyspieszenie pracy kwerend. Teraz już tak nie jest. Mimo iż transakcje mogą użyć swoich zdolności buforowania, w celu poprawy wydajności kwerend, mogą jednocześnie spowolnić ich pracę, ze względu na konieczność tworzenia na dysku tymczasowych plików, w oczekiwaniu na ponowny przebieg.
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.
Używaj wczesnego wiązania
i zwracaj uwagę na odniesienia ActiveX
Korzystaj z wczesnego wiązania. Używając formantów ActiveX, upewnij się, że istnieje odniesienie do odpowiedniego pliku OCX dla tego formantu. Możesz to sprawdzić, wybierając z menu Tools pozycję References. Wczesne wiązanie może znacznie poprawić wydajność aplikacji.
Przejście do architektury klient-serwer
Staraj się, by projekt aplikacji uwzględniał możliwość przejścia do SQL Server lub Oracle. Jeśli tak się stanie, będziesz mógł skorzystać z kwerend przekazujących i procedur przechowywanych na serwerze. Może to mieć duży wpływ na wydajność 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:
Wprowadzenie do projektów programu Microsoft Access oraz narzędzi wizualnych.
Tworzenie interfejsu użytkownika dla Microsoft SQL Server.
Interfejs Accessa 2000 do Oracle.
Rozdział 15.
Wprowadzenie do projektów programu Microsoft Access oraz narzędzi wizualnych
W tym rozdziale:
Wprowadzenie do Projektów programu Microsoft Access (ADP).
Użycie ADP.
Praca z ADP i istniejącymi bazami danych serwera SQL.
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.
Wprowadzenie do projektów programu Microsoft Access
Jako użytkownik Accessa wiesz, że używa on silnika bazy danych Microsoft Jet do zapisywania danych oraz wykonywania zapytań. Wiele aplikacji Accessa używa serwera bazy danych i połączenia ODBC do zapisywania danych. Aplikacje takie mogą korzystać z tabel połączonych, zapytań SQL i ODBCDirect. W takich aplikacjach używasz silnika Jet i ODBC, aby komunikować się z połączonymi tabelami, a aplikacja jest zwykłym plikiem MDB.
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 XE "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ś przeczytać uwagi do programu Office 2000 i wykonać plik poleceń SQL na serwerze przed rozpoczęciem pracy z ADP i SQL Serverem 6.5. |
Wady i zalety ADP
Gdy rozpatrujesz korzyści płynące z użycia ADP zamiast plików MDB, spójrz na plusy i minusy. Korzyści używania ADP są następujące:
Używając ADP, możesz zmieniać strukturę tabel w Accessie, nie możesz tego robić, używając tabel z serwera jako tabel połączonych.
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.
ADP jest łatwe w użyciu.
ADP umożliwiają użycie Accessa jako narzędzia do projektowania aplikacji.
Wadami ADP są:
ADP ogranicza Cię do używania tylko MS SQL Servera, nie możesz użyć tego typu projektu z bazami Oracle lub Sybase.
ADP jest nową technologią, a każda nowa technologia może jeszcze nie być dopracowana.
Nie możesz tworzyć żadnych lokalnych tabel ani zapytań.
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 komputerze lub mieć dostęp poprzez sieć do innego serwera SQL. Aby zainstalować 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 katalogu /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 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 |
|
||||
Rysunek 15.4. Nowe okno bazy danych dla ADP |
|
||||
|
|||||
|
Jeżeli chcesz analizować ten przykład na swoim komputerze, upewnij się, że masz zainstalowany SQL Server 7.0. Możesz zainstalować lokalną wersję serwera SQL wraz z bazą Northwind z dysku instalacyjnego Office 2000. |
Nowe okno bazy danych
Okno bazy danych dla plików ADP jest inne od tego dla plików MDB (porównaj z rysunkiem 15.4). Nowe okno wyświetla następujące elementy: tabele, widoki, procedury przechowywane, diagramy baz danych, formularze, raporty, strony, makra i moduły. W tabela 15.1 został opisany każdy element okna bazy danych.
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 bezpośrednio na serwerze |
Diagramy bazy danych |
Lista diagramów bazy danych na serwerze. Możesz tworzyć diagram takimi samymi 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
Nazwa atrybutu |
Opis |
ColumnName |
Nazwa kolumny. Musi być prawidłową nazwą kolumny dla serwera SQL |
DataType |
Typ danych kolumny. Dostępne typy danych przedstawione są poniżej |
Length |
Długość kolumny |
Precision |
Dokładność kolumny. Używane dla kolumn numerycznych |
Scale |
Skala (ilość miejsc po przecinku). Używane dla kolumn numerycznych |
Allow Nulls |
Znacznik określający, czy kolumna może zawierać puste wartości |
Default Value |
Wartość domyślna dla kolumny |
Identity |
Znacznik określający, czy kolumna jest kolumną identyfikatora. W tabeli może istnieć tylko jedna kolumna identyfikatora |
Identity Seed |
Wartość początkowa kolumny identyfikatora |
Identity Increment |
Liczba, o którą jest zwiększana wartość identyfikatora |
Is RowGuid |
Znacznik określający, czy kolumna identyfikatora jest GUID |
Zestawienie typów danych serwera SQL:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Widoki w serwerze SQL
Używając sekcji Widoki XE "widok" w oknie bazy danych, można administrować widokami serwera SQL. Jedną z największych zalet korzystania z ADP jest to, że możesz utworzyć widok w Accessie i zapisać go na serwerze. Aby utworzyć widok, kliknij przycisk Nowy. Pojawi się edytor widoków serwera SQL, jak widać to na rysunku 15.6. Wygląda znajomo? Powinno, ponieważ został utworzony na wzór sławnego edytora QBE Accessa.
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 |
|
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 XE "procedura przechowywana" 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 XE "Transact SQL" XE "TSQL" 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 |
|
Diagramy bazy danych
Prawdopodobnie najbardziej interesującą opcją ADP są diagramy bazy danych XE "diagram bazy danych" . Dla tych, którzy nie znają narzędzi baz danych firmy Microsoft, a które są teraz częścią ADP, wyjaśniam, że diagramy bazy danych umożliwiają zarządzanie i projektowanie tabel bazy danych w sposób wizualny. Baza danych „Northwind” w wersji na serwer SQL ma utworzony diagram powiązań. Diagram ten przedstawia zależności w bazie danych oraz pozwala na zmiany powiązań, modyfikację tabel oraz na dodawanie lub usuwanie kolumn bezpośrednio w oknie edytora diagramu.
Aby edytować diagram bazy danych, kliknij go dwa razy, a zostanie on pokazany na ekranie jak na rysunku 15.11.
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 |
|
Formularze, strony, raporty i moduły
Użycie formularzy, stron, raportów i modułów nie różni się niczym od użycia tych obiektów w plikach MDB, z tą różnicą, że teraz obiekty bazy danych są obiektami serwera SQL, a nie obiektami Accessa.
Zarządzanie serwerem SQL poprzez ADP
Chociaż nie ma miejsca w tej książce na szczegółowy opis administrowania serwerem SQL, powinieneś wiedzieć, że można zarządzać bazą danych na serwerze poprzez aplikację ADP.
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.
Twoja aplikacja może administrować następującymi obszarami:
Składowanie i odtwarzanie.
Replikacja.
Bezpieczeństwo.
Składowanie XE "składowanie" i odtwarzanie XE "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.
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.
Replikacja XE "replikacja" serwera SQL
W Accessie można utworzyć nowe publikacje, synchronizować repliki oraz rozwiązywać konflikty. Aby utworzyć nową publikację, wybierz Narzędzia|Replikacja|Utwórz publikację z głównego menu. Na ekranie pojawi się okno replik, pokazane na rysunku 15.14. Wybierz bazę danych na diagramie i kliknij przycisk Twórz publikację. Uruchomiony zostanie kreator publikacji pokazany na rysunku 15.15.
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 XE "prawa dostępu" , 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.
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 XE "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.
Powtórne przyłączenie do bazy serwera SQL
Co się stanie, gdy po utworzeniu aplikacji ADP chciałbyś zainstalować ją u użytkownika w innej sieci komputerowej? Aby aplikacja prawidłowo działała, musisz zsynchronizować plik ADP tak, aby przyłączył się do właściwej bazy danych. Jak omawialiśmy w rozdziale 7., używałeś uniwersalnych połączeń danych do zarządzania ciągiem połączeniowym OLE DB w ADO. Poprzez ustanowienie odwołania do komponentu Microsoft OLE DB ServiceComponent 1.0 Type Library, w sposób pokazany na rysunku 15.17, możesz użyć interfejsu automatyzacji UDL XE "UDL" do synchronizacji aplikacji ADP z właściwą bazą danych.
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 XE "PromptNew:metoda" obiektu DataLink XE "DataLink:obiekt" . 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ę.
Wydruk 15.1. Uaktualnianie połączenia ADP
Sub UpdateConnection()
' Procedura używa interfejsu UDL Automation
' do utworzenia obiektu połączenia
' i użycia tego połączenia do synchronizacji ADP
' Autorzy: Forte, Howe, Ralston
Dim strConnect As String
Dim rst As ADODB.Recordset
' Odwołanie do Microsoft UDL
Dim udl As MSDASC.DataLinks
On Error GoTo Proc_Err
' Tworzenie obiektu Data Link
Set udl = New MSDASC.DataLinks
StrConnect = udl.PromptNew
' Pobranie informacji o połączeniu z UDL i synchronizacja ADP
CurrentProject.OpenConnection strConnect
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
|
||
|
W CurrentProject.Connection ADP używa obiektu MSDataShape OLE DB oprócz SQL Server OLE DB. Spotkałem się z tym, że niektóre funkcje ADO działają nieco inaczej w VB, gdy używa się SQL Server OLE DB bez MSDataShape. Szukaj w Microsoft KnowledgeBase opisu użycia kodu Accessa 2000 w Visual Basic. |
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 XE "kreator 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 |
|
Tworzenie tabel
Chcemy utworzyć prosty system śledzenia wykonywania zadań. Aby to zrealizować, potrzebujemy kilku tabel XE "tabela:tworzenie" . 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.
Tabela 15.3.
Projekt tabeli tblWydanie
Nazwa kolumny |
Typ danej |
Opis |
IDWydania |
Int(4) |
Klucz główny, identyfikator |
IDTypTransakcji |
Int(4) |
Będzie kluczem obcym |
Komentarz |
Text(16) |
|
Tabela 15.3.
Projekt tabeli tblWydanie (ciąg dalszy)
Nazwa kolumny |
Typ danej |
Opis |
DataZapisu |
Datetime |
Domyślna wartość: getdate() |
DataZakończenia |
Datetime |
Kolumna może być pusta |
Tabela 15.4.
Projekt tabeli tlkpTypTransakcji
Nazwa kolumny |
Typ danej |
Opis |
IDTypTransakcji |
Int(4) |
Klucz główny, identyfikator |
OpisTransakcji |
Varchar(50) |
|
Ustawienie właściwości tabeli i indeksów
Aby ustawić indeksy XE "indeks" oraz właściwości tabeli wybierz Widok|Właściwości z głównego menu. Uruchomi się okno dialogowe pokazane na rysunku 15.20. W tym oknie można ustawić atrybuty indeksu takie jak: unikatowość, poziom wypełnienia, czy jest indeksem grupowym (CLUSTERED) czy nie. Poprzez edytor struktury tabel ustawiłeś klucz główny, więc istnieje już dla niego unikatowy indeks.
Rysunek 15.20. Właściwości tabeli |
|
Tworzenie zależności na diagramie bazy danych
Teraz, gdy masz utworzone dwie tabele (to było TAKIE proste), powinieneś zdefiniować zależności pomiędzy nimi. Tworzenie zależności pomiędzy tabelami jest bardzo proste przy użyciu ADP. Aby wizualnie zdefiniować związki pomiędzy tabelami za pomocą diagramu bazy danych, przejdź do sekcji Diagramy bazy danych w oknie bazy danych i dodaj nowy diagram. Aby wyświetlić listę tabel, wybierz Widok|Pokaż tabele z głównego menu. Następnie przeciągnij dwie tabele z okna Pokaż tabelę na diagram, jak widać na rysunku 15.21. Aby utworzyć relację XE "relacja" , przeciągnij pole z tblkTypTransakcji do tblWydanie. Przeciągnięcie pola spowoduje otwarcie okna relacji (rysunek 15.22), które pozwoli na określenie pól wchodzących w skład zależności. Po ustanowieniu zależności zapisz diagram. Pamiętaj, możesz go użyć jako dokumentację do Twojego projektu.
Rysunek 15.21. Tryb edycji diagramu bazy danych |
|
Rysunek 15.22. Właściwości relacji |
|
Tworzenie kaskad poprzez wyzwalacze
SQL Server 7.0 nie zapewnia kaskadowego uaktualniania i kaskadowego kasowania poprzez więzy integralności. Jeżeli chcesz skorzystać z tego mechanizmu, musisz zrobić to, wykorzystując wyzwalacze XE "wyzwalacz" . Aby utworzyć lub edytować wyzwalacz, kliknij prawym przyciskiem na nazwę tabeli w oknie bazy danych i wybierz Wyzwalacze z menu kontekstowego. Uruchomi się okno dialogowe pokazane na rysunku 15.23. Jeżeli wyzwalacz już istnieje, wybierz go lub kliknij przycisk Nowa, aby utworzyć nowy wyzwalacz.
Rysunek 15.23. Zarządzanie wyzwalaczami |
|
Tworzenie widoków
Zamierzasz utworzyć widok XE "widok:tworzenie" 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
Rysunek 15.24. Edytor widoków |
|
Wydruk 15.2. Prosty widok
SELECT tlkpTypTransakcji.OpisTransakcji, tblWydanie.IDWydania,
tblWydanie.Komentarz, tblWydanie.DataZapisu,
tblWydanie.DataZakończenia
FROM tblWydanie INNER JOIN
tlkpTypTransakcji ON
tblWydanie.IDTypTransakcji = tlkpTypTransakcji.IDTypTransakcji
WHERE (tblWydanie.DataZakończenia IS NOT NULL)
Tworzenie procedur przechowywanych
Aby utworzyć procedurę przechowywaną XE "procedura przechowywana:tworzenie" , otwórz edytor procedur i wpisz odpowiednie wyrażenie TSQL XE "TSQL" . Utworzymy prostą procedurę, która wybierze jedną transakcję określoną przez jej numer. Kod procedury pokazany jest na wydruku 15.3.
Wydruk 15.3. Prosta procedura przechowywana
Create Procedure "WybierzTransakcje"
@NumerWyd int
As
SELECT tlkpTypTransakcji.OpisTransakcji, tblWydanie.IDWydania,
tblWydanie.Komentarz, tblWydanie.DataZapisu,
tblWydanie.DataZakończenia
FROM tblWydanie INNER JOIN
tlkpTypTransakcji ON
tblWydanie.IDTypTransakcji = tlkpTypTransakcji.IDTypTransakcji
WHERE tblWydanie.IDWydania=@NumerWyd
Tworzenie aplikacji w Accessie
Aby przekonać się, jak łatwo tworzy się aplikacje w Accessie, używając ADP, spójrz na prosty formularz pokazany na rysunku 15.25. Jest on związany z tabelą tblWydanie i za jego pomocą można wpisywać i przeglądać dane, filtrować, itp., tak samo jak w zwykłym pliku MDB. Tworzenie raportów jest równie proste jak w Accessie 97. Po prostu uruchom kreatora i utwórz swój raport.
Rysunek 15.25. Nasza formatka |
|
Tworzenie plików ADE XE "ADE"
W Accessie 97 wprowadzono w życie nowy pomysł, pliki MDE. Jest to skompilowana i zablokowana wersja pliku MDB. W Accessie 2000 masz możliwość tworzenia plików MDE dla aplikacji MDB oraz plików ADE dla plików ADP. Aby 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.
Zakończenie: przenoszenie bazy danych Access 97
na serwer SQL i do pliku ADP
We wcześniejszych wersjach Accessa kreator rozbudowy bazy danych nie był doskonały. Potrafił przenieść tabele na serwer SQL i to wszystko. Zapytania pozostawały w Accessie i były uruchamiane na tabelach połączonych, co było bardzo nieefektywne. Jeżeli jednak uruchomisz tego samego kreatora z Accessa 2000, otrzymasz dużo lepsze rezultaty. Kreator zamieni wszystkie „widoki” dla silnika bazy Jet oraz zapytania typu SELECT na widoki serwera SQL, a także procedury Accessa na procedury przechowywane (jeżeli będzie to możliwe). Następnie zostanie utworzona aplikacja ADP oparta o serwer SQL. Mimo że jeszcze jest wiele ograniczeń, kreator ten jest wart zainteresowania; w najgorszym razie pomoże Ci rozpocząć pracę nad przeniesieniem bazy. Jest on bardzo prosty w użyciu, więc wybierz Narzędzia|Narzędzia bazy danych|Kreator rozbudowy.
Rysunek 15.26. Tworzenie pliku ADE |
|
Rozdział 16.
Tworzenie interfejsu użytkownika dla Microsoft SQL Server
W tym rozdziale:
Architektura klient-serwer: OLE DB kontra ODBC.
Tworzenie połączenia z serwerem SQL.
Procedury przechowywane i kwerendy przekazujące.
Raportowanie z serwera SQL w Accessie.
Formularze w aplikacji.
Zaawansowane właściwości: dostawca OLE DB dla SQL serwera.
Wykonywanie poleceń z parametrami.
Użycie klasy Connection.
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.
Architektura klient-serwer: OLE DB kontra ODBC
Systemem klient-serwer nazywamy system, który używa serwera bazy danych (np. SQL Server lub Oracle) do przechowywania danych oraz aplikacji klientów, które komunikują się z bazą danych (systemy trójwarstwowe, o których się dużo mówi, mają podobną architekturę za wyjątkiem tego, że logika biznesowa umieszczona jest w oddzielnej logicznej warstwie).
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.
Tworzenie połączenia z serwerem SQL
Aby rozpocząć pracę z bazą danych na serwerze SQL, należy zestawić z nią połączenie. Ponieważ będziemy używać połączenia ODBC do komunikacji z bazą, upewnijmy się, że na komputerze, którego używamy, zainstalowany jest właściwy sterownik. Standardowa instalacja Accessa 2000 instaluje sterownik ODBC do SQL Server (jeżeli chcesz użyć 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.
Tworzenie źródła danych ODBC (DSN)
Systemowe DSN XE "DSN" jest miejscem, gdzie zapisujesz wszystkie informacje o połączeniach ODBC. Każdy DSN posiada unikatową nazwę, której używają aplikacje. Aby utworzyć DSN na Twoim komputerze, wykonaj następujące czynności.
Uruchom Źródła danych ODBC (32 bity) z Panelu sterowania, na zakładce Systemowe DSN naciśnij Dodaj. Gdy uruchomi się okno dialogowe DSN wybierz SQL Server i naciśnij przycisk Zakończ. Uruchomi się kreator tworzenia DSN, taki jak na rysunku 16.1.
Rysunek 16.1. Tworzenie nowego źródła danych w Panelu sterowania |
|
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.
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).
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 |
|
Czwarta strona zawiera opcje specyficzne dla ODBC, jak śledzenie. Zatwierdź domyślne opcje i naciśnij Zakończ.
Ostatnia strona pozwala na sprawdzenie nowo utworzonego połączenia. Dobrze jest sprawdzić tutaj połączenie i w wypadku niepowodzenia testu, wprowadzić od razu poprawki.
Teraz jesteś gotowy do użycia serwera SQL w aplikacji Access 2000.
Łączenie tabel XE "łą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.
Upewnij się, że istnieje prawidłowe źródło danych (zajrzyj do „Tworzenie źródła danych ODBC (DSN)”).
Otwórz bazę danych Access i wybierz z menu: Plik|Pobierz dane zewnętrzne|Połącz tabele.
Na ekranie pojawi się lista wszystkich źródeł danych ODBC. Wybierz ten DSN, na którym chcesz pracować, i naciśnij OK.
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 |
|
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).
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.
Wady tabel połączonych
Łączenie tabel ze źródeł danych ODBC do Accessa może być bardzo nieefektywne i niebezpieczne. Silnik Jet musi pośredniczyć w całej komunikacji pomiędzy serwerem SQL a aplikacją. Jeżeli nie może użyć unikatowego indeksu na serwerze, może wczytać wszystkie rekordy tabeli do przetwarzania na komputerze klienta. Wyobraź sobie taką sytuację. Łączysz tabelę z 5 milionami rekordów, tworzysz zapytanie wybierające około 500 rekordów, ale warunek selekcji nie opiera się o żaden unikatowy indeks. W zależności od projektu tabeli serwer SQL może zwrócić całe 5 milionów rekordów do posortowania przez silnik Jet! Jeżeli uruchomisz to na niezbyt szybkim komputerze, będzie to trwało godzinami.
Aby wydobyć całą moc z serwera SQL, powinieneś użyć procedur przechowywanych. Procedura przechowywana XE "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.
Połączenie najlepszych metod:
wypełnianie tabel podczas startu aplikacji
Ponieważ zwykle używam procedur przechowywanych jako podstawowej metody manipulacji danymi w moich aplikacjach klient-serwer, zwykle używam tabel połączonych do wypełniania list i list rozwijanych danymi wykorzystywanymi na formatkach i raportach. Aby uzyskać najlepszą wydajność, możesz przy starcie aplikacji tworzyć kopie tabel serwera do tabel lokalnych. Oczywiście, używaj tej techniki tylko do danych statycznych (nie zmieniających się zbyt często).
|
||
|
Technika ta, chociaż bardzo użyteczna, nie jest dostępna w projektach ADP, które były omawiane w rozdziale 15. „Wprowadzenie do projektów programu Microsoft Access oraz narzędzi wizualnych”, ponieważ lokalne tabele opierają się o silnik Jet, a ADP w ogóle go nie ładuje. |
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 XE "kwerenda przekazująca" , 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.
Wydruk 16.1. Prosta procedura przechowywana
CREATE PROCEDURE dbo.sp_OrdersByDate
@StartDate datetime, @EndDate datetime AS
SELECT Customers.CustomerID, Customers.CompanyName,
Orders.OrderDate, [Order Details].Quantity,
[Order Details].UnitPrice, Quantity*UnitPrice AS TotalAmount
FROM Customers INNER JOIN Orders ON
Customers.CustomerID=Orders.CustomerID INNER JOIN
[Order Details] ON Orders.OrderID = [Order Details].OrderID
Where OrderDate Between @StartDate and @EndDate
Uruchomienie procedury przechowywanej jest proste. Logujemy się do bazy danych i wpisujemy polecenie EXECUTE XE "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.
Tworzenie raportów opartych na procedurach przechowywanych poprzez zapytania przekazujące
Aby uruchomić procedurę przechowywaną w zapytaniu przekazującym, należy użyć polecenia Execute, która została wcześniej omówiona. Możesz utworzyć kwerendę przekazującą poprzez wybranie z menu: Kwerenda|Wyłącznie SQL|Przekazująca, po przejściu do trybu projektowania zapytań (rysunek 16.6).
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 XE "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 |
|
Rysunek 16.8. Zapisana kwerenda przekazująca |
|
Raportowanie z serwera SQL w Accessie
Jeżeli spytasz doświadczonych programistów, co lubią najbardziej w Accessie, wielu z nich odpowie, że ma on jeden z najlepszych modułów raportowych. Access umożliwia łatwe tworzenie wspaniałych raportów bardzo szybko, nawet jeżeli dane nie pochodzą z tabel Accessa. Możliwość łatwego raportowania z danych ODBC sprawia, że Access jest dobrym wyborem dla całego raportowania w przedsiębiorstwie.
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 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.
Wydruk 16.2. Zmiana wyrażenia SQL i uruchomienie raportu
Private Sub cmdPrint_Click()
'''''''''''''''''''''''''''''''''''''''
' Przeznaczenie: Zmiana kodu SQL, aby wywołać
' procedurę przechowywaną z nowymi parametrami
''''''''''''''''''''''''''''''''''''''''
Dim db DAO.Database
Dim strSql As String
Rysunek 16.10. Formularz pobierania parametrów do uruchomienia raportu |
|
On Error GoTo Click_Err
StrSQL = "Execute sp_OrdersbyDate @StartDate=" & _
Chr(39) & Me.txtStartDate & Chr(39) & _
", @EndDate=" & Chr(39) Me.txtEndDate & Chr(39)
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
Dodatkowe filtrowanie danych raportu
Czasami warunek Where XE "Where" w procedurze przechowywanej nie zapewnia dokładnie tych informacji, których potrzebujesz. Możesz dostać 500 zamówień i chcesz odfiltrować je, określając minimalną wartość zamówienia. Access dostarcza dwóch metod do filtrowania raportów poprzez metodę DoCmd.OpenReport XE "DoCmd.OpenReport" : można podać nazwę zapisanej kwerendy lub przekazać warunek Where do raportu. Rysunek 16.10 przedstawia formatkę wprowadzania wartości parametrów, która umożliwia także przekazanie wartości do filtra, bazującego na wartości zamówienia, oprócz wprowadzenia zakresu dat. Jeżeli użytkownik zdecyduje się na użycie filtra oprócz zakresu dat, wykonany zostanie kod wywołujący metodę BuildCriteria XE "BuildCriteria:metoda" z obiektu Application XE "Application:obiekt" . Prawidłowym filtrem będzie np.: OrderAmount>500. Metoda BuildCriteria utworzy prawidłowy filtr, który następnie będzie zastosowany podczas wykonania metody DoCmd.OpenReport. Wydruk 16.3 zawiera kod, który zarówno zmienia wyrażenie SQL w zapytaniu przekazującym, jak i tworzy filtr.
Wydruk 16.3. Użycie metody BuildCriteria do założenia filtra w raporcie
Function BuildWhere(curAmt As Currency) As String
' Tworzy warunek Where za pomocą metody BildCriteria
BuildWhere = BuildCriteria( "TotalAmount", dbCurrency,
">=" & curAmt)
End Function
Private Sub cmdPrint_Click()
'''''''''''''''''''''''''''''''''''''''
' Przeznaczenie: Zmiana kodu SQL, aby wywołać
' procedurę przechowywaną z nowymi parametrami
' oraz dodaje możliwość filtrowania.
' Filtrowanie jest realizowane poprzez właściwość
' Where Clause metody DoCmd.OpenReport
''''''''''''''''''''''''''''''''''''''''
Dim db DAO.Database
Dim strSql As String
On Error GoTo Click_Err
StrSQL = "Execute sp_OrdersbyDate @StartDate=" & _
Chr(39) & Me.txtStartDate & Chr(39) & _
", @EndDate=" & Chr(39) Me.txtEndDate & Chr(39)
Set db = CurrentDb
Db.QueryDefs("qsptOrdersbyDate").SQL = strSQL
' Tutaj sprawdzamy, czy jest potrzebny filtr
' tzn. czy jest zaznaczone pole wyboru
if Me.chkFilter Then
'Zastosuj filtr
DoCmd.OpenReport "qsptOrdersbyDate", acViewPreview, , _
BuildWhere(Me.txtFilter)
Else
DoCmd.OpenReport "qsptOrdersbyDate", acViewPreview
End If
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.
Wydruk 16.4. Kod w raporcie obsługujący filtr oraz zdarzenie NoData
Private Sub Report_NoData(Cancel As Integer)
' Brak danych!
On Error Resume Next
' Ostrzegaj użytkownika o pustym raporcie
MsgBox "Ten raport nie zawiera danych" & vbNewLine & _
"Proszę podać inny warunek", vbCritical, Me.Name
' Nie otwieraj tego raportu
Cancel = True
End Sub
Private Sub Report_Open (Cancel As Integer)
On Error Resume Next
' Sprawdź, czy zastosowano filtr
If Forms!frmPrintReport!chkFilter Then
' Wpisz w nagłówku raportu warunek filtra
Me.lblFilter.Caption = _
"Raport filtrowany według zamówień > " & _
Forms!frmPrintReport!txtFilter
Me.lblFilter.Visible = True
End If
End Sub
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 XE "formularz związany"
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 modyfikować dane, użyj ADO i formularzy niezwiązanych w sposób opisany w następnych częściach tego rozdziału.
Formularze niezwiązane XE "formularz niezwiązany"
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.
Wydruk 16.5. Wypełnianie formularza zawarością obiektu recordset
Private Sub cboFind_AfterUpdate()
' Ta funkcja pobierze rekord, bazując na wartości klucza głównego
' i wypełni wartości w niezwiązanym formularzu
Dim conn As ADODB.Connection
Dim rst As ADODB.Recordset
Dim strSQL As String
On Error GoTo Proc_Err
DoCmd.Hourglass False
Set rst = New ADODB.Recordset
Set conn = New ADODB.Connection
' Tworzę wyrażenie SQL, bazując na aktualnej
' wartości pola listy rozwijalnej
strSQL = "Select * from Categories Where CategoryID=" & Me.cboFind
' Tworzenie połączenia ADO do serwera SQL
With conn
.Provider = "SQLOLEDB"
.ConnectionString = "data source=pawel;user id=sa;" & _
"initial catalog=NorthWindCS"
' Tryb tylko do odczytu
.Mode = adModeRead
.Open
End With
' Otwórz Recordset
rst.Open strSQL, conn
' Wypełnij wartości
Me.CategoryID = rst!CategoryID
Me.CategoryName = rst!CategoryName
' Zamknij połączenie
rst.Close
conn.Close
Set conn = Nothing
Set rst = Nothing
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.
Zaawansowane właściwości: dostawca OLE DB dla serwera SQL
Aby użyć dostawcy OLE DB dla serwera SQL, musisz upewnić się, czy jest on zainstalowany na komputerze. W trakcie standardowej instalacji Accessa 2000 instalowany jest także dostawca OLE DB do SQL Server. Po zainstalowaniu dostawcy możesz używać obiektu połączenia. Aby ustawić obiekt połączenia (ang.: connection), należy użyć składni przedstawionej na wydruku 16.6.
Wydruk 16.6. Podłączanie do serwera SQL przez OLE DB
Sub SQLServer()
' Procedura podłączenia do serwera SQL
Dim conn As ADODB.Connection
Set conn = New ADODB.Connection
With conn
.Provider = "SQLOLEDB"
.ConnectionString = "data source=(local);" & _
"user id=sa;initial catalog=NorthWindCS"
.Mode = adModeRead
.Open
End With
MsgBox "Połączony z " & conn.Provider, vbInformation
End Sub
Następny zestaw wyników
Jedną z właściwości serwera SQL, której nie dało uzyskać się przy użyciu technologii Jet, jest wykonywanie dwóch wyrażeń SQL jak jednego. Używając tej właściwości, możesz kilkakrotnie wykonywać wyrażenie SQL zwracające różne zestawy rekordów, używając jednego obiektu Recordset. Aby to zrobić, użyj metody NextRecordset XE "NextRecordset" .
Wydruk 16.7. Użycie NextRecordset
Sub NextRst(strCustomerId As String)
' Użyj ALFKI lub ANTON dla przykładu
' Procedura używa jednego obiektu Recordset dwa razy
Dim cmd As ADODB.Command
Dim conn As ADODB.Connection
Dim rst As ADODB.Recordset
Dim strSQL As String
Set conn = New ADODB.Connection
' Podłączenie do serwera SQL
With conn
.Provider = "SQLOLEDB"
.ConnectionString = "data source=(local);" & _
"user id=sa;initial catalog=NorthWindCS"
.Mode = adModeRead
.Open
End With
' Wyrażenie SQL zwracające dwa zestawy wyników
' Możesz to uruchomić tylko na serwerze, który
' wspiera wielokrotne zestawy wyników
strSQL = "Select * From Customers Where CustomerID=" & _
Chr(39) & strCustomerId & Chr(39)
strSQL = strSQL & vbNewLine
strSQL = strSQL & "Select * From Orders Where CustomerID=" & _
Chr(39) & strCustomerId & Chr(39)
Set cmd = New ADODB.Command
With cmd
.CommandText = strSQL
.ActiveConnection = conn
.CommandType = adCmdText
End With
Set rst = cmd.Execute
' Otwarcie pierwszego zestawu wyników
Do Until rst.EOF
Debug.Print rst!CompanyName
rst.MoveNext
Loop
' Pobierz następny zestaw
Set rst = rst.NextRecordset
Do Until rst.EOF
Debug.Print rst!OrderDate
rst.MoveNext
Loop
rst.Close
conn.Close
Set rst = Nothing
Set cmd = Nothing
Set conn = Nothing
End Sub
Wykonywanie poleceń z parametrami
Wcześniej, w rozdziale 1., kładłem nacisk na korzyści z użycia procedur przechowywanych w aplikacji, wszędzie tam, gdzie jest to możliwe, aby wykorzystać szybkość wykonania i zmniejszenie ruchu w sieci. Teraz gdy wykorzystujemy ADO, użycie procedur przechowywanych daje te same korzyści. W ADO, gdy używasz obiektów poleceń dostawcy OLE DB dla serwera SQL, można odwzorować ten obiekt na procedurę przechowywaną i przekazywać do niej parametry poprzez obiekty parametrów. Jak większość rzeczy w ADO, można zrobić to na kilka sposobów. W dalszej części rozdziału prześledzimy najczęstsze sposoby użycia procedur przechowywanych i obiektów poleceń, jednak musisz sam stwierdzić, który najlepiej pasuje do Twojego stylu programowania. Ja postaram się przekazać moje komentarze, aby pomóc Ci w tych wyborach.
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 XE "Connection:obiekt" , Command XE "Command:obiekt" i Parameter XE "Parameter:obiekt" , 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).
Wydruk 16.8. Wykonanie polecenia z parametrem
Sub ExecuteCommandwithParms()
' Procedura uruchamia procedurę przechowywaną z parametrami
Dim conn As ADODB.Connection
Dim cmd As ADODB.Command
Dim prm As ADODB.Parameter
Set conn = New ADODB.Connection
' Zestawienie połączenia z bazą danych
With conn
.Provider = "SQLOLEDB"
.ConnectionString = "data source=(local);" & _
"user id=sa;initial catalog=NorthWindCS"
.Open
End With
' Utworzenie i inicjalizacja obiektu Connection
Set cmd = New ADODB.Command
With cmd
.ActiveConnection = conn
.CommandText = "byroyality"
.CommandType = adCmdStoredProc
End With
' Utworzenie i inicjalizacja obiektu parameter
Set prm = New ADODB.Parameter
With prm
.Name = "@percentage"
.Direction = adParamInput
.Type = adInteger
.Value = 50
End With
cmd.Parameters.Append prm
' Otwarcie obiektu Recordset z wykonanego polecenia
Dim rst As ADODB.Recordset
Set rst = cmd.Execute
' odczytanie wszystkich rekordów wyniku
Do Until rst.EOF
Debug.Print rst!au_id
rst.MoveNext
Loop
' Zakończenie
rst.Close
conn.Close
Set rst = Nothing
Set conn = Nothing
Set cmd = Nothing
Set prm = Nothing
End Sub
Użycie metody CreateParameters
Prostą metodą obsługi procedur przechowywanych bez pisania dużej ilości kodu jest użycie metody CreateParameter XE "CreateParameter:metoda" obiektu Command. Metoda ta nie zmusza Cię do tworzenia obiektu dla każdego parametru aktualnego procedury przechowywanej, co zmniejsza ilość kodu, szczególnie, jeżeli procedura ma wiele parametrów. Uważam tę metodę za najmniej uciążliwą do programowania i najbardziej niezawodną do uruchamiania poleceń na SQL Server 6.5 i 7.0. Jak widać na wydruku 16.9, użycie metody CreateParameter tworzy obiekty parametrów bez dodatkowego kodu.
Wydruk 16.9. Wykonanie polecenia bez obiektu parametru
Sub ExecuteCommandwithCreateParms()
' Wykonanie procedury przechowywanej
' przy użyciu metody CreateParameter
Dim conn As ADODB.Connection
Dim cmd As ADODB.Command
Set conn = New ADODB.Connection
' Zestawienie połączenia z bazą danych
With conn
.Provider = SQLOLEDB
.ConnectionString = "data source=(local);" & _
"user id=sa;initial catalog=NorthWindCS"
.Open
End With
' Utworzenie i inicjalizacja obiektu Connection
Set cmd = New ADODB.Command
With cmd
.ActiveConnection = conn
.CommandText = "byroyality"
.CommandType = adCmdStoredProc
' Utworzenie informacji parametrów
' używamy metody CreateParameter obiektu
' command, aby uprościć program
.Parameters.Append .CreateParameter("@Percentage", _
adInteger, adParamInput, , 50)
End With
' Otwarcie wyniku wykonania procedury
Dim rst As ADODB.Recordset
Set rst = cmd.Execute
' Odczytanie wszystkich rekordów wyniku
Do Until rst.EOF
Debug.Print rst!au_id
rst.MoveNext
Loop
' Zakończenie
rst.Close
conn.Close
Set rst = Nothing
Set conn = Nothing
Set cmd = Nothing
End Sub
Użycie Refresh
Użycie metody Refresh XE "Refresh:metoda" 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ś 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.
Wydruk 16.10. Użycie metody Refresh obiektu Command
Sub ExecuteCommandwithParmRefresh()
' Wykonanie procedury przechowywanej bez tworzenia
' obiektów Parameter. Pomocne przy procedurach
' z dużą ilością parametrów
Dim conn As ADODB.Connection
Dim cmd As ADODB.Command
Set conn = New ADODB.Connection
' Zestawienie połączenia z bazą danych
With conn
.Provider = SQLOLEDB
.ConnectionString = "data source=(local);" & _
"user id=sa;initial catalog=NorthWindCS"
.Open
End With
' Utworzenie i inicjalizacja obiektu Connection
Set cmd = New ADODB.Command
With cmd
.ActiveConnection = conn
.CommandText = "byroyality"
.CommandType = adCmdStoredProc
' W tym przykładzie używamy metody Refresh,
' która pobiera parametry z serwera.
' Po jej wykonaniu wypełniamy parametry
' i wykonujemy procedurę. Unikamy tworzenia
' i dołączania parametrów
.Parameters.Refresh
.Parameters("@Percentage").Value = 50
End With
' Otwarcie wyniku wykonania procedury
Dim rst As ADODB.Recordset
Set rst = cmd.Execute
' Odczytanie wszystkich rekordów wyniku
Do Until rst.EOF
Debug.Print rst!au_id
rst.MoveNext
Loop
' Zakończenie
rst.Close
conn.Close
Set rst = Nothing
Set conn = Nothing
Set cmd = Nothing
End Sub
Obsługa zwracanych wartości
Czasami procedura przechowywana zwraca wartość, która świadczy o prawidłowym lub nieprawidłowym wykonaniu procedury. Może ona również zwrócić wartość identyfikatora nowo dodanego rekordu. W każdym wypadku będziesz chciał znać wartość zwracaną. ADO pozwala na pobranie wartości zwracanych poprzez odczytanie zbioru parametrów po wykonaniu polecenia. Na wydruku 16.11 przedstawiony jest program, który wykonuje bardzo prostą procedurę przechowywaną, zwracającą po prostu wartość 55. Procedura wygląda następująco:
CREATE PROCEDURE sp_CmdWithParm AS
/* Wartość zwracana */
Return 55
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
Wydruk 16.11. Pobieranie wartości zwracanej
Sub CommandReturnValues()
' Procedura uruchamia procedurę przechowywaną
' i odczytuje zwracaną wartość
' Treść procedury przechowywanej:
' CREATE PROCEDURE sp_CmdWithParm AS
' /*Wartość zwracana*/
' Return 55
Dim conn As ADODB.Connection
Dim cmd As ADODB.Command
Set conn = New ADODB.Connection
Set cmd = New ADODB.Command
' Zestawienie połączenia z bazą danych
With conn
.Provider = SQLOLEDB
.ConnectionString = "data source=(local);" & _
"user id=sa;initial catalog=NorthWindCS"
.Open
End With
' Utworzenie i inicjalizacja obiektu command
With cmd
.ActiveConnection = conn
.CommandText = "sp_CmdWithParm"
.CommandType = adCmdStoredProc
.Parameters.Refresh
End With
cmd.Execute
MsgBox "Wartość zwracana: " & cmd.Parameters(0).Value
conn.Close
Set conn = Nothing
End Sub
Wykonanie procedury bez obiektu Command
Procedury z parametrami, które zwracają wiersze tabeli, można uruchomić bez używania obiektu Command. Aby to wykonać, należy utworzyć wyrażenie SQL i użyć metody open obiektu Recordset.
rst.open 'exec sp_SimpleProc @OrderID=1', conn
Użycie klasy Connection
Gdy Twoja aplikacja coraz bardziej zależy od napisanego kodu, powinieneś zacząć przyzwyczajać się do pisania kodu ogólnego i nadającego się do powtórnego użycia. W tej książce postaram się pokazać Ci możliwie dużo przykładów programowania klas. Tworzenie obiektu klasy Connection XE "Connection:klasa" jest jednym z najważniejszych przykładów, które chciałbym Ci pokazać. Jest to klasa do natychmiastowego użycia nie tylko w Accessie, ale także w każdym programie obsługującym VBA, włączając inne aplikacje Office 2000 oraz Visual Basic 5 i 6.
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”).
Wydruk 16.12. Prosta klasa Connection
Function Connect() As ADODB.Connection
' Komponent do wielokrotnego użycia. Tworzy połączenie
' z bazą danych. Możesz użyć tego komponentu, aby
' zcentralizować miejsce, gdzie są ustawiane informacje o
' bazie danych
Dim conn As ADODB.Connection
Set conn = New ADODB.Connection
' Informacje o połączeniu się z bazą
With conn
.Provider = "SQLOLEDB"
.ConnectionString = "data source=(local); user id=sa;" & _
"initial catalog=airline"
.Open
End With
Set Connect = conn
End Function
Użycie klasy Connection w aplikacji
Użycie klasy Connection w aplikacji jest proste. Gdziekolwiek chcesz podłączyć się do bazy danych, tworzysz obiekt DBConnection, aby utworzył dla Ciebie obiekt ADO Connection, jak widać to na wydruku 16.13. Pozwoli to na ukrycie specyficznego dla procesu połączenia kodu w ogólnej nadającej się do powtórnego wykorzystania klasie lub obiekcie COM do późniejszego wykorzystania.
Wydruk 16.13. Użycie klasy Connection
Sub UseConnect()
' Używa komponentu Connection, aby podłączyć się do bazy
Dim conn As ADODB.Connection
Dim oConnect As DBConnection
Set oConnect = New DBConnection
Set rst = oConnect.Connect
End Sub
Rozdział 17.
Interfejs Accessa 2000
do Oracle XE "Oracle" 'a
W tym rozdziale:
Dostęp do danych Oracle'a przez Accessa
Funkcje w Oracle'u i Accessie
Poznajemy widoki i procedury przechowywane
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ć.
Dostęp do danych Oracle'a przez Accessa
Istnieje kilka sposobów dostępu do danych Oracle'a przez Accessa. W tym rozdziale skupimy się na dwóch: podstawowych technikach ODBC bez programowania dla ODBC oraz programowaniu z użyciem ADO. W czasie powstawania aplikacji możesz korzystać z obu sposobów, jednak w gotowej aplikacji powinieneś używać tylko jednego.
Dwie podstawowe techniki dostępu do danych są stosowane na trzy sposoby:
Łączenie tabel (ODBC).
Kwerendy przekazujące (SPT) (ODBC).
Bezpośrednie połączenie poprzez ADO.
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.
Aby utworzyć połączenie z tabelą Oracle'a, musisz posiadać:
Zgodny z Oracle'em sterownik ODBC.
Połączenie sieciowe z bazą Oracle poprzez SQLNet lub Net8 (Oracle używa własnego protokołu sieciowego). Bez tych narzędzi nie będziesz w stanie połączyć się z bazą.
Sterownik ODBC w Accessie.
Poprzez ODBC możesz: połączyć się do bazy, pracować z tabelami, widokami i procedurami oraz wysyłać do wykonania wyrażenia SQL.
Tworzenie ciągu połączenia ODBC
Zarządca ODBC na komputerze klienta komunikuje się pomiędzy Twoim programem a odpowiednim dla Twojego źródła danych sterownikiem ODBC. Aby podłączyć się do bazy Oracle, powinieneś najpierw utworzyć odpowiedni ciąg połączenia ODBC. Ciąg ten składa się z części przedstawionych w tabeli 17.1.
Ciąg ODBC może wyglądać następująco:
ODBC;DSN=MSOracleDriver;UID=Scott;SERVER=empexample;;TABLE=SCOTT.DEPT
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 |
Tworzenia nazwy źródła danych
Aby przygotować ODBC do pracy z Accessem, powinieneś utworzyć nazwę źródła danych. Jest to bardzo prosta operacja. Poniższe punkty wskażą sposób utworzenia DSN dla Oracle'a.
Uruchom administrator ODBC z Panelu sterowania.
W programie administratora naciśnij przycisk Nowy, aby dodać źródło danych dla Oracle'a.
Wybierz Oracle ODBC Driver, Microsoft ODBC Driver dla Oracle'a lub inny sterownik ODBC dla Oracle'a. Naciśnij Zakończ. W tym miejscu będziesz zapytany o informacje w okienku podobnym do okna z rysunku 17.1. Wygląd tego okna zależy od wybranego sterownika i jego wersji.
Rysunek 17.1. Wpisywanie informacji o DSN |
|
Po utworzeniu DSN można rozpocząć dołączanie tabel Oracle'a do twojej aplikacji.
Koszt połączenia z Oracle'em
Tworzenie połączenia z bazą danych Oracle zajmuje dużo więcej czasu i zasobów niż połączenie z bazą Jet. W czasie programowania z użyciem ODBC, RDO, DAO, ODBC Direct lub ADO powinieneś spróbować trzymać cały czas otwarte połączenie do bazy
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 |
|
SELECT SCOTT_EMP.ENAME, SCOTT_DEPT.DNAME
FROM SCOTT_DEPT INNER JOIN SCOTT_EMP ON SCOTT_DEPT.DEPTNO=
SCOTT_EMP.DEPTNO
WITH OWNERACCESS OPTION;
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.
Kwerendy przekazujące XE "kwerenda przekazująca" (SPT XE "SPT" )
Poprzez użycie tego samego połączenia, którego używasz do łączenia tabel, otrzymujesz dostęp do serwera Oracle i przenosisz ciężar wykonania kwerendy na serwer - tam, gdzie powinna być wykonana. Oczywiście w SPT wszystkie źródła danych, do których odwołujesz się w kwerendzie, muszą znajdować się w bazie Oracle oraz wyrażenia SQL muszą być zapisane w dialekcie Oracle, jednak są to małe problemy, jeżeli skonfrontuje się je ze skróconym czasem odpowiedzi oraz zmniejszonym ruchem w sieci. W kwerendach SPT jedyną informacją, jaką przesyłasz poprzez sieć, jest wyrażenie SQL, a jedyną jaką otrzymujesz jest wynik.
Aby utworzyć SPT, wykonaj następujące czynności:
Utwórz nową kwerendę.
Z menu Kwerenda wybierz Tylko SQL.
Wybierz Przekazująca.
W widoku SQL edytora kwerend (dostępny tylko tryb projektowania) wybierz Widok i Właściwości.
Wpisz ciąg połączeniowy ODBC do właściwości Ciąg połączenia ODBC.
Ciąg ODBC powinien wyglądać podobnie do takiego:
ODBC;DSN=EmpExample;UID=SCOTT;PWD=tiger;DBQ=empexample;
|
||
|
Możesz skopiować ciąg z tabeli połączonej. |
Wpisz wyrażenie SQL.
Przykładowe wyrażenie SQL wygląda następująco:
Select * from emp
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.
Niektóre sytuacje gdzie mogą być użyte SPT to:
Wykonanie wyrażeń SQL zmieniających strukturę bazy.
Uzyskanie wybranych wierszy i kolumn z tabel Oracle'a.
Sprawdzenie ilości wierszy zmienionych wyrażeniem Update.
Dostarczenie źródła rekordów dla prostego formularza związanego pokazującego małą ilość rekordów.
Utworzenie, zmiana i wykonanie widoków i procedur przechowywanych w Oracle'u.
Powinieneś zawsze sprawdzić, czy zastosowanie kwerend SPT ulepszy Twoją aplikację.
Określanie właściwości kwerend przekazujących
Gdy tworzysz kwerendę przekazującą, musisz ustawić właściwość kwerendy, która określa, czy zwraca ona rekordy, czy nie. Kwerendy, które wstawiają, zmieniają lub kasują rekordy, nie zwracają rekordów, natomiast kwerendy typu Select zwykle to robią. Jeżeli nie ustawisz odpowiednio tej właściwości, dostaniesz komunikat błędu.
Składnia kwerend przekazujących
Musisz pisać wyrażenia SQL zgodnie ze składnią Oracle'a, która różni się znacznie od składni generowanej przez tabelkę QBE. Access 2000 obsługuje dialekt SQL, który najbardziej odpowiada standardowi ANSI-92, lecz jeżeli używałeś SQL Accessa począwszy od wersji 1.1, przegląd różnic pomoże Ci efektywnie używać bazy Oracle.
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
Tylko pierwsze z dwóch poniższych wyrażeń zwróci prawidłową wartość:
Select ename, job from EMP where JOB='MANAGER'
Select ename, job from EMP where JOB='manager'
Wyrażenie Select XE "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 XE "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 XE "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)
Użycie znaków specjalnych
Access używa * i ? jako znaków specjalnych XE "znaki specjalne" . Gwiazdka (*) zastępuje dowolną ilość znaków w tekście, natomiast znak zapytania - jeden znak. W Oracle'u istnieją te same możliwości, ale używamy znaku % zamiast *, a _ zastępuje jeden znak. Znaki te mogą być używane w następujący sposób:
Select * from emp where ename like 'M%'
Select * from emp where ename like 'J__S'
Użycie Null XE "Null" i Not Null XE "Not Null"
W Oracle'u testowanie wartości null odbywa się identycznie jak w Accessie.
SELECT * FROM emp WHERE comm IS NULL
SELECT * FROM emp WHERE comm IS NOT NULL
Tworzenie wyrażeń Insert XE "Insert"
W Accessie kwerenda wstawiająca nowe wartości do tabeli generuje wyrażenie SQL, które wygląda następująco:
INSERT INTO SCOTT_EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, DEPTNO)
SELECT '9999' AS Expr1, 'JP' AS Expr2, 'SALESMAN' AS Expr3, _
7698 AS Expr4, #7/27/1997# AS Expr5, 2380 AS Expr6, 10 AS Expr7;
Jednak Access dopuszcza klauzulę Values tak samo jak Oracle (patrz poniżej), ale musisz ją wpisać samemu.
W Oracle'u możesz uprościć to wyrażenie:
INSERT INTO SCOTT_EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, _
COMM, DEPTNO)
VALUES ('9999', 'JP', 'SALESMAN', 7698, _
TO_DATE('7/27/1997', 'MM/DD/YYYY'), 2380, 0, 10)
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.
Tworzenie wyrażeń Update XE "Update"
Implementacja wyrażenia Update w SQL Oracle nie różni się wiele od tej z Accessa. Poniżej przedstawione jest wyrażenie SQL, wygenerowane przez QBE Accessa, skojarzone z tabelą połączoną.
UPDATE SCOTT_EMP
SET SCOTT_EMP.SAL = [7000]
WHERE ((([SCOTT_EMP].[EMPNO])=9999));
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
Użycie Group By XE "Group By" /Having XE "Having"
QBE Accessa samo troszczy się o prawidłową składnię, gdy tworzysz kwerendę grupującą. W Oracle'u musisz sam się tym zająć zająć. Tak jak w Accessie, Group By grupuje dane w wymienionych kolumnach. Wszystkie inne kolumny muszą być przeglądane poprzez funkcje agregujące (np.: Sum XE "Sum:funkcja agregująca" (), Avg XE "Avg:funkcja agregująca" () i inne).
SELECT deptno, count(*)
FROM emp
WHERE deptno<>10
GROUP BY deptno
HAVING count(*)<6
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.
Funkcje w Oracle'u i Accessie
W Accessie, przed wykonaniem kwerendy jest ona przeszukiwana pod kątem występowania funkcji zarówno VBA, jak i utworzonych przez Ciebie. Analizator wyrażeń (ang. Jet Expression Service) dopuszcza stosowanie dowolnych funkcji w wyrażeniach SQL. Nie możesz jednak stosować funkcji VBA oraz napisanych przez siebie, gdy używasz kwerend SPT. Powód jest prosty, SPT nie używa w ogóle silnika Jet. Oracle odbiera SQL jako ciąg znaków i musi on być zrozumiały dla Oracle'a. Mimo że jest możliwe utworzenie w Oracle'u podobnego zestawu funkcji jak w Accessie, wykracza to jednak poza ramy tego rozdziału.
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.
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
Initcap XE "Initcap" , Lower XE "Lower" , Upper XE "Upper"
Funkcja Initcap(string) zmienia na wileką pierwszą literę każdego wyrazu ciągu.
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
james
ford
miller
Instr
Instr XE "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.
Instr ma cztery parametry:
String - wymagany. Ciąg znaków lub odwołanie do ciągu, który chcesz przeszukać.
Set - wymagany. Znak lub ciąg znaków, które chcesz znaleźć.
Start - nieobowiązkowy. Pozycja, na której powinno się rozpocząć szukanie. Domyślnie jest to pierwsza pozycja.
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 XE "LTrim" (), aby usunąć znaki z lewej strony, Rtrim XE "Rtrim" , aby usunąć znaki z prawej strony oraz Trim XE "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.
Funkcje obcinające mają dwa argumenty:
String - wymagany. Ciąg lub odwołanie do ciągu, na którym chcesz wykonać operacje.
Set - nieobowiązkowy. Znaki, które chcesz usunąć.
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 XE "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')
powinno zwrócić nazwiska takie jak:
Mailer
Miller
Molar
Moller
Muler
Mulronsky
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 XE "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:
String - ciąg lub odwołanie do ciągu
Start - podana jawnie lub obliczona pozycja początku podciągu
End - podana jawnie lub obliczona wartość reprezentująca ilość znaków po prawej stronie pozycji Start
W sytuacjach, kiedy nazwisko klienta występuje w postaci:
MacIntyre, Alastair
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 XE "Decode"
Wielu programistów Accessa przyzwyczaiło się opierać na natychmiastowym porównaniu (IIf XE "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)
Ilość konstrukcji if/then jest prawie nieograniczona.
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 XE "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 XE "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
Nvl()
Funkcja Nvl XE "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ń.
Posiada ona dwa parametry:
Value - wymagana. Wartość lub odwołanie do wartości.
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 XE "Round" (). W Accessie 2000 użytkownicy nareszcie mogą z niej skorzystać. Funkcja ma dwa parametry:
Value - wymagana. Wartość lub odwołanie do wartości do przetworzenia.
Precision - nieobowiązkowa. Ilość miejsc po przecinku, do ilu będzie zaokrąglana liczba. Domyślnie przyjmowane jest zero.
Sign()
Sign XE "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 XE "Trunc" () po prostu obcina liczbę do żądanej długości. Funkcja posiada dwa parametry:
Value - wymagana. Wartość lub odwołanie do wartości do przetworzenia.
Precision - nieobowiązkowa. Ilość miejsc po przecinku, do ilu będzie obcięta liczba. Domyślnie przyjmowane jest zero.
Greatest/Least
Greatest XE "Greatest" i Least XE "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
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 XE "Sysdate" () sięga do systemu operacyjnego i zwraca bieżącą datę i czas.
Select SYSDATE FROM sys.Dual
Wyrażenie to zwróci datę systemową, używając systemowej tabeli testowej.
Add_Months
Jeżeli pierwsza ocena pracownika powinna być po 6 miesiącach pracy, możesz użyć funkcji Add_Months XE "Add_Months" , aby zaplanować ocenę.
Add_Months posiada dwa parametry:
Date - wymagana. Data lub odwołanie do prawidłowej daty.
Count - wymagana. Ilość miesięcy, jaką należy dodać do Date.
Poniższe wyrażenie SQL przedstawia datę pierwszej oceny pracownika.
SELECT ename, hiredate, add_months(hiredate, 6) FROM emp
SELECT ENAME, LEAST(HIREDATE, TO_DATE('1-JAN-85')) FROM EMP
ENAME HIREDATE ADD_MONTH
---------- --------- ---------
JP 27-JUL-97 27-JAN-98
ALLEN 20-FEB-81 20-AUG-81
WARD 22-FEB-81 22-AUG-81
JONES 02-APR-81 02-OCT-81
MARTIN 28-SEP-81 28-MAR-82
BLAKE 01-MAY-81 01-NOV-81
CLARK 09-JUN-81 09-DEC-81
SCOTT 19-APR-87 19-OCT-87
KING 17-NOV-81 17-MAY-82
TURNER 08-SEP-81 08-MAR-82
ADAMS 23-MAY-87 23-NOV-87
JAMES 03-DEC-81 03-JUN-82
FORD 03-DEC-81 03-JUN-82
MILLER 23-JAN-82 23-JUL-82
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 XE "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
MARTIN 28-SEP-81 17.39
BLAKE 01-MAY-81 17.8
CLARK 09-JUN-81 17.69
SCOTT 19-APR-87 11.83
KING 17-NOV-81 17.25
TURNER 08-SEP-81 17.44
ADAMS 23-MAY-87 11.74
JAMES 03-DEC-81 17.21
FORD 03-DEC-81 17.21
MILLER 23-JAN-82 17.07
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 XE "Next_Day" () może pomóc w takich obliczeniach.
Next_Day() posiada dwa parametry:
Date - data lub odwołanie do prawidłowej daty
Day - angielska nazwa dnia tygodnia ('Sunday', 'Monday', itd.)
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 XE "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.
To_Date posiada dwa parametry:
String - wymagany. Ciąg reprezentujący datę (np.: 'July 27, 1997'). Domyślnym formatem daty jest „DD-MON-YYYY”.
Format - nieobowiązkowy.
SELECT TO_DATE('27-jul-97', 'dd-mon-yyyy') "Data sformatowana" FROM sys.dual
Data sformatowana
-----------
27-JUL-1997
Problem roku 2000 XE "Problem roku 2000"
Oracle nie przetwarza dat w sposób, w jaki robi to Access.
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
SELECT MONTHS_BETWEEN('27-JUL-01', '27-JUL-97') FROM SYS.DUAL
MONTHS_BETWEEN('27-JUL-01', '27-JUL-97')
----------------------------------------
-1152
Podczas tworzenia aplikacji musisz brać to pod uwagę.
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 XE "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.
Spójrzmy na proste wyrażenie SQL zapisane zgodnie ze składnią Oracle'a.
Select * from emp where sal>3000
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 XE "Create" , Alter XE "Alter" , Drop XE "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:
Create or Replace View MyView As Select * from emp where sal>3000
Klauzula Or Replace XE "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
Połączenie z Oracle'em poprzez ADO
Tworzenie kwerend SPT jest świetną metodą komunikacji z Oracle'em, ponieważ przerzucają ciężar pracy na serwer zamiast na Jet, który nie jest uruchamiany. Możesz skorzystać z wszystkich zalet kwerend SPT, łącząc się z Oracle'em poprzez ADO. Podejście to pozwala efektywnie kontrolować poprawność danych, dynamicznie tworzyć wyrażenia SQL i wykonywać procedury przechowywane.
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 XE "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.
Wydruk 17.1. Tworzenie widoku w Oracle'u z Accessa
Function Create0racleView() As Boolean
Dim conn As New ADODB.Connection
Dim cmd As New ADODB.Command
On Error GoTo Create0racleView Err
With conn
.Provider = "MSDAORA"
.ConnectionString = "Data Source=empexample;
User ID=Scott;password=Tiger"
.Open
End With
cmd.ActiveConnection = conn
cmd.CommandType = adCmdText
' Wyrażenie SQL Create or Replace oszczędza nam obsługi błędów
cmd.CommandText = "Create or Replace View MyView As _
Select * firom emp where SAL>2000"
cmd.Execute
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.
Program na wydruku 17.2 przedstawia, w jaki sposób można to wykonać.
Wydruk 17.2. Użycie parametrów Oracle'a z VBA Accessa
Function OracleParams(SalAmnt As Long) As Boolean
Dim conn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim rsfield as New Field
Dim cmd As New ADODB.Command
' Tworzenie połączenia
With conn
.Provider = "MSDAORA"
.ConnectionString = "Data Source=empexample;
User ID=Scott;password=Tiger"
.Open
End With
' Użyjemy kursorów po stronie serwera
With rs
.CursorLocation = adUseServer
End With
' Tworzenie obiektu polecenia
With cmd
cmd.ActiveConnection = conn
' Ustawienie CommandType, aby akceptował wyrażenia SQL
cmd.CommandType = adCmdText
' Ustawienie tekstu polecenia
cmd.CommandText = "Select * from emp where sal > ?"
' Tworzenie parametru i dołączenie go do zbioru
' parametrów polecenia
cmd.Parameters.Append
cmd.CreateParameter("SAL", adNumeric, adParamInput)
' Przypisanie wartości SalAmnt do pierwszego parametru
cmd(0) = SalAmnt
End With
' Wykonaj polecenie i przypisz wynik do obiektu ADO Recordset
Set rs = cmd.Execute
If conn.Errors.Count = 0 Then
OraclParams = True
End If
rs.MoveFirst
While Not rs.EOF
strfield = ""
For Each rsfield In rs.Fields
strfield = strfield & " " & rsfield
Next
Debug.Print strfield & Chr(9)
rs.MoveNext
Wend
End Function
Tworzenie procedur przechowywanych
Procedura przechowywana XE "procedura przechowywana" w Oracle'u jest podobna do modułu w Accessie. Wykonuje zbiór poleceń na serwerze.
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.
Poniżej utworzymy i uruchomimy prostą procedurę przechowywaną.
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 dzieli się na następujące części:
Deklaracja parametrów.
Rozpoczęcie przetwarzania.
Zatwierdzenie zmian.
Obsługa wyjątków.
Odwołanie zmian.
Obsługa błędów.
Procedura wstawiająca rekord do tabeli z dwoma polami przedstawiona jest na wydruku 17.3.
Wydruk 17.3. Procedura Oracle'a dodająca nowy rekord
(Ename CHAR, EJob CHAR) IS
BEGIN
INSERT INTO SCOTT.TESTTABLE
VALUES(Ename, EJob);
COMMIT;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
RAISE;
END;
W tym przypadku procedura posiada dwa parametry, nazwisko i nazwę stanowiska.
Access może utworzyć procedurę poprzez kwerendę SPT w następujący sposób:
CREATE OR REPLACE PROCEDURE MyStoredProcedure
(Ename CHAR, EJob CHAR) IS
BEGIN
INSERT INTO SCOTT.TESTTABLE
VALUES(Ename, EJob);
COMMIT;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
RAISE;
END;
Po utworzeniu procedury może być ona wywoływana poprzez kwerendę SPT lub VBA.
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.
Wydruk 17.4. Wykonanie procedury przechowywanej z parametrami za pomocą VBA w Accessie
Function RunOracleStoredProcedures(ProcName As String, _
DestTable as String, ParamArray ParamArgs() As Variant) As Boolean
Dim conn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim i As Integer
Dim cmd As New ADODB.Command
Dim rsfield As Field
Dim strfield As String
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
' A teraz wyświetlamy wynik w oknie uruchamiania
' Nie będziesz potrzebował tego fragmentu kodu
' w swoich aplikacjach
rs.Open "Select * from " & destTable, conn,_
adOpenForwardOnly, adLockReadOnly
rs.MoveFirst
While Not rs.EOF
strfield = ""
For Each rsfield In rs.Fields
strfield = strfield & " " & rsfield
Next
Debug.Print strfield & Chr(9)
rs.MoveNext
Wend
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.
Tworzenie niezwiązanego interfejsu do Oracle'a
Mając na uwadze ograniczenia wydajności i duże obciążenie sieci, gdy używamy tabel połączonych, powinniśmy rozważyć użycie niezwiązanego interfejsu użytkownika wszędzie tam, gdzie jest to możliwe. Utworzenie niezwiązanego interfejsu pomaga zastosować w Twojej aplikacji architekturę wielowarstwową, co zwiększa jej skalowalność i ułatwia jej konserwację. Umożliwi także łatwe łączenie różnych narzędzi programowania. Możesz użyć ADO, ADOX, DAO, RDO i inne narzędzia tam, gdzie uważasz, że przyniosą korzyści. Niezwiązany interfejs ułatwia migrację do innego środowiska, 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.
Tworzenie niezwiązanego interfejsu
Na początek utwórz formularz taki, jak na rysunku 17.3.
Rysunek 17.3. Formularz z danymi w trybie projektowania |
|
Dla uproszczenia, nazwy obiektów ekranowych odpowiadają nazwom pól w tabeli EMP:
Empno,
Ename,
Job,
Mgr,
Hiredate,
Sal,
Comm,
Deptno.
Przyciski nawigacyjne i manipulacyjne będą nazywały się następująco:
BtnGotoFirst,
BtnGotoPrevious,
BtnGotoNext,
BtnGotoLast,
BtnEdit,
BtnNew,
BtnDelete,
BtnSave,
BtnClose.
Tworzenie zmiennych globalnych
Podstawowe operacje można zrobić na kilka sposobów. Dla uproszczenia przyjmijmy, że obiekty Connection i Recordset oraz zmienna, która informuje o zmianie danych, będą przechowywane przez trzy zmienne globalne przechowywane w głównym module:
Global conn As ADODB.Connection
Global rs As ADODB.Recordset
Global EditRec As Boolean
Ładowanie danych i inicjalizacja formularza
Program przedstawiony na wydruku 17.5 wykonany zostanie jako obsługa komunikatu OnOpen. Procedura ta załaduje dane i zainicjuje aplikację.
Wydruk 17.5. Utworzenie i otwarcie połączenia z Oracle'em oraz wypełnienie formularza
Private Sub Form Open(Cancel As Integer)
Set conn = New ADODB.Connection
Set rs = New ADODB.Recordset
With conn
.Provider = "MSDAORA"
.ConnectionString = "Data Svurce-ernpexample;_
User ID=Scott;password=Tiger"
.Open
End With
rs.CursorLocation = adUseClient
rs.Open "Select * from emp", conn, adOpenStatic,_
adLockOptimistic, adAsyncFetch
FillForm
EditRec = True
End Sub
Oracle nie zwraca obiektów typu Recordset XE "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.
Wydruk 17.6. Wypełnianie formularza danymi
Function FillForm() As Boolean
On Error GoTo FillForm Err
[Empno] = rs(0)
[ENAME] = rs(1)
[Job] = rs(2)
[MGR] = rs(3)
[HIREDATE] = rs(4)
[SAL] = rs(5)
[COMM] = rs(6)
[DEPTNO] = rs(7)
FillForm = True
FillForm_Exit:
Exit Function
FillForm_Err:
FillForm = False
Exit Function
End Function
Programowanie przycisków sterujących
Aby przeglądać cały wynik zapytania, należy oprogramować przyciski sterujące, tak jak jest to pokazane na wydrukach od 17.7 do 17.10.
Wydruk 17.7. Przejście do pierwszego rekordu
Private Sub btnGotoFirst_Click()
On Error Resume Next
rs.MoveFirst
If Not rs.BOF Then
FillForm
End If
CurrentContext Me
End Sub
Wydruk 17.8. Przejście do poprzedniego rekordu
Private Sub btnGotoPrevious_Click()
On Error Resume Next
rs.MovePrevious
If Not rs.BOF Then
FillForm
End If
CurrentContext Me
End Sub
Wydruk 17.9. Przejście do następnego rekordu
Private Sub btnGotoNext_Click()
On Error Resume Next
rs.MoveNext
If Not rs.BOF Then
FillForm
End If
CurrentContext Me
End Sub
Wydruk 17.10. Przejście do ostatniego rekordu
Private Sub btnGotoLast_Click()
On Error Resume Next
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).
Wydruk 17.11. Włączanie i wyłączanie przycisków nawigacyjnych
Sub CurrentContext(frm As Form)
Dim bFirstRec As Boolean
Dim bLastRec As Boolean
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
!btnGotoLast.Enabled = Not bLastRec
!btnGotoNext.Enabled = Not bLastRec
GoTo CurrentContext_Exit
End If
End With
End Sub
Zmiana danych Oracle'a przy użyciu formularza
Do tej pory możesz tylko oglądać dane, ale zmiany, jakie wprowadziłeś, nie zostaną zapisane w bazie. Funkcja z wydruku 17.12 wywołuje metodę Update XE "Update:metoda" obiektu OLEDB Recordset, aby wysłać zmiany do Oracle'a zaraz po tym, jak zmieniłeś dane. Daje to możliwości takie same jak możliwości formularza związanego. Funkcja pokazana na wydruku 17.12 musi być wywołana jako odpowiedź na zdarzenie AfterUpdate XE "AfterUpdate:zdarzenie" dla każdego pola tekstowego.
Wydruk 17.12. Funkcja UpdateField
Function UpdateField(FieldName As Variant, NewValue As Variant)_
As Boolean
If EditRec = False Or IsEmpty(EditRec) Then Exit Function
Dim rsOrigSource As String
Dim errDesc As String
Dim i As Integer
On Error GoTo UpdateField Err
' Zachowaj początkowe źródło recordset-u na wypadek błędu
rsOrigSource = rs.Source
' Próba zmiany pola przy użyciu metody update obiektu Recordset
rs.Update FieldName, NewValue
' Udało się
UpdateField = True
UpdateField_Exit:
Exit Function
UpdateField_Err:
' Błąd
UpdateField = False
' Sprawdź, jaki wystąpił błąd, 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
' Informacja dla użytkownika
MsgBox "Wystąpił błąd: " & errDesc
' Musisz odwołać metodę Update metodą CancelUpdate
' gdyż nie będziesz mógł wykonać żadnej operacji na wyniku
rs.CancelUpdate
' Zamknięcie istniejącego wyniku
rs.Close
' Otwórz Recordset z zachowanym źródłem, przywracając
' mu stan początkowy
rs.Open rsOrigSource, conn, adOpenStatic, adLockOptimistic, _
adAsyncFetch
' Wywołaj FillForm
Forms![forml].FillForm
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.
Wydruk 17.13. Wyrażenie zapisujące zmiany po edycji zawartości pola
=UpdateField(screen.activecontrol.[Name],screen.activecontrol)
Teraz, gdy przechodzisz między rekordami i zmieniasz dane pracowników, zmiany zapisane będą w bazie po przejściu do innego rekordu.
Wstawienie danych do Oracle'a przy użyciu formularza
Aby dodać nowy rekord, powinieneś wyczyścić wszystkie pola na formularzu i ustawić zmienną EditRec na false. Kod programu z wydruku 17.14 powinien być wprowadzony jako obsługa zdarzenia OnClick przycisku btnNew.
Wydruk 17.14. Przygotowanie formularza do wpisania nowego rekordu
Private Sub btnNew Click()
ClearForm
EditRec = False
End Sub
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).
Wydruk 17.15. Czyszczenie formularza
Sub ClearForm()
Me![Empno] = ""
Me![ENAME] = ""
Me![Job] = ""
Me!(MGR] = ""
Me![HIREDATE] = ""
Me![SAL] = ""
Me![COMM] = ""
Me![DEPTNO] = ""
End Sub
Zapisywanie danych do Oracle'a przy użyciu formularza
Gdy trzeba zapisać rekord, możesz wywołać poniższą procedurę za pomocą zdarzenia OnClick przycisku btnSave. Sprawdzając stan zmiennej EditRec, wiemy, czy wprowadzasz nowy rekord i tworzymy odpowiednie wyrażenie SQL. Zostanie ono wykonane poprzez obiekt Command. Technika ta pokazana jest na wydruku 17.16, jest standardowa dla Oracle'a.
Wydruk 17.16. Zapis do Oracle'a poprzez SQL i ADO
Private Sub btnSave Click()
Dim cmd As New ADODB.Command
Dim strCmdtxt as string
' Jeżeli wstawiamy nowy rekord
If EditRec = False Then
' Po upewnieniu się, że obiekt Command jest prawidłowo ustawiony
' utworzymy i wykonamy wyrażenie SQL Insert
With cmd
.ActiveConnection = conn
.CommandType = adOmdText
with Me
strOmdtxt = strOmdtxt & "insert into emp values ("
strCmdtxt = strCmdtxt & "'![Empno] ',"
strOmdtxt = strCmdtxt & "'![ENAME] ',"
strCmdtxt = strCmdtxt & "'![Job] ',"
strCmdtxt = strCmdtxt & "'![MGR] ',"
strCmdtxt = strCmdtxt & "' to date('" &![HIREDATE] &
"','MM/DD/YY') ',"
strCmdtxt = strCmdtxt & "'![SAL] ',"
strCmdtxt = strCmdtxt & "'![COMM] ',"
end with
.Execute
End With
End If
' Zamknij, ustaw i otwórz jeszcze raz Recordset
With rs
.Close
.CursorLocation = adUseClient
.Open "Select * from emp", conn, adOpenStatic, adLockOptimistic,
adAsyncFetch
End With
' Wypełnij formularz
FillForm
' Zmień tryb aplikacji na edycję danych
EditRec = True
End Sub
Usuwanie danych przy użyciu formularza
To samo podejście zastosowane jest przy usuwaniu danych. Procedura na wydruku 17.17 usuwa bieżący rekord z Oracle'a, gdy wykonamy ją jako obsługę zdarzenia OnClick przycisku btnDelete.
Wydruk 17.17. Usunięcie bieżącego rekordu
Private Sub btnDelete Click()
Dim cmd As New ADODB.Command
' Jeżeli zmieniamy rekord
If EditRec = True Then
' Po upewnieniu się, że obiekt command jest prawidłowo ustawiony
' utworzymy i wykonamy wyrażenie SQL Delete
With cmd
.ActiveConnection = conn
.CommandType = adCmdText
.CommandText = "Delete from emp where empno= " & Me![Empno]
.Execute
End With
End If
' Zamknij, ustaw i otwórz jeszcze raz Recordset
With rs
.Close
.CursorLocation = adUseClient
.Open "Select * from emp", conn, adOpenStatic, adLockOptimistic,
adAsyncFetch
End With
' Wypełnij formularz
FillForm
End Sub
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.
Wydruk 17.18. Wypełnienie pól formularza danymi i sprawdzenie bieżącego kontekstu
Private Sub Form Current()
On Error Resume Next
Dim bFirstRec As Boolean
Dim bLastRec As Boolean
If Not rs.BOF Then
With Me
![Empno] = rs(0)
![ENAME] = rs(1)
![Job] = rs(2)
![MGR] = rs(3)
![HIREDATE] = rs(4)
![SAL] = rs(5)
![COMM] = rs(6)
![DEPTNO] = rs(7)
End With
End If
Current0ontext Me
End Sub
Zamykanie połączenia z Oracle'em
Gdy zamykamy formularz, należy zakończyć połączenie z Oracle'em i ustawić obiekty Connection i Recordset na wartość nothing, ponieważ może zechcesz użyć tych obiektów w innych aplikacjach. Funkcja przedstawiona na wydruku 17.19 pomoże przeprowadzić prace porządkowe.
Wydruk 17.19. Porządki podczas zamykania formatki
Private Sub btnClose_Click()
On Error GoTo Err_btnClose_Click_Err
DoCmd.Close
Exit_btnClose_Click_Exit:
conn.Close
Set conn = Nothing
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życie automatyzacji ActiveX.
Integracja z Office 2000.
Użycie Visual Basic z Accessem.
Rozdział 18.
Użycie automatyzacji ActiveX
W tym rozdziale:
Co to jest automatyzacja ActiveX.
Dlaczego używamy automatyzacji.
Odróżnienie serwera automatyzacji od klienta automatyzacji.
Określanie zasobów wymaganych przez automatyzację.
Wielka trójka.
Tworzenie i ustanowienie odwołania do innej aplikacji.
Przypisywanie zmiennej obiektowej do aplikacji.
Tworzenie egzemplarza aplikacji.
Użycie metod i właściwości obiektów automatyzacji.
Zwalnianie obiektu automatyzacji.
Łączymy wszystko razem.
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.
Co to jest automatyzacja XE "automatyzacja" ActiveX
Technologia ActiveX jest bazowana na Component Object Model XE "Component Object Model" (COM) firmy Microsoft. Automatyzacja ActiveX pozwala na współpracę programów ze sobą. Automatyzacja pozwala jednemu programowi na dostęp i manipulowanie obiektami innego programu. Przykładem użycia automatyzacji jest drukowanie listów i raportów w Wordzie z Accessa.
Dlaczego używamy automatyzacji
Użycie automatyzacji jest efektywną metodą tworzenia i rozbudowy aplikacji. Automatyzacja może radykalnie skrócić czas tworzenia aplikacji, ponieważ zamiast tworzyć i testować opcję od podstaw, możemy ją sobie „pożyczyć” z innej aplikacji.
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.
Różnice między serwerem automatyzacji
a klientem automatyzacji
Gdy dwie aplikacje współpracują ze sobą, ważne jest, aby ustalić, która z nich udostępnia swoje obiekty, a która ich używa. Serwer automatyzacji XE "serwer automatyzacji" jest aplikacją, która udostępnia obiekty klasy Automation. Klient automatyzacji XE "klient automatyzacji" (nazywany czasami kontrolerem automatyzacji) to aplikacja, która decyduje, które obiekty będą używane i w jaki sposób.
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:
Pobranie obiektu Automation XE "Automation:obiekt" . Utworzenie nowego albo odwołanie się do już istniejącego.
Użycie obiektu Automation w aplikacji.
Zwolnienie obiektu Automation.
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.
Tworzenie i ustanowienie odwołania do innej aplikacji
Aby użyć jakiejś aplikacji, niezbędne jest ustanowienie odwołania do tej aplikacji, poprzez utworzenie zmiennej obiektowej i przypisanie jej egzemplarza aplikacji.
Ustanawianie odwołania do innej aplikacji
Za pomocą automatyzacji używasz i sterujesz pracą innych aplikacji spoza Accessa. Ilekroć używa się komponentu lub aplikacji spoza Accessa, musisz ustanowić odwołanie do tej aplikacji. Aby to zrobić, otwórz edytor Visual Basica i wybierz Tools, References. Na ekranie pojawi się okno dialogowe References, które zawiera listę bibliotek typów, programów, bibliotek DLL i kontrolek ActiveX (rysunek 18.1). Ustaw odwołanie do aplikacji, której chcesz użyć w swoim programie. Na przykład, aby odwołać się do Worda 2000, zaznacz pole wyboru obok Microsoft Word 9.0 Object Library.
|
||
|
Jeżeli nie możesz znaleźć potrzebnej Ci biblioteki na liście, naciśnij przycisk Browse i odszukaj ją na dysku. |
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ń |
|
Przegląd obiektów, właściwości i metod
Przed omówieniem sposobów użycia obiektów innej aplikacji przypomnijmy kilka podstawowych pojęć. Bardzo ważne jest, abyś rozumiał pojęcia: obiekt, właściwość i metoda. Bez tego nie ma sensu czytanie reszty tego rozdziału.
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.
Poznajemy strukturę obiektów
Gdy korzystamy z innej aplikacji, dobrze jest najpierw zapoznać się ze strukturą obiektów tej aplikacji. Łatwo wtedy sprawdzić, z których obiektów można skorzystać, aby wykonać określoną czynność. Model obiektów stanowi szablonową reprezentację struktury aplikacji. Jest to szybka i prosta metoda sprawdzenia, jakie obiekty są dostępne w programie. Modele różnych aplikacji można znaleźć w ich plikach pomocy. W rozdziale 19. przedstawię modele obiektów programów Microsoft Office.
Użycie narzędzia Object Browser
Inną metodą szybkiego odszukania obiektów dostępnych w aplikacji jest użycie narzędzia Object Browser XE "Object Browser" . Zaletami tego sposobu jest dostęp do właściwości, metod i zdarzeń oraz to, że obiekty te są połączone z ich plikami pomocy. Object Browser jest świetnym narzędziem do tego, aby szybko odszukać właściwy obiekt i poznać jego sposób działania.
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.
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.
|
||
|
Domyślnie elementy wyświetlane w panelach Classes i Members są uporządkowane alfabetycznie. Dobrze jest nacisnąć prawy klawisz myszki na panelach i wybrać Group Members. Spowoduje to pogrupowanie listy według typów elementów. Elementy w każdej grupie uporządkowane będą alfabetycznie. |
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ą.
Tworzenie zmiennej obiektowej
Zmienna jest fragmentem pamięci przeznaczonym do zapisywania i odczytywania informacji. Niewątpliwie masz już duże doświadczenie w stosowaniu prostych zmiennych, takich jak liczby lub ciągi znaków. Poniższy przykład przedstawia sposób deklaracji i użycia dwóch prostych zmiennych:
Dim strName as String
Dim I as integer
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 XE "zmienna obiektowa:tworzenie" deklaruje się instrukcją Dim, identycznie jak zmienne proste.
Dim objWord.application
Dim objExcel.application
|
||
|
Zawsze kwalifikuj wszystkie obiekty użyte w automatyzacji. Zamiast Dim objWord as Application używaj Dim objWord as Word.Application Kilka programów, do których się odwołujesz, może posiadać obiekt Application. Kwalifikacja nazwy obiektu zapewnia użycie właściwego obiektu i prawidłowe działanie programu |
Odwołanie do pracującej aplikacji
Po utworzeniu zmiennej obiektowej następnym krokiem jest odwołanie się do aplikacji, której chcesz użyć. Jednak pamiętaj, nie wiesz czy aplikacja ta jest uruchomiona czy nie. Jeżeli chcesz użyć Worda, użytkownik być może ma go już otwartego. W tym wypadku, możesz użyć do Twoich celów bieżącego egzemplarza Worda. W przeciwnym wypadku, gdy otworzysz kolejny egzemplarz Worda, błyskawicznie zużyjesz zasoby w komputerze.
Aby sprawdzić, czy jest uruchomiony program, użyj funkcji GetObject XE "GetObject" . Funkcja ta zwróci odwołanie do aktualnie uruchomionej aplikacji.
' Deklaracja zmiennej obiektowej objWord
Dim objWord as Word.Application
' Użycie funkcji GetObject do pobrania odwołania do
' aktualnie uruchomionej aplikacji
Set objWord = GetObject(, "Word.Application")
Przypisywanie zmiennej obiektowej
do aplikacji
Aby przypisać odwołanie do obiektu do zmiennej, używamy słowa kluczowego Set XE "Set" . Przykładowo:
Set objExcel = Excel.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ść”.
Tworzenie egzemplarza aplikacji
Jeżeli aplikacja nie pracuje lub chcesz utworzyć nowy egzemplarz obiektu XE "tworzenie obiektu" , użyj słowa kluczowego New XE "New" . Poniższy przykład tworzy nowy egzemplarz aplikacji Word.
' Deklaracja zmiennej objWord
Dim objWord As Word.Application
' Tworzenie nowego egzemplarza aplikacji Word
Set objWord = New Word.Application
|
||
|
Zawsze pisz wyrażenia Dim i Set w osobnych wierszach programu. Nie łącz ich razem w jednym wierszu w następujący sposób: Dim objWord = New Word.application Jeżeli użyjesz takiej deklaracji, program będzie wykonywał się wolniej, a Ty nie będziesz wiedział, kiedy zostanie utworzony obiekt. |
Jednoczesne użycie funkcji GetObject i New
Jeżeli aplikacja jest uruchomiona, użyj jej, nie otwieraj kolejnego egzemplarza. Jeżeli nie jest uruchomiona, uruchom ją. Aby zrealizować taki scenariusz, użyj funkcji GetObject, aby sprawdzić, czy aplikacja pracuje, i słowa kluczowego New, aby ją uruchomić w razie potrzeby.
' Jeżeli Word pracuje, użyj go. Jeżeli nie, uruchom go.
' Deklaracja zmiennej obiektowej objWord
Dim objWord As Word.Application
' Gdy Word nie jest uruchomiony, wystąpi błąd. Ignorujemy go.
On Error Resume Next
' Próba odwołania się do pracującego Worda.
Set objWord = GetObject(, "Word.Application")
' Jeżeli zmienna objWord ma wartość Nothing (nieutworzona
' zmienna obiektowa), Word nie jest uruchomiony
If objWord Is Nothing Then
' Utwórz egzemplarz aplikacji
Set objWord = New Word.Application
' Jeżeli objWord nadal zawiera "Nothing" MS Word 9.0
' nie jest zainstalowany.
If objWord Is Nothing Then
MsgBox "MS Word 2000 nie jest zainstalowany"
End If
End If
' On Error GoTo ErrorNandler (Tu wstaw obsługę błędów)
|
||
|
Słowo kluczowe New może być użyte, gdy tworzysz odwołanie do biblioteki typów aplikacji. |
Użycie wczesnego i późnego łączenia typów
Zauważ, że zmienna obiektowa w wyrażeniu Dim i Set odwołuje się do Word.Application. Taka deklaracja nazywana jest wczesnym łączeniem typów XE "wczesne łączenie typów" . W czasie kompilacji zmienna obiektowa jest wiązana z biblioteką typów Worda. Skutkuje to szybszym wykonywaniem tak napisanego fragmentu kodu, ponieważ większość czynności została wykonana w trakcie kompilacji, a nie w trakcie wykonania.
Jeżeli zmienna objWord zostanie zadeklarowana jako Object, łączenie z biblioteką typów Worda nastąpi w trakcie wykonania programu, co znacznie spowolni program.
Przykład poniższy przedstawia oba podejścia:
' Użycie wczesnego łączenia typów. Program jest szybszy.
Dim objWord as Word.Application
' Późne łączenie typów, taki program wykonuje się wolniej.
Dim objWord as Object
|
||
|
W pliku Automation.mdb załączonym do rozdziału 19., znajdują się przykłady testów wydajności, które pokazują znaczną różnicę szybkości między wczesnym i późnym łączeniem typów. |
Użycie funkcji CreateObject
Aby uzyskać najwydajniejszy kod Automation, deklarujemy zmienne obiektowe jako obiekty specyficznych typów (wczesne łączenie), używamy funkcji GetObject XE "GetObject" , aby sprawdzić czy aplikacja jest uruchomiona i przy użyciu New tworzymy egzemplarz aplikacji w razie potrzeby.
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 XE "CreateObject" .
Kiedy nie można uzyskać odwołania do aplikacji
Gdy używamy Automation z niektórych aplikacji (na szczęście nie z Accessa), nie można utworzyć odwołania do innej aplikacji (nie da się uzyskać odwołania do okna dialogowego). Przykładem jest Outlook 97/98 i aplikacje dla Internetu. W takich wypadkach zmuszony jesteś użyć późnego łączenia typów i użycia funkcji CreateObject. Przykład poniższy zawiera kod Automation, który należy użyć w programie Outlook, aby automatyzować Word.
|
||
|
Możesz używać funkcji GetObject, aby sprawdzić, czy jest uruchomiony Word. Funkcja CreateObject tworzy nowy egzemplarz aplikacji. |
' Deklaracja objWord jako zmiennej obiektowej.
Dim objWord As Word.Application
' Gdy Word nie jest uruchomiony, wystąpi błąd. Ignorujemy go.
On Error Resume Next
' Próba odwołania się do pracującego Worda.
Set objWord = GetObject(, "Word.Application")
' Wystąpi błąd nr 429, jeżeli Word NIE pracuje
If Err.Number = 429 Then
Err.Number = 0
' Utwórz nowy egzemplarz aplikacji
Set objWord = Create0bject("Word.Application")
' 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)
Co wtedy, gdy użytkownik ma inną wersję aplikacji?
W niektórych firmach użytkownicy mogą mieć zainstalowane różne wersje aplikacji. Niektórzy mogą używać Word 95 inni Word 97, podczas gdy jeszcze inni używają Worda 2000. Niektórzy z nich mogą mieć nawet zainstalowanych kilka wersji Worda!
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
' Tworzenie egzemplarza aplikacji Word 97
Set objWord = Create0bject("Word.Application.8")
|
||
|
Numer wersji Office 95 to 7.0, Office 97 to 8.0, a Office 2000 to 9.0. Możesz także przesyłać numer wersji przy użyciu New. |
Użycie metod i właściwości obiektów automatyzacji
Po utworzeniu egzemplarza obiektu aplikacji możesz używać go w swoich programach, korzystając z metod i właściwości obiektu.
Ustawianie właściwości obiektu
Teraz możesz korzystać z innych aplikacji, używając ich możliwości w swojej aplikacji. Tak samo jak korzystasz z właściwości obiektu z Accessa, możesz używać właściwości obiektów automatyzacji. Poniższy przykład używa właściwości w Wordzie i Excelu:
' Ustawianie właściwości obiektów Automation
objWord.Visible = True
objExcel.Cells(1,1).Value = "Sprzedaż roczna"
Wykonywanie metod obiektów
Używając automatyzacji, można wykonywać metody obiektów. Przykład:
' Wykonywanie metod Add obiektów.
objWord.Documents.Add
objExcel.Workbooks.Add
Zwalnianie obiektów automatyzacji
Gdy zakończyłeś pracę na zmiennej obiektowej, należy ją zwolnić, przypisując jej wartość Nothing. Zasoby zajmowane przez zmienną zostaną wtedy zwolnione. Właściwa składnia przedstawiona jest na przykładzie:
' Zwalnianie zmiennej obiektowej
Set objWord = Nothing
|
||
|
Gdy deklarujesz zmienną obiektową, od razu przejdź na dół procedury i przypisz jej wartość Nothing. Zabezpieczy Cię to przed tym, że zapomnisz zwolnić zmienną obiektową po napisaniu długiej procedury. |
Łączymy wszystko razem
Przedyskutowaliśmy wszystkie kroki potrzebne do uruchomienia automatyzacji w aplikacji. Teraz spójrzmy na przykład programu, który łączy te kroki ze sobą. Przykład ten drukuje dokument Worda za pomocą automatyzacji. Przykład zawiera wszystkie kroki przedstawione do tej pory: tworzenie lub pobranie odwołania do Worda, użycie obiektów Worda (a dokładniej metody PrintOut XE "PrintOut:metoda" ) oraz zwolnienie obiektu automatyzacji.
' Deklaracja zmiennej obiektowej objWord
Dim objWord As Word.Application
' Gdy Word nie jest uruchomiony, wystąpi błąd. Ignorujemy go.
On Error Resume Next
' Pobranie odwołania do obiektu aplikacji Word
Set objWord = GetObject(, "Word.Application")
' Jeżeli zmienna objWord ma wartość Nothing (nieutworzona
' zmienna obiektowa), Word nie jest uruchomiony
If objWord Is Nothing Then
' Create a new instance of the Word application.
Set objWord = New Word.Application
' Jeżeli objWord nadal zawiera "Nothing" MS Word 9.0
' nie jest zainstalowany.
If objWord Is Nothing Then
MsgBox "MS Word 2000 nie jest zainstalowany"
End If
End If
' On Error GoTo ErrorHandler (Tu wstaw obsługę błędów)
' Otwórz dokument Worda
objWord.Documents.Open ("C:\Automation\Northwind Magazine Ad.doc")
' Wydrukuj dokument Worda
objWord.PrintOut Background:=False
' Zamknij aplikację Word
objWord.Quit
' Zwolnij zmienną obiektową
Set objWord = Nothing
|
||
|
Jest to bardzo prosty przykład. Rozdział 19. zawiera bardziej skomplikowane programy używające automatyzacji, a także plik Automation.MDB zawierający tysiące wierszy kodu automatyzacji, który możesz użyć w Twoich aplikacjach. |
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
Użycie właściwości UserControl do sprawdzenia, w jaki sposób została otwarta aplikacja
Właściwość UserControl XE "UserControl:właściwość" umożliwia sprawdzenie, czy aplikacja lub dokument został utworzony lub otwarty przez użytkownika, czy w sposób programowy. Jeżeli właściwość UserConrol (zmienna logiczna) zawiera wartość true, aplikacja lub dokument został otwarty przez użytkownika. Jeżeli zawiera false, aplikacja lub dokument został otwarty programowo.
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
' Otwarcie programowe Worda.
Set objWord = New Word.Application
' Sprawdzenie właściwości UserControl, aby stwierdzić, czy Word
' został otwarty programowo, czy przez użytkownika
If objWord.Application.UserControl Then
MsgBox "Word został otwarty przez użytkownika"
Else
MsgBox "Word został otwarty programowo".
End If
Set objWord = Nothing
Użycie WithEvents w celu udostępnienia zdarzeń serwera automatyzacji
Użycie automatyzacji w sposób pokazany do tej pory można porównać do jednostronnej rozmowy telefonicznej. Access kontrolował Worda i nakazywał wykonanie pewnych czynności. Przez użycie klauzuli WithEvents XE "WithEvents" możesz utworzyć dwukierunkową komunikację pomiędzy Accessem i Wordem. Access może zlecać do Worda drukowanie dokumentu lub raportu, Word natomiast odpowiada Accessowi po wystąpieniu odpowiedniego zdarzenia.
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.
' Deklaracja zmiennej modułu używająca klauzuli WithEvents
Private WithEvents objWord as Word.Application
|
||
|
Klauzula WithEvents może być używana tylko w modułach klasowych (moduł formularza jest modułem klasowym). WithEvents nie może być używane w zwykłych modułach. |
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 udostępnionych przez Worda zdarzeń DocumentChange i Quit.
Rysunek 18.7. Procedury używające udostępnionych zdarzeń programu Microsoft Word |
|
Techniki i wskazówki do automatyzacji
Od dawna automatyzacja nie ma dobrej opinii z powodu słabej wydajności. Używając rozsądnego sprzętu i właściwych technik kodowania, automatyzacja może pracować wydajnie. Zapamiętaj poniższe porady, gdy będziesz programował automatyzację.
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.
Wszystkie te zagadnienia były już wcześniej omawiane.
Użycie istniejącego egzemplarza aplikacji,
jeżeli jest ona uruchomiona
Nie otwieraj nowego egzemplarza aplikacji w każdej sesji automatyzacji. Jeżeli aplikacja jest uruchomiona, użyj istniejącego egzemplarza w sesji automatyzacji.
Wyłącz odświeżanie ekranu
Podczas typowej sesji automatyzacji z użyciem Excela czy Worda następuje ogromna ilość odświeżeń ekranu. Zawsze, gdy ważna jest dla nas wydajność, przełączaj ScreenUpdating XE "ScreenUpdating:właściwość" na False. Wydajność się polepszy, gdyż nie będzie konieczne odświeżanie ekranu.
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.
Poniższy przykład przedstawia tę technikę.
' Wyłącz odświeżanie ekranu
Application.ScreenUpdating = False
' Tutaj jest przetwarzanie przez automatyzację
' Włącz odświeżanie ekranu
Application.ScreenUpdating = False
|
||
|
Pewnego razu omyłkowo zainstalowałem użytkownikom aplikację z włączonym odświeżaniem ekranu, co spowalniało aplikację. W następnej wersji odświeżanie zostało wyłączone. Dostałem tak wiele skarg od użytkowników, że dokonałem korekty i dałem im wersję znowu z włączonym odświeżaniem ekranu. Użytkownicy wyjaśniali, że gdy był odświeżany ekran, mieli możliwość przeczytania dokumentu, rozpoczęcia korekty lub upewnienia się, że wybrali właściwy dokument do druku. Przez zmuszenie użytkowników do czekania aż cały dokument będzie gotowy, tracili oni trzy do pięciu sekund czasu poświęcanego na korektę. Uważali również, że jest to coś ciekawego, oglądać jak dokument jest tworzony fragment po fragmencie w „magiczny” sposób. Zatem należało tu rozpatrzyć „czas przetwarzania” człowieka przy przeglądaniu dokumentu, a nie tylko czas przetwarzania komputera. |
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.
|
||
|
Tworzyłem aplikację dla firmy lotniczej, która wymagała wykonania skomplikowanego kodu automatyzacji Excela. W trakcie przetwarzania mała ikona samolotu przesuwała się po ekranie. Użytkownicy byli bardziej zainteresowani tym małym samolocikiem lecącym przez ich ekran niż skomplikowanym programem wykonującym dla nich pracę. |
Wykonywanie programu przez serwer automatyzacji
Program zawsze działa szybciej, jeżeli serwer automatyzacji wykonuje swój kod. Przykładowo, jeżeli Twoja aplikacja Accessa używa Worda, na początku utwórz egzemplarz obiektu dokumentu Worda. Następnie umieść cały kod VBA, który zajmuje się manipulowaniem Wordem (zmiany czcionek lub stylu tekstu, drukowanie dokumentu) w Wordzie.
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ść.
|
||
|
Kod VBA w aplikacjach Word i Excel umieszczony jest w szablonach. Aby ułatwić rozprowadzanie szablonów, umieść je w udostępnionym katalogu na serwerze plików. W menu Narzędzia, Opcje, na zakładce Położenie plików można ustawić położenie szablonów grupy roboczej na ten sieciowy katalog. Gdy potrzebne są zmiany w kodzie lub dodajesz nowy szablon, kopiujesz pliki tylko do jednego katalogu na serwerze. |
Użycie konstrukcji With/End With
Są dwa powody, aby używać konstrukcji With/End With XE "With/End With" . Po pierwsze, kod działa szybciej, ponieważ odwołanie do obiektu jest wykonywane tylko raz. Drugi powód to czytelność kodu. Pomyśl o każdej kropce jak o ograniczniku prędkości na drodze. Im mniej kropek, tym lepiej! Porównaj dwa poniższe przykłady:
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
Zwalnianie zmiennych obiektowych
Tak jak wcześniej o tym mówiliśmy, zawsze zwalniaj zmienne obiektowe na końcu sesji automatyzacji przez przypisanie im wartości Nothing, aby odzyskać zasoby.
Nie wyświetlaj okien dialogowych i komunikatów
Unikaj operacji, które zatrzymują sesję automatyzacji, takich jak okna dialogowe lub okna komunikatów. Jeżeli nastąpi zatrzymanie, może nie być widoczne przez użytkownika, ponieważ inna aplikacja posiada w tym czasie fokus.
Używaj obsługi błędów
Automatyzacja komplikuje Twoje aplikacje. Zalety użycia właściwości innych aplikacji są ograniczane przez to, że więcej rzeczy może źle zadziałać. Istotne jest, aby obsłużyć wszystkie błędy, które mogą zdarzyć się w trakcie sesji automatyzacji. W aplikacjach Microsoft Office aplikacja serwera może zwracać informacje o błędach. Popatrz do rozdziału 13. „Profesjonalna obsługa błędów”, aby znaleźć informacje na temat obsługi błędów.
Rozdział 19.
Integracja z Office 2000
W tym rozdziale:
Powody integracji z Office 2000.
Wybór właściwego narzędzia.
Wszędzie VBA.
Użycie rejestratora makr do pisania kodu.
Użycie makr automatycznych.
Microsoft Forms.
Object Browser.
Nazwy klas aplikacji Office.
Przykład Automation.
Automatyzacja Worda.
Automatyzacja Excela.
Automatyzacja PowerPoint.
Automatyzacja Outlooka.
Automatyzacja Graph.
Automatyzacja MapPoint.
Automatyzacja FrontPage.
Automatyzacja Binder.
Zabezpieczanie dokumentów, szablonów i kodu.
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). |
||||
Rysunek 19.1. Plik Automation.MDB |
|
Powody integracji z Office 2000
Office 2000 jest pełnym pakietem produktów będącym odpowiedzią na oczekiwania i potrzeby klientów. Produkty te oferują ogromną ilość opcji, które zostały napisane i przetestowane przez Microsoft. Office 2000 udostępnia setki obiektów, którymi programista może manipulować przy użyciu VBA. Żaden inny pakiet biurowy w chwili obecnej nie zapewnia takiej siły i integracji, jaką oferuje Office 2000.
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.
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.
Wybór właściwego narzędzia
Pierwszym i prawdopodobnie najistotniejszym wyborem, jakiego dokonano programista, jest odpowiedź na pytanie „Jakiego narzędzia powinienem użyć do stworzenia tej opcji?”.
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:
Access - usługi baz danych.
Word - edycja tekstu i usługi małej poligrafii.
Excel - obliczenia i usługi finansowe.
PowerPoint - prezentacje
Outlook - poczta, kalendarz, kontakty, zadania i inne usługi.
Graph - wykresy i schematy.
MapPoint - usługi związane z mapami.
FrontPage - usługi tworzenia stron internetowych.
Binder - usługi łączenia dokumentów.
Wszędzie VBA
Visual Basic for Applications (VBA XE "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.
Użycie rejestratora makr do pisania kodu
Rejestrator makr XE "rejestrator makr" jest doskonałym generatorem kodu i może być użyty do błyskawicznego programowania w Wordzie, Excelu i PowerPoincie. Aby uruchomić rejestrator makr w tych aplikacjach, wybierz Makro z menu Narzędzia, a następnie Zarejestruj nowe makro (rysunek 19.2).
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 |
|
||||
|
|||||
|
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. |
Użycie makr automatycznych
Word, Excel i PowerPoint zawierają mechanizm makr automatycznych. Mogą być one użyte do uruchamiania programu po zajściu określonych zdarzeń. Przykładowo, w Wordzie istnieją następujące makra automatyczne:
AutoExecute XE "AutoExecute" - jest wykonywane w czasie uruchamiania Worda;
AutoNew XE "AutoNew" - jest wykonywane podczas tworzenia nowego dokumentu;
AutoOpen XE "AutoOpen" - jest wykonywane podczas otwierania dokumentu;
AutoClose XE "AutoClose" - jest wykonywane podczas zamykania dokumentu;
AutoExit XE "AutoExit" - jest wykonywane podczas zamykania Worda.
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 XE "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.
|
||
|
Microsoft Forms są oddzielne od formularzy Accessa, Visual Basica i Outlooka. Jest to osobny pakiet. Nie można konwertować formularzy Accessa do Microsoft Forms i odwrotnie |
Object Browser
Gdy pracujesz z różnymi aplikacjami omawianymi w tym rozdziale, nie zapominaj o użyciu narzędzia Object Browser XE "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).
Rysunek 19.5. Object Browser wyświetlający obiekty Worda |
|
Nazwy klas aplikacji Office
Aby użyć innych aplikacji Office, musisz znać nazwy klas występujących w tych aplikacjach:
|
|||
Aplikacja |
Nazwa klasy |
||
Access |
Access.Application |
||
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()
Dim objWord As Word.Application
DoCmd.Hourglass True
' Przejdz do następnego wiersza w przypadku błędu
On Error Resume Next
' Próba pobrania odwołania do pracującego Worda
Set objWord = GetObject(, "Word.Application")
' Word nie działa
If objWord Is Nothing Then
' Utwórz nowy egzemplarz Worda
Set objWord = New Word.Application
' Jeżeli objWord jest Nothing to znaczy, że nie da się
' uruchomić Worda
If objWord Is Nothing Then
MsgBox "MS Word 8.0 nie jest zainstalowany"
End If
End If
' On Error GoTo ErrorHandler (Tu wstaw obsługę błędów)
' Otwórz nowy dokument oparty na szablonie Normal.dot
objWord.Documents.Add
' Przełączenie się na Worda
objWord.Activate
' Pokazujemy Worda użytkownikowi
objWord.Visible = True
' Tworzenie nagłówka raportu
With objWord.Selection
.TypeText vbTab & vbTab & "Raport o aplikacji Accessa"
.StartOf Unit:=wdStory, Extend:=wdExtend
.Font.Bold = True
.Font.Size = 20
.EndKey Unit:=wdLine
.TypeParagraph
.TypeParagraph
.Font.Bold = False
.Font.Size = 16
End With
' Wstaw informacje o tej aplikacji Accessa do dokumentu Worda
With objWord.Selection
.TypeText "Obiekt aplikacji" & vbTab & "Wartość" & vbCrLf
.TypeText "Nazwa i ścieżka do bazy" & vbTab & _
Application.CurrentDb.Name & vbCrLf
.TypeText "Nazwa bieżącego formularza" & vbTab & _
Forms.Item(0).Name & vbCrLf
.TypeText "Nazwa bieżącego obiektu" & vbTab & _
Application.CurrentObjectName & vbCrLf
.TypeText "Nazwa bieżącego użytkownika" & vbTab & _
Application.CurrentUser & vbCrLf
.TypeText "Wersja Jet" & vbTab & _
Application.DBEngine.Version & vbCrLf
.TypeText "Kompilacja aplikacji" & vbTab & _
Application.IsCompiled & vbCrLf
.TypeText "Ilość odwołań" & vbTab & _
Application.References.Count & vbCrLf
.TypeText "Kursor myszy" & vbTab & _
Application.Screen.MousePointer & vbCrLf
.TypeText "User Control" & vbTab & Application.UserControl & _
vbCrLf
.TypeText "Widoczność aplikacji" & vbTab & Application.Visible & _
vbCrLf
.StartOf Unit:=wdStory
.MoveDown Unit:=wdLine, Count:=2
.StartOf Unit:=wdLine
.EndOf Unit:=wdStory, Extend:=wdExtend
.ConvertToTable Separator:=wdSeparateByTabs, NumColumns:=2, _
NumRows:=11, Format:=wdTableFormatColorful2, _
ApplyBorders:=True, ApplyShading _
:=True, ApplyFont:=True, ApplyColor:=True, _
ApplyHeadingRows:=True, ApplyLastRow:=False, _
ApplyFirstColumn:=False, ApplyLastColumn:=False, _
AutoFit:=True, AutoFitBehavior:=wdAutoFitFixed
.EndOf Unit:=wdStory
End With
' Wyłącz pokazywanie znaków końca akapitu
objWord.ActiveWindow.ActivePane.View.ShowAll = False
DoCmd.Hourglass False
' Zwolnij obiekt
Set objWord = Nothing
End Sub
Automatyzacja Worda
W tej części opiszę specyficzne zagadnienia i przykłady automatyzacji Worda.
Model obiektów Worda
Poprzedni przykład przedstawia program, zawierający wszystkie operacje potrzebne do automatyzacji. Skupię się teraz na opisie obiektów, właściwości i metod dostępnych w Wordzie. Model obiektów XE "model obiektów: Word" jest w tym względzie bardzo pomocny.
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.
|
||
|
Spójrz do „Obiekty Microsoft Word” w pliku pomocy. Zamieszczony jest tam diagram struktury obiektów w Wordzie. |
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
Obiekt Worda |
Opis |
Application XE "Application" |
Aplikacja Word. Zwykle nie potrzebujesz odwoływać się do tego obiektu z Worda. Jeżeli używasz Worda z innej aplikacji, musisz użyć tego obiektu |
AutoCaption XE "AutoCaption" (s) |
Automatycznie dodawane nagłówki |
AutoCorrect XE "AutoCorrect" |
Funkcja Autokorekta |
Character XE "Character" |
Znaki w otwartym dokumencie |
CommandBar XE "CommandBar" (s) |
Poszczególne paski narzędzi dostępne są poprzez indeks lub nazwę |
DefaultWebOptions XE "DefaultWebOptions" |
Domyślne ustawienia dla publikowania lub zapisywania jako strona WWW |
Dialog XE "Dialog" (s) |
Okna dialogowe |
Dictionary XE "Dictionary" (s) |
Słowniki w Wordzie |
Document XE "Document" (s) |
Otwarte dokumenty. Można się do nich odwoływać przez indeks lub nazwę |
Email XE "Email" |
Przesyłka e-mail dla dokumentu |
Tabela 19.1.
Obiekty Worda (ciąg dalszy)
Obiekt Worda |
Opis |
EmailSignature XE "EmailSignature" |
Informacja o podpisie przesyłki e-mail |
Find XE "Find" |
Obiekt używany do przeszukiwania słów, zakresów itd. |
Paragraphs XE "Paragraphs" |
Kolekcja akapitów. |
Range XE "Range" |
Zdefiniowany punkt początkowy i końcowy akapitu. Dokument może zawierać kilka zakresów |
Replacement XE "Replacement" |
Obiekt określający warunki zastępowania |
Selection XE "Selection" |
Zaznaczony tekst. Może być tylko jeden zaznaczony fragment tekstu w dokumencie |
Table XE "Table" (s) |
Pojedyncza tabela |
Template XE "Template" (s) |
Szablon dokumentu |
WebOptions XE "WebOptions" |
Ustawienia nadpisujące DefaultWebOptions |
Window XE "Window" (s) |
Okna dokumentów. Poszczególne okna dostępne są przez indeks lub nazwę |
Words XE "Words" |
Kolekcja słów |
Użycie szablonów Worda
Jak mówiłem w poprzednim rozdziale, kod automatyzacji działa szybciej, gdy jest wykonywany przez serwer automatyzacji. Inaczej mówiąc, gdy używamy obiektów Worda, kod VBA powinien być umieszczony w szablonie XE "szablon" Worda zamiast w Accessie.
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 XE "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.
|
||
|
W pliku dołączonym do tego rozdziału znajdują się przykłady używające tego samego kodu automatyzacji w Accessie i przedstawia szablon Worda. Stoper pokazuje różnicę szybkości. Umieszczenie kodu w Wordzie powoduje znaczną różnicę szybkości. |
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 XE "szablony 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 |
|
Wstawianie danych do dokumentu Worda
Word jest wspaniałym edytorem raportów. Dane korporacyjne mogą być prezentowane w postaci dokumentów możliwych do modyfikacji przez użytkowników. Poniższy przykład przedstawia gazety reklamowe (rysunek 19.7.).
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 XE "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.
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 XE "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
Zakładki XE "zakładka"
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
Przykłady kodu automatyzacji Worda
Poniższe przykłady przedstawiają programy używające specyficzne właściwości i metody obiektów Worda.
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
' Formatowanie akapitu
With Selection.ParagraphFormat
.LeftIndent = InchesToPoints(0)
.RightIndent = InchesToPoints(0)
.SpaceBefore = 0
.SpaceAfter = 0
.LineSpacingRule = wdLineSpaceSingle
.Alignment = wdAlignParagraphLeft
.KeepWithNext = False
.KeepTogether = False
.PageBreakBefore = False
.NoLineNumber = False
.Hyphenation = True
.FirstLineIndent = InchesToPoints(0)
.OutlineLevel = wd0utlineLevelBodyText
End With
' Ustawianie podwójnego odstępu między wierszami
Selection.ParagraphFormat.LineSpacingRule = wdLineSpaceDouble
' Wstawienie znaku końca strony
Selection.InsertBreak Type:=wdPageBreak
' Wstawienie znaku końca sekcji
Selection.InsertBreak Type:=wdSectionBreakNextPage
Użycie stylów dokumentu
Styl to zestaw instrukcji formatowania, który posiada swoją nazwę i może być przypisywany do tekstu. Style umożliwiają formatowanie kilku bloków tekstu lub akapitów jedną instrukcją. Dodatkowo pomagają utrzymać spójność formatowania dokumentu.
' Zastosowanie stylu Nagłówek 1
Selection.Style = ActiveDocument.Styles("Heading 1")
' Tworzenie nowego stylu
ActiveDocument.Styles.Add Name:="MyNewStyle", Type:=wdStyleTypeParagraph
With ActiveDocument.Styles("MyNewStyle")
.AutomaticallyUpdate = False
.BaseStyle = "Heading 5"
End With
With ActiveDocument.Styles("MyNewStyle").Font
.Name = "Times New Roman"
.Size = 12
.Bold = False
.Italic = False
.Underline = wdUnderlineSingle
.StrikeThrough = False
.DoubleStrikeThrough = False
.Outline = False
.Emboss = False
.Shadow = False
.Hidden = False
.SmallOaps = False
.AllCaps = False
.ColorIndex = wdAuto
.Engrave = False
.Superscript = False
.Subscript = False
.Scaling = 100
.Kerning = 0
.Animation = wdAnimationNone
End With
Autokorekta
Autokorekta XE "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 XE "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
' Wstawianie do autotekstu.
NormalTemplate.AutoTextEntries("Microsoft").Insert _
Where:= Selection.Range
Autopodsumowanie
Autopodsumowanie XE "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
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
' Układ sieci WWW
ActiveWindow.View.Type = wdOnlineView
' Układ strony
ActiveWindow.View.Type = wdPageView
' Układ konspektu
ActiveWindow.ActivePane.View.Type =wd0utlineView
' Główny dokument
ActiveWindow.ActivePane.View.Type = wdMasterView
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 XE "przypis" 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 XE "nagłówek" są umieszczone na górze każdej strony dokumentu.
' Tworzenie nagłówka
ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageHeader
Selection.TypeText Text:="My Header"
Stopki
Stopki XE "stopka" 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 XE "hiperłącze" 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 hiperłącza do innego dokumentu
ActiveDocument.Hyperlinks.Add Anchor:=Selection.Range, Address:= _
"C:\MyDoc.doc", SubAddress:=""
' Tworzenie hiperłącza do dokumentu w Internecie
ActiveDocument.Hyperlinks.Add Anchor:=Selection.Range, Address:= _
"http://www.microsoft.com/office/", SubAddress:=""
Tworzenie tabel
Tabele XE "tabela:Worda" 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
' Wstawianie kolumn do tabeli
Selection.InsertColumns
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
' Ustawienie poziomej orientacji papieru.
ActiveDocument.PageSetup.Orientation = wdOrientLandscape
Podgląd wydruku
Aby wywołać podgląd wydruku, należy użyć poniższej instrukcji.
' Podgląd wydruku
ActiveDocument.PrintPreview
Drukowanie XE "drukowanie" dokumentów, kopert i etykiet
Poniższy przykład przedstawia sposób, jak programowo wydrukować dokument, kopertę i etykietę:
' Drukowanie dokumentu
Application.PrintOut FileName:="", Range:=wdPrintAllDocument, _
Item:= wdPrintDocumentContent, Copies:=1, Pages:="", _
PageType:=wdPrintAllPages, Collate:=True, Background:=True,
PrintToFile:=False
' Drukownanie koperty
ActiveDocument.Envelope.PrintOut ExtractAddress:=False, _
OmitReturnAddress :=False, PrintBarCode:=False, _
PrintFIMA:=False, Height:=InchesToPoints(4.13), _
Width:=InchesToPoints(9.5), Address:="Tom Howe", _
AutoText:= "ToolsCreateLabelsl", ReturnAddress:=_
"1001 SW Fifth Avenue, Suite 1100",ReturnAutoText:= _
"ToolsCreateLabels2", AddressFromLeft:=wdAutoPosition, _
AddressFromTop:=wdAutoPosition, ReturnAddressFromLeft:=_
wdAutoPosition, ReturnAddressFromTop:=wdAutoPosition
' Drukowanie etykiety
Application.MailingLabel.DefaultPrintBarCode = False
Application.MailingLabel.PrintOut Name:="2160 Mini", _
Address:="Tom Howe"
|
||
|
Gdy codziennie drukowane są obszerne dokumenty i raporty, rozważ użycie procedury uruchamiającej drukowanie w nocy, gdy drukarki są wolne i ruch w sieci minimalny. |
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.
Pola mogą być uaktualniane ręcznie przez naciśnięcie F9 lub automatycznie podczas drukowania dokumentu.
Niektóre często używane pola zamieszczone są w tabeli 19.2.
Tabela 19.2.
Pola Worda
Pole Worda |
Opis |
Ask |
Prosi użytkownika o wprowadzenie tekstu skojarzonego z zakładką |
CreateDate |
Data utworzenia dokumentu |
Fill-in |
Prosi użytkownika o wprowadzenie tekstu do wstawienia do dokumentu |
Tabela 19.2.
Pola Worda (ciąg dalszy)
Pole Worda |
Opis |
Hyperlink |
Otwiera i przeskakuje do pliku |
If |
Instrukcja warunkowa |
MergeField |
Wstawia pole korespondencji seryjnej |
Next |
Przejście do następnego rekordu korespondencji seryjnej |
SectionPages |
Wstawia ilość stron w sekcji |
W czasie pracy z polami przydatne są następujące skróty klawiszowe:
|
|||
Skrót klawiszowy |
Opis |
||
Alt+F9 |
Przełącza pomiędzy tekstem i kodami pól |
||
Ctrl+F9 |
Wstawia znak pola |
||
Ctrl+Shift+F9 |
Odłącza kody pól |
||
Delete |
Usuwa pole |
||
F9 |
Uaktualnia pola |
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 |
|
W dokumencie zapisywane są następujące informacje:
Nazwa dokumentu;
Rozmiar dokumentu;
Data i czas utworzenia;
Data i czas ostatniej modyfikacji;
Nazwa bazowego szablonu;
Słowa kluczowe identyfikujące dokument;
Miejsce zapisu dokumentu;
Nazwisko autora;
Nazwisko kierownika;
Firma;
Kategoria;
Komentarz;
Statystyka dokumentu;
Informacje o zawartości.
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.
Inne możliwości Worda
Word posiada wiele funkcji małej poligrafii. Są to m.in.:
Układ wielokolumnowy;
Możliwość importu grafiki z innych aplikacji;
Wbudowywanie czcionek True Type;
Krawędzie i cieniowanie;
Word Art.;
Wiele narzędzi rysunkowych.
Automatyzacja Excela
W tej części opisane są specyficzne dla Excela zagadnienia oraz przykłady automatyzacji.
Model obiektów Excela
Excel zawiera ponad 140 obiektów dostępnych poprzez VBA.
|
||
|
Zajrzyj do „Obiekty Microsoft Excel” w pomocy do Excela. Zamieszczony jest tam diagram obiektów Excela. |
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
Obiekty Excela |
Description |
Application XE "Application" |
Cała aplikacja Excel |
Characters XE "Characters" |
Znaki w obiekcie zawierającym znaki |
Chart XE "Chart" (s) |
Wykresy w skoroszycie |
CubeField XE "CubeField" (s) |
Hierarchia lub pole wymiaru sześcianu OLAP |
DefaultWebOptions XE "DefaultWebOptions" |
Ustawienia dla publikacji i zapisywania jako strony WWW |
Dialog XE "Dialog" (s) |
Wbudowane okna dialogowe |
DocumentProperty XE "DocumentProperty" (s) |
Wbudowane i zdefiniowane właściwości dokumentu |
Name XE "Name" (s) |
Nazwa dla obszaru komórek |
PivotCache XE "PivotCache" (s) |
Pamięć podręczna dla raportu z tabeli przestawnej |
PivotTable XE "PivotTable" (s) |
Raport z tabeli przestawnej |
PublishObject XE "PublishObject" (s) |
Obiekt w arkuszu, który będzie zapisywany na stronie WWW |
Range XE "Range" |
Komórka, wiersz, kolumna lub obszar komórek zawierający ciągły blok komórek lub trójwymiarowy obszar |
Shape XE "Shape" (s) |
Rysunek lub panel do rysowania |
ShapeRange XE "ShapeRange" |
Podzbiór obiektów |
Style XE "Style" (s) |
Opis stylu dla obszaru |
WebOptions XE "WebOptions" |
Ustawienia nadpisujące DefaultWebOptions |
Workbook XE "Workbook" (s) |
Otwarty arkusz dostępny przez numer lub nazwę |
Worksheet XE "Worksheet" (s) |
Otwarty skoroszyt dostępny przez numer lub nazwę |
Przykłady automatyzacji Excela
Przykłady poniższe przedstawiają automatyzację charakterystycznych właściwości i metod obiektów Excela.
Formatowanie dokumentów Excela
Excel posiada szerokie możliwości formatowania. Poniższe przykłady przedstawiają sposób w jaki należy formatować nagłówki kolumn danych i w jaki sposób wywoływać metodę AutoFit XE "AutoFit:metoda" :
' Formatowanie nagłówków kolumn
With objWorkSheet.
' Pogrubienie nagłówków kolumn
.Cells(1, 1).Font.Bold = True
.Cells(1, 2).Font.Bold = True
End With
' Formatowanie danych w arkuszu
With objWorkSheet.Columns
With .Item(2)
.NumberFormat = "0.00"
.AutoFit
End With
' Użycie metody AutoFit do formatowania danych
.Item(1).AutoFit
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)"
' Tworzenie wykresu kolumnowego
With ObjChart.ActiveChart
.ChartType = xlColumnClustered
.SetSourceData Source:=_
Sheets("5 najlepszych produktów").Range("Al:B6"), _
PlotBy:=xl0olumns
End With
' Tworzenie wykresu pierścieniowego
With ObjChart.ActiveChart
.ChartType = xlDoughnut
.SetSourceData Source:=_
Sheets("5 najlepszych produktów").Range("Al:B6"), _
PlotBy:=xlColumns
.Location Where:=xlLocationAsNewSheet, Name:="Wykres pierścieniowy"
.HasLegend = True
.ChartTitle.Characters.Text = "Sprzedaż (wykres pierścieniowy"
End With
Program korzystający z automatyzacji może tworzyć w Excelu wykresy takie jak pokazany na rysunku 19.10.
Użycie właściwości Parent XE "Parent:właściwość"
Excel zawiera obiekt aplikacji oraz obiekt reprezentujący arkusz. Możesz dostać się do wszystkich obiektów Excela przez właściwości tych obiektów wysokiego poziomu. Generalnie, kod automatyzacji rozpoczyna pracę od tych obiektów i schodzi w dół hierarchii obiektów. W Excelu program może rozpocząć pracę od obiektu aplikacji, a następnie przenieść się do obiektu zeszytu i dalej do arkuszy i komórek.
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
' Otwarcie pliku Excela
' Upewnij się, że przykładowy plik znajduje się w podanym katalogu
objExcel.Workbooks.Open _
("C:\Automation\Sales by Country Data.xls")
' Ustaw zmienną objWork na aktywny zeszyt
Set objWorkBook = objExcel.ActiveWorkBook
' Pobierz nazwę zeszytu z objWorkBook ("Sales by Country")
MsgBox objWorkBook.Name
' Pobierz nazwę z obiektu aplikacji, używając właściwości Parent
' ("Microsoft Excel").
MsgBox objWorkBook.Parent.Name
' Maksymalizuj okno
objExcel.WindowState = xlMaximized
' Pokaż Excela użytkownikowi
objExcel.Visible = True
' Zakończ aplikację używając metody Quit
'objExcel.Quit
' Zwolnij obiekt aplikacji
Set objExcel = Nothing
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.
Model obiektów PowerPoint
PowerPoint zawiera ponad 85 obiektów dostępnych poprzez VBA.
|
||
|
Zajrzyj do „Obiekty Microsoft PowerPoint” w pomocy do PowerPoint. Zamieszczony jest tam diagram obiektów PowerPoint. |
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
Obiekt PowerPoint |
Opis |
ActionSetting XE "ActionSetting" (s) |
Ustawienia opisujące sposób reakcji rysunków lub obszaru tekstu na manipulacje myszką w czasie pokazu |
Animationsetting XE "Animationsetting" (s) |
Ustawienia animacji rysunków w czasie pokazu |
Application XE "Application" |
Cała aplikacja PowerPoint |
Cell XE "Cell" |
Komórka w tabeli |
CellRange XE "CellRange" |
Zbiór komórek we wierszu lub kolumnie tabeli |
ColorScheme XE "ColorScheme" (s) |
Schemat kolorów dla slajdu. |
Column XE "Column" (s) |
Kolumna tabeli |
DefaultWebOptions XE "DefaultWebOptions" |
Ustawienia dla publikacji i zapisywania jako strony WWW |
DocumentWindow XE "DocumentWindow" (s) |
Okno dokumentu |
Pane XE "Pane" (s) |
Fragment okna dokumentów |
Presentation XE "Presentation" (s) |
Otwarta prezentacja dostępna przez numer lub nazwę |
Row XE "Row" (s) |
Wiersz tabeli |
Selection XE "Selection" |
Zaznaczenie w dokumencie |
ShapeRange XE "ShapeRange" |
Zbiór kształtów w dokumencie |
SlideRange XE "SlideRange" |
Zbiór slajdów |
SlideShowwindow XE "SlideShowwindow" (s) |
Okno, w którym odbywa się pokaz |
Table XE "Table" |
Tabela na slajdzie |
TextRange XE "TextRange" |
Tekst dołączony do kształtu |
WebOptions XE "WebOptions" |
Ustawienia nadpisujące DefaultWebOptions |
Przykłady automatyzacji PowerPoint
Poniższe przykłady przedstawiają przykłady użycia specyficznych właściwości i metod obiektów PowerPoint (rysunek 19.11)
Dodanie slajdu
Do dodania slajdu do prezentacji używana jest metoda Add XE "Add:metoda" .
' Dodaj slajd
Set ppPres = objPP.Presentations.Add
Rysunek 19.11. Prezentacja PowerPoint stworzona za pomocą automatyzacji |
|
Dodanie efektu przejścia
Poniższy fragment programu dodaje do slajdu efekt przejścia:
' Dodanie do slajdu efektu przejścia
objPresentation.Slides(5).SlideShowTransition.EntryEffect = _
ppEffectFade
Wstawianie danych i formatowanie slajdów
Program ten wstawia dane i formatuje slajd:
With objPresentation.Slides(5).Shapes(1)
.TextFrame.TextRange.Text = "Suma sprzedaży"
.Shapes(1).TextFrame.TextRange.Characters.Font.Size = 80
End With
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
Wstawienie rysunku do slajdu
Poniższy fragment dodaje do slajdu fotografię oraz formatuje slajd:
Dim strFileName as String
strFileName = ADOrs!Photos
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.
Model obiektów Outlook
Outlook zawiera ponad 55 obiektów dostępnych poprzez VBA.
|
||
|
Zajrzyj do „Obiekty Microsoft Outlook” w pomocy do Outlooka. Zamieszczony jest tam diagram obiektów Outlooka. |
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
Obiekt Outlook |
Opis |
Action XE "Action" (s) |
Specjalizowana czynność na obiekcie |
AddressEntries XE "AddressEntries" (s) |
Informacje o adresie przesyłki |
Application XE "Application" |
Cała aplikacja Outlook |
AppointmentItem XE "AppointmentItem" |
Spotkanie w kalendarzu |
Tabela 19.4.
Obiekty Outlook (ciąg dalszy)
Obiekt Outlook |
Opis |
Attachment XE "Attachment" (s) |
Dołączony do przesyłki dokument |
ContactItem XE "ContactItem" |
Pojedynczy kontakt w folderze Kontakty |
DistListItem XE "DistListItem" |
Lista wysyłkowa w folderze Kontakty |
DocumentItem XE "DocumentItem" |
Dokument w folderze Outlook |
Explorer XE "Explorer" (s) |
Okno wyświetlające zawartość foldera |
Folders XE "Folders" |
Kolekcja obiektów MAPIFolder |
Inspector XE "Inspector" (s) |
Okno wyświetlające element Outlook |
Items XE "Items" |
Kolekcja elementów w MAPIFolder |
JournalItem XE "JournalItem" |
Pozycja w folderze dziennika |
NameSpace XE "NameSpace" |
Główny obiekt umożliwiający dostęp do danych |
NoteItem XE "NoteItem" |
Notatka w folderze notatek |
Pages XE "Pages" |
Kolekcja stron |
PostItem XE "PostItem" |
List w folderze publicznym |
PropertyPage XE "PropertyPage" (s) |
Strona właściwości definiowanych przez użytkownika |
Recipient XE "Recipient" (s) |
Użytkownik lub zasób |
SyncObject XE "SyncObject" (s) |
Profil synchronizacji dla użytkownika |
TaskItem XE "TaskItem" |
Zadanie w folderze zadań |
Przykłady automatyzacji Outlook
Poniższe przykłady przedstawiają przykłady użycia specyficznych właściwości i metod obiektów Outlooka.
Dodawanie i wyświetlanie folderów
Fragment programu, który dodaje folder oraz wyświetla folder Public.
' Dodaj folder do domyślnego foldery kalendarza
Set objSubFolder = objOutlook.GetNamespace("MAPI").GetDefaultFolder_
(olFolderCalendar).Folders.Add("New Calendar")
Dodawanie nowego zadania i wyświetlenie zadań
Poniższy kod dodaje nowe zadanie i wyświetla zadania:
Dim objOutlook As Outlook.Application
Dim objTaskFolder As Object
Dim objTaskItem As Object
Set objTaskItem = objOutlook.CreateItem(olTaskItem)
With objTaskItem
.Subject = "To jest temat zadania"
.Body = "To jest treść zadania"
' Możesz także dodać przypominanie, czas i datę
.Save
End With
' Przejście do foldera zadań
Set objTaskFolder = obj0utlook.GetNamespace("MAPI")._
GetDefaultFolder(13)
' Wyświetlenie zawartości foldera zadań
objTaskFolder.Display
Tworzenie wiadomości e-mail z załącznikiem
W łatwy sposób możesz wysłać wiadomość e-mail z aplikacji Accessa, automatyzując Outlooka (rysunek 19.12).
Rysunek 19.12. Wysłanie wiadomości e-mail z załącznikiem z Accessa |
|
Program ten tworzy nową wiadomość e-mail i załącza arkusz Excela:
Dim objOutlook As Outlook.Application
Dim objRecipient As Recipient
Dim objAttachment As Attachment
Dim objMailItem As MailItem
' Tworzenie przesyłki e-mail
Set objMailltem = obj0utlook.CreateItem(olMailItem)
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")
' rozwinięcie nazw odbiorców
For Each objRecipient In .Recipients
objRecipient.Resolve
Next
' Wyświetlenie wiadomości
.Display
' Wysłanie wiadomości
.Send
End With
Tworzenie elementów Outlooka
Poniższe instrukcje tworzą różne elementy Outlooka.
|
|||
Element Outlook |
Instrukcja tworząca element |
||
Spotkanie |
Set objItem = objOutlook.CreateItem(olAppointmentItem) |
||
Kontakt |
Set objItem = objOutlook.CreateItem(olContactItem) |
||
Dziennik |
Set objItem = objOutlook.CreateItem(olJournalItem) |
||
Wiadomość e-mail |
Set objItem = objOutlook.CreateItem(olMailItem) |
||
Notatka |
Set objItem = objOutlook.CreateItem(olNoteItem) |
Wyświetlanie domyślnych folderów
W tabeli 19.6 zamieszczone są stałe używane w metodzie GetDefaultFolder do wyświetlenia domyślnych folderów Outlooka.
Tabela 19.6.
Stałe folderów
Nazwa foldera |
Stała dla metody GetDefaultFolder |
Kalendarz |
GetDefaultFolder(olFolderCalendar) |
Kontakty |
GetDefaultFolder(olFolderContacts) |
Skrzynka odbiorcza |
GetDefaultFolder(olFolderInbox) |
Dziennik |
GetDefaultFolder(olFolderJournal) |
Notatki |
GetDefaultFolder(olFolderNotes) |
Zadania |
GetDefaultFolder(olFolderTasks) |
Wyświetlenie foldera publicznego
Poniższy fragment programu wyświetla publiczny folder programu Outlook.
Dim objOutlook As Outlook.Application
Dim objNameSpace As Outlook.NameSpace
Dim objPublicFolders As Outlook.Folders
Dim objAllPublicFolders As Object
Dim objOffice0ontacts As Object
Set objNameSpace = obj0utlook.GetNamespace("MAPI")
Set objPublicFolders = objNameSpace.Folders("Public Folders")
Set objAllPublicFolders = objPublicFolders.Folders("Favorites")
Set objOffiEeContacts = objAllPublicFolders.Folders("Office Contacts")
' Wyświetlenie publicznego foldera "Office Contacts."
objOfficeContacts.DisplayThe
Szukanie elementu w Outlooku
Kod ten pokazuje jak znaleźć kontakt w Outlooku.
Set objItem = objContactItems.Find("[File As] = 'Zelko, John'")
objItem.Display
Filtrowanie elementów w Outlooku
Do filtrowania elementów Outlooka używana jest metoda Restrict. Poniższy program zwraca tylko te kontakty, które mają imię „Steve”:
Set objFilter = objContactItems.Restrict("[First Name] = 'Steve' ")
|
||
|
W przykładach do tego rozdziału znajduje się kompletny program do internetowej poczty elektronicznej. Przesyłki mogą być wysyłane z Outlooka do grup odbiorców zapisanych w bazie danych Accessa. W przykładach znajdują się także program przesyłający listy z Worda do odbiorców z kontaktów Outlooka. |
Automatyzacja Graph
W tej części opisane są specyficzne dla Graph zagadnienia oraz przykłady automatyzacji.
Model obiektów Graph
Graph zawiera ponad 10 obiektów dostępnych poprzez VBA. Tabela 19.7 zawiera często używane obiekty. Obiekty, które mają także kolekcje, zakończone są literą (s).
Tabela 19.7.
Obiekty Graph
Obiekt Graph |
Opis |
Application XE "Application" |
Cała aplikacja Microsoft Graph |
AutoCorrect XE "AutoCorrect" |
Funkcja autokorekty w Graph |
Axis XE "Axis" (s) |
Oś |
Chart XE "Chart" |
Wykres |
Tabela 19.7.
Obiekty Graph (ciąg dalszy)
Obiekt Graph |
Opis |
ChartArea XE "ChartArea" |
Obszar wykresu |
ChartGroup XE "ChartGroup" (s) |
Jedna lub więcej serii punktów narysowanych na wykresie |
Datasheet XE "Datasheet" |
Arkusz danych |
DataTable XE "DataTable" |
Tabela danych w wykresie |
Legend XE "Legend" |
Legenda na wykresie |
PlotArea XE "PlotArea" |
Obszar rysowania w wykresie |
Series XE "Series" (s) |
Serie danych w wykresie |
Tworzenie wykresu
Skomplikowane dokumenty często zawierają wykresy i diagramy. Word i inne produkty Office używają Microsoft Graph XE "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).
Rysunek 19.13. Pojedynczy formularz może pokazywać różne typy wykresów |
|
Przykłady automatyzacji Graph
Po utworzeniu formularza z wykresem użyj obiektu Chart XE "Chart:obiekt" i zmień właściwość ChartType XE "ChartType:właściwość" , aby uzyskać różne typy wykresu. Przykładowo, aby zmienić wykres kolumnowy na kołowy, użyj następującego programu:
' Przypisanie zmiennej do wykresu na ekranie
Set objChart = Me.objProductsSold.Object
' Zmień typ wykresu na kołowy
objChart.ChartType = xl3DPie
' Pokaż legendę
objChart.HasLegend = True
' Usuń zmienną obiektową
Set objChart = Nothing
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.
|
||
|
Gdy automatyzujesz aplikację ze względu na jej możliwości rysowania wykresów, możesz użyć Microsoft Excel lub Microsoft Graph. Powinieneś użyć Excela, ze względu na bardziej rozwinięty model obiektów. |
Automatyzacja MapPoint
W tej części opisane są specyficzne dla MapPoint zagadnienia oraz przykłady automatyzacji.
Model obiektów MapPoint
Obiekty MapPoint są dostępne poprzez VBA.
|
||
|
Zajrzyj do „Obiekty Microsoft MapPoint” w pomocy do MapPoint. Zamieszczony jest tam diagram obiektów MapPoint. |
W tabeli 19.8 zestawione zostały często używane obiekty MapPoint.
Tabela 19.8.
Obiekty MapPoint
Obiekty MapPoint |
Opis |
AppLication XE "AppLication" |
Cała aplikacja MapPoint |
Location XE "Location" |
Lokalizacja |
Map XE "Map" |
Mapa |
PushPin XE "PushPin" |
Pineska |
Przykłady automatyzacji MapPoint
Poniższy przykład automatyzacji MapPoint ma na celu wyświetlenia odpowiedniej mapy (popatrz na rysunek 19.14). Może być on użyty do otwarcia mapy i pokazania położenia klienta.
' Ustaw odwołanie do MapPoint 1.0
Dim objMapPoint As MapPoint.Application
Dim objMap As MapPoint.Map
Set objMapPoint = New MapPoint.Application
' Otwórz mapę Portland w Oregonie
Set objMap = objMapPoint.OpenMap("C:\Maps\Portland, OR.ptm")
' Zwolnienie zmiennej obiektowej
Set objMap = Nothing
Set objMapPoint = Nothing
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.
Model obiektów FrontPage
Obiekty FrontPage są dostępne poprzez VBA.
|
||
|
Zajrzyj do „Obiekty Microsoft FrontPage” w pomocy do FrontPage. Zamieszczony jest tam diagram obiektów FrontPage. |
W tabeli 19.9 zestawione zostały często używane obiekty FrontPage.
Tabela 19.9.
Obiekty FrontPage
Obiekt FrontPage |
Opis |
Application XE "Application" |
Cała aplikacja FrontPage |
HomeNavigationNode XE "HomeNavigationNode" |
Węzeł nawigacji dla strony domowej |
Theme XE "Theme" (s) |
Temat |
Web XE "Web" (s) |
Sieć FrontPage |
WebFile XE "WebFile" (s) |
Plik w opartej na FrontPage sieci |
WebFolder XE "WebFolder" (s) |
Folder w opartej na FrontPage sieci |
WebWindow XE "WebWindow" (s) |
Otwarte okno w opartej na FrontPage sieci |
Przykłady automatyzacji FrontPage
Automatyzując FrontPage, możesz m.in.:
Utworzyć nową sieć lub otworzyć już istniejącą;
Tworzyć lub otwierać foldery sieci;
Tworzyć, otwierać i modyfikować pliki w sieci;
Stosować schematy.
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
Set objFrontPage = New FrontPage.WebWindow
Set objWeb = Webs.Open("C:\Automation\Web")
Set objWebFile = ActiveWeb.RootFolder.Files.Add _
("Podsumowanie sprzedazy.htm")
' Tworzenie połączenia ADO
Set Conn = New ADODB.Connection
' Tworzenie recordsetu ADO
Set ADOrs = New ADODB.Recordset
With Conn
.Provider = "Microsoft.JET.OLEDB.3.51"
.Open "C:\Automation\Automation.mdb"
End With
strSQL = "SELECT Categories.CategoryName AS Category,
Sum([Order Details].UnitPrice) AS Price FROM _
(Categories INNER JOIN Products ON Categories CategoryID = _
Products.CategoryID) INNER JOIN [Order Details]
ON Products.ProductID = [Order Details].ProductID _
GROUP BY Categories.CategoryName _
HAVING (((Sum([Order Details].UnitPrice))>0));"
' Otwarcie recordsetu ADO
ADOrs.Open strSOL, Conn
Set objWebWindow = Webs(0).WebWindows(0)
objWebWindow.Visible = True
' Aktywacja okna sieci
objWebWindow.Activate
' Otwórz stronę sieci
objWebFile.Open
' Wstaw nagłówek
objFrontPage.ActiveDocument.Body.insertAdjacentText "BeforeEnd", _
"Suma sprzedaży kategorii"
' Wstaw dane z bazy danych
Do Until ADOrs.EOF
objFrontPage.ActiveDocument.Body.insertRdjacentText _
"BeforeEnd", ADOrs!Category.Value & vbTab & vbTab &_
ADOrs!Price.Value
ADOrs.MoveNext
Loop
' Zmień schemat strony na "artsy"
objWebWindow.ActivePageWindow.ApplyTheme "artsy", _
fpThemePropertiesAll
' Zapisz stronę
objWebWindow.ActivePageWindow.Save
' Zamknij recordset.
ADOrs.Close
' Wyłącz klepsydrę
Screen.MousePointer = 0
' Zwolnij zmienne obiektowe
Set ADOrs = Nothing
Set objWeb = Nothing
Set objWebFile = Nothing
Set objWebWindow = Nothing
Set objFrontPage = Nothing
Automatyzacja Bindera
W tej części opisane są specyficzne dla Bindera zagadnienia oraz przykłady automatyzacji.
Model obiektów Bindera
Obiekty Bindera są dostępne poprzez VBA.
|
||
|
Zajrzyj do pomocy Bindera. Zamieszczony jest tam diagram obiektów Bindera. |
W tabeli 19.10 zestawione zostały często używane obiekty Bindera.
Tabela 19.10.
Obiekty Bindera
Obiekt Bindera |
Opis |
Binder XE "Binder" |
Aplikacja Microsoft Office Binder |
DocumentProperty XE "DocumentProperty" (s) |
Wbudowana lub zdefiniowana właściwość dokumentu |
PageSetup XE "PageSetup" |
Atrybuty ustawień strony |
Section XE "Section" (s) |
Sekcja w Binderze |
Przykłady automatyzacji Bindera
Zamieszczony tutaj kod tworzy nowy spinacz i dodaje do niego dokumenty:
Dim objBinder As Binder
Set objBinder = New Binder
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
' Zapisz binder
' objBinder.SaveAs "Automation.odb"
Set objBinder = Nothing
Program ten przy użyciu automatyzacji tworzy nowy binder z różnymi dokumentami Office (patrz rysunek 19.15).
Rysunek 19.15. Automatyzacja Microsoft Binder |
|
Zabezpieczanie dokumentów XE "zabezpieczanie dokumentów" , szablonów i kodu programu
Dokumenty, formularze, szablony i moduły kodu mogą być zabezpieczone hasłem. Aby je zabezpieczyć, przejdź do okna projektu w edytorze Visual Basic. Aby zabezpieczyć cały projekt, wywołaj właściwości projektu. Kliknij zakładkę Protection i wprowadź hasło. W ten sam sposób można zabezpieczać hasłem formularze, szablony, dokumenty i moduły kodu.
Rozdział 20.
Użycie Visual Basic z Accessem
W tym rozdziale:
Tworzenie komponentów ActiveX.
Tworzenie formantów ActiveX.
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.
|
||
|
Aby prześledzić przykłady zawarte w tym rozdziale, powinieneś mieć dowolną wersję Visual Basic 6. Jeżeli nie masz Visual Basica, najtańszą wersją jest Learning Edition. |
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.
Tworzenie komponentów ActiveX
Za pomocą Visual Basica możesz tworzyć komponenty ActiveX i używać ich w aplikacjach Accessa. Przykładowym komponentem, który utworzymy w tym rozdziale, będzie komponent umożliwiający odgrywanie plików dźwiękowych w aplikacjach Accessa.
|
||
|
Komponenty ActiveX oraz kontrolki ActiveX omówione w tym rozdziale zawarte są na płycie CD-ROM dołączonej do książki. Komponenty te muszą zostać zarejestrowane w systemie. Aby to zrobić, otwórz plik projektu i skompiluj go. W dalszej części rozdziału znajdziesz dodatkowe informacje na temat rejestrowania komponentów. |
Czym są komponenty ActiveX
Komponent ActiveX XE "komponent ActiveX" to kod w module klasowym skompilowany do postaci pliku wykonywalnego (EXE) lub biblioteki dynamicznej (DLL). Korzyścią tworzenia komponentów ActiveX jest to, że można go stosować w każdej aplikacji wspierającej COM XE "COM" . Dlatego, zamiast ograniczać się tylko do pojedynczej aplikacji Accessa, komponent może być użyty w wielu aplikacjach Accessa, Visual Basica, Office i innych.
W rozdziale 11. „Tworzenie obiektów w modułach klasowych” tworzyłeś obiekt dźwiękowy przy użyciu modułu klasowego cSound XE "cSound:klasa" . W module klasowym plik dźwiękowy jest przekazywany do wywołania Windows API XE "Windows API" , aby odegrać dźwięk. Kod w module klasowym zamieszczony jest na wydruku 20.1.
Wydruk 20.1. Moduł klasowy cSound
Option Explicit
' Wywołanie Windows API
Private Declare Function sndPlaySound Lib "winmm.dll" Alias "sndPlaySoundA" (ByVal lpszSoundName As String, ByVal uFlags As Long) As Long
Public Sub PlaySound(SoundFile As String)
' Odegraj plik dźwiękowy
sndPlaySound SoundFile, 1
End Sub
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.
Różnice między ActiveX EXE i ActiveX DLL
Gdy tworzysz komponent ActiveX w Visual Basicu, możesz utworzyć ActiveX EXE albo ActiveX DLL. Jaka jest różnica?
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.
|
||
|
ActiveX DLL jest wykonywany przez ten sam proces, co wywołująca go aplikacja Accessa. Dlatego ActiveX DLL jest wyraźnie szybszy niż ActiveX EXE. |
Tworzenie komponentu ActiveX
Aby utworzyć komponent ActiveX odgrywający dźwięki, uruchom Visual Basic. W oknie dialogowym New Project, pokazanym na rysunku 20.1, wybierz ActiveX DLL XE "ActiveX DLL" .
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.
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 XE "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 XE "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 obiektu, program zostanie wstrzymany aż do zakończenia obsługi wcześniejszego żądania. Najczęściej używana jest domyślna wartość MultiUse.
|
||
|
Istnieje sześć ustawień właściwości Instancing. Ponieważ w tym rozdziale skupimy się na programowaniu dla potrzeb Accessa, nie będą one szczegółowo opisane. Dodatkowe informacje znajdują się w pomocy do Visual Basica. |
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 |
|
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 XE "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).
Kompilowanie biblioteki DLL
Po utworzeniu i zapisaniu projektu może zostać skompilowana biblioteka DLL zawierająca obiekt. Jest to bardzo łatwe. Wybierz Make cSound Object DLL z menu File. Prawdopodobnie VB zaproponuje zapis pliku DLL w katalogu Visual Basica. Zapisz plik DLL z obiektem cSound w tym samym katalogu co plik projektu.
|
||
|
Zapis pliku DLL w jednym katalogu razem z plikiem projektu ułatwia późniejsze odszukanie plików. |
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.
|
|||||
|
Jeżeli zajrzysz do katalogu z zapisanym projektem (rysunek 20.7), zauważysz wiele plików. Visual Basic zapisuje formularze, moduły i inne obiekty w oddzielnych plikach. Inaczej postępuje Access, który umieszcza wszystkie obiekty w jednym pliku MDB. |
||||
Rysunek 20.7. Visual Basic zapisuje obiekty w oddzielnych plikach |
|
||||
|
|||||
|
Przykład ten przedstawia sposób, jak utworzyć ActiveX DLL. Podobnie tworzy się ActiveX EXE. Rozpocznij po prostu od wybrania ActiveX EXE w oknie New Project. |
Użycie komponentu ActiveX cSound
Po utworzeniu komponentu możesz użyć go w aplikacji Accessa. Aplikacja Accessa musi ustawić odwołanie do komponentu, utworzyć egzemplarz obiektu i użyć go.
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.
Jako obsługę zdarzenia Click wpisz następującą procedurę:
Private Sub cmdSound_Click()
Dim objSound As cSound
Set objSound = New cSound
' Jeżeli używasz Windows NT, użyj ścieżki "C:\WINNT"
objSound.PlaySound "C:\Windows\Media\chimes.wav"
Set objSound = Nothing
End Sub
Czy zauważyłeś w trakcie wpisywania tekstu programu działanie IntelliSense XE "IntelliSense" dla Twojego obiektu (rysunek 20.8)? Jest to wspaniała pomoc ułatwiająca i przyspieszająca wpisywanie kodu programu.
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.
Użycie komponentu w innych aplikacjach
Oprócz Accessa możesz używać komponentu cSound w innych aplikacjach wspierających COM. Możesz użyć tego komponentu w VB, Office, Outlook i programowaniu dla WWW.
Dystrybucja komponentów ActiveX
W trakcie dystrybucji komponentów do użytkowników musisz zająć się następującymi zagadnieniami:
Instalowanie komponentu;
Ustawienia rejestru komponentu;
Zgodność komponentów.
Instalowanie komponentu
Najprostszą metodą instalacji komponentu na komputerze użytkownika jest użycie kreatora Package and Deployment Wizard XE "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.
Tworzenie programu instalacyjnego
przy użyciu Package and Deployment Wizard
Po uruchomieniu kreatora na jego pierwszej stronie znajduje się przycisk Browse. Po kliknięciu tego przycisku należy odnaleźć plik projektu (np.: cSoundObject.vbp, tak jak na rysunku 20.9).
Rysunek 20.9. Pierwszy ekran kreatora Package and Deployment |
|
Na następnej stronie kreatora należy wybrać rodzaj skryptu pakowania XE "skrypt pakowania" (Packaging Script). W tym przykładzie wybierz None (rysunek 20.10).
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:
Standardowy program instalacyjny (Standard Setup Package): tworzy zwykły program instalacyjny.
Instalacja internetowa: tworzy program instalacji przez Internet.
Pliki zależne: program instalacyjny zawiera tylko pliki zależne.
W tym przykładzie użyjemy standardowego pakietu instalacyjnego.
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 |
|
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.
Rysunek 20.13. Lista plików w programie instalacyjnym |
|
||||
|
|||||
|
Biblioteki Visual Basica muszą być zainstalowane na komputerze użytkownika. Po jednokrotnym zainstalowaniu tych plików możesz nie umieszczać ich już w programie instalacyjnym, co wyraźnie zmniejsza jego objętość. |
Na następnym ekranie ustawiamy parametry plików CAB XE "plik 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.
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.
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 |
|
Na następnym ekranie wybierz skrypt dystrybucji (rysunek 20.23).
Rysunek 20.23. Wybór skryptu dystrybucji |
|
Na kolejnym ekranie wybierz pakiet, który chcesz rozprowadzać (rysunek 20.24).
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.
Rysunek 20.27. Wpisywanie nazwy skryptu i rozprowadzanie pakietu |
|
Po wykonaniu dystrybucji tworzony jest raport, który można zapisać na dysku.
Wpisy w rejestrze
Aby komponent mógł działać, do rejestru muszą być wprowadzone odpowiednie informacje. Komponentowi musi zostać przypisany globalny unikatowy identyfikator (GUID XE "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 XE "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 XE "/UNREGSERVER" . Dla ActiveX DLL do programu REGSVR32 dodaj parametr /U.
|
||
|
Jeżeli często rejestrujesz i wyrejestrowujesz komponenty przy użyciu REGSVR32, dodaj REGSVR32 do katalogu SendTo w katalogu Windows. Następnie możesz kliknąć prawym klawiszem myszy plik DLL i wybrać REGSVR32 z menu kontekstowego. |
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).
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.
|
||
|
Nawet, gdy włączysz opcję Binary Compatibility, jeżeli zmienisz interfejs komponentu, wywołująca go aplikacja zawiedzie w czasie użycia komponentu. Przykładowo, gdy metoda komponentu cSound PlaySound zostanie zmieniona na PlayMusic, komponent przestanie być zgodny z poprzednimi wersjami. W takim przypadku zmień opcję zgodności na No Compatibility i roześlij do użytkowników nowy komponent wraz z aplikacją Accessa. |
|
|
||
|
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 bezpiecznym 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.
|
||
|
Przed powtórnym zainstalowaniem komponentu najlepiej usunąć starą wersję. |
Komponent obsługi błędów
W rozdziale 13. „Profesjonalna obsługa błędów” omówiony został moduł klasowy obsługi błędów, który zawierał następujące funkcje:
Zapisywanie błędów w tabeli Accessa;
Zapisywanie błędów w pliku tekstowym;
Przesyłanie błędów jako e-mail;
Zapisywanie błędów w kalendarzu Outlooka.
Do tego rozdziału dołączony został jeszcze obszerniejszy moduł obsługi błędów, który używa komponentu cError XE "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.
|
||
|
Na dysku znajdują się aplikacje Accessa i Visual Basica, które używają komponentu cError do obsługi błędów. |
Dane modułu obsługi błędów
Moduł obsługi błędów zapisuje dane w bazie danych Accessa o nazwie Global Error Handler Data.mdb. Baza ta zawiera dwie tabele. Informacje o błędach przechowywane są w tabeli tblErrorLog. Druga tabela, tblErrorOptions, zawiera ustawienia sposobu pracy modułu. Formularz frmErrorOptions, przedstawiony na rysunku 20.30, zapewnia łatwy dostęp do tych ustawień.
Rysunek 20.30. Formularz ustawień pracy modułu obsługi błędów |
|
Dodatkowo w bazie umieszczony jest raport błędów.
Komponent cError
Komponent obsługi błędów wykonuje dużo operacji. Zawiera on sześć modułów klasowych:
cComputerName - pobiera nazwę komputera.
cDBConnection - tworzy połączenie ADO.
cError - przetwarza informacje o błędach.
cSound - odgrywa pliki dźwiękowe.
cSystemInformation - pobiera informacje o komputerze, takie jak: system operacyjny, procesor, ilość zainstalowanej i wolnej pamięci.
cUserName - pobiera nazwę użytkownika Windows.
Tworzenie formantów ActiveX
Visual Basic umożliwia tworzenie własnych formantów ActiveX, co daje ogromne możliwości rozszerzania aplikacji.
Rodzaje formantów ActiveX
W rozdziale 9. „Rozszerzanie formularzy za pomocą formantów ActiveX” opisane zostały 23 formanty wraz z przykładami ich użycia.
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.
Atrybuty formantów ActiveX
Formanty ActiveX nie mogą istnieć niezależnie, muszą zostać utworzone w aplikacji bazowej, zwykle na formularzu.
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.
Tworzenie programowych formantów ActiveX
W Accessie, gdy potrzebny jest stoper, programiści używają zdarzenia On Timer i właściwości Timer formularza. Jedynym problemem tego podejścia jest to, że może być użyty tylko jeden stoper. Co zrobić, jeżeli potrzebujemy wielu niezależnych stoperów?
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.
|
|||
|
|
Projekt formantu i baza Accessa wykorzystująca formant Timer zamieszczone są na dysku CD-ROM dołączonym do książki. Pamiętaj, że musisz zarejestrować (lub skompilować projekt) formant ActiveX. |
|
|
Utworzenie projektu dla formantu ActiveX
Aby utworzyć formant ActiveX po uruchomieniu Visual Basica, wybierz ActiveX Control w oknie New Project.
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 XE "UserControl:obiekt" . 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 XE "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).
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 XE "InvisibleAtRuntime" na True.
Ustawianie właściwości projektu
Wybierz Project1. Properties z menu Project. W oknie właściwości projektu wprowadź nazwę projektu (cTimerControl) i opis (Formant cTimer) w sposób pokazany na rysunku 20.36. Zamknij okno przez kliknięcie przycisku OK.
Rysunek 20.36. Wprowadzanie nazwy i opisu projektu |
|
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.
Dodawanie metod i zdarzeń
Kliknij obiekt UserControl (nie PictureBox) i przejrzyj listę właściwości. Zauważ, że nie ma tam właściwości Interval XE "Interval" . Musisz ją tam dodać. Również należy dodać zdarzenie Timer, aby było możliwe wpisywanie kodu procedury uruchamianej po zajściu zdarzenia. Aby dodać właściwości, metody i zdarzenia, uruchom kreator ActiveX Control Interface Wizard.
Użycie kreatora ActiveX Control Interface Wizard
Kreator ten uruchamiamy poprzez wybranie ActiveX Control Interface Wizard z menu Add-Ins. Jeżeli nie masz go w tym menu, wybierz Add-In Manager, VB 6. ActiveX Control Interface Wizard i kliknij pole wyboru Load on Startup.
Pierwszy ekran kreatora jest ekranem informacyjnym (rysunek 20.37). Kliknij przycisk Next.
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.
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.
Dodajemy kod do formantu ActiveX
Kreator ActiveX Control Interface Wizard XE "ActiveX Control Interface Wizard" wykonał za Ciebie dużą część pracy, ale musisz dodać jeszcze kilka wierszy kodu, aby dokończyć pracę nad formantem 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 |
|
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.
Użycie zdarzenia ReadProperties XE "ReadProperties:zdarzenie"
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
Upewnij się, że zapisałeś projekt.
Testowanie formantu ActiveX w Visual Basicu
Przed użyciem formantu w Accessie przetestujmy go w Visual Basicu.
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.
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.
Rysunek 20.48. Okno komunikatu otwiera się co 5 sekund |
|
Po przetestowaniu formantu w Visual Basicu użyjemy go w Accessie.
Użycie formantu Timer na formularzu Accessa
Przetestowanie formantu w Visual Basicu było bardzo proste. Aby użyć formantu w Accessie, należy skompilować formant.
Otwórz projekt formantu ActiveX i wybierz Make cTimerControl z menu File. Zapisz plik OCX w tym samym katalogu co projekt.
Formant ActiveX został skompilowany oraz zostały wprowadzone wpisy do rejestru.
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.
Formant cTimerControl będzie teraz działać na formularzu Accessa.
Tworzenie wielu formantów Timer
Na początku tego rozdziału wspominaliśmy o możliwości wykorzystania zdarzenia OnTimer z formularza Accessa jako stopera. Jednak w ten sposób możliwe jest uruchomienie tylko jednego stopera. Możesz wstawić do formularza kilka formantów Timer i każdy z nich będzie pracować niezależnie (rysunek 20.50).
Rysunek 20.50. Kilka formantów Timer pracujących jednocześnie |
|
Rozprowadzanie formantu ActiveX Timer
Sposób rozprowadzania formantów ActiveX jest w zasadzie taki sam jak rozprowadzanie komponentów ActiveX. Przeczytać możesz o tym wcześniej w części zatytułowanej „Dystrybucja komponentów ActiveX”.
Tworzenie okna właściwości XE "okno właściwości"
W rozdziale 9. opisywaliśmy, w jaki sposób utworzyć okno właściwości, aby łatwo można było ustawiać wartości właściwości formantu ActiveX. Na rysunku 20.51. pokazane jest okno właściwości formantu ImageList.
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 startowym kliknij przycisk Next.
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).
Rysunek 20.54. Okno właściwości w oknie Project Explorer |
|
Użycie okna właściwości
Aby użyć okno właściwości, zapisz i ponownie skompiluj projekt formantu ActiveX. Otwórz formularz Accessa w trybie projektowania i dodaj formant Timer. Następnie kliknij prawym klawiszem myszy formularz i wybierz z menu cTimerControl properties. Na stronie właściwości możesz wprowadzić wartość właściwości Interval (rysunek 20.55).
Rysunek 20.55. Użycie okna właściwości |
|
Użycie formantu Timer w innych aplikacjach
Nasz formant nie jest ograniczony do stosowania tylko w VB i Accessie. Ten sam formant może być używany w Wordzie, Excelu, Outlooku i innych aplikacjach.
Tworzenie formantów ActiveX interfejsu użytkownika
Większość formantów ActiveX posiada interfejs użytkownika wykorzystywany do manipulacji formantem. W tej części utworzymy taki formant ActiveX. Przykładowy formant nazywa się cSlider XE "cSlider" i zawiera dwa formanty Slider i UpDown. Gdy użytkownik zwiększa i zmniejsza wartość za pomocą formantu UpDown, Slider się przesuwa.
|
||
|
Projekt VB formantu ActiveX oraz baza danych Accessa, która używa formantu cSlider, są dostępne na dysku CD-ROM dołączonym do książki. Pamiętaj, aby zarejestrować formant (lub skompilować projekt) przed jego użyciem. |
|
|
Tworzenie interfejsu użytkownika
Tak jak dla formantów programowych otwórz projekt formantu ActiveX. Dodaj formant Slider oraz UpDown do obiektu UserControl w sposób pokazany na rysunku 20.56. Zauważ, że można w jednym formancie ActiveX umieścić wiele innych formantów.
Nazwij następująco obiekty:
UserControl: cSlider
Slider control: ctlSlider
UpDown control: ctlUpDown
a następnie zmniejsz obiekt UserControl.
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 |
|
Ustawienie właściwości projektu
Wybierz Project1 Properties z menu Project. W oknie dialogowym Project Properties wprowadź nazwę projektu (cSliderControl) oraz opis projektu (formant cSlider). Kliknięcie OK zamyka okno (rysunek 20.58).
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.
Testowanie formantu na formularzu Visual Basica
Aby przetestować formant cSlider na formularzu Visual Basica, wykonaj te same czynności co przy testowaniu formantu designtime.
Rysunek 20.58. Wprowadzanie nazwy i opisu projektu w oknie właściwości projektu |
|
Użycie formantu cSlider na formularzu Accessa
Otwórz projekt formantu i wybierz Make cSliderControl.ocx z menu File. Zapisz plik OCX w tym samym katalogu co plik projektu. Po tej operacji formant ActiveX jest gotowy do pracy, a w rejestrze są wszystkie odpowiednie wpisy.
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 |
|
Dystrybucja formantu ActiveX cSlider
Rozprowadzanie formantów ActiveX nie różni się niczym od rozprowadzania komponentów ActiveX. Zajrzyj do części „Dystrybucja komponentów ActiveX”.
Użycie formantu cSlider w innych aplikacjach
Twój formant cSlider nie jest ograniczony tylko do aplikacji VB i Accessa. Ten sam formant może być użyty Wordzie, Excelu, Outlooku i innych aplikacjach.
Tworzenie instalacyjnego pakietu internetowego
Aby użyć formantu ActiveX cSlider na stronie WWW, użyj opcji Internet Package w kreatorze Package and Deployment Wizard.
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 |
|
Wybierz typ Internet Package i kliknij Next (rysunek 20.62).
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.
|
||
|
Ustaw serwer WWW Microsoftu jako położenie bibliotek VB i innych plików Microsoftu. Microsoft zapewnia większą przepustowość łącz niż większość firm, co zapewnia poprawne załadowanie aktualnych plików. |
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.
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.
Użycie formantu cSlider na stronie WWW
Otwórz katalog, w którym zapisałeś pakiet internetowy. Zauważ, że został utworzony plik cSliderControl.htm (rysunek 20.68).
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 |
|
||||
|
|||||
|
Nie wszystkie przeglądarki obsługują formanty ActiveX. Jednak Microsoft Internet Explorer, jak widać na rysunku 20.69, obsługuje formanty ActiveX. |
||||
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:
Zagadnienia wielodostępu, serwer plików, blokowanie.
Replikacja i JRO.
Bezpieczeństwo.
Rozdział 21.
Zagadnienia wielodostępu, serwer plików, blokowanie
W tym rozdziale:
Konflikty.
Konfiguracja.
Blokady Accessa i Jet.
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 XE "blokada" i konflikty XE "konflikt" . 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:
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.
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ż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.
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.
Konfiguracja sieciowa XE "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.
Oddzielenie danych od programu. Taka konfiguracja jest zwykle nazywana konfiguracją z użyciem zdalnej bazy danych XE "zdalna baza 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.
Replikacja XE "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.
Konfiguracja klient-serwer XE "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.
Access i blokady Jet
Jet posiada schemat blokowania, który pozwala na efektywne obsługiwanie wielu użytkowników. Gdy Jet jest używany w Accessie, w odróżnieniu od użycia go w VB lub innym środowisku programowania, istnieje kilka domyślnych ustawień, które powinieneś rozpatrzyć. Ta część rozdziału zajmuje się tymi zagadnieniami.
Omówienie blokowania XE "blokowanie"
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 XE "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 |
|||
|
||||
|
Nie można pozwolić użytkownikom na otwarcie bazy na wyłączność, jeżeli ma pracować na niej wielu użytkowników. Można się przed tym zabezpieczyć, odbierając mu prawo Otwórz z wyłącznością z grupy użytkowników. Szczegółowo zostało to opisane w rozdziale 23. „Bezpieczeństwo”. |
Programista ma możliwość ustawienia w bazie domyślnego trybu blokowania rekordów. Możliwe są dwa tryby: blokowanie rekordu i blokowanie strony.
Blokowanie stron XE "blokowanie stron" kontra blokowanie rekordów XE "blokowanie rekordów"
W przeszłości Access był szczególnie podatny na konflikty z powodu sposobu zapisu rekordów i ich blokowania. Ponieważ Access posiadał rekordy o zmiennej wielkości, nie dało się łatwo zaimplementować blokowania rekordów. Access zapisywał rekordy na stronach o wielkości 2KB (w silniku bazy danych Accessa 2000 - Jet 4.0 strony mają po 4KB). Gdy rekord był blokowany umyślnie bądź przypadkowo, blokowana była cała strona. Zablokowanie strony blokowało również inne rekordy, które zapisane były na tej stronie. Mimo że ten sposób blokowania jest bardzo wydajny, połączone jest to z częstymi konfliktami i ogranicza ilość użytkowników jednocześnie korzystających z bazy. Jest to często krytykowane ograniczenie przy tworzeniu aplikacji w Accessie.
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 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.
Optymistyczne i pesymistyczne blokowanie rekordów
W aplikacjach wieloużytkownikowych jedynym bezpiecznym założeniem, jakie może zrobić programista, jest możliwość wystąpienia konfliktów przy dostępie użytkowników do jednego rekordu. Jedynym sensowną rzeczą do zrobienia jest zaplanowanie, w jaki sposób obsługiwać te sytuacje poprzez odpowiednie ustawienie opcji blokowania. Są to zasadniczo dwie opcje: blokowanie optymistyczne i pesymistyczne.
Blokowanie optymistyczne XE "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 XE "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.
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 XE "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.
Właściwość RecordLocks XE "RecordLocks: właściwość" w interfejsie związanym
Gdy w Accessie otwierany jest związany formularz lub zestaw rekordów, możliwe jest nałożenie blokady na bazowy zestaw rekordów. Oczywiście opcja ta działa tylko w przypadku rozwiązań z użyciem Jet, gdy używamy architektury klient-serwer, Access zawsze przyjmuje opcję „Bez blokowania”.
Programista ma możliwość wyboru z:
Bez blokowania - jest to odpowiednik blokowania optymistycznego.
Edytowany rekord - jest to odpowiednik blokowania pesymistycznego.
Wszystkie rekordy - blokuje wszystkie rekordy w zestawie. Należy ostrożnie używać go w aplikacjach wielodostępnych.
|
||
|
Mimo że połączenie interfejsu użytkownika z danymi jest najprostszą metodą udostępnienia użytkownikom danych, jednak robiąc to tracisz możliwość kontroli. Na formularz podłączonym do pesymistycznie zablokowanego rekordu użytkownik dostanie przekreślone O w pasku wyboru rekordu, jednak nie wiadomo, kto zablokował rekord. Jeżeli pasek wyboru rekordu jest niewidoczny, użytkownik usłyszy tylko sygnał dźwiękowy. |
Metody blokowania silnika Jet
Blokady są normalną i niezbędną operacją w bazie danych, jednak aby upewnić się, że blokady są właściwego typu i czasu trwania, powinieneś mieć możliwość dostania informacji o tym kiedy nastąpiła blokada. W tej części opisane zostało rozpoznawanie typów blokad w aplikacji, aby sprawdzić, czy projekt aplikacji jest właściwy.
Określanie stanu blokad
Jak jest to opisane wcześniej, blokowanie rekordu lub strony jest wykonywane w różnych momentach w zależności, czy jest to blokowanie optymistyczne, czy pesymistyczne. Także różne części aplikacji (lub różne aplikacje) mogą używać różnych typów blokowania tych samych danych w tym samym czasie. Z tego powodu mogą wystąpić różne typy błędów. Otrzymany błąd zależy od stanu blokady.
ADO dostarcza właściwości LockType XE "LockType:właściwość" 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ć.
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 XE "Supports:metoda" 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 |
||||
|
|||||
|
adLockPessimistic nie działa, gdy właściwość CursorLocation jest ustawiona na adUseClient, jednak nie wystąpi żaden błąd. Jet podstawi inny podobny typ blokowania. Dzieje się tak, ponieważ używając adUseClient, serwer nie śledzi bieżącego rekordu, więc nie jest możliwe pesymistyczne blokowanie. |
||||
|
|||||
|
Podzbiór ADOR (ADOR to podzbiór modelu obiektów ADO, który dostarcza tylko obiektów Recordset i Field, które mogą być tworzone lub przesyłane z serwera do klienta), dostarcza tylko typu blokowania adLockOptimisticBatch. |
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.
Inne wartości właściwości EditMode XE "EditMode:właściwość" opisane są w tabeli 21.3.
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 XE "Update" lub CancelUpdate XE "CancelUpdate" , gdy operacja została przerwana.
Tabela 21.3.
Wartości właściwości EditMode dla obiektu recordset ADO
Stała |
Opis |
adEditNone |
Rekord nie był zmieniony |
adEditInProgress |
Dane w rekordzie są zmienione, ale nie były zapisane |
adEditAdd |
Występuje, gdy wywołana została metoda AddNew. Wskazuje na to, że w buforze jest nowy rekord niezapisany do tabeli |
adEditDelete |
Bieżący rekord został skasowany |
Sprawdzanie blokad XE "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> |
Tablica błędów zawiera inne użyteczne informacje dotyczące błędu blokowania, informacje o blokadach innego użytkownika. Właściwość NativeError XE "NativeError:właściwość" oraz Number XE "Number:właściwość" 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
Użytkownik |
Właściwość |
Wartość |
Typ blokady |
Ty |
Connection.Errors(0).NativeError |
-533791822 |
Pesymistyczna |
Ty |
Connection.Errors(0).Number |
-105514571 |
Optymistyczna |
Inny |
Connection.Errors(0).NativeError |
-2147467259 |
Pesymistyczna |
Inny |
Connection.Errors(0).Number |
-2147217887 |
Optymistyczna |
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.
Użycie blokowania stron XE "blokowanie stron"
Access przez długi czas nie potrafił blokować rekordów (istniało pewne obejście problemu) i zamiast tego blokował całą stronę, jak to zostało opisane wcześniej w tym rozdziale. Aby skorzystać ze wzrostu wydajności blokowania stron, wyłącz domyślne blokowanie rekordów. Aby to zrobić wybierz Narzędzia→Opcje→Zaawansowane i wyłącz Otwórz z blokowaniem na poziomie rekordu.
Obsługa błędów blokowania
Każdy system wieloużytkownikowy powinien uprzedzać komunikaty błędów. Różne systemy obsługują błędy w różny sposób. Różne systemy dostarczają różnej informacji dla programistów i użytkowników w przypadku wystąpienia błędu blokady. W tej części omówimy niektóre ustawienia blokowania i błędy blokowania, które możesz napotkać w trakcie programowania w Accessie 2000. Przedstawione zostaną niektóre techniki obsługi błędów i unikania ich.
Ustawienia blokowania Accessa
Najlepszą metodą obsługi błędów wielodostępu jest unikanie ich. Access dostarcza kilka właściwości, które mogą zostać ustawione, aby zmniejszyć częstotliwość konfliktów. Opcje te znajdują się na zakładce Zaawansowane okna dialogowego Opcje. Jednak nie mogą same obsłużyć wszystkich błędów.
Liczba ponownych prób aktualizacji. Tyle razy Access powtarza próby zapisu lub aktualizacji rekordu, gdy wystąpiła blokada. Dopuszczalne wartości 1-10.
Interwał odświeżania ODBC. Interwał odświeżania w sekundach w czasie używania bazy danych ODBC. Dopuszczalne wartości 1-3600.
Interwał odświeżania. Interwał odświeżania w sekundach w przypadku odświeżania rekordów w formularzu lub arkuszu danych. Dopuszczalne wartości
1-32766.
Interwał ponawiania prób aktualizacji. Czas w milisekundach między próbami zapisu zmienionego rekordu, gdy wystąpiła blokada. Dopuszczalne wartości
1-32766.
Konflikty zapisu
Błąd konfliktu zapisu XE "konflikt 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 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 XE "transakcja" łą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 XE "commit" ) lub w całości się nie udać (zostają wycofane - rollback XE "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 XE "Connection:obiekt" w ADO. W tabeli 21.6 opisane są te trzy metody.
Tabela 21.6.
Definiowanie transakcji
Metoda |
Opis |
BeginTrans XE "BeginTrans" |
Od tego wywołania instrukcje będą wykonywane jak jedna. |
CommitTrans XE "CommitTrans" |
Kończy zestaw instrukcji i zatwierdza je do bazy danych. |
RollbackTrans XE "RollbackTrans" |
W wypadku błędu anuluje wszystkie instrukcje i przywraca bazę danych do postaci sprzed BeginTrans. |
Podstawowa postać przetwarzania transakcyjnego przedstawiona jest na wydruku 21.1.
Wydruk 21.1. Użycie transakcji w VBA
Function TestTrans() As Boolean
Dim conn As ADODB.Connection
Dim rst As ADODB.Recordset
On error resume Err_TestTrans
Set conn=New ADODB.Connection
Conn.BeginTrans
' wykonanie instrukcji np. instrukcji SQL lub metod Edit, Update
' AddNew
' Jeżeli wszystko się udało zatwierdzamy transakcję
Conn.CommitTrans
Exit Function
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.
Blokady Oracle/SQL Server
Gdy oprzesz aplikację na serwerze SQL, np.: Oracle, Informix czy SQL Server, Access przestaje zarządzać blokadami. Jednak założenia pozostają identyczne - kontrolować dostęp do rekordów w taki sposób, aby wielu użytkowników mogło używać bazy w tym samym czasie. Serwery baz danych realizują to bardzo dobrze. Ponieważ dane są w tym samym miejscu co silnik bazy danych, blokowanie rekordów i zarządzanie wielodostępem realizowane jest szybko, niezauważalnie i stabilnie. Każdy z tych programów przechowuje informacje o blokadach w tabeli przechowywanej w pamięci i może efektywnie wykonać nałożenie blokady, wykonanie operacji i zdjęcie blokady w przeciągu mikrosekund.
W przypadku użycia SQL Server używane są trzy typy blokad:
Blokady współdzielone XE "blokada współdzielona" - używane są przy operacjach odczytu, pozwalają innym użytkownikom odczytać rekord lub stronę, która zawiera rekord. Na rekord lub stronę może być nałożone wiele blokad współdzielonych jednocześnie. Blokady te są zdejmowane zaraz po tym, jak dane przestają być potrzebne.
Blokada na wyłączność XE "blokada na wyłączność" - gdy wykonywane są instrukcje SQL Update, Delete lub Insert, na dane zakładana jest blokada na wyłączność. Jeżeli została nałożona blokada na wyłączność, nie można wykonać żadnej innej operacji nakładającej blokadę, dopóki serwer SQL zwolni blokadę po zatwierdzeniu danych.
Blokada ruchoma XE "blokada ruchoma" - blokada ruchoma jest żądaniem blokady na wyłączność i jest nakładana po czterech kolejnych nieudanych próbach zablokowania rekordu na wyłączność. Blokada ruchoma nakładana jest również, gdy jednocześnie nałożonych jest zbyt wiele blokad współdzielonych. Gdy wystąpi taka sytuacja, serwer SQL nie nałoży więcej blokad współdzielonych. Blokady ruchome zabezpieczają przed zmonopolizowaniem tabeli przez blokady współdzielone (pochodzące z operacji odczytu) i niedopuszczeniem do operacji zapisu. Blokady ruchome zabezpieczają przed sytuacją zwaną jako „zagłodzenie blokadami”.
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 XE "blokowanie dynamiczne" 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:
Kiedy użyć replikacji.
Kiedy nie używać replikacji.
Przystosowanie bazy do replikacji.
Replikacja przy użyciu aktówki.
Użycie interfejsu użytkownika.
Jet i model obiektowy replikacji.
Opis metod i właściwości JRO.
Obiekty repliki.
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 XE "Jet Replication Model" \t "Patrz" (JRO XE "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.
Kiedy użyć replikacji
Istnieje kilka czynników, które powinny być wzięte pod uwagę przy rozważaniu użycia replikacji. Nie jest niespodzianką, że każdy potencjalny plus replikacji posiada także minus. Jednak istnieje kilka sytuacji, kiedy replikacja XE "replikacja" jest mądrym wyborem.
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 programistó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.
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ą XE "partycja pionowa" , 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ą XE "partycja pozioma" , 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 XE "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.
Kiedy nie używać replikacji
Jak wszystko inne, replikacja nie jest panaceum. Poniżej przedstawione zostały przypadki, kiedy nie powinieneś używać replikacji.
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ść.
Przystosowanie bazy do replikacji
Istnieje kilka sposobów na przystosowanie bazy danych do replikacji. W tym rozdziale opisane zostaną: aktówka, interfejs użytkownika Accessa oraz Jet Replication Object (JRO).
Replikacja przy użyciu aktówki
Najprostszą metodą replikacji danych jest użycie aktówki XE "aktówka" . Mimo że technika ta pozwala tylko na synchronizowanie komputera biurkowego z laptopem, jest dobrą metodą rozwiązania wielu problemów. Metoda ta działa także z innymi plikami, nie tylko z bazą Accessa.
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:
Otwórz Explorer.
Otwórz aktówkę.
Skopiuj bazę danych Accessa do okna aktówki i wykonaj czynności zalecone w oknach dialogowych kończących się oknem z rysunku 22.1.
Rysunek 22.1. Wybór bazy danych jako repliki w aktówce |
|
W pierwszym oknie dialogowym kliknij przycisk Tak. Baza danych musi się zwiększyć, aby mogła być replikowana.
Pozwól aktówce wykonać kopię bazy danych, jeżeli masz odpowiednią ilość miejsca na dysku.
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.
Jeżeli otworzysz jedną z kopii, zauważysz w tytule okna Wzorzec projektowania XE "wzorzec projektowania" lub Replika.
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.
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:
Z bazy danych, którą chcesz zmienić na formę niereplikowalną, wybierz Narzędzia, Opcje i zakładkę Widok. Wyłącz Obiekty systemowe.
Utwórz nową bazę danych i otwórz ją.
Zaimportuj wszystkie obiekty z repliki do nowej bazy.
Upewnij się, że na zakładce Widok w oknie dialogowym Opcje, wybrane jest pole wyboru Obiekty systemowe.
Usuń kolumny s_GUID, s_Lineage, s_Generation i s_colLineage z wszystkich tabel.
Zapisz nową bazę.
Użycie interfejsu użytkownika
Interfejs użytkownika Accessa pozwala na większą elastyczność niż aktówka, lecz jest nieco bardziej skomplikowany. Używając takiego podejścia, możesz uruchomić replikację pomiędzy różnymi użytkownikami w sieci, aby mogli współdzielić dane i inne obiekty Accessa. Gdy używamy interfejsu Accessa, można także wybrać, które z obiektów mają być replikowane i te, które nie będą replikowane. Podejście to pozwala na kontrolę, kiedy i z kim replikować.
Otwórz bazę na wyłączność, upewniając się, że nie ma założonego hasła.
Z menu Narzędzia wybierz Replikacja, Utwórz replikę (rysunek 22.2).
Rysunek 22.2. Tworzenie repliki przez interfejs Accessa odbywa się przez wybór z menu |
|
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:
Tworzony jest nowy plik MDB i importowane są do niego wszystkie obiekty.
Tworzy właściwość replicable XE "replicable:właściwość" dla każdego obiektu i ustawia jej wartość na T, więc zostanie on replikowany.
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
Nazwa pola |
Typ pola |
Opis |
s_ColLineage |
OLE Object |
Śledzi zmiany w kolumnie lub polu |
s_Generation |
Number |
Śledzi zmiany rekordu |
s_Lineage |
OLE Object |
Śledzi inne zmiany |
s_GUID |
AutoNumber |
Globalny unikatowy identyfikator rekordu |
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 XE "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
Nazwa tabeli |
Przeznaczenie |
MSysConflicts XE "MSysConflicts" |
Zapamiętuje nierozwiązane konflikty. Tabela jest pusta po rozwiązaniu wszystkich konfliktów |
MSysExchangeLog XE "MSysExchangeLog" |
Zapamiętuje różne dane na temat każdej synchronizacji |
MSysGenHistory XE "MSysGenHistory" |
Zapobiega wysłaniu niezmienionych rekordów w trakcie synchronizacji |
MSysOthersHistory XE "MSysOthersHistory" |
Zapisuje różne szczegóły działania z innych replik |
Tabela 22.2.
Tabele dodane do bazy danych podczas przystosowania do replikacji (ciąg dalszy)
Nazwa tabeli |
Przeznaczenie |
MSysRepInfo XE "MSysRepInfo" |
Informacje o zbiorze replik i wzorcu projektowania, razem z GUID |
MSysReplicas XE "MSysReplicas" |
GUID dla każdej repliki w zbiorze |
MSysRepLock XE "MSysRepLock" |
Zapisuje nieudane próby zablokowania rekordów w trakcie synchronizacji |
MSysSchChange XE "MSysSchChange" |
Zmiany schematu bazy danych wykonane we wzorcu projektowania. Są tu przechowywane, dopóki są potrzebne |
MSysSchedule XE "MSysSchedule" |
Zapisy planowania tworzone przez Replication Manager |
MSysSideTables XE "MSysSideTables" |
Nazwy tabel i GUID dla potrzeb konfliktów |
MSysTableGuids XE "MSysTableGuids" |
Nazwy replikowanych tabel wraz z GUID |
MSysTombStone XE "MSysTombStone" |
GUID tabel i rekordów dla usuniętych obiektów |
MSysTranspAddress XE "MSysTranspAddress" |
Identyfikuje replikę (repliki), z którą bieżąca replika jest synchronizowana |
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 XE "Replicable:właściwość" , ReplicableID XE "ReplicableID:właściwość" oraz DesignMasterID XE "DesignMasterID:właściwość" .
Replicable wskazuje silnikowi Jet, że baza może być replikowana.
ReplicableID w sposób jednoznaczny identyfikuje bazę danych i wyróżnia ją spośród innych replik.
DesignMasterID wskazuje na bazę, która zarządza zmianami w replikach.
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.
|
||
|
Replikacja ogranicza ilość zagnieżdżonych transakcji w bazie. Replika obsługuje tylko sześć zagnieżdżonych transakcji. |
Wybór między obiektami lokalnymi i replikowanymi
Gdy rezygnujesz z używania aktówki jako narzędzia replikacji i rozpoczynasz korzystanie z możliwości Accessa, jedną z pierwszych rzeczy, nad którą powinieneś się zastanowić, jest wybór czy obiekt ma być lokalny, czy replikowany. Kolejnymi są: wybór topologii replikacji oraz czy proces replikacji ma być kierowany, czy niekierowany, bezpośredni lub pośredni.
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.
Aby zmienić obiekt na lokalny, należy wykonać poniższe kroki:
Wybierz obiekt.
Kliknij prawym klawiszem myszy i wybierz Właściwości z menu kontekstowego.
Wyczyść pole wyboru przy właściwości Replicable i kliknij OK.
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 XE "topologia 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ą.
Planowanie topologii replikacji
Decyzja użycia replikacji i utworzenie replik to tylko część tego, co należy zrobić, aby wykorzystać możliwości replikacji Accessa. Następnie musisz ustalić, kto będzie z kim synchronizował dane, kiedy będzie je synchronizował, jak zapewnić, że replikacja będzie wykonana na czas oraz jak obsługiwać zawiłości takie jak zdalni użytkownicy i powolne połączenia.
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
Topologia |
Zalety |
Wady |
Zalecane użycie |
|
Wielokrotne połączenia |
Zapewnienie najbardziej aktualnych danych |
Możliwe duże obciążenie sieci |
Gdy ważne są szybkie aktualizacje i jest niewielu użytkowników |
|
Gwiazda |
Małe obciążenie sieci |
Środek jest newralgicznym punktem, obciążenie jest nierównomierne, wymagane są wielokrotne synchronizacje, aby rozesłać zmiany do wszystkich użytkowników |
Niewielu użytkowników i powolna sieć |
|
Rysunek 22.3. Podstawowe topologie replikacji |
|
Tabela 22.3.
Wady i zalety różnych topologii (ciąg dalszy)
Topologia |
Zalety |
Wady |
Zalecane użycie |
Drzewo |
Małe obciążenie, dokładna kontrola nad zależnymi replikami |
Nieoczywiste opóźnienia, nierówne obciążenie, uszkodzenie niektórych węzłów jest poważniejsze niż innych |
Gdy tylko niektórzy użytkownicy uaktualniają dane, drzewo jest bardzo efektywne |
Pętla |
Równe rozłożenie obciążenia, małe obciążenie sieci |
Nieodporna na uszkodzenia, jeżeli replikacja nie może odwrócić kierunku |
Użyj w sytuacjach, gdy ważne jest równe obciążenie |
Magistrala |
Największe opóźnienie, równe rozłożenie obciążenia, małe obciążenie sieci |
Bardzo nieodporna na uszkodzenia |
Proste tworzenie, dobre tylko dla replikacji pojedynczego użytkownika |
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ą.
Wybór schematu sterowanego
Schemat sterowany XE "schemat sterowany" używa aplikacji Manager replikacji oraz Manager synchronizacji. Manager replikacji pozwala na planowanie i kontrolę replikacji oraz rozwiązywanie powstałych konfliktów. Możliwość pracy w tle, przechowywanie rekordów oraz synchronizacja co 15 minut powoduje, że warto jej używać. Mimo że istnieje możliwość skopiowania takich funkcji we własnym programie JRO lub DAO, zwykle nie ma takiej potrzeby.
Synchronizacja bezpośrednia XE "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 XE "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.
Wybór schematu niesterowanego
Schemat niesterowany XE "schemat niesterowany" nie polega na Managerze synchronizacji. Jeżeli masz bardzo poważne powody, jak na przykład częstsza synchronizacja, niż pozwala na to manager lub niektóre typy synchronizacji zależnej od zdarzeń (np. gdy ilość przedmiotów w magazynie przekroczy założony poziom), możesz sterować synchronizacją za pomocą własnego programu.
Po tych wyjaśnieniach wybierz Narzędzia, Replikacja, Synchronizuj i kliknij przycisk OK, aby rozpocząć synchronizację poprzez interfejs użytkownika Accessa.
Jet i model obiektowy replikacji
Najlepszą kontrolę nad procesem replikacji oraz rozwiązywaniem konfliktów zapewnia użycie obiektów z Jet Replication Object (JRO). Przy użyciu tej metody jest możliwe prawie całkowite ukrycie przed użytkownikami procesu replikacji. Jeżeli dokładnie zaplanuje się proces replikacji, JRO pozwoli na skorzystanie ze współdzielonych danych w sposób bezbolesny i niewidoczny dla użytkowników aplikacji.
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 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 ilustruje model JRO.
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
Nazwa |
Składnik klasy |
Typ |
Uwagi |
ActiveConnection XE "ActiveConnection" |
JRO.Replica |
Object |
|
ConflictFunction XE "ConflictFunction" |
JRO.Replica |
String |
|
ConflictTables XE "ConflictTables" |
JRO.Replica |
Recordset |
Tylko do odczytu |
DesignMasterID XE "DesignMasterID" |
JRO.Replica |
Variant |
|
Priority XE "Priority" |
JRO.Replica |
Long |
Tylko do odczytu |
ReplicaID XE "ReplicaID" |
JRO.Replica |
Variant |
Tylko do odczytu |
ReplicaType XE "ReplicaType" |
JRO.Replica |
RepIicaTypeEnum |
Tylko do odczytu |
RetentionPeriod XE "RetentionPeriod" |
JRO.Replica |
Long |
|
Visibility XE "Visibility" |
JRO.Replica |
VisibilityEnum |
Tylko do odczytu |
Tabela 22.5.
Metody JRO.Replica
Metoda |
Składnia |
CreateReplica XE "CreateReplica" |
Replica.CreateReplica(NazwaRepliki, Opis [,TypRepliki] [,Widoczność] [,Priorytet] [,Aktualizacja]) |
Tabela 22.5.
Metody JRO.Replica (ciąg dalszy)
Metoda |
Składnia |
GetObjectReplicability XE "GetObjectReplicability" |
Set ReturnValue = Replica.GetObjectReplicability (NazwaObiektu, TypObiektu) |
MakeReplicable XE "MakeReplicable" |
Replica.MakeReplicable([CiągPołączenia] [,Śledzenie kolumn]) |
PopulatePartial XE "PopulatePartial" |
Replica.PopulatePartial(PełnaReplika) |
SetObjectReplicability XE "SetObjectReplicability" |
Replica.SetObjectReplicability(NazwaObiektu, TypObiektu, Replikowalność) |
Synchronize XE "Synchronize" |
Replica.Synchronize(Cel [,TypSynchronizacji] (,TrybSynchronizacji]) |
Tabele 22.6 i 22.7 zawierają właściwości i metody kolekcji JRO.Filters.
Tabela 22.6.
Właściwości kolekcji JRO.Filters
Nazwa |
Składnik klasy |
Typ |
Uwagi |
Count |
JRO.Filters |
Long |
Tylko do odczytu |
Item |
JRO.Filters |
Filter |
Tylko do odczytu |
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 zawiera właściwości JRO.Filter.
Tabela 22.8.
Właściwości JRO.Filter
Nazwa |
Składnik klasy |
Typ |
Uwagi |
FilterCriteria XE "FilterCriteria" |
JRO.Filter |
String |
Tylko do odczytu |
FilterType XE "FilterType" |
JRO.Filter |
Enum |
Tylko do odczytu |
TableName XE "TableName" |
JRO.Filter |
String |
Tylko do odczytu |
Opis metod i właściwości JRO
Jet Replication Object zawiera do swojego użytku kilka metod i właściwości. Właściwości są używane do identyfikacji bazy danych, umieszczenia jej w Twojej topologii replikacji oraz wyznaczają sposób obsługi konfliktów. Metody zajmują się tworzeniem replik, synchronizacją między replikami oraz określają, które informacje są przesyłane pomiędzy replikami. Obiekt JRO Replica zawiera również kolekcję filtrów, które ograniczają poprzez zdefiniowane warunki, dane przesyłane pomiędzy replikami.
Właściwość ActiveConnection XE "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 XE "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.
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 problemów replikacji.
W czasie tworzenia schematu replikacji powinieneś spodziewać się następujących typów konfliktów:
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.
Błąd powtórzenia klucza. W czasie synchronizacji dwa rekordy mają taką samą wartość w polu klucza.
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 naruszenie reguł poprawności, rekord jest odrzucany.
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.MakeReplicable. 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 XE "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.
Wydruk 22.1. Proste rozwiązywanie konfliktów
Function CustomDataConflictResolver()
Dim jro As New jro.Replica
Dim cat As New ADOX.Catalog
Dim conflrs As New Recordset
Dim rs As New Recordset
On Error Goto CustomDataConflictResolver Error
Set jro.ActiveConnection = CurrentProject.Connection
Set cat.ActiveConnection = CurrentProject.Connection
' jro.ConflictTables zwraca Recordset z nazwami tabelami
' zawierających konflikty
Set conflrs = jro.ConflictTables
' Dla każdej związanej tablicy konfliktów rozpoznaj konflikt
' i rozwiąż go
While Not conflrs.EOF
' Otwórz tabelę aktualnego konfliktu i analizuj utracony rekord
rs.Open "Select * From " & conflrs.Fields(1), jro.ActiveConnection
While Not rs.EOF
' Oceń tutaj rekordy pozostające w konflikcie i
' użyj SQL lub ADO, aby zapisać właściwe zmiany
' Upewnij się, że zachowałeś rekordy, w których nie rozwiązałeś
' konfliktu
rs.MoveNext
Wend
' Zamknij recordset z utraconymi rekordami
rs.Close
' Pobierz nazwę następnej tabeli
conflrs.MoveNext
Wend
' Gdy tworzysz własną funkcję rozwiązywania konfliktów
' musisz usunąć zawartość tabeli konfliktów
While Not conflrs.EOF
cat.Tables.Delete (conflrs.Fields(1))
conflrs.MoveNext
Wend
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.
Właściwość DesignMasterID XE "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.
|
||
|
Ustawienie tej właściwości w replice, jeżeli w tym zbiorze replik istnieje wzorzec projektowania, może podzielić zbiór na dwa niezgodne zbiory replik. Jeżeli się to zdarzy, nie będziesz mógł wykonać synchronizacji z wszystkimi dotychczasowymi użytkownikami. Ponieważ GUID wzorca projektowania jest globalnie unikatowy, konwertuj replikę na |
|
wzorzec projektowania tylko w nadzwyczajnych sytuacjach, kiedy wzorzec projektowania został stracony lub uszkodzony i nie istnieje inny 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 XE "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 XE "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
Stała |
Wartość |
Opis |
jrRepTypeNotReplicable |
0 |
Domyślna. Baza danych nie jest replikowana |
jrRepTypeDesignMaster |
1 |
Replika jest wzorcem projektowania |
jrRepTypeFull |
2 |
Replika jest pełną repliką |
jrRepTypePartial |
3 |
Replika jest repliką częściową |
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 XE "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ść ta musi być ustawiana we wzorcu projektowania.
Właściwość Visibility
Właściwość Visibility XE "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
Stała |
Wartość |
Opis |
jrRepVisibilityGlobal |
1 |
Domyślna. Replika globalna |
jrRepVisibilityLocal |
2 |
Replika lokalna |
jrRepVisibilityAnon |
4 |
Replika anonimowa |
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 XE "CreateReplica"
Metoda ta tworzy nową replikę na podstawie bieżącej replikowalnej bazy danych.
Replica.CreateReplica(NazwaRepliki, Opis [,TypRepliki] [,Widoczność] [,Priorytet] [,Aktualizacja])
NazwaRepliki - ciąg przechowujący pełną ścieżkę dostępu do tworzonej repliki.
Opis - ciąg opisujący tworzoną replikę.
TypRepliki - parametr opcjonalny. Typ tworzonej repliki. Wartością domyślną jest jrRepTypeFull. Gdy tworzona jest pełna replika, w trakcie synchronizacji wymieniane są wszystkie dane. W częściowej replice wymieniane są tylko dane spełniające warunki filtra. Prawidłowe wartości stałych dla tego parametru opisane są w tabeli 22.11.
Tabela 22.11.
Możliwe wartości parametru TypRepliki
Stała |
Wartość |
Opis |
jrRepTypeNotReplicable |
0 |
Domyślna. Baza danych nie jest replikowana |
jrRepTypeDesignMaster |
1 |
Replika jest wzorcem projektowania |
jrRepTypeFull |
2 |
Replika jest pełną repliką |
jrRepTypePartial |
3 |
Replika jest repliką częściową |
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ść
Stała |
Wartość |
Opis |
jrRepVisibilityGlobal |
1 |
Domyślna. Replika globalna |
jrRepVisibilityLocal |
2 |
Replika lokalna |
jrRepVisibilityAnon |
4 |
Replika anonimowa |
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
Stała |
Wartość |
Opis |
jrRepUpdFull |
0 |
Replika może być zmieniana |
jrRepUpdReadOnly |
2 |
Replika nie może być zmieniana |
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 XE "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.
Parametry metody GetObjectReplicability przedstawione są poniżej.
NazwaObiektu - nazwa obiektu, z którego odczytywany jest stan replikacji.
TypObiektu - typ obiektu wyszczególnionego w pierwszym parametrze.
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 XE "MakeReplicable"
Metoda ta przystosowuje bazę danych do replikacji. Składnia jej jest przedstawiona poniżej.
Replica.MakeReplicable([CiągPołączenia] [,ŚledzenieKolumn])
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 XE "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:
Zsynchronizuj pełną replikę z replikami częściowymi, w których ma zostać zmieniony warunek filtra.
Użyj obiektu Filter, aby wprowadzić zmiany do warunku filtra repliki.
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.
|
||
|
Mimo że PopulatePartial wykonuje jednokierunkową synchronizację przed wyczyszczeniem i powtórnym ładowaniem repliki częściowej, dobrym pomysłem jest wywołanie Synchronize przed PopulatePartial. Gdy używa się połączenia bezpośredniego lub połączenia internetowego, w razie wystąpienia błędu w trakcie metody Synchronize, wystąpi błąd, który można przechwycić. Można na podstawie tego błędu zdecydować, czy uruchamiać metodę PopulatePartial (która usuwa wszystkie rekordy z repliki częściowej). W wypadku synchronizacji pośredniej nie występuje przechwytywalny błąd, więcej informacji znajdziesz w opisie metody Synchronize. Jeżeli wywołana zostanie metoda PopulatePartial i wystąpi błąd w trakcie synchronizacji, rekordy w częściowej replice pozostaną usunięte. Nie jest to satysfakcjonujący rezultat. |
Metoda SetObjectReplicability XE "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ść)
NazwaObiektu - nazwa obiektu, w którym będzie ustawiany status replikacji.
TypObiektu - typ obiektu, w którym będzie ustawiany status replikacji.
Replikowalność - wartość logiczna wskazująca na to, czy obiekt może być replikowany.
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 XE "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
Stała |
Wartość |
Opis |
jrSyncTypeExport |
1 |
Wysyła zmiany z bieżącej repliki do docelowej |
jrSyncTypeImport |
2 |
Wysyła zmiany z repliki docelowej do bieżącej |
jrSyncTypeImpExp |
3 |
Wartość domyślna. Wysyła zmiany z bieżącej repliki do docelowej i odwrotnie |
TrybSynchronizacji - parametr opcjonalny. Wartość wyliczeniowa określająca tryb synchronizacji. Wartością domyślną jest jrSyncModeIndirect. Właściwe wartości parametru przedstawione są w tabeli 22.15.
Tabela 22.15.
Wartości parametru TrybSynchronizacji
Stała |
Wartość |
Opis |
jrSyncModeIndirect |
1 |
Wartość domyślna. Synchronizacja pośrednia |
jrSyncModeDirect |
2 |
Synchronizacja bezpośrednia |
jrSyncModeInternet |
3 |
Pośrednia synchronizacja przez Internet |
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 XE "Filters"
Kolekcja ta zawiera wszystkie obiekty Filter w replice. Każdy obiekt filtra pozwala na ograniczenie ilości replikowanych rekordów.
Właściwości i metody kolekcji Filters wymienione są w tabeli 22.16.
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.
Jeżeli wartość właściwości Count wynosi 0, kolekcja nie zawiera obiektów.
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 )
Zwraca odwołanie do obiektu.
Indeks - wartość typu Variant, która może być nazwą lub numerem obiektu w kolekcji.
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)
NazwaTabeli - ciąg będący nazwą tabeli, na którą nakładany jest filtr.
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 XE "Filter"
Właściwość ta definiuje kryteria, jakie musi spełniać rekord, aby został replikowany z pełnej repliki.
Właściwość FilterCriteria XE "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.
Wartością domyślną jest pusty ciąg znaków.
Właściwość FilterType XE "FilterType"
Właściwość ta określa typ filtra.
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 XE "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:
Elementy bezpieczeństwa.
Tworzenie grupy roboczej.
Użytkownicy i grupy.
Tworzenie systemu bezpieczeństwa przy użyciu opcji startowych.
Zagadnienia bezpieczeństwa przy użyciu replikacji.
Ochrona dzielonych baz danych.
Bezpieczeństwo systemu klient-serwer.
Zabezpieczanie bazy danych krok po kroku.
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 XE "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.
Istnieją dwie możliwości zabezpieczenia aplikacji Accessa 2000:
Ustawienie hasła bazy danych.
Utworzenie systemu bezpieczeństwa opartego o grupę roboczą.
Zabezpieczenie bazy danych hasłem
Ustawienie hasła bazy danych XE "hasło bazy danych" jest szybką i prostą metodą zabezpieczenia pliku MDB. Po jej zastosowaniu (menu Narzędzia, Zabezpieczenia, Ustaw hasło bazy danych w bazie otwartej na wyłączność) wszystkim użytkownikom zostanie przypisane to samo hasło. W czasie uruchamiania pliku MDB każdy użytkownik musi podać to hasło. Wszyscy mają to samo hasło i przez to każdy, kto zna hasło, może dostać się do bazy. Łatwo zauważyć, że ten sposób jest dużym 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.
System bezpieczeństwa grupy roboczej
Hasło bazy oparte jest o bazę danych (chroniona jest baza danych bez rozróżniania użytkowników), natomiast Access/Jet jest zabezpieczany w oparciu o informacje podawane przy logowaniu do grupy roboczej XE "grupa robocza" . Jest to skomplikowany i elastyczny system, gdzie identyfikacja użytkownika w grupie roboczej determinuje sposób pracy schematu bezpieczeństwa. W tej strukturze bezpieczeństwa użytkownicy są jednoznacznie identyfikowani i mogą indywidualnie dostawać uprawnienia do bazy i zawartych w niej obiektów. Można powiedzieć, że dyskusja o plikach grupy roboczej, przestrzeniach roboczych i grupach, która zostanie zaraz przeprowadzona, jest w rzeczywistości dyskusją o organizacji, rozszerzaniu i ułatwianiu podstawowych operacji tworzenia i przypisywania praw użytkownikom.
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:
nazwa użytkownika;
hasło użytkownika;
identyfikator użytkownika (PID);
właściwości użytkownika (ustawienia paska narzędzi i niektóre wartości domyślne);
ostatnie cztery bazy otwarte przez użytkownika (widoczne w menu Plik);
nazwy grup;
grupy (PID);
członków grup (użytkownicy należący do grupy).
Tworzenie grupy roboczej XE "grupa robocza:tworzenie"
Zaraz po zainstalowaniu, Access jest podłączony do domyślnej grupy roboczej definiowanej przez plik system.mdw XE "system.mdw" . System.mdw jest utworzony jedynie dla wygody. Gdy jest on tworzony w trakcie instalacji, informacje krytyczne dla działania systemu bezpieczeństwa są pozostawione poza nim, więc są one na stałe niechronione. Każdy, kto chce zobaczyć plik pomocy Accessa, musi przebić się przez ochronę domyślnego system.mdw. Powinieneś pozostawić ten plik i w razie potrzeby utworzyć nowy plik grupy roboczej.
Aby to wykonać, należy użyć programu wrkgadm.exe, który zwykle jest instalowany w ...\Microsoft Office\Office\wrkgadm.exe XE "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 XE "Workgroup Security ID" (SID XE "SID" ). Jeżeli właściwie zabezpieczysz identyfikator grupy, nie może ona zostać przeję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.
|
||
|
Zapisz wartość identyfikatora grupy i przechowuj w bezpiecznym miejscu. Możesz jej potrzebować, aby powtórnie utworzyć grupę roboczą. Jet nigdy nie udostępni tej wartości. |
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 wypadku awarii.
|
||
|
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]
|
||
|
Parametry wywołania /WRKGRP, /USER, /PWD działają tylko dla baz danych Accessa, nie dla projektów Accessa. |
Użytkownicy i grupy
Użytkownicy XE "grupa robocza:użytkownik" 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 XE "grupa robocza:grupa" , 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.
|
||
|
Ponieważ raporty są tworzone przez kreatorów, a budowniczy zapytań pomaga użytkownikom precyzyjnie definiować wymagane dane bez dodawania obiektów zapytań do bazy danych, możliwe jest danie szerokich uprawnień do tworzenia raportów, nawet w zabezpieczonej bazie danych. Zaoszczędzi to mnóstwo nudnej pracy przy ich tworzeniu. |
|
|
||
|
Grupa Użytkownicy domyślnie posiada wszystkie uprawnienia, a każdy użytkownik jest jej członkiem. Musisz usunąć wszystkie uprawnienia z grupy Użytkownicy, aby prawidłowo zabezpieczyć bazę danych. Inaczej każdy użytkownik bazy będzie dziedziczył prawa administratora. |
Omówienie domyślnych ustawień użytkowników i grup
Przed rozpoczęciem pracy nad zabezpieczeniami należy zapoznać z domyślnymi ustawieniami. Jet rozpoczyna pracę z dwiema grupami i jednym domyślnym użytkownikiem. Te dwie grupy to Administratorzy i Użytkownicy. Domyślnym użytkownikiem jest Administrator. Administrator jest członkiem obu grup, a obie grupy posiadają wszystkie uprawnienia w bazie danych.
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 XE "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 XE "użytkownik:tworzenie" 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.
Aby utworzyć użytkownika, należy wykonać następujące kroki:
Z menu Narzędzia wybrać Zabezpieczenia, Konta użytkowników i grup.
Wybrać zakładkę Użytkownicy i kliknąć przycisk Nowa.
Wprowadź Nazwę i Identyfikator osobisty (PID), w sposób pokazany na rysunku 23.4. PID musi mieć od 4 do 20 znaków. Wielkość liter ma znaczenie. Służy on jako ziarno dla tworzenia identyfikatora zabezpieczeń (SID). Musisz zapisać PID, ponieważ nie da się go później odczytać.
Rysunek 23.4. Tworzenie nowego użytkownika i przypisywanie mu identyfikatora PID |
|
Ustawianie i zmiana hasła użytkownika
Po utworzeniu użytkownika XE "użytkownika:zmiana hasła" możesz przypisać mu hasło. Nie musisz tego robić, ale powinna być to standardowa procedura.
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 |
|
||
|
Zawodowa odpowiedzialność nie pozwala mi na podanie sposobów złamania zabezpieczeń Accessa pozwalających na odtworzenie zapomnianego hasła. Pamiętaj, aby używać hasła, którego nie zapomnisz, a nikt inny nie będzie go znał. Gdy wybierzesz takie hasło dobrze je zapamiętaj lub zapisz i przechowuj w bezpiecznym miejscu. |
Tworzenie grup
Jak wspomnieliśmy wcześniej, grupy XE "grupa:tworzenie" pozwalają na ułatwienie administracji przez ustawianie identycznego profilu zabezpieczeń wszystkim członkom grupy.
Aby utworzyć grupę, wykonaj następujące czynności:
Z menu Narzędzia wybierz Zabezpieczenia, Konta użytkowników i grup.
Wybierz zakładkę Grupy i kliknij przycisk Nowa.
Wprowadź Nazwę i Identyfikator osobisty (PID). PID musi mieć od 4 do 20 znaków. Wielkość liter ma znaczenie. Służy on jako ziarno dla tworzenia identyfikatora zabezpieczeń (SID). Musisz zapisać PID, ponieważ nie da się go później odczytać (rysunek 23.6).
Rysunek 23.6. Tworzenie grupy przez nadanie jej nazwy i PID przez interfejs użytkownika |
|
||||
|
|||||
|
PID grupy jest ziarnem używanym do jednoznacznej identyfikacji grupy. Jeżeli kiedykolwiek będziesz potrzebował odtworzyć grupę, musisz podać ten sam PID. Zapisz go i przechowuj w bezpiecznym miejscu. |
Przypisywanie użytkowników do grup
Użytkownicy i grupy są tak ściśle związani, że ich tworzenie i przypisywanie jest wykonywane w jednym miejscu. Użyj tej samej zakładki okna Konta użytkowników i grup, gdzie tworzyłeś użytkownika, aby połączyć go z grupą.
Wykonaj następujące kroki:
U góry okna wybierz użytkownika.
Na dole okna dialogowego wybierz z listy Dostępne grupy grupę, do której chcesz przypisać użytkownika.
Dwukrotnie kliknij wybraną grupę lub użyj przycisku Dodaj, aby dodać użytkownika do grupy. Możesz również usunąć użytkownika z grupy przez dwukrotne kliknięcie w liście Członek grupy lub używając przycisku Usuń. Nie można usunąć użytkownika z grupy Użytkownicy.
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.
Rozróżnianie między domyślnymi
i specjalnymi grupami i użytkownikami
Po utworzeniu nowej bazy danych struktura bezpieczeństwa Accessa nie jest pozbawiona użytkowników i grup. Posiada ona zestaw domyślnych użytkowników i grup. Ci użytkownicy i grupy muszą istnieć, aby system bezpieczeństwa działał poprawnie. Dopóki Access nie wie, kto się loguje do bazy, wszyscy są identyfikowani jako użytkownik Administrator, który jest członkiem domyślnych grup Użytkownicy XE "Użytkownicy" i Administratorzy XE "Administratorzy" , do czasu utworzenia systemu bezpieczeństwa. Grupy te nie powinny posiadać żadnego znaczenia w Twoim systemie bezpieczeństwa. W tej części opisane są te domyślne 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 XE "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. 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ć
Uprawnienie |
Opis |
Obiekt |
Otwórz z wyłącznością XE "prawo:Otwórz z wyłącznością" |
Otwieranie z zabronieniem innym dostępu do obiektu |
Baza danych |
Otwórz/Uruchom XE "prawo:Otwórz/Uruchom" |
Otwieranie w trybie pracy |
Baza danych |
Czytanie projektu XE "prawo:Czytanie projektu" |
Otwieranie w trybie projektowania |
Wszystkie poza modułami |
Modyfikuj projekt XE "prawo:Modyfikuj projekt" |
Oglądanie, zmiana lub usuwanie obiektów struktury i ich właściwości |
Wszystkie |
Administruj (baza danych) XE "prawo:Administruj (baza danych)" |
Ustawianie hasła bazy danych, tworzenie wzorca replikacji, zmiana opcji startowych. Bez administracji uprawnieniami |
Baza danych |
Administruj (inne) XE "prawo:Administruj (inne)" |
Pełne prawa, włączając administrowanie uprawnieniami |
Wszystkie poza bazą danych |
Odczytaj dane XE "prawo:Odczytaj dane" |
Tylko odczyt danych |
Tabele i zapytania |
Aktualizuj dane XE "prawo:Aktualizuj dane" |
Oglądanie i zmiana danych, bez dopisywania i kasowania |
Tabele i zapytania |
Wstaw dane XE "prawo:Wstaw dane" |
Oglądanie i dopisywanie danych, bez zmieniania i usuwania |
Tabele i zapytania |
Usuń dane XE "prawo:Usuń dane" |
Oglądanie i usuwanie danych, bez zmieniania i wstawiania |
Tabele i zapytania |
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 XE "Uruchom uprawnienia właściciela:właściwość" 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 XE "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.
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ł.
Tworzenie systemu bezpieczeństwa przy użyciu opcji startowych
Oprócz rygorystycznego, prawidłowo zaprojektowanego systemu zabezpieczeń, powinieneś ustawić kilka opcji startowych, aby poprawić bezpieczeństwo Accessa. Nie powinno być to mylone lub używane zamiast właściwego systemu bezpieczeństwa, może jednak załatać jakąś nieprzewidzianą dziurę. To rozwiązanie może służyć jako tymczasowe zabezpieczenie aplikacji.
W menu Autostart znajduje się kilka opcji:
Wyświetl okno bazy danych. W oknie bazy danych użytkownicy mogą zrobić najwięcej szkody. Poprzez ukrycie tego okna po wczytaniu bazy danych, mniej doświadczeni (i zwykle najbardziej ciekawi) użytkownicy nie będą mieli ochoty na zabawę tym oknem.
Pasek menu skrótów. Danie użytkownikowi dostępu do podstawowych możliwości Accessa może spowodować, że mała wyrwa w systemie bezpieczeństwa powiększy się. Nie pozwalaj zamknąć formatki innym sposobem niż ten, który przewidziałeś, lub zapisać dane bez sprawdzenia tożsamości i uprawnień bieżącego użytkownika. Wyłączenie pełnego menu, domyślnych skrótów klawiszowych, pasków narzędzi oraz dostosowywania menu i pasków narzędzi może zabezpieczyć przed włamaniem. Dokładnie przemyśl, które z opcji pozostaną aktywne.
Wyświetl kod po błędzie. Bez właściwego systemu bezpieczeństwa (i odpowiedniej obsługi błędów) użytkownicy mogą otrzymać na ekran denerwujący i tajemniczy komunikat błędu lub, co gorsza, kod programu, co jest skrajnie niewłaściwym i kłopotliwym zachowaniem aplikacji. Należy wyłączyć tę opcję.
Użyj specjalnych klawiszy programu Access. Naciśnięcie F11, Control-Break, Control-G może zrujnować aplikację. Wyłącz tą opcję przed wysłaniem aplikacji do klientów.
Ikona aplikacji. Tutaj można wskazać inną ikonę, która zastąpi ikonę Accessa. Jeżeli tego nie zrobisz, niektórzy użytkownicy mogą mieć kłopoty z odróżnieniem czy pracują w Accessie, czy w Twojej aplikacji. Można tutaj podać nazwę pliku z ikoną (ICO) lub rysunkiem (BMP).
Zagadnienia bezpieczeństwa przy użyciu replikacji
Użycie replikacji XE "replikacja" w aplikacji powoduje wystąpienie problemów, które daje się jednak rozwiązać. Repliki mogą być zabezpieczane na poziomie użytkowników. Wszystkie zmiany wprowadzane do uprawnień obiektów wzorca projektowania zostaną w trakcie synchronizacji rozprowadzone do wszystkich replik, ponieważ uprawnienia te stanowią część samych obiektów. Niestety plik grupy roboczej nie jest replikowany. Jeżeli użytkownicy nie mogą używać wspólnego pliku grupy roboczej, co zdarza się w większości struktur replikacji, plik grupy roboczej musi być rozprowadzany, gdy utworzony zostanie nowy obiekt lub gdy inne zmiany w strukturze zabezpieczeń tego wymagają.
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.
Ochrona podzielonych baz danych
Bazy danych Accessa zawsze mogą zostać podzielone. Po tej operacji dane umieszczone są w jednym pliku MDB, natomiast część wykonywalna: formularze, raporty i moduły, w innym pliku. W jaki sposób zabezpieczyć taką aplikację.
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.
Database=c:\Program Files\Microsoft Office\Office\Samples\Northwind.mdb
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:
RefreshLink XE "RefreshLink" - wymagane prawo czytania danych w tabeli źródłowej.
RefreshLink - wymagane prawo czytania projektu w tabeli źródłowej.
Właściwość Connect XE "Connect:właściwość" - 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.
Wydruk 23.1. Wiązanie formularza z odłączonym obiektem recordset
Dim wrk As Workspace
Dim db As Database
Dim rdb As Database
Dim rs As Recordset
Dim Connstr as String
Set wrk = DBEngine.Workspaces(0)
Set db = CurrentDb()
Connstr = "C:\program files\microsoft office\"
Connstr = Connstr & "office\samples\northwind.mdb"
Set rdb = wrk.OpenDatabase(Connstr, , , "admin")
Set rs = rdb.OpenRecordset("Select * from Customers") ...
Łą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 XE "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”.
Wydruk 23.2. Otwarcie bazy danych przez ADOX i nadanie uprawnień
Dim cnn As New ADODB.Connection
Dim cat As New ADOX.Catalog
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
Set cat.ActiveConnection = cnn
cat.Users("JP").SetPermissions objName, adPermObjTable, _
adAccessGrant, adRightFull
Opcja With OwnerAccess
Jedną z możliwości jest usunięcie wszystkich uprawnień z tabel w bazie źródłowej. Można wtedy wykonywać kwerendy oparte na połączonych tabelach, używając klauzuli With OwnerAcces XE "With OwnerAcces" s na końcu wyrażenia SQL lub ustawiając tę właściwość we właściwościach kwerendy. Tym sposobem kwerenda będzie mogła wykonać się i zwrócić wynik, jednak użytkownik nie będzie mógł zmienić danych ani struktury tabeli.
Przykładowe wyrażenie SQL używające tej klauzuli wygląda następująco.
SELECT Customers.* FROM Customers
WITH OWNERACCESS OPTION
Aby utworzyć zapytania wykorzystujące opcję With OwnerAccess, wykonaj następujące czynności:
Usuń wszystkie uprawnienia z tabel dla grup, które będą używać kwerendy.
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.
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ę.
Bezpieczeństwo systemu klient-serwer
W czasie pracy z danymi umieszczonymi na serwerze np.: SQL Server, Oracle lub Sybase, te same serwery zabezpieczają dane, masz zwykle małą kontrolę nad tym systemem zabezpieczeń.
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ś modyfikować 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, _
ParamArray JoinGroups() As Variant)
Dim cnn As New ADODB.Connection
Dim cat As New ADOX.Catalog
Dim Group As Variant
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
Set cat.Active0onnection = cnn
With cat
' Nie przewidujemy błędów
On Error ReSume Next
' Sprawdź czy nazwa istnieje
' Jeżeli tak, usuń użytkownika
' Usunięcie użytkownika usuwa go również z wszystkich grup
If strUserName = .Users(strUserName).Name Then
.Users.Delete strUserName
End If
' Utwórz nowego użytkownika
.Users.Append strUserName, strPWD
' Gdy użytkownik istnieje, można dodać go
' do podanych grup
For Each Group In JoinGroups()
.Groups(Group).Users.Append strUserName
Next
' Przed zakończeniem powinniśmy być zgodni z UI
' sprawdzam, czy użytkownik należy co najmniej do grupy
' Użytkownicy. Nie trzeba przeglądać wszystkich członków grupy
' wystarczy sprawdzić, czy nazwa występuje w kolekcji Users
If Not strUserName = .Groups("Users").Users(strUserName).Name Then
.Groups("Users").Users.Append strUserName
End If
End With
End Sub
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 XE "Users:kolekcja" . 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.
Wyliczanie grup i użytkowników oraz wyświetlanie przynależności
Byłoby prawie niemożliwe administrowanie bazą danych, gdyby nie można było programowo uzyskać informacji, kto może używać bazy i w jakim stopniu jej używa. VBA Accessa pozwala poprzez ADOX pobrać listę wszystkich użytkowników z bazy danych, ich przynależność do grup oraz inne informacje. Przykład procedury wykonującej te czynności znajduje się na wydruku 23.4.
Wydruk 23.4. Użycie ADOX do pobrania informacji o użytkownikach
Public Sub ADOXGroupsandUsers()
Dim cnn As New ADODB.Connection
Dim cat As New ADOX.Catalog
Dim i As Integer, k As Integer
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
Set cat.ActiveConnection = cnn
With cat
Debug.Print
' Pobranie i wypisanie listy grup
Debug.Print "Ilość grup = " & .Groups.Count
For i = 0 To .Groups.Count - 1
Debug.Print " " & .Groups(i).name
Next
Debug.Print
' Pobranie i wypisanie listy użytkowników
Debug.Print "Ilość użytkowników = " & .Users.Count
For i = 0 To .Users.Count - 1
' Nie pokazuj użytkowników 'Engine' i 'Creator'
If .Users(i).Groups.Count > 0 Then
Debug.Print " " & .Users(i).name
End If
Next
Debug.Print
'Wypisz zawartość kolekcji Groups z katalogu wraz z ich członkami
Debug.Print "Przynależność do grup"
For i = 0 To .Groups.Count - 1
Debug.Print " " & .Groups(i).name
For k = 0 To .Groups(i).Users.Count - 1
Debug.Print " " & .Groups(i).Users(k).name
Next
Next
Debug.Print
' Wypisz zawartość kolekcji Users z katalogu
' wraz z przynależnością do grup
Debug.Print "Przynależność użytkowników"
For i = 0 To .Users.Count - 1
' Nie pokazuj użytkowników 'Engine' i 'Creator'
If .Users(i).Groups.Count > 0 Then
Debug.Print " " & .Users(i).name
For k = 0 To .Users(i).Groups.Count - 1
Debug.Print " " & .Users(i).Groups(k).name
Next
End.If
Next
End With
End Sub
Identyfikacja bieżących użytkowników za pomocą ADOX
Często pojawiało się pytanie: „Kto jest teraz zalogowany” i do tej pory nie było eleganckiej metody sprawdzenia tego. Teraz za pomocą ADOX można użyć wykazu, aby sprawdzić, kto używa bazy danych w każdym momencie. Przykład tego znajduje się na wydruku 23.5.
Wydruk 23.5. ADOX pozwala na sprawdzenie, kto używa bazy danych
Sub UserRoster()
' Procedura używa rejestru użytkowników
' lub Jet 4.0, aby podłączyć się do bazy danych
' i sprawdzić, kto używa bazy danych
Dim conn As ADODB.Connection
Dim rst As ADODB.Recordset
On Error GoTo Proc_Err
Set conn = New ADODB.Connection
'Otwórz bazę źródłową
With conn
.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
' Otwórz recordset oparty na ilości użytkowników w bazie
Set rst = conn.OpenSchema(adSchemaProviderSpecific, ,
"{947bb102-5d43-11d1-bdbf-00c04fb92675}")
' Dla każdego użytkownika wypisz nazwę komputera i inne dane
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
Proc_Exit:
Exit Sub
Proc_Err:
MsgBox Err.Description
Resume Proc_Exit
End Sub
Wyszukiwanie użytkowników z pustym hasłem
Jedną z największych dziur w zabezpieczonej bazie danych jest użytkownik z pustym hasłem XE "puste hasło" . Jet nie wymaga hasła, więc musi ono zostać wymuszone poprzez własne funkcje tworzenia użytkownika lub ktoś musi dla każdego użytkownika sprawdzić, czy można otworzyć bazę danych baz hasła. Funkcja na wydruku 23.6 przedstawia sposób, jak to zrobić przy użyciu ADOX.
Wydruk 23.6. Wyszukiwanie pustych haseł
Public Sub ADOXPasswordCheck()
Dim strcnn1 As String
Dim strcnn2 A5 String
Dim cnn As New ADODB.Connection
Dim pwrdtestcnn As New ADODB.Connection
Dim cat As New ADOX.Catalog
Dim pwdCat As New ADOX.Catalog
Dim i As Integer, k As Integer
Strcnn1 = "data source=C:\Program Files\Microsoft Office\Office\"
Strcnn1 = strcnn1 & "Samples\NorthWind.mdb;"
Strcnn1 = strcnn1 & "jet oledb:system database="
Strcnn1 = strcnn1 & "C:\Program Files\Microsoft Office\Office\"
Strcnn1 = strcnn1 & "Samples\sysnwind.mdw; "
Strcnn1 = strcnn1 & "user id=NWindAdmin;Password=OpenSaysaMe"
With cnn
.Provider = "Microsoft.Jet.OLEDB.4.O"
.ConnectionString = strcnn1
.Open
End With
Set cat.ActiveConnection = cnn
With cat
For i = 0 To .Users.Count - 1
' Nie pokazuj użytkowników 'Engine' i 'Creator'
If .Users(i).Groups.Count > 0 Then
' Spróbuj otworzyć następne połączenie z nazwą użytkownika
' i pustym hasłem
With pwrdtestcnn
.Provider = cnn.Provider
strcnn2="data source=C:\Program Files\"
strcnn2= strcnn2 & "Microsoft Office\Office\Samples\"
strcnn2= strcnn2 & "NorthWind.mdb; "
strcnn2= strcnn2 & "jet oledb:system databa5e="
strcnn2= strcnn2 & "C:\Program Files\"
strcnn2= strcnn2 & "Microsoft Office\Office\"
strcnn2= strcnn2 & "Samples\sysnwind.mdw;
strcnn2= strcnn2 & "user id=NWindAdmin;Password= " "
.ConnectionString = strcnn2
' Zwykle dostaniemy błąd, a nie chcemy,
' żeby nas zatrzymał
On Error Resume Next
.Open
' Brak błędu oznacza, że udała się próba wejścia bez hasła
If Err = 0 Then
' użyj katalogu z bieżącego połączenia
Set cat.ActiveConnection = pwrdtestenn
Debug.Print cat.Users(i).name & " nie ma hasła"
' Zamknij to połączenie
pwrdtestcnn.Close
End If
End With
End If
Next
End With
End Sub
Ustawianie i usuwanie hasła
Ustawienie lub usunięcie hasła można wykonać przy użyciu interfejsu użytkownika lub poprzez ADOX. Poniższy wiersz kodu zmienia hasło.
Cat.Users("Admin").changepassword "StareHasło", "NoweHasło"
Ustawienie obu argumentów metody changepassword XE "changepassword:metoda" 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ń.
Zarządzanie właściwością obiektów
Aby posiadać pełną kontrolę nad obiektami, powinieneś wiedzieć, w jaki sposób dostać się i zmodyfikować właściciela obiektu XE "właściciel obiektu" . Na wydruku 23.7 przedstawione jest, jak dowiedzieć się, do której grupy należy obiekt i zmienić właściciela na grupę, co ułatwi administrację.
Wydruk 23.7. Przypisywanie właściciela obiektu
Public Sub ADOXGroupOwnership(strObjectName As String, strGroupName As
String)
Dim cat As New ADOX.Catalog
Dim n As 5tring
' 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
Zarządzanie wieloma aplikacjami
Przy użyciu ADOX Twoja aplikacja nie ładuje DDL lub zabezpieczeń, jeżeli tego nie potrzebuje, i ładuje, gdy tego potrzebuje. ADOX znajduje się w niewielkiej bibliotece (msadox.dll) z jasnym i uniwersalnym interfejsem programowym.
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.
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 XE "Create:User" User i Create XE "Create:Group" 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 XE "Add:User" 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 XE "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 |
|
|
Za pomocą SQL można nadawać uprawnienia do tabel, indeksów, kwerend i kontenerów.
Po nadaniu uprawnień można je odebrać za pomocą odwrotnego do Grant wyrażenia Revoke XE "Revoke" . Składnia i opcje są identyczne jak dla wyrażenia Grant, a rezultat dokładnie odwrotny.
Drop
Po usunięciu uprawnień możesz usunąć użytkownika za pomocą wyrażenia Drop XE "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.
Zabezpieczanie bazy danych krok po kroku
Dobrze jest wiedzieć, że mimo oszałamiającej liczby opcji i nowych funkcji podstawowe czynności przy zabezpieczaniu bazy danych Accessa nie zmieniły się.
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.
Utwórz nową grupę roboczą. Użyj programu wrkgadm.exe opisanego na początku tego rozdziału. Wybierz opcję tworzenia nowego pliku grupy roboczej.
Otwórz Accessa, używając pliku grupy roboczej utworzonego specjalnie dla Twojej aplikacji.
Otwórz lub utwórz bazę danych, którą chcesz zabezpieczyć.
Utwórz nowego użytkownika i dodaj go do grupy Administratorzy.
Zmień hasło użytkownika Administrator.
Usuń wszystkie uprawnienia dla grupy Użytkownicy z wszystkich obiektów w bazie danych.
Zamknij bazę danych.
Otwórz Accessa, logując się jako nowy administrator.
Otwórz bazę danych, którą chcesz zabezpieczać.
Uruchom kreatora zabezpieczania na bazie danych. Zaoszczędzi Ci wiele żmudnej pracy, zmieniając właściciela obiektów.
Usuń użytkownika Administrator z grupy Administratorzy.
Utwórz użytkowników i grupy potrzebne w aplikacji.
Przypisz użytkowników do odpowiednich grup.
Ustaw odpowiednie uprawnienia dla grup.
Dodawaj i usuwaj grupowe uprawnienia, tak jak tego potrzebujesz.
Częste błędy bezpieczeństwa
Jeden z częstych problemów występuje, gdy użytkownik logując się do jednej grupy roboczej może wejść do innej bazy danych na użytkownika Administrator.
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 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:
Konfiguracja serwera WWW dla publikowania w sieci WWW.
Przenoszenie Accessa 2000 do sieci WWW.
Użycie stron dostępu do danych.
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:
Środowisko programistyczne a środowisko produkcyjne.
Wybór platformy.
Co to jest Option Pack.
Uruchomienie serwera WWW.
Zarządzanie i konfiguracja serwera WWW.
Zabezpieczanie aplikacji WWW.
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.
Środowisko programistyczne a środowisko produkcyjne
Należy uściślić terminologię, której będziemy używać w tej części książki. Podczas tworzenia projektu wystąpią prawdopodobnie dwa różne środowiska: środowisko programistyczne XE "środowisko programistyczne" i środowisko produkcyjne XE "środowisko produkcyjne" . Środowisko programistyczne jest miejscem, w którym tworzysz aplikację. Środowisko produkcyjne jest miejscem, gdzie Twoja aplikacja będzie umieszczona po jej ukończeniu. Jeżeli tworzysz strony na komputerze z Windows 95, a umieszczasz je na komputerze z Windows NT Server w celu ich przetestowania i wykrycia błędów, komputer Windows 95 jest Twoją maszyną programistyczną, natomiast Windows NT Server jest środowiskiem produkcyjnym.
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.
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 XE "Personal Web Server" 4.0 (PWS4), działa na Windows 95/98 i dostarcza podstawowych funkcji serwera WWW. Kolejny, Peer Web Services XE "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 XE "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.
Wybranymi funkcjami tych dwóch produktów są:
Możliwość udostępniania prostych stron WWW.
Możliwość tworzenia aplikacji Active Server Pages XE "Active Server Pages" .
Możliwość tworzenia transakcyjnych aplikacji WWW za pośrednictwem Microsoft Trasaction Server XE "Microsoft Trasaction Server" .
Obsługa połączeń ODBC.
Możliwość użycia komponentów dostępu do danych: Microsoft Data Access Components XE "Microsoft Data Access Components" (MDAC XE "MDAC" ).
Microsoft Message Queue XE "Microsoft Message Queue" (MSMQ XE "MSMQ" ).
|
||
|
W czasie instalacji Option Pack instalowane są komponenty Microsoft Data Access Components w wersji 1.5. Zaleca się zainstalowanie najnowszej wersji tych komponentów. W czasie pisania tej książki dostępną były MDAC 2.1 instalowane razem z Accessem 2000. Powinieneś również wiedzieć, że istnieje różnica pomiędzy wersjami MSMQ, instalowanymi z Option Pack, w zależności od systemu operacyjnego. MSMQ instalowane na Windows NT Server jest w pełni funkcjonalną usługą kolejki komunikatów, natomiast wersja dla Windows NT Workstation i Windows 95/98 są po prostu klientami używającymi usługi MSMQ na serwerze. |
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.
Personal Web Server i Peer Web Services
Personal Web Server XE "Personal Web Server" i Peer Web Services XE "Peer Web Services" są wspaniałymi narzędziami do tworzenia aplikacji lokalnie na swoim komputerze, bez potrzeby korzystania z NT Server. Pozwalają na tworzenie i testowanie aplikacji przed wypuszczeniem jej do produkcyjnego serwera WWW. Jeżeli aplikacja działa prawidłowo na PWS, masz zapewnione, że będzie działała po przeniesieniu jej na IIS4.
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.
Internet Information Server
Internet Information Server XE "Internet Information Server" 4.0 jest dużo wydajniejszym serwerem WWW niż Personal Web Server. Jest to zalecana platforma dla wszystkich produkcyjnych serwerów WWW, ponieważ lepiej wytrzymuje duże obciążenie. Powinieneś zauważyć lepsze osiągi IIS4 w porównaniu z PWS4. IIS4 nie posiada ograniczeń na ilość jednocześnie podłączonych użytkowników. W zależności od projektu Twojej aplikacji może potencjalnie obsłużyć tysiące równoległych użytkowników.
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.
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 XE "Option Pack" .
|
||
|
Pomiędzy ASP działającymi na IIS3 i IIS4 występują różnice. IIS3 używa VBScript 2, natomiast IIS4 używa VBScript 3. Wszystkie wersje VBScript są ze sobą zgodne w tył, natomiast każda nowa ma nowe funkcje. Musisz być ostrożny, wymagając nowszych funkcji, chyba że jesteś pewien, że Twój serwer WWW już je obsługuje.
Jeżeli masz zainstalowany Internet Explorer 5 na serwerze, posiadasz VBScript 5, który zawiera wszystkie wcześniejsze funkcje oraz dodatkowe zalety. Jeżeli nie masz zainstalowanego w Twoim systemie Internet Explorer 5, a chcesz skorzystać z zalet najnowszej maszyny skryptowej, możesz załadować najnowszą wersję z HYPERLINK "http://www.miscrosoft.com/scripting/" |
Co to jest Option Pack
Jedynie standardowa instalacja Windows 2000 zawiera wszystkie niezbędne pliki do tworzenia aplikacji dla WWW, natomiast usługi Web są bezpłatnym dodatkiem do NT 4.0 i Windows 95/98. Windows NT Option Pack jest pakietem, który dostarcza funkcji niezbędnych do programowania dla WWW i publikowania w Sieci. Mimo że nazywa się „Windows NT” Option Pack, ten sam pakiet instalacyjny może być użyty do zainstalowania Personal Web Server 4 i innych rozszerzeń sieciowych do Windows 95/98.
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: |
||||
|
HYPERLINK "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 XE "Service Pack 3" .
|
||
|
Service Pack 4 jest najnowszym pakietem poprawek dla Windows NT dostarczonym przez Microsoft, ale powinien być zainstalowany PO zainstalowaniu Option Pack. |
|
|
||
|
Jeżeli z jakiegoś powodu musisz przeinstalować Service Pack 3 po instalacji Option Pack, nie nadpisuj żadnych nowszych plików zainstalowanych przez Option Pack. |
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
Komponent sprzętu |
Wymagane |
Zalecane |
Procesor |
66 MHz 486 |
90 Mhz Pentium |
RAM |
32 MB |
64 MB |
Wolne miejsce na dysku |
30 MB |
100 MB |
Monitor |
VGA |
Super VGA |
CD-ROM (niewymagany) |
3x |
6x |
Uruchomienie serwera WWW
Serwery WWW XE "serwer WWW" mogą być, w zależności od potrzeb Twojej aplikacji, proste lub skomplikowane. Powodem dużego skomplikowania jest możliwość całkowitej kontroli, jaką możesz mieć przy użyciu serwerów WWW firmy Microsoft.
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.
NT Option Pack dla Windows 95/98
Komponenty dostępne w czasie instalacji NT Option Pack różnią się w zależności od platformy, na jaką instalujesz pakiet.
Dostępne komponenty instalacji
Poniżej wymienione zostały komponenty dostępne w czasie instalacji, gdy po uruchomieniu programu instalacyjnego wybierzesz Custom Installation. Opcje wymagane przez konkretny system operacyjny zostały odpowiednio opisane. Zaznaczone zostały również komponenty niezbędne do tworzenia aplikacji WWW przy użyciu Office 2000, Active Server Pages oraz obiektów COM.
Certificate Server (tylko NT Server). Pozwala na tworzenie i wysyłanie certyfikatów cyfrowych. Możliwości te pozwalają na uruchomienie w aplikacjach dodatkowej warstwy zabezpieczeń. Można utworzyć osobisty certyfikat bezpieczeństwa dla klienta, który ładuje ten certyfikat do komputera i instaluje w oprogramowaniu klienta (w przeglądarce). W przyszłości możesz upewnić się, że klient jest tym, za kogo się podaje.
Option Pack Common Program Files. Zawiera pliki wspólne dla większości komponentów. Są one wymagane, aby tworzyć aplikacje dla WWW.
FrontPage 98 Server Extensions. Umożliwia tworzenie witryn i wykonanie podstawowych czynności administracyjnych za pomocą Microsoft FrontPage i Microsoft Visual InterDev. Nie musisz instalować tego komponentu, chyba że chcesz używać FrontPage lub Visual InterDev do tworzenia aplikacji.
|
||
|
Można używać ograniczonej ilości funkcji tworzenia aplikacji przy użyciu FrontPage bez instalowania rozszerzeń FrontPage, ale nie będzie można korzystać z wbudowanych kreatorów, robotów WWW i funkcji publikacji. Ponieważ rozszerzenia te powodują pewien narzut na serwerze, wielu programistów używa tych narzędzi do tworzenia szkieletu kodu, który jest modyfikowany przez inne narzędzia i następnie przenoszony na serwer za pomocą standardowego oprogramowania FTP. |
Internet Connection Services for RAS. Zarządza wieloma połączeniami wdzwanianymi oraz książkami telefonicznymi. Pakiet ten nie jest wymagany.
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).
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.
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.
Internet Information Server (tylko Windows NT Server). Pakiet zawiera:
Usługę File Transfer Protocol (FTP XE "FTP" );
Usługę NNTP XE "NNTP" (do utrzymywania grup dyskusyjnych)
Internet Service Manager (ISM). Jest to komponent wymagany do administracji i konfiguracji usługi WWW poprzez Microsoft Management Console XE "Microsoft Management Console" .
Usługę Simple Mail Transfer Protocol XE "Simple Mail Transfer Protocol" (SMTP XE "SMTP" ). Pozwala na generowanie przesyłek e-mail z aplikacji i wysyłania ich do adresatów.
World Wide Web Server (usługa HTTP). Jest niezbędna, jeżeli chcesz tworzyć, testować i udostępniać aplikacje WWW na Twoim serwerze.
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.
ISM w wersji HTML (Internet Service Manager). Pozwala on na zdalną administrację serwerem WWW poprzez interfejs HTML.
Microsoft Transaction Server 2.0 (MTS). Instaluje administratora COM i DCOM. Jest wymagany przy programowaniu dla WWW.
Microsoft Index Server XE "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.
Microsoft Script Debugger XE "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.
Windows Scripting Host XE "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.
Microsoft Management Console XE "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.
Visual InterDev XE "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.
|
||
|
Instalowanie Visual InterDev RAD Support powoduje potencjalne osłabienie systemu bezpieczeństwa twojego systemu, więc powinieneś być ostrożny. Komponent ten pozwala na zdalne rozsyłanie aplikacji, nawet bez Twojej wiedzy. Tak jak w przypadku platformy programistycznej możliwe jest, że komponent zdalnie zainstalowany na Twoim komputerze będzie miał niesprzyjające efekty w Twoim systemie. |
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.
Opcje instalacji: minimalna, typowa i niestandardowa
Jeżeli wybierzesz instalację niestandardową (custom), będziesz mógł wybrać dowolne składniki z listy, którą przedstawiliśmy powyżej. Nie jest to zwykle potrzebne lub wymagane, więc Microsoft dał możliwość skorzystania z dwóch innych opcji.
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:
Microsoft Data Access Components 1.5;
Personal Web Server (tylko Windows 95/98 lub NT Workstation);
Internet Information Server (tylko NT Server);
Transaction Server;
SMTP Service (tylko NT Server).
Instalacja typowa zawiera wszystkie komponenty wymienione powyżej oraz dodatkowo:
FrontPage Server Extensions;
Dokumentacja do Personal Web Server (tylko Windows 95/98 i NT Workstation);
Dokumentacja do Internet Information Server (tylko NT Server);
Dodatkowa dokumentacja do: Active Server Pages, usługi SMTP, ADO oraz Index Server (tylko NT Server);
Microsoft Index Server (tylko NT Server);
Microsoft Management Console (tylko NT Server);
Index Server (tylko NT Server);
Microsoft Script Debugger;
Windows Scripting Host.
|
||
|
Aby wykonać pełną instalację dokumentacji do Active Server Pages dla Personal Web Server, musisz uruchomić instalację niestandardową i włączyć ten składnik instalacji. Z jakiegoś powodu Microsoft zdecydował się nie włączać tego składnika do żadnej z dwóch przygotowanych opcji instalacji. |
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.
Microsoft Transaction Server 2.0
Microsoft Transaction Server XE "Microsoft Transaction Server" (MTS) jest jednym z ważniejszych składników Option Pack i jest niezbędny do pracy wielu innych usług, włączając w to IIS/PWS. MTS jest brokerem wywołań obiektów (object request broker) oraz brokerem transakcji (transaction broker). Do tej pory krytyczne aplikacje musiały pracować na wielkich systemach zaopatrzonych w specjalne oprogramowanie zapewniające wymaganą niezawodność.
|
||
|
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. |
Co to jest broker transakcji?
Dobre pytanie. Broker transakcji XE "broker transakcji" zarządza transakcjami, jednak to stwierdzenie również nie mówi zbyt wiele. Większość systemów baz danych, jak Microsoft SQL Server, zapewnia zarządzanie transakcjami. Serwer bazy danych rozpoczyna transakcję, a następnie wykonywane jest jedno lub więcej wyrażeń SQL na jednej lub więcej tabelach. Serwer bazy danych nie zatwierdza zmian, dopóki nie dostanie polecenia mówiącego, że wszystko się udało. Pomaga to na zachowanie integralności danych w bazie danych i spójności w aplikacji. Zapewnia to, że wyrażenie 1 zostanie wykonane tylko razem z wyrażeniem 2 i 3. Jeżeli transakcja nie powiodła się, jest ona wycofywana, co oznacza, że wszystkie wyrażenia SQL są anulowane i baza danych jest przywrócona do stanu sprzed transakcji.
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.
|
||
|
Access 2000 (i wszystkie poprzednie wersje) nie potrafi w pełni wykorzystać możliwości Microsoft Transaction Server. Mimo to możesz tworzyć aplikacje z wykorzystaniem MTS, aby uzyskać szybkość działania, skalowalność i łączenie połączeń, musisz użyć bardziej zaawansowanej bazy danych, takiej jak Microsoft SQL Server, aby w pełni skorzystać z wszystkich poziomów wsparcia transakcyjności. |
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.
Zarządzanie i konfiguracja serwera WWW XE "serwer WWW:konfiguracja"
Do konfiguracji serwisów WWW, w zależności od tego czy pracujesz na Windows 95/98, czy Windows NT (Server lub Workstation), używa się dwóch różnych narzędzi. Powinieneś zapoznać się z interfejsem użytkownika narzędzia właściwego dla Twojej platformy.
Personal Web Manager XE "Personal Web Manager"
Program pracujący na Windows 95/98 nazwany został Personal Web Manager i posiada bardzo prosty interfejs użytkownika umożliwiający konfigurację serwera WWW. Dostępne jest pięć głównych opcji: Main, Publish, Web site, Tour oraz Advanced. Wybór opcji z paska nawigacyjnego z lewej strony okna lub z menu View otwiera odpowiedni obszar w głównej części okna.
Ekran Main (rysunek 24.1) jest miejscem, w którym można uruchamiać i zatrzymywać lokalną usługę WWW. Na tym ekranie wyświetlone są również podstawowe informacje na temat serwisu.
Oprócz uruchamiania i zatrzymywania serwisu można odczytać położenie głównej strony WWW (katalog domowy), adres WWW strony głównej (ponad przyciskiem start / stop) i niektóre statystyki ruchu na Twoim serwerze (grupa Monitoring).
Rysunek 24.1. Strona Main programu Personal Web Manager jest zwykle używana do uruchamiania i zatrzymywania usługi WWW |
|
||||
|
|||||
|
Możesz uruchomić lub zatrzymać usługę WWW, klikając prawym klawiszem myszki ikonę PWS w zasobniku systemowym (dolny prawy róg ekranu obok zegara) i wybierając żądaną opcję z menu. |
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.
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.
Tour dostarcza podstawowych informacji, prawdopodobnie nic ponad to, co już wiesz. Jeżeli jesteś ciekawy, przejrzyj dostępne ekrany informacyjne.
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.
|
||
|
Termin „katalog wirtualny” nie jest właściwie rozumiany przez niektórych programistów. Jest on dokładnie wyjaśniony w części „Różnica pomiędzy witryną a katalogiem wirtualnym” tego rozdziału. |
Katalogi wirtualne XE "katalog wirtualny" 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 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.
Microsoft Management Console
Program Microsoft Management Console (MMC), pokazany na rysunku 24.4, jest głównym narzędziem do zarządzania wszystkimi usługami, które są częścią Option Pack na Windows NT, oraz będzie dużą i ważną częścią Windows 2000 (następcy Windows NT). Dobrym pomysłem jest zapoznanie się z nim, jeżeli planujesz używać kolejnych wersji Microsoft Windows NT.
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 |
|
Konfiguracja Internet Information Server
Pierwsza wtyczka (jedyna, którą opiszemy w tej książce) służy do zarządzania programem Internet Information Server. Jeżeli rozwiniesz jeden poziom tej gałęzi, zobaczysz tam nawę NetBios Twojego komputera. Rozwinięcie jeszcze jednego poziomu odkryje różne opcję zależne od zainstalowanych usług.
Zwykle znajdują się tam:
Default FTP Site;
Default Web Site;
Administration Web Site;
Default SMTP Site.
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.
Wykonamy teraz kilka zmian w konfiguracji serwera.
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 XE "plik ś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.
|
||
|
Nie wybieraj wszystkiego. Każda rzecz, którą zapisujesz, powoduje dodatkową aktywność dysków i obciążenie systemu. Dla najlepszej wydajności wybierz tylko te informacje, których naprawdę potrzebujesz. |
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 XE "dokument domyślny" (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.
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 |
|
Anonymus Access and Authentication Control (Dostęp anonimowy i zarządzanie uwierzytelnianiem);
Secure Comunications (Bezpieczny przesył danych);
IP Address and Domain Name Restrictions (Ograniczenie adresów IP i nazw domen).
Wybierz Anonymus Access and Authentication Control. Masz do wyboru trzy opcje:
Allow Anonymous Access (zezwolenie na dostęp anonimowy);
Basic Authentication (podstawowe uwierzytelnianie, hasło przesyłane jest otwartym tekstem);
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 XE "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 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 XE "Secure Socket Layer" (SSL XE "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 XE "klucz 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://.
|
||
|
Elektroniczny handel staje się coraz bardziej popularny. Aby bezpiecznie przesyłać przez Internet poufne dane (jak numery kart kredytowych), musisz użyć SSL. |
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.
Za pomocą pól Content Control można ustawiać cztery opcje:
Rysunek 24.8. Zakładka Home Directory pozwala na zarządzanie najniższą warstwą ustawień witryny WWW, takich jak katalog na serwerze |
|
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.
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.
Index This Directory. Mówi usłudze Index Server, że należy śledzić i indeksować pliki zawarte, w tej witrynie dla potrzeb przeszukiwania serwera.
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).
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 XE "VBScript" , ale może być JScript XE "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.
Zabezpieczanie aplikacji WWW
Jednym z problemów, z którymi stykają się użytkownicy po zainstalowaniu IIS lub PWS, jest bezpieczeństwo. Jest ono szczególnie ważne, gdy pisze się aplikację obsługującą handel elektroniczny lub inną zawierającą ważne dane.
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.
|
||
|
Wiele firm uruchamia ściany ognia (ang. firewall XE "firewall" ) pomiędzy ich serwerami a Internetem. Takie zabezpieczenie pozwala na uruchomienie szczegół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.
Różnice pomiędzy witryną a katalogiem wirtualnym
Witryna XE "witryna" jest oddzielną jednostką na serwerze WWW identyfikowaną przez unikatową nazwę domeny. Internet Information Server na Windows NT Server dobrze obsługuje wiele witryn na pojedynczym serwerze. Tylko sprzęt ogranicza ilość witryn, które możesz uruchomić na pojedynczym serwerze.
Katalog wirtualny XE "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.
|
||
|
Microsoft FrontPage i Visual InterDev w różny sposób traktują konfiguracje katalogów wirtualnych. Jeżeli używasz któregoś z tych narzędzi, najlepiej pozwolić na stworzenie katalogu wirtualnego przez narzędzie. Po utworzeniu katalogu przez program nie zmieniaj jego ustawień. Wielu programistów „zepsuło” swoje witryny przez zmianę ustawień WWW lub uprawnień plików na witrynach tworzonych przez FrontPage lub Visual InterDev. |
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 HYPERLINK "http://www.witryna.com"
www.witryna.com, a katalog wirtualny o nazwie „użytkownik1” umieszczony jest w d:\użytkownik1, będzie on dostępny jako HYPERLINK "http://www.witryna.com/uzytkownik1/"
http://www.witryna.com/uzytkownik1/ nawet, gdy katalog ten jest fizycznie odizolowany od obszaru serwera.
|
||
|
Mimo że katalog wirtualny może znajdować się w dowolnym miejscu, powinien być umieszczony w drzewie katalogów WWW. Struktura katalogów dla aplikacji WWW powinna zostać wcześniej przemyślana. Posiadanie wielu katalogów wirtualnych rozsianych w różnych miejscach serwera powoduje duże problemy w utrzymaniu. |
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.
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 XE "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.
|
||
|
Globalny plik global.asa powinien być umieszczony w katalogu będącym punktem startowym aplikacji. Jeżeli zadeklarowałeś katalog wirtualny jako aplikację, plik global.asa powinien znajdować się w fizycznym katalogu, który zdefiniowałeś jako katalog startowy katalogu wirtualnego. |
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 XE "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.
Typ systemu plików
Mimo że IIS posiada kilka zaszytych w sobie opcji zapewniających niewielki poziom bezpieczeństwa witryny, jest on niewystarczający dla większości wypadków bez wsparcia ze strony zabezpieczeń Windows NT. Gorąco polecamy użycie Windows NT File Sysem (NTFS) na partycji zawierającej pliki witryny WWW oraz bazę danych. Pozwala to na uaktywnienie zabezpieczeń na poziomie dostępu do plików i katalogów, co jest jedyną drogą zabezpieczenia serwera produkcyjnego.
|
||
|
NTFS jest dostępny tylko na Windows NT. Jeżeli tworzysz aplikację na Windows 95/98, nie będziesz mógł utworzyć tak szczelnego systemu bezpieczeństwa, jaki można utworzyć na Windows NT. Jest to jeszcze jeden powód umieszczenia gotowej aplikacji na Windows NT. |
Struktura katalogów i wymagane uprawnienia
Standardowa konfiguracja komputera na serwer WWW XE "serwer WWW:konfiguracja komputera" posiada dwie partycje, jedna mała (około 1 GB) na system operacyjny i druga na wszystkie związane z WWW pliki oraz pliki śladu. Rodzaj systemu plików użytego dla partycji systemowej jest zależny od upodobań, ale prawie zawsze partycja zawierająca witrynę WWW posiada system plików NTFS w celu zapewnienia odpowiedniego poziomu bezpieczeństwa.
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.
ASP/HTML - położenie i uprawnienia
Zakładamy, że posiadasz ogólną wiedzę na temat uprawnień XE "uprawnienia" w NT i szybko prześledzimy wymagania dla IIS.
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 |
|
Bazy danych - położenie i uprawnienia
Jeżeli używasz Active Server Pages, aby podłączyć się do bazy danych Accessa, baza danych nie musi znajdować się w głównym katalogu witryny WWW. Ponieważ ścieżka jest podana w ciągu połączenia, możesz umieścić ją w dowolnym miejscu. Ze względów bezpieczeństwa zaleca się umieścić bazę danych w katalogu, który jest odizolowany od plików WWW. D:\databases\ jest świetnym rozwiązaniem. Uniemożliwia to złośliwym klientom wpisanie HYPERLINK "http://www.witryna.com/baza/bazadanych.mdb"
http://www.witryna.com/baza/bazadanych.mdb i zapisanie pliku bazy danych na swoim komputerze.
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:
Czym są komponenty sieciowe Office.
Użycie formantu Office Arkusz.
Użycie formantu Office Wykres.
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.
Czym są komponenty sieciowe Office
Komponenty sieciowe XE "komponenty sieciowe" Office są zbiorem formantów ActiveX opartych na technologii COM, dostarczających niektóre podstawowe funkcje arkusza, wykresu i tabeli przestawnej, zawarte w Office, dla przeglądarki internetowej obsługującej technologię ActiveX. W Office 2000 komponenty sieciowe składają się z:
Formantu Office Arkusz XE "Arkusz:komponent sieciowy" ;
Formantu Office Wykres XE "Wykres:komponent sieciowy " ;
Formantu Office Tabela przestawna XE "Tabela przestawna:komponent sieciowy " .
Te trzy formanty graficzne (Spreadsheet XE "Spreadsheet" , Chart XE "Chart" oraz PivotTable XE "PivotTable" ) oraz formant DataSource XE "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.
Rysunek 25.1. Komponent sieciowy Office umieszczony na formularzu Accessa |
|
Co potrafią komponenty sieciowe Office
Każdy komponent posiada inne funkcje, które można użyć w aplikacji. Formant Arkusz to mini Excel do wbudowania w stronę WWW lub formularz. Posiada on większość podstawowych funkcji Excela, jak przeliczanie, filtrowanie czy sortowanie. Możesz użyć formantu Arkusz jako niewidocznej maszyny liczącej w aplikacji Accessa, VB lub WWW. Wykres umożliwia tworzenie dwuwymiarowych wykresów i posiada możliwość łączenia z innymi elementami HTML jak formant Arkusz lub źródło danych. Wykres pozwala również na eksport rysunków GIF dla przeglądarek WWW, które nie obsługują formantów ActiveX. Formant Tabela przestawna udostępnia funkcję tworzenia tabel przestawnych dostępną w Excelu, poprzez formant ActiveX. Tabela przestawna tak jak Wykres potrafi również eksportować pliki GIF. Dostępny jest również formant DataSource, który nie posiada postaci graficznej. DataSource działa analogicznie do formantu Data w Visual Basicu. Łączy się on z bazą danych i pozwala innym formantom na dołączenie się do niego. Każdy z wymienionych formantów zostanie bliżej omówiony w następnym rozdziale.
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.
Użycie formantu Office Arkusz
Użycie formantu Arkusz XE "Arkusz" jest podobne do użycia Excela. Można go stosować na dwa sposoby, w formie związanej i niezwiązanej. Forma związana wymusza użycie formantu DataControl, który omówimy w następnym rozdziale. Tutaj zajmiemy się użyciem formantu w postaci niezwiązanej.
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 wyboru Dodaj interakcję XE "Dodaj interakcję:pole wyboru" (rysunek 25.2).
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 XE "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 |
|
Użycie formantu w Accessie
Aby wstawić formant Arkusz na formularz Accessa, z głównego menu wybierz Wstaw, Formant ActiveX. Otworzy się okno dialogowe Wstawianie formantu ActiveX (rysunek 25.5). Przewiń listę dostępnych formantów do Arkusz pakietu Microsoft Office 9.0 i kliknij OK. Spowoduje to wstawienie formantu do formularza w trybie projektowania (rysunek 25.6).
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 XE "ActiveCell:właściwość" 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.
Po wstawieniu zmień nazwę formantu na Spreadsheet1 w oknie właściwości.
Rysunek 25.5. Okno dialogowe Wstawianie formantu ActiveX |
|
Rysunek 25.6. Formant Arkusz na formularzu Accessa w trybie edycji |
|
Wydruk 25.1. Ładowanie danych do formantu Arkusz w trakcie pracy programu
Private Sub Form_Load()
'Ładuje do formantu ActiveX Arkusz
'dane pochodzące z kwerendy z Accessa
Dim rst As ADODB.Recordset
Dim intCount As Integer
On Error GoTo Proc_Err
Set rst = New ADODB.Recordset
rst.Open "[Ten Most Expensive Products]", CurrentProject.Connection
' Wpisywanie nagłówków
Spreadsheetl.ActiveCell(1, 1) = "Produkt"
Spreadsheetl.ActiveCell(1, 2) = "Cena"
' Inicjuj licznik pętli
intCount = 2
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
Użycie formantu Office Wykres
Mogłeś pomyśleć, że straciłeś zbyt dużo czasu, zajmując się programem Microsoft Graph. Formant Wykres XE "Wykres:formant sieciowy" jest prosty do użycia i bardzo potężny. Jak inne formanty, może być użyty w trybie związanym i niezwiązanym. Teraz zajmiemy się użyciem formantu w trybie niezwiązanym, natomiast tryb związany zostanie omówiony w następnym rozdziale. 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 |
|
Użycie formantu w Accessie
Wstaw formant na formularz Accessa przy użyciu Wstaw, Formant ActiveX. Musisz wybrać z listy formantów ActiveX „Wykres pakietu Microsoft Office 9.0”. Po utworzeniu formantu zmień jego nazwę na Chart1 w oknie właściwości. Gdy używasz formantu Wykres w trybie niezwiązanym musisz pamiętać o dwóch ważnych sprawach. Po pierwsze, formant Wykres może przechowywać wiele obiektów, więc każdy utworzony wykres będzie częścią kolekcji Charts XE "Charts:kolekcja" . Po drugie, możesz wypełnić tablice wartości dla serii wykresów i tablicę wartości dla danych serii wykresów.
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)
In ("Qtr 1","Qtr 2","Qtr 3","Qtr 4");
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.
Wydruk 25.2. Tworzenie niezwiązanego wykresu
Private Sub Form Open(Cancel As Integer)
'Ładuje do formantu ActiveX Wykres
'dane pochodzące z kwerendy z Accessa
Dim ChartSpace1, aHeaders(3), aValues(3)
Dim rst As ADODB.Recordset
On Error GoTo Proc_Err
Set rst = New ADODB.Recordset
' Tworzenie tablicy elementów dla wykresu
aHeaders(0) = "Q1"
aHeaders(1) = "Q2"
aHeaders(2) = "Q3"
aHeaders(3) = "Qq"
' Otwarcie recordsetu opartego o kwerendę XTAB
' i wypełniamy wartości dla słupków wykresu
rst.Open "qry0uarterlySales", CurrentProject.Connection
aValues(0) = rst![Otr 1]
aValues(1) = rst![Qtr 2]
aValues(2) = rst![Otr 3]
aValues(3) = rst![Otr 4]
Set ChartSpace1 = Me.Chart1
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
Użycie formantu Office Tabela przestawna XE "Tabela przestawna:formant sieciowy"
Tak jak w przypadku dwóch formantów przedstawionych w tym rozdziale, Tabela przestawna może być używana w trybie związanym i niezwiązanym. Dalsza część rozdziału przedstawi sposób użycia formantu w trybie niezwiązanym, natomiast w następnym rozdziale przedstawimy sposób wiązania formantu do danych na stronie dostępu do danych.
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:
Tworzenie pierwszej strony dostępu do danych
Tworzenie interaktywnych odnośników
Łączenie komponentów sieciowych Office z DAP
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 XE "strony dostępu do danych" (DAP XE "DAP" - Data Access Pages XE "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.
Czym są strony dostępu do danych?
Prawdopodobnie zauważyłeś nową pozycję w oknie bazy danych nazwaną Strony. Jest to miejsce na nowe obiekty bazy danych zwane stronami dostępu do danych (DAP). Rysunek 26.1 przedstawia okno bazy danych otwarte na pozycji Strony. DAP to podzbiór raportów i formularzy Accessa zaprojektowanych do pracy w sieci, a dokładniej w Intranecie. Strony te są zapisane jako Dynamic HTML XE "Dynamic HTML" i mogą być oglądane w Internet Explorer 5.0 lub późniejszych. Strona taka podłącza się do pracującej bazy danych i daje możliwość wprowadzania do bazy danych z formularza lub tworzenia raportu z bazy danych.
Rysunek 26.1. Nowa sekcja w oknie bazy danych zawierająca strony dostępu do danych |
|
Architektura oraz wymagania stron dostępu do danych
Strony dostępu do danych używają formantów ActiveX, dynamicznego HTML, ADO oraz skryptów wykonywanych po stronie klienta. Używając skryptów wykonywanych po stronie klienta, musisz mieć zainstalowane na stacjach roboczych ADO i dostawcę OLEDB dla Accessa i serwera SQL. Formaty ActiveX są obsługiwane tylko przez Internet Explorer 4.0 oraz 5.0, 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.
Tworzenie Twojej pierwszej strony dostępu do danych
Rozpocznijmy tworzenie naszej pierwszej strony dostępu do danych XE "strony dostępu do danych:tworzenie" . Przełącz okno bazy danych na Strony i wybierz Nowy. Następnie wybierz Widok projektu. Na ekranie pojawi się pusta strona w widoku projektu (rysunek 26.2).
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).
|
|||||
|
Musisz pamiętać, że DAP nie są przechowywane w pliku MDB. Sprawia to wiele kłopotów podczas rozprowadzania aplikacji. Musisz rozprowadzać plik MDB wraz z wszystkimi utworzonymi stronami dostępu. Oprócz tego musisz utrzymywać zgodność między ADP na dysku i informacją zapisaną w bazie. Możesz jednak zmienić to ograniczenie w korzyść, jeżeli umieścisz DAP na serwerze WWW. Dopóki użytkownicy mają dostęp do serwera WWW poprzez Internet lub Intranet, możesz umieścić pliki DAP na serwerze WWW. |
||||
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 XE "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).
Rysunek 26.7. Okno dialogowe Motyw |
|
Oglądanie strony dostępu do danych
Gotową stronę można oglądać na dwa sposoby: jako część aplikacji Accessa lub w przeglądarce WWW. Aby oglądać stronę w Accessie, kliknij ikonę Widok strony lub wybierz z menu Widok, Widok strony, będąc w trybie projektowania. Jeżeli chcesz wyświetlić stronę w aplikacji Accessa, użyj metody OpenDataAccessPage XE "OpenDataAccessPage:metoda" obiektu DoCmd:
DoCmd.OpenDataAccessPage "Kategorie", acDataAccessPageBrowse
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 |
|
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.
Tworzenie interaktywnych odnośników
Potężną opcją w stronach dostępu do danych jest możliwość tworzenia odnośników XE "odnośnik" opartych o relacje jeden - do - wielu zdefiniowane w bazie danych. Utworzymy teraz odnośnik, oparty o relację jeden do wielu z Categories do Products, na naszej stronie Kategorie. Otwórz stronę i wyświetl w przedstawiony wcześniej sposób listę pól dostępnych w bazie danych. Przenieś pola z tabeli Products: ProductName, UnitPrice oraz Discontinued na dół strony. Access utworzy nową sekcję, która będzie sekcją odnośnika (rysunek 26.10).
Rysunek 26.10. Podrzędna sekcja odnośnika dla tabeli Products w trybie projektowania |
|
||||
|
|||||
|
Mimo że Microsoft wymaga przestrzegania standardów Windows w aplikacjach, które chcą używać logo Windows, jednak sam ich nie dotrzymuje. Strony dostępu do danych nie posiadają funkcji Cofnij. |
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 |
|
Łączenie komponentów sieciowych Office z DAP
Potężną opcją w stronach dostępu do danych jest możliwość umieszczania na nich komponentów sieciowych Office, które są połączone dynamicznie z danymi. Rysunek 26.12 przedstawia stronę dostępu do danych utworzoną z użyciem komponentów sieciowych Office.
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
WHERE (((Orders.OrderDate) Between #1/1/1997# And #12/31/1997#))
GROUP BY Categories.CategoryName
PIVOT "Qtr " & DatePart("q",[OrderDate],1,0)
In ("Qtr 1","Qtr 2","Qtr 3","Qtr 4");
Zapisz tę kwerendę jako QuaterlyProducts i utwórz stronę dostępu do danych bazującą na tej kwerendzie.
Dodanie komponentu sieciowego Arkusz XE "Arkusz:komponent sieciowy" Excel
Aby dodać komponent Excel do strony dostępu do danych, kliknij ikonę podobną do ikony Excela na pasku narzędzi (rysunek 26.13) i umieść komponent na stronie. Po umieszczeniu komponentu w odpowiednim miejscu należy związać komórki arkusza z polami na stronie tak, aby arkusz zmieniał się, gdy użytkownik będzie przechodził między rekordami. Musisz użyć modelu obiektowego DHTML XE "DHTML" , gdzie wszystkie obiekty są udostępnione poprzez obiekt document. Aby odwołać się do pola o nazwie txtQ1, wprowadź do komórki:
=document.txtQ1.value
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 |
Dodanie komponentu sieciowego Wykres
Po dodaniu do strony komponentu Arkusz Excel, dodajmy komponent Wykres XE "Wykres:komponent sieciowy" wiążąc go z danymi w arkuszu. Gdy będziemy przechodzić pomiędzy rekordami, będzie się zmieniać zawartość arkusza oraz uaktualniany będzie wykres.
Rysunek 26.13. Pasek narzędzi strony dostępu do danych |
|
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.
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.
Skrypty w stronach dostępu do danych
Pisanie procedur kontrolujących strony dostępu do danych nie jest tak proste jak pisanie procedur dla formularzy i raportów. Gdy chcesz napisać program zawarty w stronie DAP, musisz użyć skryptów, aby móc kontrolować zachowanie się strony. Gdy tworzysz przycisk lub inny obiekt udostępniający zdarzenia, musisz napisać VBScript XE "VBScript" (lub JavaScript XE "JavaScript" ). W Accessie nie ma edytora skryptów dla stron dostępu do danych, należy użyć Microsoft Script Editor XE "Microsoft Script Editor" (MSE), który pokazany jest na rysunku 26.15.
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 XE "onClick:zdarzenie" . W oknie z kodem HTML powinien pokazać się fragment kodu HTML:
<SCRIPT event=onclick for=Polecenie0 language=vbscript>
<!--
-->
</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 XE "MSODSC:obiekt" , który z kolei zawiera obiekt DataPage XE "DataPage:obiekt" . Użyjemy metod MoveFirst XE "MoveFirst:metoda" , MoveLast XE "MoveLast:metoda" , MoveNext XE "MoveNext:metoda" i MovePrevious XE "MovePrevious:metoda" w odpowiednich przyciskach. Po oprogramowaniu wszystkich czterech przycisków kod powinien wyglądać podobnie do zamieszczonego na wydruku 26.1.
Wydruk 26.1. Tworzenie własnych przycisków nawigacyjnych na stronie dostępu do danych
<SCRIPT event=onclick for=cmdFirst language=vbscript>
<!--
MSODSC.CurrentSection.DataPage.MoveFirst
-->
</SCRIPT>
<SCRIPT event=onclick for=cmdLast language=vbscript>
<!--
MSODSC.CurrentSection.DataPage.MoveLast
-->
</SCRIPT>
<SCRIPT event=onclick for=cmdNext language=vbscript>
<!--
MSODSC.CurrentSection.DataPage.MoveNext
-->
</SCRIPT>
<SCRIPT event=onclick for=cmdPrev language=vbscript>
<!--
MSODSC.CurrentSection.DataPage.MovePrevious
-->
</SCRIPT>
Zmiana źródła danych w trakcie działania strony
Dopóki strony dostępu do danych nie będą zapisywane we wnętrzu pliku MDB, dystrybucja ich będzie stanowić problem. Najczęściej spotykanym problemem jest to, że strona odwołuje się do niewłaściwej bazy danych. Gdy umieścisz strony DAP na serwerze WWW lub wyślesz pliki HTML do kogoś innego, strony odwoływać się będą do niewłaściwego pliku MDB lub jakiś użytkownik może mieć pliki w innym miejscu niż inni użytkownicy.
W stronach DAP zarządzaniem połączeniami zajmuje się niewidoczny komponent sieciowy DataSource XE "DataSource:komponent sieciowy" , za pomocą którego można dowolnie programować połączenia. Komponent DataSource posiada właściwość ConnectionString XE "ConnectionString:właściwość" , 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 XE "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 XE "UDL" po stronie klienta, aby wyeliminować konieczność ręcznego wpisywania danych.
Rysunek 26.16. Wprowadzanie danych o połączeniu |
|
Wydruk 26.2. Ustawianie właściwego ciągu połączeniowego w stronie dostępu do danych
<SCRIPT language=vbscript>
<!--
'Przykład ten ustawia połączenie strony DAP do dowolnej
'bazy danych wprowadzonej przez użytkownika
Dim strConnect
Dim strPath
'Użytkownik wprowadza nazwę bazy przy użyciu InputBox
strPath=inputbox("Wprowadź ścieżkę do bazy NorthWind","Połączenie", _
"C:\Program Files\Microsoft Office\Office\Samples")
'Dla serwera SQL powinieneś zmienić na
'strConnect="Provider=SQLOLEDB.1"
strConnect="Provider=Microsoft.JET.OLEDB.4.0"
'Dodaj informacje o dostawcy do ścieżki
strConnect=strConnect & ";Data Source=" & strPath
'Ustawienie właściwości DataSource
'Domyślnie obiekt źródła danych nazywa się MSODSC
'Jeżeli zmieniłeś jego nazwę, musisz dokonać zmiany również tutaj
MSODSC.ConnectionString = strConnect
'Poinformuj użytkownika o zmianie połączenia
Msgbox "Połączenie zmienione na " & strPath,64
-->
</SCRIPT>
Rozdział 27.
Publikowanie w sieci
przy użyciu Accessa 2000
i Active Server Pages
W tym rozdziale:
Użycie Active Server Pages.
Architektura Active Server Pages.
Rozpoczynamy pracę z Active Server Pages.
Active Server Pages.
Przykład: Tworzenie strony WWW dostępnej dla członków grupy.
Publikacja w sieci z Accessa 2000 przy użyciu XML.
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 XE "Active Server Pages" (ASP XE "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żytkownikom 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.
Użycie Active Server Pages
Strony Active Server Pages są najnowszą technologią oferowaną przez Microsoft dla dynamicznego udostępniania danych w sieci WWW. ASP jest częścią Internet Information Server 3.0 i późniejszych, jest również dostępna w Personal Web Server. Przy użyciu ASP można tworzyć strony WWW następnej generacji, które nie mają ograniczeń starszych technologii jak Common Gateway Interface XE "Common Gateway Interface" (CGI XE "CGI" ) i Internet Database Connector XE "Internet Database Connector" (IDC XE "IDC" ). Przy użyciu ASP można łatwo tworzyć interaktywne witryny, które umożliwiają indywidualną obsługę klientów, wprowadzanie zamówień, koszyk zakupów i wiele innych funkcji interaktywnych. Wygląd stron WWW może być dostosowywany przez użytkowników i ustawienia te zostaną odtworzone podczas ich kolejnych wizyt.
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 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ć.
Architektura Active Server Pages
Na pewno widziałeś w Internecie adres URL podobny do HYPERLINK "http://www.microsoft.com/default.asp"
http://www.microsoft.com/default.asp. Plik z rozszerzeniem ASP zawiera stronę Active Server Page. Strony ASP są dostępne tak jak strony HTML za pomocą protokołu HTTP. Ogromną różnicą pomiędzy ASP i HTML jest sposób traktowania takiej strony przez serwer WWW. Strony ASP zawierają zarówno HTML, jak i instrukcje dla serwera WWW. Instrukcje te są skryptami wykonywanymi na serwerze, które dynamicznie tworzą kod HMTL w zależności od warunków, jakie podałeś lub od zawartości bazy danych. Serwer WWW przetwarza instrukcje zawarte na stronie ASP i przesyła wynikowy kod HTML do przeglądarki użytkownika.
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 XE "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.
Active Server Pages kontra CGI
Strony Active Server Pages są integralną częścią systemu operacyjnego i nie wymagają kompilacji. Aplikacje CGI są kompilowane na docelowym serwerze WWW i wykonywane jako osobny proces. Dla każdego aktywnego użytkownika witryny uruchamiany jest osobny egzemplarz aplikacji CGI, co nie jest efektywne. Program CGI musi być skompilowany za każdym razem, gdy go zmienimy, natomiast gdy zmienimy plik ASP, zostanie on skompilowany przy następnej próbie dostępu do tego skryptu. Oznacza to, że w trakcie tworzenia aplikacji ASP po zapisaniu strony można ją natychmiast obejrzeć 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.
Uruchomienie stron ASP
Przed konwersją wszystkich obiektów aplikacji należy się upewnić, czy są zainstalowane i działają strony Active Server Pages, czy źródło ODBC lub dostawca OLEDB jest skonfigurowany dla bazy danych i czy skonfigurowany jest katalog wirtualny z prawami do wykonywania skryptów aplikacji. Wszystkie te zagadnienia zostały opisane w rozdziale 24. „Konfiguracja serwera WWW do publikowania w sieci WWW”.
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 XE "eksport:jako ASP" 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>
<TH BGCOLOR=#c0c0c0 BORDERCOLOR=#000000 ><FONT SIZE=2 FACE="Arial" COLOR=#000000>Przedstawiciel</FONT></TH>
<TH BGCOLOR=#c0c0c0 BORDERCOLOR=#000000 ><FONT SIZE=2 FACE="Arial" COLOR=#000000>Stanowisko</FONT></TH>
<TH BGCOLOR=#c0c0c0 BORDERCOLOR=#000000 ><FONT SIZE=2 FACE="Arial" COLOR=#000000>Adres</FONT></TH>
<TH BGCOLOR=#c0c0c0 BORDERCOLOR=#000000 ><FONT SIZE=2 FACE="Arial" COLOR=#000000>Miasto</FONT></TH>
<TH BGCOLOR=#c0c0c0 BORDERCOLOR=#000000 ><FONT SIZE=2 FACE="Arial" COLOR=#000000>Region</FONT></TH>
<TH BGCOLOR=#c0c0c0 BORDERCOLOR=#000000 ><FONT SIZE=2 FACE="Arial" COLOR=#000000>Kod pocztowy</FONT></TH>
<TH BGCOLOR=#c0c0c0 BORDERCOLOR=#000000 ><FONT SIZE=2 FACE="Arial" COLOR=#000000>Kraj</FONT></TH>
<TH BGCOLOR=#c0c0c0 BORDERCOLOR=#000000 ><FONT SIZE=2 FACE="Arial" COLOR=#000000>Telefon</FONT></TH>
<TH BGCOLOR=#c0c0c0 BORDERCOLOR=#000000 ><FONT SIZE=2 FACE="Arial" COLOR=#000000>Faks</FONT></TH>
</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></FONT></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.
Konstrukcja kodu ASP
Jak można zauważyć, kreator eksportu tworzy bardzo prosty kod. Na początku otwierany jest obiekt połączenia ADO i na bazie tego połączenia otwierany jest obiekt ADO recordset. W trakcie przesuwania się po wyniku dane kierowane są do tabeli HTML. Dokładniej zostanie to opisane w dalszej części rozdziału.
Rysunek 27.2. Tabela skonwertowana do postaci ASP |
|
Ograniczenia eksportu stron ASP
Mimo że eksport z Accessa pozwala w łatwy sposób rozpocząć pracę z ASP, nie jest tak elastyczny jak mógłby być ani nie utworzy dla Ciebie całej niestandardowej strony ASP. Eksport nie zapewnia żadnej interaktywności tworzonej strony, nie pozwalając na zmiany rekordów czy ich usuwanie. Ponadto strona ASP wygenerowana przez eksport używa wolniejszego i mniej efektywnego połączenia ODBC do podłączenia się do bazy danych.
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.
Active Server Pages
Aby tworzyć aplikacje ASP oparte o bazę danych Access 2000, musisz poznać podstawy ASP. Mimo że na temat ASP można napisać oddzielną książkę, ta część rozdziału przedstawia podstawowe informacje pozwalające rozpocząć pracę. Materiał tu przedstawiony pozwala na zbudowanie całkiem rozbudowanej aplikacji WWW. Omówione zostaną:
Silnik ASP;
Skrypty VBScript wykonywane na serwerze;
Obiekty aplikacji i sesji;
Obiekty żądań i odpowiedzi;
Plik global.asa.
Silnik ASP
Active Server Pages to jeden z interfejsów Internet Server Application Programming Interface XE "Internet Server Application Programming Interface" (ISAPI XE "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.
Skrypty wykonywane na serwerze
Plik ASP zawiera skrypty wykonywane na serwerze XE "skrypty wykonywane na serwerze" oraz kod HTML. Skrypty domyślnie są zapisane w języku VBScript i w tym rozdziale skupimy się na nim. Visual Basic Scripting Edition XE "Visual Basic Scripting Edition" , znany pod nazwą VBScript, jest rozbudowanym językiem skryptów wykonywanych zarówno na serwerze, jak i na maszynie klienta.
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 XE "Long:typ" , String XE "String:typ" itd.), a w zamian wszystkie zmienne są typu Variant XE "Variant:typ" . 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
Kategoria |
Usunięta funkcja lub słowo kluczowe |
Obsługa tablic |
Option Base |
Kolekcje |
Add, Count, Item, Remove |
Kompilacja warunkowa |
#Const |
Przepływ sterowania |
DoEvents |
Konwersje |
CVar, CVDate, Str, Val |
Typy danych |
Wszystkie wewnętrzne typy danych oprócz Variant |
Data i czas |
Instrukcja Date, Instrukcja Time |
Tabela 27.1.
Wszystkie funkcje VBA niedostępne w VBScript (ciąg dalszy)
Kategoria |
Usunięta funkcja lub słowo kluczowe |
DDE |
LinkExecute, LinkPoke, LinkRequest, LinkSend |
Uruchamianie |
Debug, PrintEnd, Stop |
Deklaracje |
Declare (dla deklarowania bibliotek DLL) |
Obsługa błędów |
Erl |
Obsługa plików |
Tradycyjna obsługa plików |
Funkcje finansowe |
Wszystkie funkcje finansowe |
Manipulacja obiektami |
TypeOf |
Obiekty |
Clipboard |
Operatory |
Like |
Opcje |
Deftype |
Ciągi znaków |
Ciągi o stałej długości |
Użycie obiektów |
Dostęp do kolekcji przy użyciu ! |
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.
Tabela 27.2 pochodząca z dokumentacji VBScript zawiera listę dostępnych funkcji.
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 zainstalowany pełny opis języka oraz przykładowe pliki (rysunek 27.3).
Tabela 27.2.
Funkcje dostępne w VBScript
Kategoria |
Słowo kluczowe |
Obsługa tablic |
Array, Dim, Private, Public, ReDim |
Przypisanie |
Set |
Komentarze |
Komentarze przy użyciu ' lub Rem |
Stałe, literały |
Empty, Nothing, Null, True, False |
Przepływ sterowania |
Do...Loop, For...Next, |
Konwersje |
Abs, Asc, AscB, AscW, Chr, ChrB, ChrW, |
Deklaracje |
Const, Dim, Private, Public, ReDim, Function, Sub |
Formatowanie ciągów |
FormatCurrency, FormatDateTime, |
Obsługa błędów |
On Err, Err |
Wejście/wyjście |
InputBox, LoadPicture, MsgBox |
Literały |
Empty, False, Nothing, Null, True |
Matematyka |
Atn, Cos, Sin, Tan, Exp, Log, Sgr, Randomize, Rnd |
Obiekty |
CreateObject, Dictionary, Err, |
Operatory |
Dodawanie (+), Odejmowanie (-), Potęga (^), |
Opcje |
Option Explict |
Procedury |
Call, Function, Sub |
Zaokrąglanie |
Abs, Int, Fix, Round, Sgn |
Identyfikacja silnika skryptów |
ScriptEngine, ScriptEngineBuildVersion, |
Tabela 27.2.
Funkcje dostępne w VBScript (ciąg dalszy)
Kategoria |
Słowo kluczowe |
|
Ciągi |
Asc, AscB, AscW, Chr, ChrB, ChrW, Filter, Instr, InstrB, |
|
Warianty |
IsArray, IsDate, IsEmpty, IsNull, IsNumeric, IsObiect, |
|
Rysunek 27.3. Dokumentacja do VBScript |
|
Użycie VBScript na stronach ASP
Przy użyciu VBScript można utworzyć świetnie wyglądające witryny, wykorzystując jego możliwość tworzenia skryptów wykonywanych na komputerze klienta (a właściwie skrypty wykonywane są przez przeglądarkę). W tym rozdziale skupimy się tylko na wykorzystaniu skryptów wykonywanych na serwerze, ponieważ tylko ten rodzaj skryptów wykorzystywany jest przez ASP do generowania wynikowego kodu HTML. Poniżej wymienione zostało kilka funkcji, które realizuje VBScript:
Tworzenie zmiennych, przypisywanie do nich wartości, wykorzystywanie ich w warunkach logicznych lub umieszczanie ich wartości w wynikowym kodzie HTML.
Wykonywanie operacji na zmiennych przy użyciu If...Then, Select Case i innych operatorów.
Tworzenie procedur wykonywanych na serwerze w celu wykonania logowania, kontroli dat i formatowania.
Dynamiczne tworzenie skryptów VBScript w wynikowym kodzie HTML do wykonania w przeglądarce klienta.
Skrypty znajdują się w kodzie HTML pomiędzy znacznikami <%> XE "<%>:znacznik" . 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.
Wydruk 27.2. Przykład pliku ASP używającego zmiennej
<HTML>
<HEAD><TITLE>Variables</TITLE></HEAD>
<BODY BGCOLOR=#FFFFFF>
<% strName="Stephen Forte" %>
Hello <%=strName%>
</BODY>
</HTML>
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.
Wydruk 27.3. Źródło HTML strony WWW z rysunku 27.4
<HTML>
<HEAD><TITLE>Variables</TITLE></HEAD>
<BODY BGCOLOR=#FFFFFF>
Hello Stephen Forte
<BR>
</BODY>
</HTML>
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.
Wydruk 27.4. Skrypt ASP wykonywany na serwerze
<HTML>
<HEAD>
<TITLE>Creating Hello World with Incremental Text Size Increase </TITLE>
</HEAD>
<BODY BGCOLOR=#FFFFFF>
<% for i = 3 to 7 %>
<FONT SIZE=<% = i %>>Hello World</FONT><BR>
<% next %>
<BR>
<BR>
</BODY>
</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.
Obiekty aplikacji i sesji
Używając ASP, można skorzystać z kilku wbudowanych obiektów, które są dostępne dla aplikacji. W tej części opiszemy sposób użycia każdego z tych obiektów w aplikacji ASP. Jest to jednak tylko wprowadzenie w temat użycia obiektów w aplikacjach. Dokładnego opisu zagadnienia należy szukać w innych książkach serii „Księga eksperta”.
Użycie obiektu aplikacji XE "obiekt aplikacji"
W czasie tworzenia stron ASP zakłada się, że każdy katalog wirtualny jest odrębną aplikacją. ASP odwołuje się do każdej aplikacji jako obiektu. Obiekt Application XE "Application:obiekt" używany jest do zarządzania wspólnymi danymi i jest dostępny dla wszystkich użytkowników aplikacji. Obiekt Application tworzony jest z chwilą pierwszego dostępu do stron aplikacji po uruchomieniu serwera WWW. Jest dostępny dla wszystkich użytkowników odwiedzających witrynę tak długo dostępny aż do chwili, gdy we wszystkich sesjach upłynie limit czasu oczekiwania lub zostanie wyłączony serwer WWW.
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 %>
Podczas wylogowywania użytkownika należy użyć:
<%Application("VisitorNum")= Application("VisitorNum")-1 %>
Aby wyświetlić liczbę jednocześnie zalogowanych użytkowników, użyj następującego wiersza:
Jednocześnie pracuje <%Application("VisitorNum")%> użytkowników
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.
Użycie obiektu sesji XE "obiekt sesji"
Prawdopodobnie najważniejszym obiektem, o którym powinieneś się dowiedzieć, jest obiekt Session XE "Session:obiekt" . ASP utrzymuje automatycznie stan sesji i to właśnie obiekt Session przechowuje stan sesji dla bieżącego użytkownika. Jeżeli jednocześnie strony używa 200 użytkowników, utworzonych jest 200 obiektów Session. Obiekt ten pozwala na tworzenie własnych właściwości dostępnych globalnie dla użytkownika odwiedzającego witrynę. Przykładowo można pozwolić użytkownikowi na podanie imienia i wybór ulubionego koloru. Przy użyciu właściwości obiektu Session można wygenerować stronę WWW w podanym przez użytkownika kolorze i umieścić na niej imię użytkownika.
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ść %>
Po ustawieniu właściwości można odwoływać się do niej z wszystkich stron witryny.
Użycie obiektów żądań i odpowiedzi
Opisane w poprzedniej części obiekty Application i Session mają możliwość tworzenia niestandardowych właściwości i utrzymują stan sesji. Kolejne dwa obiekty, Response XE "Response:obiekt" i Redirect, posiadają metody pozwalające, poprzez skrypty wykonywane na serwerze, na wykonywanie określonych akcji i dostęp do danych.
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 XE "Redirect:metoda" i Write XE "Write:metoda" .
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 XE "Request:obiekt"
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 XE "Form:metoda" 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. XE "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:
Application_OnStart XE "Application_OnStart:zdarzenie" ;
Application_OnEnd XE "Application_OnEnd:zdarzenie" ;
Session_OnStart XE "Session_OnStart:zdarzenie" ;
Session_OnEnd XE "Session_OnEnd:zdarzenie" .
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. „Zaawansowane ADO”). Oprócz połączenia do bazy tworzonych jest pięć zmiennych dostępnych dla całej sesji zainicjowanych informacjami pochodzącymi z bazy danych.
Wydruk 27.6. Plik global.asa dla przykładowego katalogu wirtualnego
<SCRIPT LANGUAGE="VBScript" RUNAT="Server">
' Plik Global.asa dla www.orcs.com/access2000
' Zadanie: przygotowanie właściwości obiektów Application i Session
' Stephen Forte
</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łady użycia obiektów ASP
Na koniec przedstawimy przykład, w którym używane są obiekty ASP.
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.
Wydruk 27.7. Zmienne obiektów Application i Session
<hr>
<%Application("VisitorNum")=Application("VisitorNum")+1%>
<p align="left"><strong>
Zmienne obiektów Application i Session:</strong></p>
<p><strong>Aplikacja uruchomiona: <%=Application("Start")%> </strong></p>
<p><strong>Użytkownik odwiedzający aplikację:
<%=Application("VisitorNum")%> </strong></p>
<p><strong>Sesja uruchomiona: <%=Session("Start")%> </strong></p>
<hr>
Rysunek 27.6. Obiekty ASP |
|
Użycie ADO w aplikacjach ASP
Obiekt recordset udostępnia do potencjalnego użycia wiele właściwości i metod. W następnym przykładzie użyjemy właściwości EOF XE "EOF:właściwość" (koniec pliku). EOF pozwala na uruchomienie pętli przeglądającej wszystkie rekordy wyniku od pierwszego do ostatniego. Skrypt zamieszczony na wydruku 27.8 otwiera połączenie oraz po wykonaniu kwerendy w pętli przebiega przez rekordy wyniku, wypisując je do wynikowego wyjścia HTML.
Wydruk 27.8. Użycie ADO na stronie ASP
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<title>Rozdział 26.: Przykład użycia ADO</title>
</head>
<body>
<h2 align="center"> Lista klientów Northwind Traders </h2>
<p align="center"> Rozdział 26.: Przykład użycia ADO </p>
<hr>
<% ' Początek skryptu VBScript
Dim x
Dim dbconn
Dim rst
' Zestawienie połączenia
Set dbconn=server.createobject("adodb.connection")
' Inicjowanie połączenia z bazą danych
dbconn.open "provider=Microsoft.Jet.OLEDB.4.O;" & _
"data source=D:\wwwroot\db\ch27.mdb"
' Wykonanie zapytania
set rst=dbconn.execute ("Select * from Customers")
' Używane jako licznik
x=1
Do Until rst.eof
response.write x & ". " & rst("CompanyName")%>
<br>
<%rst.movenext
x=x+1
loop
dbconn.close
' Koniec skryptu%>
<hr>
</body>
</html>
Wykonanie skryptu 27.8 da w rezultacie stronę pokazaną na rysunku 27.7.
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.
Przykład: tworzenie strony WWW dostępnej dla członków grupy
Jeżeli chcesz stworzyć witrynę WWW dostępną dla określonej grupy użytkowników, chronioną przed niepowołanym dostępem poprzez konieczność zalogowania się, Access 2000 oraz ASP są właściwym rozwiązaniem. Prowadzę lokalną grupę użytkowników Accessa i Visual Basica w Nowym Jorku. Mamy własną witrynę WWW, która znajduje się pod adresem www.nycaccessvb.com. Używa ona ASP do wyświetlania listy członków, listy spotkań i prowadzi bibliotekę programów. Strony ASP mają połączenie do bazy danych zawierającej informacje o członkach. Dodatkowo członkowie mogą po podaniu hasła uaktualniać informacje o sobie oraz przeglądać strony dostępne tylko dla nich, jak na przykład forum o miejscach pracy.
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.
Wydruk 27.9. Kod HTML do tworzenia kodu logowania
<form action="login.asp"
method="post" name="frmLogin">
<p align="right">ID <input type="text" size="15" name="txtID"></p>
<p align="right">Hasło<input type="password" size="15"
name="txtPass"></p>
<p align="right"><input type="submit" name="cmdOK"
value=" OK "> </p>
</form>
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.
Wydruk 27.10. Plik ASP login.asp
<%@ LANGUAGE--"VBSCRIPT" %>
<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
' Argumenty dla obiektu recordset
ado_OpenKeyset=1
ado_LockOptimistic=3
' Przypisanie ciągu połączenia
strConnect="provider=Microsoft.Jet.OLEDB.4.O;" & _
"data source=D:\wwwroot\db\ch27.mdb"
' Pobranie danych z formularza do zmiennych
strPass=request.form("txtPass")
strUserID=request.form("txtID")
' Tworzenie wyrażenia SQL
strSOL="SELECT FName, LName, Email, lastLogin, pass, " & _
"Status FROM tblMembers WHERE (Email =' & " "' & strUserID & _
" "' & ")"
' Tworzenie obiektu rst
Set rst=server.createobject("ADODB.RECORDSET")
' Otwarcie obiektu rst
rst.open strSOL, _
strConnect, ado_OpenKeyset, ado_LockOptimistic
' Sprawdzenie, czy użytkownik podał identyfikator użytkownika i hasło
If strUserID="" or strPass="" then
Response.Write "Nie podałeś identyfikatora użytkownika " & _
"lub hasła. Proszę poprawić."
else
' jeżeli rst.eof (koniec pliku), to znaczy, że nie znaleziono
if rst.eof then
response.write "Nie ma takiego użytkownika w systemie !!!"
else
'Sprawdzenie, czy podano właściwe hasło
If rst("pass")= strPass Then
' Hasło prawidłowe
' Tworzymy stronę WWW
Response.Write "Witaj " & rst("FName") & _
" " & rst("LName")
Response.Write "<br>"
Response.Write "Ostatnio logowałeś się: " & rst("lastLogin")
Response.Write "<br><br>" & _
"<a href=" & chr(34) & "admin.htm" & chr(34) & _
">Aktualizacja" & "</a>danych konta "
Response.Write "<br> <a href=" & _
chr(34) & "job.htm" & chr(34) & _
">Forum o pracy </a> tylko dla członków"
' Ustaw czas ostatniego logowania
rst.update ("lastlogin"),Date()
' Ustawienie zmiennej sesji
Session("User") = strUserID
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.
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.
Wydruk 27.11. Formularz zmiany hasła
<form action= "changepass.asp" form method="POST" name="frmNew">
<p>Hasło<input type="password" size="20" name="txtPass"></p>
<p>Weryfikacja<input type="password" size="20" name="txtVer"></p>
<p><input type="submit" name="cmdOK" value="Wyślij"></p>
</form>
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.
Wydruk 27.12. Plik changepass.asp
<%@ LANGUAGE="VBSCRIPT" %>
<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual InterDev 1.0">
<META HTTP-EOUIV="Content-Type" content="text/html;
charset=iso-8859-1">
<TITLE>Zmiana hasła</TITLE>
</HEAD>
<BODY>
<%
' 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
' Przypisanie ciągu połączenia
strConnect="provider=Microsoft.Jet.OLEDB.4.O;" & _
"data source=D:\wwwroot\db\ch27.mdb"
' Pobranie danych z formularza
strPass=request.form("txtPass")
strVerify=request.form("txtVerify")
' Sprawdzenie, czy zgadzają się wartości w polach
If strpass <> strVerify then
response.write "Nie zgadzają się wartości w " & _
" polach hasła ! <br>"
response.write "Proszę powtórzyć."
else
strSOL="SELECT pass, Status FROM tblMembers " & _
"WHERE (Email =" & "'" & Session("User") & "'" & ")"
' Utworzenie obiektu rst
Set rst=server.createobject("ADODB.RECORDSET")
rst.open strSOL, _
strConnect,ado_OpenKeyset,ado_LockOptimistic
If rst.eof then
response.write "Nie ma takiego użytkownika w systemie!!!"
else
rst.update ("pass"),strVerify
Response.Write "Hasło zostało zmienione, " & _
"proszę je zapamiętać !!"
end if
rst.close
end if%>
</BODY>
</HTML>
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 XE "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.
Publikacja w sieci z Accessa 2000 przy użyciu XML
Najprawdopodobniej natknąłeś się już na nowe słowo w technologii Internetu: XML XE "XML" lub Extensible Markup Language XE "Extensible Markup Language" . XML jest zorientowanym na dane standardem zapisu dokumentów i został zdefiniowany przez konsorcjum W3C XE "W3C" . Programiści internetowych baz danych powinni zainteresować się tym sposobem zapisu dokumentów. W tej części rozdziału opiszemy dokumenty XML i użyjemy ich w aplikacji.
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 (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 XE "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 XE "węzeł:potomny" 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.
Wydruk 27.13. Prosty dokument XML, który opisuje klientów
<?xml version="1.0"?>
<Customers>
<Customer>
<CustomerID>ALFKI</CustomerID>
<CompanyName>Alfreds Futterkiste</CompanyName>
<ContactName>Maria Anders</ContactName>
<ContactTitle>Sales Representative</ContactTitle>
</Customer>
<Customer>
<CustomerID>ANATR</CustomerID>
<CompanyName>Ana Trujillo Emparedados y helados</CompanyName>
<ContactName>Ana Trujillo</ContactName>
<ContactTitle>Owner</ContactTitle>
</Customer>
<Customer>
<CustomerID>ANTON</CustomerID>
<CompanyName>Antonio Moreno Taqueria</CompanyName>
<ContactName>Antonio Moreno</ContactName>
<ContactTitle>Owner</ContactTitle>
</Customer>
</Customers>
Teraz zapisz plik jako customers.xml.
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 XE "applet" XE "Java" . 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 |
|
Wydruk 27.14. Dołączanie danych XML w IE 4 i IE 5
<html>
<head>
<title>Dołączanie danych XML z pliku na dysku</title>
<meta name="GENERATOR" content="Microsoft FrontPage 3.0">
</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.
Programowe tworzenie pliku XML
Ponieważ XML jest tak łatwy do tworzenia i używania w aplikacji, utwórzmy własną bibliotekę DLL ActiveX, która utworzy kod XML. Za pomocą tej biblioteki można tworzyć na bieżąco pliki XML używane w witrynach WWW lub aplikacjach.
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 XE "CreateXML:metoda" . 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.
Wydruk 27.15. Programowe tworzenie XML jako komponent VB
Public Function CreateXML _
(strEntity As String, strSOLStatement As String, _
strConnectionString As String) As String
' Funkcja tworzy XML z wyniku wykonania kwerendy.
' Używa Recordset ADO i zwraca wynik do aplikacji
Dim rst As ADODB.Recordset
Dim fld As ADODB.Field
Dim strReturn As String
On Error GoTo Proc_Err
Set rst = New ADODB.Recordset
' Otwarcie obiektu recordset opartego o wyrażenie SQL
' które jest przekazane do metody wraz z ciągiem połączeniowym
rst.Open strSQLStatement, StrConnectionString
' Rozpoczynamy tworząc nagłówek z numerem wersji
strReturn = "<?XML version= '1.0'?>"
If rst.EOF And rst.BOF Then
'Jeżeli nie ma danych tworzymy pusty element
strReturn = strReturn & vbNewLine & "<" & strEntity & "s/>"
Else
' Znacznik otwierający element
strReturn = strReturn & vbNewLine & "<" & strEntity & "s>"
'Pętla przebiegająca przez wynik zapytania i umieszczająca go w
' w pliku XML
Do Until rst.EOF
' Otwórz element
strReturn = strReturn & vbNewLine & "<" & strEntity & ">"
' Każde pole jest zapisywane do pliku
' Jeżeli chcesz mniej pól, wylicz je w wyrażeniu SQL
For Each fld In rst.Fields
strReturn = strReturn & vbNewLine & "<" & fld.Name & ">"
strReturn = strReturn & fld.Value
strReturn = strReturn & "</" & fld.Name & ">"
Next fld
' Zamknij element
strReturn = strReturn & vbNewLine & "</" & strEntity & ">"
' Przejście do następnego elementu
rst.MoveNext
Loop
' Znacznik kończący element
strReturn = strReturn & vbNewLine & "</" & strEntity & "s>"
End If
' Przepisz utworzony tekst do wyniku metody
CreateXML = strReturn
' 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 XE "DSN" bazy danych na serwerze SQL.
Wydruk 27.16. Wywołanie komponentu utworzonego na wydruku 27.15
Private Sub cmdPrintXML Click()
Dim xml As XML_Tool.Database
Set xml = New XML Tool.Database
Debug.Print xml.CreateXML("Publishers", "Select * From Publishers",
"Pubs")
End Sub
Wynik działania programu jest następujący:
<?XML version= '1.0'?>
<Publishers>
<Publisher>
<pub_id>0736</pub id>
<pub_name>New Moon Books</pub name>
<city>Boston</city>
<state>MA</state>
<country>USA</country>
</Publisher>
<Publisher>
<pub_id>0877</pub_id>
<pub_name>Binnet & Hardley</pub_name>
<city>Washington</city>
<state>DC</state>
<country>USA</country>
</Publisher>
</Publishers>
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 wykorzystywany w aplikacji WWW. Poniższy kod tworzy taką samą jak poprzednio stronę WWW, jednak teraz jest dynamiczna i tworzy XML na bieżąco.
Wydruk 27.17. Tworzenie XML w skrypcie ASP
<%
Dim xml
Dim strSOL
Dim strConnect
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>
Tworzenie wykresów przy użyciu formantu Wykres
Rozdział 25. zawiera wprowadzenie do komponentów sieciowych Office i wyjaśnia, jak używać ich w Accessie 2000 oraz Visual Basicu. W rozdziale 26. objaśniliśmy sposób ich użycia na stronach dostępu do danych. Co zrobić, jeżeli przeglądarka, której używasz, nie obsługuje formantów ActiveX? Formant Wykres XE "Wykres:formant sieciowy" pozwala na użycie rysunków GIF XE "GIF" dla przeglądarek nie obsługujących ActiveX.
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).
Wydruk 27.18. Tworzenie wykresu w pliku GIF na serwerze
<SCRIPT LANGUAGE="VBScript" RUNAT="Server">
Sub Session_OnStart
Session("nFiles") = 0
Set Session("FileSystem") = Create0bject("Scripting.FileSystemObject")
End Sub
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.
Wydruk 27.19. Praca z komponentem sieciowym Wykres z pakietu Office
<%@ language="vbscript" %>
<html>
<body>
<%
Dim ChartSpace1, c, aHeaders(3), aValues(3)
Dim rst
' Tworzenie tablicy nagłówków wykresu
aHeaders(0) = "01"
aHeaders(1) = "02"
aHeaders(2) = "03"
aHeaders(3) = "04"
' Otwarcie wyniku kwerendy krzyżowej z bazy Notrhwind
' i wpisanie jej wartości do słupków wykresu
Set rst=Server.Create0bject("ADODB.Recordset")
rst.Open "qry0uarterlySales", "File Name=" & Server.MapPath("Jet.UDL")
aValues(0) = rst![Otr 1]
aValues(1) = rst!(Otr 2]
aValues(2) = rst![Otr 3]
aValues(3) = rst![Otr 4]
' - Tworzenie niewidocznej wersji komponentu wykres
Set ChartSpace1 = Create0bject("OWC.Chart")
Set c = ChartSpacel.Constants
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 _
c.chDimCategories, c.chDataLiteral, aHeaders
ChartSpacel.Charts(0).SeriesCollection(0).SetData _
c.chDimValues, c.chDataLiteral, aValues
ChartSpacel,Charts(0).HasLegend = True
'—- Pobranie nazwy tymczasowego pliku z global.asa
szFilename = Session("FileSystem").GetTempName & ".gif"
'—- Eksport pliku GIF z wykresu
ChartSpacel.ExportPicture "D:\ntstuff\WebStuff\" & _
szFilename, "gif", 600, 512
'—- Tworzenie łącza do pliku GIF
Response.Write "<img src= "' & szFilename
Session("szFile" & Session("nFiles")) = szFilename
Session("nFiles") = Session("nFiles") + 1
%>
</body>
</html>
PAGE 18
Spis treści
PAGE 19
PAGE 24
Część I ♦ Projektowanie bazy danych
PAGE 23
Rozdział 1. ♦ Co nowego w Accessie 2000
PAGE 44
Część I ♦ Projektowanie bazy danych
PAGE 43
Rozdział 2. ♦ Planowanie procesu rozwoju
PAGE 52
Część I ♦ Projektowanie bazy danych
PAGE 53
Rozdział 3. ♦ Projekt bazy danych i normalizacja
PAGE 76
Część I ♦ Projektowanie bazy danych
PAGE 75
Rozdział 4. ♦ Zaawansowane kwerendy
PAGE 86
Część I ♦ Projektowanie bazy danych
PAGE 87
Rozdział 5. ♦ Jet 4.0 - silnik baz danych Microsoft
PAGE 88
Część I ♦ Projektowanie bazy danych
PAGE 87
Rozdział 5. ♦ Jet 4.0 - silnik baz danych Microsoft
PAGE 102
Część II ♦ Dostęp do danych
PAGE 103
Rozdział 6. ♦ Wprowadzenie do obiektów danych Active X
PAGE 122
Część II ♦ Dostęp do danych
PAGE 123
Rozdział 7. ♦ Zaawansowane ADO
PAGE 124
Część II ♦ Dostęp do danych
PAGE 123
Rozdział 7. ♦ Zaawansowane ADO
PAGE 136
Część III ♦ Interfejs użytkownika
PAGE 135
Rozdział 8. ♦ Projektowanie formularza
PAGE 158
Część III ♦ Interfejs użytkownika
PAGE 159
Rozdział 9. ♦ Rozbudowa formularzy przy użyciu formantów ActiveX
PAGE 186
Część III ♦ Interfejs użytkownika
PAGE 185
Rozdział 10. ♦ Tworzenie raportów
PAGE 186
Część III ♦ Interfejs użytkownika
PAGE 187
Rozdział 10. ♦ Tworzenie raportów
PAGE 206
Część IV ♦ Tajniki VBA
PAGE 207
Rozdział 11. ♦ Tworzenie obiektów przy użyciu modułów klas
PAGE 220
Część IV ♦ Tajniki VBA
PAGE 219
Rozdział 12. ♦ Usuwanie błędów w aplikacjach Accessa
PAGE 238
Część IV ♦ Tajniki VBA
PAGE 239
Rozdział 13. ♦ Profesjonalna obsługa błędów
PAGE 264
Część IV ♦ Tajniki VBA
PAGE 265
Rozdział 14. ♦ Optymalizacja aplikacji
PAGE 266
Część IV ♦ Tajniki VBA
PAGE 265
Rozdział 14. ♦ Optymalizacja aplikacji
PAGE 280
Część V ♦ Access i architektura klient-serwer
PAGE 279
Rozdział 15. ♦ Wprowadzenie do projektów programu Microsoft Access
PAGE 294
Część V ♦ Access i architektura klient-serwer
PAGE 295
Rozdział 16. ♦ Tworzenie interfejsu użytkownika dla Microsoft SQL Server
PAGE 320
Część V ♦ Access i architektura klient-serwer
PAGE 319
Rozdział 17. ♦ Interfejs Access'a 2000 do Oracle'a
PAGE 280
Część V ♦ Access i architektura klient-serwer
PAGE 281
Rozdział 15. ♦ Wprowadzenie do projektów programu Microsoft Access
PAGE 334
Część VI ♦ Współoperatywność
PAGE 333
Rozdział 18. ♦ Użycie automatyzacji Active X
PAGE 362
Część VI ♦ Współoperatywność
PAGE 363
Rozdział 19. ♦ Integracja z Office 2000
PAGE 392
Część VI ♦ Współoperatywność
PAGE 391
Rozdział 20. ♦ Użycie Visual Basic z Access'em
PAGE 334
Część VI ♦ Współoperatywność
PAGE 335
Rozdział 18. ♦ Użycie automatyzacji Active X
PAGE 402
Część VII ♦ Zagadnienia wielodostępu
PAGE 403
Rozdział 21. ♦ Zagadnienia wielodostępu, serwer plików, blokowanie
PAGE 422
Część VII ♦ Zagadnienia wielodostępu
PAGE 423
Rozdział 22. ♦ Replikacja i JRO
PAGE 440
Część VII ♦ Zagadnienia wielodostępu
PAGE 441
Rozdział 23. ♦ Bezpieczeństwo
PAGE 406
Część VII ♦ Zagadnienia wielodostępu
PAGE 405
Rozdział 21. ♦ Zagadnienia wielodostępu, serwer plików, blokowanie
PAGE 458
Część VIII ♦ Publikowanie w sieci za pomocą Access'a 2000
PAGE 459
Rozdział 24. ♦ Konfiguracja serwera WWW dla publikowania w sieci WWW
PAGE 466
Część VIII ♦ Publikowanie w sieci za pomocą Access'a 2000
PAGE 465
Rozdział 25. ♦ Przenoszenie Access'a 2000 do sieci WWW
PAGE 476
Część VIII ♦ Publikowanie w sieci za pomocą Access'a 2000
PAGE 475
Rozdział 26. ♦ Użycie stron dostępu do danych
PAGE 498
Część VIII ♦ Publikowanie w sieci za pomocą Access'a 2000
PAGE 489
Rozdział 27. ♦ Publikowanie w sieci przy użyciu Access'a 2000 i Active Server
PAGE 504 Część VIII ♦ Publikowanie w sieci za pomocą Accessa 2000
Rozdział 27. ♦ Publikowanie w sieci przy użyciu Accessa 2000 i Active Server Pages PAGE 503
PAGE 504 FILENAME \p D:\ksiazki\Access 2000 - Księga eksperta\Access 2000 - Księga eksperta.doc
PAGE \# "'Strona: '#'
'" Co to jest? Poprawiłem (PG)