Przegląd ważniejszych poleceń języka VBA (z punktu widzenia procedur zdarzeń)
DoCmd - reprezentuje polecenie,
Application - reprezentuje aplikacje MS Access,
Debug - reprezentuje środowisko uruchamiania kodu,
Err - reprezentuje błąd,
jak i samych obiektów interfejsu użytkownika:
1. Chodzenie po rekordach formularza, wyświetlenie pustego rekordu do wprowadzenia:
DoCmd.GoToRecord , , acFirst
(w miejsce acFirst można użyć: acPrevious, acNext, acLast, acNewRec)
2. Otwieranie formularza, raportu:
DoCmd.OpenForm "Wprowadz_wyswietl
firmy", , , , acAdd
(w miejsce acAdd można użyć: acEdit, acReadOnly)
3. Zamykanie obiektów
zamknięcie obiektu aktywnego
- DoCmd.Close
zamknięcie konkretnego obiektu -
DoCmd.Close acForm, "Firmy"
4. Drukowanie bieżącego formularza
DoCmd.PrintOut
5. Wykonanie kwerendy
DoCmd.OpenQuery <nazwa-kwerendy>, acNormal, acEdit
lub
DoCmd.RunSQL <instrukcja-SQL>
6. Ponowienie kwerendy (aktualizacja) dla pola listowego lub formularza.
Dla pola listowego:
DoCmd.Requery
"Id firmy"
– tylko dla pola w aktualnym formularza lub
Me![Id
firmy].Requery
i wówczas można używać także dla innych formularzy.
Dla formularza:
DoCmd.Requery
lub
Me.Requery
7. Zakończenie aplikacji:
DoCmd.Quit
lub
Application.Quit
8. Aktualizacja formularza po zmianie pola tekstowego:
DoCmd.ApplyFilter
, "[Data ukazania]>=Forms![Wyszukaj według wymagań]![Data od]"
9. Wyświetlenie wszystkich rekordów:
DoCmd.ShowAllRecords
Operacje 8 i 9 można wykonać korzystając ze sposobu reprezentowania filtrów przez Access. Mianowicie, filtrowanie rekordów odbywa się za pomocą dwóch właściwości formularza:
Filter - napis określający warunek WHERE;
FilterOn - wartość logiczna określająca, czy filtr jest włączony.
A więc istniejący filtr można włączyć za pomocą instrukcji
Me.FilterOn = True
a wyłączyć za pomocą:
Me.FilterOn = False
(równoważne operacji 9)
Wartość właściwości Filter zostaje
zachowana po zamknięciu formularza. Przy powtórnym
otwarciu jest ona dostępna, przy czym na początku filtr jest wyłączony
Me.FilterOn = False
, a więc aby zastosować istniejący filtr trzeba wykonać:
Me.FilterOn = True
Specjalną podgrupę stanowią polecenia realizujące wykonanie akcji z wbudowanych menu - z zastosowaniem metody RunCommand obiektu DoCmd (obiekt DoCmD można pominąć).
[DoCmd.]RunCommand polecenie
gdzie polecenie jest stałą reprezentującą odpowiednie polecenie z wbudowanych menu - lista w pomocy Help MsAccess pod tematem "RunCommand Method Constants" np.
DoCmd.RunCommand acCmdOptions
otwiera okienko dialogowe "Options" z menu "Tools".
Polecenie Print jest metodą specjalnego obiektu Debug - wypisuje wartości kontrolne w okienku analizy programu (Immediate Window). Np.
Debug.Print
"Przechodzę
do obliczania współczynnika zysku"
Instrukcja MsgBox i obsługa błędów
Tak jak instrukcja Debug.Print
służy do
wypisywania informacji (z myślą o osobie tworzącej aplikację) przy
wykrywaniu błędów w aplikacji, tak instrukcje MsgBox i InputBox służą do
bezpośredniego kontaktu z użytkownikiem w trakcie wykonywania aplikacji
poprzez wyświetlanie odpowiednich informacji w okienkach dialogowych oraz
poprzez przyjmowanie danych od użytkownika.
Na przykład, wykonanie instrukcji
MsgBox "Formularz zostaje zamknięty!",,"UWAGA"
powoduje wyświetlenie następującego okienka dialogowego:
A wykonanie instrukcji
x = MsgBox("Czy zapisać na dysku?",vbYesNo ,
"UWAGA")
powoduje wyświetlenie następującego okienka dialogowego:
Bezpośredni kontakt z użytkownikiem jest potrzebny na przykład, gdy trzeba poinformować użytkownika o wystąpieniu błędu. Załóżmy, że naciśnięcie przycisku powoduje przejście do poprzedniego rekordu. Gdy użytkownik naciśnie przycisk w sytuacji, gdy aktualnie w formularzu jest wyświetlany pierwszy rekord, instrukcja
DoCmd.GoToRecord , , acPrevious
nie może być wykonana i powstaje błąd. Ten błąd zostaje obsłużony w poniższej procedurze, poprzez skok do etykiety Error_handler znajdującej się w instrukcji On Error GoTo. Następuje wypisanie numeru błędu i tekstu opisu błędu, po czym instrukcja
Resume Next
kieruje sterowanie do następnej instrukcji po powodującej błąd.
Sub Polecenie61_Click ()
"Znajdujesz się już przy pierwszym
zamówieniu"
On Error GoTo Error_handler
DoCmd.GoToRecord , , acPrevious
Exit Sub
Error_Handler:
MsgBox
Resume Next
End Sub
Err.Description - standardowy tekst błędu.
Do obsługi błędów używamy instrukcji On Error. Specyfikuje ona co zrobić, gdy w trakcie wykonywania następnych instrukcji wystąpi błąd:
On Error GoTo etykieta -
przejdź
do obsługi błędu w instrukcji oznaczonej przez etykieta,
On Error Resume -
powtórz
instrukcję powodującą błąd,
On Error Resume Next -
przejdź
do następnej instrukcji
po powodującej błąd,
On Error Resume etykieta -
wznów obliczenia od etykieta
,
On Error Stop -
zatrzymaj
obliczenia.
Podobne znaczenie mają opcje służące do zakończenia obsługi błędów:
GoTo etykieta | Resume [ | Next | etykieta]|Stop
Poza tym są jeszcze dodatkowe konstrukcje związane z obsługą błędów:
Err.Raise numer_błędu
- spowodowanie
powstania błędu o podanym numerze i wymuszenie (w sposób sztuczny) jego obsługi;
Error(i)
- komunikat o błędzie dla błędu
o numerze i.
Wykonanie instrukcji
On Error GoTo 0
wyłącza obsługę błędów.
MsgBox może być również użyte jako funkcja za pomocą, której użytkownik przekazuje do aplikacji swój wybór np. wartość “Tak” lub “Nie”.
x = "Czy chcesz wprowadzić nowe wymagania do oferty?"
If MsgBox(x, vbYesNo) = vbYes Then
'Gdy wybór użytkownika jest "Tak"
W przypadku, gdy nie można wykonać pewnej akcji np. zapisu do bazy danych, używając MsgBox jako polecenia, informujemy o tym użytkownika, wymuszając na nim przyjęcie tej wiadomości przez naciśnięcie przycisku OK w odpowiednim okienku dialogowym. Rodzaj odpowiedniego okienka uzyskujemy dobierając argumenty operacji MsgBox.
W przypadku niemożliwości wykonania operacji np. zapisu do bazy danych, jest konieczne odwołanie odpowiedniego zdarzenia - w poniższym przykładzie zdarzenia “Przed aktualizacją”.
Procedura wyświetla komunikat, jeśli pole kombi IDklienta jest puste a następnie odwołuje zdarzenie “Przed aktualizacją” zapobiegając aktualizacji:
Private Sub IDklienta_BeforeUpdate(Cancel As Integer)
Dim strMsg As String, strTitle As String
Dim intStyle As Integer
If IsNull([Idklienta]) Or [Idklienta] = "" Then
strMsg="Musisz wybrać wartość z listy Faktura dla."
strTitle = "Wymagany klient faktury"
intStyle = vbOKOnly + vbExclamation
MsgBox strMsg, intStyle, strTitle
Cancel = True
End If
End Sub
Funkcja InputBox służy do wyświetlenia okienka dialogowego, do którego użytkownik wprowadza dane np.
Firma = InputBox("Podaj nazwę firmy, której ogłoszenia chcesz
obejrzeć?")
Funkcja/polecenie MsgBox ma następujący format:
MsgBox Tekst, Wygląd_okienka, Tytuł_okienka
Tekst i Tytuł_okienka to odpowiednie
teksty, które mają się ukazać w okienku dialogowym, natomiast Wygląd_okienka
to wyrażenie liczbowe określające liczbę i typ wyświetlanych przycisków i
ich rodzaj, styl używanych ikon, identyfikator domyślnego przycisku oraz
modalność okna komunikatu. Brak tego parametru spowoduje przyjęcie wartości
domyślnej vbOKOnly=0
.
Aktualizacja listy pola kombi (opcja “Ogranicz do listy” ustawiona na “Tak”)
Gdy do pola kombi wpiszemy wartość spoza źródła danych tego pola kombi i będziemy chcieli opuścić to pole, zajdzie zdarzenie “Przy wartości spoza listy” - "NotInList", którego standardowa obsługa polega na poinformowaniu o błędzie i nie dopuszczeniu do wyjścia z pola. Procedura obsługi zdarzenia “Przy wartości spoza listy” ma jeden parametr wejściowy:
- NewData – przekazujący wprowadzoną przez użytkownika do pola kombi wartość,
oraz jeden parametr wyjściowy:
- Response – informujący system jak postępować po zakończeniu wykonywania tej procedury zdarzenia:
w procedurze następuje dodanie nowego elementu do źródła danych pola kombi:
Response = acDataErrAdded
.
w procedurze następuje usunięcie wartości NewData z pola kombi za pomocą metody Undo
Response = acDataErrContinue
.
Z kolei albo “zapomina się” o wprowadzonej
przez użytkownika wartości, traktując ją jako błąd użytkownika albo
zapamiętuje się ją na zmiennej lub w polu formularza, aby po zakończeniu obsługi
zdarzenia NotInList przejść do aktualizacji źródła danych dla listy kombi a
następnie listy rozwijanej pola kombi za pomocą metody Requery. Ten sposób
jest przyjęty w przykładowej aplikacji MS wprowadzania zamówień.
jest też możliwość przejścia do standardowej obsługi błędów, ustawiając
Response = acDataErrDisplay
.
Przykład
Załóżmy, że mamy listę kolorów o
nazwie “Kolory” i chcemy oprogramować dodanie
nowego koloru do listy. Lista kolorów jest bezpośrednio wpisana do pola
“Źródło wierszy”. Właściwość “Ogranicz do listy” jest ustawiona
na “Tak”.
Private Sub Kolory_NotInList(NewData As String, Response As Integer)
Dim ctl As Control
' Zwraca obiekt Control, który wskazuje na pole kombi.
Set ctl = Me!Kolory
' Zachęca użytkownika do potwierdzenia dodania nowego koloru
If MsgBox("Koloru nie ma na liście. Dodać go?", vbOKCancel) = vbOK Then
' Jeśli użytkownik wybiera OK.:
' ustawienie argumentu Response - zaakceptowanie wyboru użytkownika
Response = acDataErrAdded
' dodanie nowego koloru z parametru NewData do źródła wiersza.
ctl.RowSource = ctl.RowSource & ";" & NewData
Else
' Jeśli użytkownik wybiera Cancel: nie wyświetlanie komunikatu o błędzie
Response = acDataErrContinue
' i anulowanie zmiany (Undo jest metodą pola formularza)
ctl.Undo
End If
End Sub
Procedury zdarzeń z parametrami
Część procedur będących wartościami właściwości zdarzeń, jak to już było widoczne w rozważanych przykładach, ma parametry. Przy tworzeniu procedury zdarzenia, Access sam wpisuje nazwy tych parametrów.
Poniżej zamieszczamy listę nagłówków procedur zdarzeń z parametrami w odniesieniu do formularzy i wyjaśniamy znaczenie tych parametrów. Pomijamy tylko zdarzenia związane z użyciem filtrów.
Podstawowymi parametrami są Cancel i Response.
Nadanie parametrowi Cancel niezerowej wartości (np. True) powoduje skasowanie zdarzenia, którego dotyczy dana procedura.
Parametr Response przyjmuje na ogół dwie wartości:
acDataErrContinue - kontynuuj bez wyświetlania domyślnego komunikatu,
acDataErrDisplay - wyświetl domyślny komunikat (opcja domyślna).
Oto grupa procedur, w których nagłówkach występują te parametry.
Sub Form_Open (Cancel As Integer)
Sub Form_Unload (Cancel As Integer)
Sub Form_BeforeInsert (Cancel As Integer)
Sub Form_BeforeUpdate (Cancel As Integer)
Sub Form_Delete (Cancel As Integer)
Sub Form_BeforeDelConfirm (Cancel As
Integer, Response As Integer)
Pozostałe procedury, mające parametry to:
Sub Form_AfterDelConfirm (Status As
Integer)
Samego zdarzenia “Po usunięciu” nie można
anulować. Status
określa czy rekord został usunięty:
acDeleteOK - rekord został usunięty,
acDeleteCancel - usuwanie zostało anulowane w Visual Basicu,
acDeleteUserCancel - usuwanie zostało anulowane przez użytkownika.
Sub Form_KeyPress (KeyAscii As Integer) -
KeyAscii kod ASCII
Sub Form_Error(DataErr As Integer, Response
As Integer)
- DataErr kod błędu. Umożliwia globalną obsługę błędów w module formularza.
Przedstawimy przykład anulowania zdarzenia poprzez ustawienie parametru Cancel na True. Zdarzenia, których procedury mają parametr Cancel mogą zostać anulowane.
W przykładzie poniżej w procedurze zwolnienia formularza “Form1” następuje sprawdzenie, czy w danej chwili pozostał otwarty formularz “Form2”. Jeśli tak, zdarzenie zwolnienia formularza zostaje anulowane (przez ustawienie parametru Cancel na True) - tj. formularz “Form1” pozostaje dalej otwarty.
Sub Form_Unload (Cancel As Integer)
' Formularz Form2 nie może być otwarty bez otwartego formularza Form1.
If Otwarty("Form2") Then Cancel = True
End Sub
Użycie instrukcji SQL
Efekt użycia kwerendy wybierającej będącej źródłem danych dla formularza jest widoczny bezpośrednio w formularzu. Często zachodzi potrzeba użycia instrukcji SQL (kwerendy funkcjonalnej) zmieniającej dane w tabeli bazy danych i ta zmiana jest uzależniona od wartości na polach formularza.
Przykład 1
Używając zwykłej semantyki usuwania, nie można usunąć działu, do którego są przypisani pracownicy. Najbardziej naturalnym rozwiązaniem w takiej sytuacji jest zmiana identyfikatora działu w rekordach wszystkich pracowników usuwanego działu na Null, dokonywana przed usunięciem działu, w procedurze zdarzenia “Przy usunięciu”,
Private Sub Form_Delete(Cancel As Integer)
DoCmd.RunSQL "UPDATE Pracownicy " & _
"SET Id_działu = Null" & _
"WHERE Id_działu = " & Me![Id_działu]
End Sub
Zwróćmy uwagę na sposób formowania instrukcji UPDATE, w szczególności sposób dołączenia do niej zawartości pola formularza.
Przykład 2
Jeśli użytkownik wprowadza do pola listy kombi nową wartość, której nie ma na liście rozwijanej i chce aby odpowiedni rekord został dopisany do tabeli bazy danych, dołączenie nowego rekordu najlepiej zrealizować za pomocą kwerendy dołączającej. Załóżmy na przykład, że przy wprowadzaniu nowego pracownika, zachodzi potrzeba wprowadzenia jednocześnie nowego działu. Użytkownik podaje nazwę nowego działu i zachodzi zdarzenie “Przy wartości spoza listy”.
Private Sub Id_działu_NotInList(NewData As String, Response As Integer)
Dim ctl As Control
Set ctl = Me![Id_działu]
If MsgBox("Czy chcesz dodać nowy dział?", vbYesNo, "UWAGA") = vbYes Then
DoCmd.RunSQL "INSERT INTO Działy(Nazwa) VALUES('"& _ NewData & "')"
'Wprowadzenie nowego działu do tabeli Działy
Response = acDataErrAdded
Else
' Jeśli użytkownik wybiera "Nie": nie wyświetlanie komunikatu o błędzie
Response = acDataErrContinue
'i anulowanie zmiany
ctl.Undo
End If
End Sub
Zwróćmy uwagę na brak w instrukcji Insert pola Id_działu typu Autonumer. Jego wartość jest automatycznie ustalana przez Access.
Przykład 3
Za pomocą kodu jest możliwa obsługa jednoczesnego wyboru wielu elementów na liście. Właściwość “Wybór wielokrotny” powinna być ustawiona na “Prosty” lub “Rozszerzony” Domyślne ustawienie “Brak” oznacza, że wybór dotyczy tylko jednego elementu listy. Korzystając z możliwości wyboru wielokrotnego możemy zaznaczyć wszystkie wymagane elementy z listy a następnie zbiorczo wykonać na nich pewną operację.
Rozważmy formularz działu, na którym jest wyświetlana lista zatrudnionych w nim pracowników. Pole listowe o nazwie Lista składa się z dwóch kolumn zawierających odpowiednio identyfikator pracownika (kolumna o szerokości 0cm - nie wyświetlana) oraz nazwisko pracownika. Po zaznaczeniu grupy pracowników, możemy spowodować ich usunięcie.
Przeglądanie wybranych na liście elementów odbywa się przy użyciu kolekcji ItemsSelected pola listowego oraz funkcji Column zwracającej wartość odpowiedniego elementu na liście. Pierwszym argumentem jest numer kolumny. Drugim argumentem jest pozycja (na liście) będąca elementem kolekcji ItemsSelected. Pozycja na liście jest wartością typu Variant. W przypadku listy powyżej, kolekcja ItemsSelected składa się z numerów 0,3,4. Przy wyborze jednokrotnym można pominąć drugi argument. Do usunięcia osoby wykorzystujemy tutaj metodę RunSQL obiektu DoCmd, której parametrem jest instrukcja SQL. Odpowiednia procedura wygląda następująco:
Private Sub Usuń_Click()
On Error GoTo Obsługa_błędów
Dim elem As Control, poz As Variant, odp As Integer
Dim Tekst As String, ZapSQL As String
Set elem = Me!Lista
'elem.ItemsSelected - kolekcja zaznaczonych na liście elementów.
'Można je przejrzeć za pomocą instrukcji:
For Each poz In elem.ItemsSelected
'Wartości w kolejnych kolumnach wiersza poz listy to:
'elem.Column(0,poz), elem.Column(1,poz)
Tekst = "Czy na pewno chcesz usunąć osobę " & elem.Column(1, poz)
odp = MsgBox(Tekst, vbYesNo, "UWAGA!")
If odp = vbYes Then
ZapSQL = "DELETE FROM Pracownicy "& _
"WHERE Id_prac=" & elem.Column(0,poz)
DoCmd.RunSQL ZapSQL
End If
Next poz
elem.Requery
Koniec:
Exit Sub
Obsługa_błędów:
MsgBox Err.Description
Resume Koniec
End Sub
Zauważmy, w jaki sposób na zmiennej ZapSQL jest tworzona instrukcja SQL do wykonania – przez wstawienie konkretnej wartości elem.Column(0,poz) do warunku WHERE.