Procedury - służą do programowania aplikacji bazodanowych w MS Access (programowanie zdarzeniowe):
Są wiązane na ogół z pewnymi zdarzeniami interfejsu użytkownika jak:
naciśnięcie przycisku na formularzu,
zmiana wartości w polu tekstowym formularza,
otwarcie lub zamknięcie formularza,
drukowanie raportu,
początkowe otwarcie bazy danych, itd.
Zobacz "Events and Event Properties Reference" w MS Access Help.
Każda powtarzająca się rutynowa czynność, w szczególności każda, którą można wykonać za pomocą opcji znajdujących się we wbudowanych menu, nadaje się do zautomatyzowania za pomocą procedury.
Na przykład, na formularzu można umieścić zbiór przycisków, po których naciśnięciu użytkownik uzyskuje:
wyświetlenie tekstu pomocy;
wyświetlenie innego formularza;
zamknięcie danego formularza;
wydrukowanie zawartości formularza;
wyświetlenie następnego (poprzedniego) rekordu, przejście do pierwszego, ostatniego lub nowego rekordu;
wykonanie obliczeń i wyświetlenie wyniku w polu niezwiązanym;
wykonanie kopii zabezpieczającej bazy danych na dyskietkę;
przeniesienie danych do Worda, Excela lub innej bazy danych.
Visual Basic for Applications (w skrócie VBA) jest językiem programowania dla aplikacji systemu Microsoft Office będący podzbiorem języka Visual Basic.
Służy do powiązania obiektów bazy danych w jedną spójną aplikację.
Zawiera standardowe konstrukcje programistyczne jak If ... Then ... Else, For, Case, procedury, zmienne.
Są dwa typy procedur:
funkcje (Function) - zwracające wartość; mogą być używane w wyrażeniach jak również jako wartości właściwości zdarzeń;
podprogramy (Sub) - nie zwracające bezpośrednio wartości; mogą występować jako procedury zdarzeń w formularzach i raportach.
Moduł jest zbiorem deklaracji i definicji procedur języka Visual Basic for Applications przechowywanych razem jako jedna całość.
Moduł może zawierać zarówno procedury zdarzeń jak i zwykłe nazwane procedury.
Dwa rodzaje modułów:
moduły klas w tym:
moduły klas stanowiące część formularza lub raportu,
moduły klas definiujące niezależne obiekty.
moduły standardowe - nie związane z żadnym obiektem.
Procedury
typu Public
mogą być
wywoływane w dowolnym miejscu aplikacji (opcja domyślna).
Procedury typu Private
są
prywatne dla danego modułu (w tym modułu formularza i raportu) - nie można
ich używać
spoza modułu - wszystkie procedury zdarzeń są prywatne.
deklarowane
lokalnie w procedurze (przy pomocy Dim
),
deklarowane
jako Private
w module - ograniczony dostęp do tego modułu (opcja domyślna),
deklarowane jako Public
w module - dostęp
w całej aplikacji.
Typy danych dla zmiennych
Access | Visual Basic | Default |
Text | String | "" |
Number | Integer, Long, Double, Single | 0 |
Currency | Currency | 0 |
Yes/No | Boolean | False |
Date/Time | Date | 30.12.1899 |
Specjalny typ danych Visual Basic - Variant - oznacza dowolny typ wartości.
Przykład 1
Obliczanie pierwiastka kwadratowego.
Function SquareRoot (X As Double) As Double
Dim Msg As String
Select Case Sgn(X) ' Oblicz znak argumentu.
Case 1 ' OK jeśli dodatni.
SquareRoot = Sqr(X)
Exit Function
Case 0 ' Powiadom użytkownika jeśli 0.
Msg = "Przekazana wartość to 0."
Case -1 ' Powiadom użytkownika jeśli <0.
Msg = "Niedozwolona liczba."
End Select
MsgBox Msg ' Wyświetl komunikat Msg
End Function
W przypadku wywołania funkcji, gdy nie nastąpi przypisanie wartości do nazwy funkcji SquareRoot, system przypisze wartość 0.
Przykład 2
Deklaracje i definicje modułu. Opcje:
Option Compare Database
- użycie metody z bazy danych w porównaniachOption Explicit
- wymagane jest deklarowanie zmiennychsą zwykle domyślnie przyjmowane przez system.
Option Compare Database
Option Explicit
Private licznik As Integer 'Zmienna lokalna
Public pokaż As Integer 'Zmienna globalna
Sub Zeruj() 'Procedura globalna
licznik = 0
pokaż = licznik
End Sub
Sub Dodaj() 'Procedura globalna
licznik = licznik + 1
pokaż = licznik
MsgBox licznik, , "LICZNIK"
End Sub
Edytor kodu Visual Basic (Visual Basic Editor) – zawierający środowisko uruchamiania i debuggowania kodu VBA.
Okno analizy programu (Immediate Window) – CTRL-G, View -> Immediate Window - jest możliwość wykonywania kodu (instrukcji, metod, funkcji i procedur) oraz sprawdzania wartości wyrażeń, pól i właściwości – pisząc w pojedynczym wierszu np.
? licznik
gdzie licznik
jest zmienną, której wartość
chcemy wypisać.
Jest możliwość przerwania działania funkcji lub procedury przez ustawienie w kodzie punktu przerwania (breakpoint) – "Debug -> Toggle Breakpoint" (F9).
Można też wyświetlić (z menu View):
nawigator po klasach bieżącego projektu (Project Explorer) oraz
nawigator po klasach zarejestrowanych bibliotek jak Access, VBA (Object Browser).
Na ogół jednej klasie odpowiada dokładnie jeden obiekt tej klasy (obiekt klasy – class object).
Przykład 3
Sprawdzanie, czy dany formularz jest otwarty w widoku Formularz - rozwiązanie używające standardowej funkcji SysCmd.
Function Otwarty(ByVal Mój As String) As Integer
' SysCmd - czy formularz jest otwarty
If SysCmd(acSysCmdGetObjectState,acForm,Mój) <> 0 Then
' CurrentView - czy jest otwarty w widoku Formularz
If Forms(Mój).CurrentView <> 0 Then Otwarty = True
End If
End Function
Formularze są obiektami. Do formularza o nazwie "Pracownicy" można się odwołać w następujący sposób:
Forms![Pracownicy]
Forms("Pracownicy")
Forms(numer)
gdzie numer jest numerem przyporządkowanym danemu formularzowi w
sesji.
Używając dostępu kropkowego możemy odwoływać się do właściwości formularza a także do jego metod jako obiektu. Np:
Forms![Pracownicy].Caption
zwraca tytuł
formularza,
Forms![Pracownicy].SetFocus
jest metodą,
której wykonanie przenosi fokus do tego formularza.
Wykrzyknik ! oznacza wybór elementu z
kolekcji: Forms![Pracownicy]
- wybór formularza z kolekcji
wszystkich formularzy;
Forms![Pracownicy]![Nazwisko]-
wybór
pola Nazwisko
z kolekcji wszystkich obiektów związanych z formularzem
Pracownicy.
Reasumując:
wykrzyknik oznacza wybór elementu z kolekcji elementów,
kropka - wybór właściwości obiektu lub kolekcji.
Zapis Forms![Pracownicy]![Nazwisko]
oznacza
także domyśnie wartość pola tekstowego “Nazwisko” czyli konkretne nazwisko –
alternatywnie można używać
Forms![Pracownicy]![Nazwisko].Value
.
Przy wpisywaniu do pola tekstowego lub listowego bieżącą wartość – jeszcze nie zapisaną do bazy danych – uzyskuje się przy użyciu:
Forms![Pracownicy]![Nazwisko].Text
Przy odczytywaniu wartości Text fokus musi znajdować się na danym polu:
[Nazwisko].SetFocus
MsgBox "Nazwisko = "&[Nazwisko].Text
Sprawdzenie czy formularz jest otwarty można zrealizować jeszcze w inny sposób – przeglądając kolekcję wszystkich otwartych formularzy i sprawdzając ich nazwy.
Function Otwarty1 (ByVal Mój As String) As Integer
' Zwraca True, jeśli podany formularz jest otwarty w widoku formularz.
Dim I As Integer
' Forms.Count to liczba obiektów w kolekcji Forms
For I = 0 To Forms.Count - 1
If Forms(I).Name = Mój Then
Otwarty1 = True
Exit For
End If
Next I
End Function
Jest możliwość używania kilku kopii
jednego formularza (tj. kilku instancji jednej klasy).
Używając
DoCmd.OpenForm "Osoby"
tworzymy pierwszą kopię (instancję). Kolejną kopię tworzymy w następujący sposób:
Dim Kopia As New Form_Osoby
' Aby je odróżnić, zmieniamy tytuł kopii formularza “Osoby”
Kopia.Caption = "Kopia: Osoby"
Przykład 4
Kolejna procedura specyfikuje reakcję na zdarzenie naciśnięcia lewego przycisku myszy (obiekt: przycisk “Witaj”, zdarzenie: “Przy kliknięciu”).
Private Sub Witaj_Click()
[Pole] = "Witaj w klubie VBA"
End Sub
Przykład 5
Zwróćmy uwagę na procedurę, jaką tworzy kreator przycisków w celu zrealizowania zadania otwarcia formularza o nazwie “Osoby”:
Private Sub Przycisk_Click()
On Error GoTo Err_Przycisk_Click
Dim stDocName As String
Dim stLinkCriteria As String
stDocName = "Osoby"
DoCmd.OpenForm stDocName, , , stLinkCriteria
Exit_Przycisk_Click:
Exit Sub
Err_Przycisk_Click:
MsgBox Err.Description
Resume Exit_Przycisk_Click
End Sub
Instrukcja
DoCmd.OpenForm "Osoby"
zawierająca wywołanie metody OpenForm
wbudowanego obiektu o nazwie DoCmd
, powoduje otwarcie formularza “Osoby”.
W procedurze tej występuje obsługa błędów. Kreator przycisków tworząc procedurę zdarzenia “Przy kliknięciu” standardowo realizuje następującą strategię:
W przypadku wystąpienia błędu -
to jest
niemożliwości otwarcia formularza "Osoby" - przerwij obliczenia
i przejdź do sekcji obsługi błędów przy etykiecie Err_Przycisk_Click
Wypisz informację o błędzie korzystając
z metody Description specjalnego obiektu Err
.
Zakończ wykonywanie procedury.
W powyższej procedurze można byłoby
standardowy tekst błędu Err.Description
zastąpić własnym tekstem
skierowanym do użytkownika aplikacji:
MsgBox "Błąd aplikacji. Skontaktuj
się z administratorem aplikacji"
Przykład 6
Otwarcie formularza może być bardziej skomplikowane, aby mogło wystarczyć użycie samego kreatora przycisków np. procedura otwierająca formularz "Uczestnictwo w projektach" w oparciu o wartość znajdującą się w polu [Numer] będącym częścią podformularza przy czym sam przycisk "Projekty" znajduje się w głównym formularzu “Departament”.
Procedura otwiera formularz "Uczestnictwo w projektach" w celu pokazania uczestnictwa w projektach wybranej aktualnie osoby (w podformularzu):
Private Sub Projekty_Click()
On Error GoTo Err_Projekty_Click
Dim stDocName As String
Dim stLinkCriteria As String
stDocName = "Uczestnictwo w projektach"
stLinkCriteria = "Numer=Forms![Departament]![Osoba
Subform].Form![Numer]"
DoCmd.OpenForm stDocName, , , stLinkCriteria
Forms![Departament].SetFocus
Forms![Departament]![Osoba Subform].SetFocus
Exit_Projekty_Click:
Exit Sub
Err_Projekty_Click:
MsgBox Err.Description
Resume Exit_Projekty_Click
End Sub
Przykład 7 Synchronizacja dwóch formularzy
Formularz wyskakujący "Uczestnictwo w projektach" powinien pokazywać dane o aktualnie rozpatrywanym pracowniku z podformularza w formularzu “Departament”. Uaktualnienie wartości następuje przy pojawieniu się nowego rekordu w podformularzu czyli jako reakcja na zdarzenie “Przy bieżącym”. Przy czym to uaktualnienie ma sens, tylko wtedy gdy użytkownik wcześniej otworzył formularz wyskakujący “Uczestnictwo w projektach” naciskając przycisk “Projekty”. Z kolei naciśnięcie przycisku “Projekty” ma sens tylko wtedy, gdy pole [Numer] w podformularzu jest niepuste.
W poniższej procedurze występują dwie nowe właściwości, których wartościami są obiekty:
Me – formularz lub raport, którego procedura jest wykonywana;
Parent – formularz lub raport nadrzędny względem danego formularza lub raportu.
Private Sub Form_Current()
On Error GoTo Err_Form_Current
If IsNull(Me![Numer]) Then
Me.Parent![Projekty].Enabled = False
Else
Me.Parent![Projekty].Enabled = True
End If
Dim Projekt As String
Projekt = "[Numer]=Forms![Departament]![Osoba Subform].Form![Numer]"
If Otwarty("Uczestnictwo w projektach") Then
DoCmd.OpenForm "Uczestnictwo w projektach", , , Projekt
Forms![Departament].SetFocus
Forms![Departament]![Osoba Subform].SetFocus
End If
Exit_Form_Current:
Exit Sub
Err_Form_Current:
MsgBox Err.Description
Resume Exit_Form_Current
End Sub
Uaktualnienie formularza wyskakującego jest konieczne nie tylko, gdy fokus w podformularzu przejdzie do nowego rekordu, ale również gdy w bieżącym rekordzie zmieni się wartość [Numer]. Realizuje to procedura zdarzenia “Po aktualizacji” dla pola [Numer] - jej kod jest analogiczny do procedury zdarzenia "Przy bieżącym".
Zdarzenia dla obiektów interfejsu użytkownika (formularzy, raportów, elementów dialogowych)
"Przy otwarciu" - "Open" (formularza, raportu) - Po otwarciu formularza (raportu) ale przed wyświetleniem pierwszego rekordu (przed zdarzeniem "Load"). Można:
zamknąć inne okno,
ustawić fokus na konkretnym elemencie,
spytać użytkownika jakie rekordy mają się pojawić na formularzu,
spytać użytkownika o wymagane hasło i odwołać otwieranie formularza, gdy użytkownik nie potrafi podać poprawnego hasła.
Private Sub Form_Open(Cancel As Integer)
Dim strPass as String
strPassword = InputBox("Please enter the password: ")
If strPass<>"IloveVB" Then
MsgBox "Incorrect password"
Cancel = True
End If
End Sub
"Przy załadowaniu" - "Load" (formularza) - Po otwarciu formularza i wyświetleniu jego rekordów:
określa się domyślne ustawienia dla elementów formularza,
wyświetla się okienka informacyjne oraz pola wyliczane w oparciu o inne dane na formularzu.
Private Sub Form_Load()
Dim StrName As String
MsgBox "Formularz wita!"
End Sub
"Przy bieżącym" - "Current" (formularza) - Przy pojawieniu się pierwszego i każdego kolejnego rekordu (przy nawigacji po rekordach), również przy usuwaniu rekordu i po odświeżeniu formularza. Można:
wyświetlać komunikat przy przejściu do nowego rekordu,
wyświetlać powiązane informacje,
zmieniać właściwości elementów (np. chowając lub odkrywając pewne elementy, lub zmieniając wyświetlony tytuł Caption na formularzu).
Private Sub Form_Current()
Forms!Pracownik.Caption = Me![Nazwisko]
End Sub
"Przy usunięciu" - "Delete" (formularza) - zanim rekord zostanie usunięty.
Można uzyskać potwierdzenie, że na prawdę chodzi użytkownikowi o usunięcie bieżącego rekordu.
Private Sub Form_Delete(Cancel As Integer)
If MsgBox("Czy na pewno usunąć?", vbYesNo) = vbNo Then Cancel = True
End Sub
"Przy zwolnieniu" - "Unload" (formularza) - Można:
uzyskać potwierdzenie, że na prawdę chodzi użytkownikowi o zamknięcie formularza,
wykonać dodatkowe akcje jak zapisanie informacji do dziennika (logu).
"Przy zamknięciu" - "Close" (formularza, raportu) - Po zamknięciu formularza (raportu) i usunięciu go z ekranu.
Można
użyć metody OpenForm aby otworzyć kolejny formularz.
"Po wstawieniu" - "After Insert" (formularza) - Po dodaniu nowego rekordu do bazy danych.
Jest możliwość odświeżenia
danych.
"Przed aktualizacją" - "BeforeUpdate" (formularza, elementu dialogowego)
Jest możliwość sprawdzenia poprawności i cofnięcia
aktualizacji.
"Po aktualizacji" - "AfterUpdate" (formularza, elementu dialogowego) - Po aktualizacji zmienionych danych w rekordzie lub elemencie dialogowym. Można:
zastosować filtr,
odświeżyć dane.
"Przy kliknięciu" - "Click" (formularza, elementu dialogowego) - Przy naciśnięciu i zwolnieniu lewego przycisku myszy. Np. naciśnięcie przycisku.
Private Sub cmdClickMe_Click()
MsgBox "You clicked me."
End Sub
Private Sub Nazwisko_GotFocus()
[lblNazwisko].Caption = "Rozpatrywany w tej chwili
klient"
End Sub
"Wyjście" – "Exit", "Utrata Fokusu" - "LostFocus" - gdy element traci fokus. Używa się do:
weryfikacji wprowadzonych danych,
zmiany ustawień dla opuszczanego pola.
Private Sub txtPass_Exit(Cancel As Integer)
If Len(txtPass) < 8 Then
MsgBox "Enter 8 or more characters."
Cancel = True
End If
End Sub
- bez wstrzymywania wyjścia:
Private Sub txtPass_LostFocus()
If Len(txtPass) < 8 Then
MsgBox "Enter 8 or more characters."
End If
End Sub
Funkcja DLookUp
Funkcja DLookUp umożliwia sprowadzenie z bazy danych pojedynczej wartości. Np.
jeśli w formularzu "Osoba" opartym na tabeli Osoba jest potrzebna Nazwa departamentu zapisanego w tabeli Departament, to można dodać pole wyliczane:
=DLookUp("[Nazwa]";"Departament";"[Id]=Forms![Osoba]![Id]")
Ten sam efekt można byłoby uzyskać opierając formularz na kwerendzie złączającej zamiast na tabeli.
Za pomocą funkcji DLookUp można do pola formularza wprowadzać wartości obliczane przez kwerendę wybierającą - wystarczy najpierw zdefiniować taką kwerendę np. Zap_max jako
SELECT IIf(IsNull(Max([Numer])),1,Max([Numer])+1) AS Maks
FROM Osoba;
a następnie użyć kwerendy jako źródła dla pola na formularzu:
=DLookUp("[Maks]";
"Zap_max")
Metodę tę można zastosować więc do generowania jednoznacznych numerów dla kluczy.