Edytor VBA – prywatne i publiczne

W edytorze  VBA każdy moduły własne obiektów ma charakter prywatny. Oznacza to, że wszystkie zapisane w nim funkcje i procedury są dostępne tylko z poziomu VBA.

Moduły ogólne są domyślnie publicznie. Zdefiniowane w nich procedury i funkcje publiczne są widoczne również z poziomu Accessa (m.in. w kreatorze wyrażeń). Funkcje i procedury prywatne mogą być wykorzystane jedynie z poziomu procedur zapisanych w tym samym module. 

Np. taka funkcje w module ogólnym:

Public Function PierwszyNumer()
   'funkcja publiczna
Pierwszy = DFirst(„NumerKatalogowy”, „TabelaKsiazki”, „DataP is null”)
End Function


Private Function OstatniNumer()
   'funkcja prywatna
OstatniNumer = DLast(„NumerKatalogowy”, „TabelaKsiazki”, „DataP is null”)
End Function

W kreatorze wyrażeń wygląda to tak:

kliknij, aby powiększyć

W bazie Biblioteka, w module ModuleFunction  widoczna jest tylko jedna funkcja – zdeklarowana jako Public. Prywatna funkcja OstatniNumer nie jest tu widoczna, może być wykorzystana tylko w obrębie tego samego modułu. 

Przy bardziej rozbudowanych projektach i  wielu procedurach w kodzie może być więcej modułów ogólnych z różnymi procedurami i funkcjami. Nie wszystkie z nich muszą być widoczne i dostępne również bezpośrednio w Accessie, czasem warto je „utajnić”. Wystarczy na początku modułu ogólnego wstawić Option Private Module

kliknij, aby powiekszyć

Od tej pory – wszystkie funkcje i procedury publiczne w takim module będą dostępne z innych modułów, ale nie w Accessie. 
W praktyce zawsze tak robię, porządkując funkcje i procedury i część z nich umieszczając je modułach prywatnych, a część – publicznych. Zmieniam też nazwy modułów, żeby się nie pogubić i utrzymać porządek w kodzie. 
Np. tak:

kliknij, aby powiększyć

 


A tu możesz mi postawić kawę: 

buycoffee.to/marzatela

Zdarzenie formularza: przy zamknięciu

 Przy zamknięciu to jedno ze zdarzeń uruchamiających się automatycznie przy zamykaniu formularza. Dostępne jest w arkuszu właściwości formularza oraz w module VBA formularza. 

W edytorze VBA jest to procedura o nazwie Form_Close. Jest uruchamiana automatycznie przy zamknięciu, niezależnie od sposobu, a jaki formularz jest zamykany: makrem, procedurą VBA czy po prostu przyciskiem Zamknij.
W ramach tej procedury można uruchomić każdą dowolną procedurę, sprawdzić np. czy wszystkie zmiany zostały zapisane, otworzyć inny formularz, tak, żeby  użytkownik nagle nie zobaczył pustego okna bazy Access itp. Możliwości jest sporo, w zależności od potrzeb. 

Trzeba jednak pamiętać o tym, że gdy w formularzu mamy przycisk do zamykania formularza, a jednocześnie jest oprogramowane zdarzenie Form_Close, zadziałają obie procedury. Musimy uważać, żeby nie były sprzeczne z sobą. 

Np.w takich procedurach:

Private Sub Form_Close()
DoCmd.OpenForm „menustart”    ’2 linia
End Sub
Private Sub Zamknij_Click()
DoCmd.Close   ’1 linia
DoCmd.OpenForm „ksiazka”     ’3 linia
End Sub

Po naciśnięciu przycisku Zamknij, uruchomiona zostanie przypisana do niego procedura i wykonana pierwsza linia kodu. Ponieważ do procedura zamykająca formularz, nastąpi przejście do automatycznego zdarzenia formularza czyli Form_Close i wykonana zostanie 2 linia kodu. Potem powrót do procedury Zamknij_Click i trzecia linia kodu. W efekcie zostaną otwarte 2 różne formularze, aktywny będzie formularza „ksiazka”. 

Linki do innych zdarzeń formularza:

Najczęściej używane zdarzenia formularza


A tu możesz mi postawić kawę: 

buycoffee.to/marzatela

Zdarzenie formularza: przy otwarciu

 Przy otwarciu to jedno ze zdarzeń uruchamiających się automatycznie po otwarciu formularza. Dostępne jest w arkuszu właściwości formularza oraz w module VBA formularza. 
Zdarzenie to sprawdza, czy dany użytkownik ma prawo otworzyć ten formularz, przekazuje argumenty wejściowe itp. Dopiero później następuje załadowanie rekordów. 

W edytorze VBA jest to procedura o nazwie Form_Open:Procedura ma jeden argument: 
   Cancel – as Integer, argument opcjonalny. Wartość domyślna to 0 lub False

Przypisanie do zmiennej Cancel wartości 1 (lub Prawda/True) spowoduje anulowanie zdarzenia inicjującego czyli otwarcia formularza. W efekcie formularz nie zostanie otwarty. 

Przykładowa procedura:

Private Sub Form_Open(Cancel As Integer)
Dim DzienTygodnia As Integer
DzienTygodnia = Weekday(Date, vbMonday)
If DzienTygodnia = 7 Then
   MsgBox „Dziś jest niedziela, odpocznij”
Cancel = 1
End If
End Sub

W procedurze tej następuje sprawdzenie bieżącego dnia tygodnia i jeżeli jest to niedziela – wyświetla się komunikat i formularz zostaje zamknięty. 
Oczywiście w ramach tej procedury można uruchomić każdą dowolną procedurę, sprawdzić przekazany argumentem wejściowym login użytkownika itp. Możliwości jest sporo, w zależności od potrzeb. 

Linki do innych zdarzeń formularza:

Najczęściej używane zdarzenia formularza


A tu możesz mi postawić kawę: 

buycoffee.to/marzatela

Etykieta w kodzie VBA

Etykieta w kodzie VBA to konkretne miejsce w kodzie VBA. Jest to zawsze jedno słowo (ciąg znaków bez spacji) zakończone dwukropkiem.
Linia z etykietą zawsze zaczyna się od pierwszego znaku w danej linii.

If Warunek Then GoTo Etykieta1
   ’ciag instrukcji A
Etykieta1:
  ’ciag instrukcji B
End If

W tym kodzie VBA jeżeli jest spełniony Warunek, za pomocą wyrażenia GoTo następuje od razu skok wykonywania kodu do znajdującej się tuż pod Etykietą1 ciągu instrukcji B, z pominięciem ciągu instrukcji A.
Linia  z etykietą nie zatrzymuje kodu, nie można tez w niej ustawić punktu przerwania.

Generalnie jednak taki przykład kodu nie jest wzorcowy i wprawdzie działa i to skutecznie, ale raczej, jeżeli są inne możliwości, nie powinno się go stosować.
Za to jest to zdecydowanie najlepsze i standardowo stosowane działanie do obsługi błędów wykonania.


 

Data jako parametr kwerendy

Czy data/czas może być parametrem kwerendy? Oczywiście.
W dodatku najczęściej stosowana jest tu nie pojedyncza data tylko zakres dat od-do.

W siatce kwerendy wpisujemy kryterium:

kliknij, aby powiększyć

Zakres dat wpisujemy przy zastosowaniu słów kluczowych Between i And. Oczywiście można też wstawić tu kryterium w formie pola parametru, gdzie zamiast sztywnego wpisania dat – można wstawić je jako parametr np.
Between [DataOd] And [DataDO]
J
akoś jednak nie polecam, gdyż praktyka wskazuje, że tam gdzie użytkownik wpisuje daty – wcześniej czy później pojawią się problemy związane z formatem tej daty i w konsekwencji – będą błędy.

Jako parametry kwerendy można też wykorzystać pola formularza.
Np.

kliknij, aby powiększyć

W formularzu są 2 pola TOD i TDO, w których wpisujemy daty, a w kwerendzie odwołania do tych pól:
Between [Formularze]![SpisKasiazek]![TOD] And [Formularze]![SpisKasiazek]![TDO]
Oczywiście w porządnej aplikacji należałoby zabezpieczyć się przed wstawieniem tu innej wartości niż data, rozważyć możliwość, że jedno pole jest puste lub data DO jest mniejsza od daty OD itp., ale w formularzu da się bez problemu wprowadzić takie mechanizmy przed błędami.

A jak to wygląda w kodzie VBA? Na przykład tak.

Private Sub PolecenieSzukaj_Click()
Dim MojaKwerenda As String
Dim DataOD As Date
Dim DataDO As Date
DataOD=Me.TOD
DataDO=Me.TDO
MojaKwerenda = „SELECT TabelaKsiazki.NumerKatalogowy, TabelaKsiazki.Autor, TabelaKsiazki.Tytul, TabelaKsiazki.Cena, TabelaKsiazki.Dzial, TabelaKsiazki.DataP ” & _
„FROM TabelaKsiazki LEFT JOIN TabelaDzial ON TabelaKsiazki.Dzial = TabelaDzial.IDKat ” & _
„WHERE TabelaKsiazki.DataP  Between #” & DataOD &_
„# AND #” &  DataDO & „#;”
Me.RecordSource = MojaKwerenda
Me.Requery
End Sub

Teoretycznie – wszystko to powinno działać. A w praktyce – może się okazać, że nie zawsze i nie wszędzie. Na kilku komputerach – jest OK, a na jakimś jednym – nagle nie. Ostatnio taki problem pojawił się u mnie w aplikacje Excela – opisałam to tu:
Filtrowanie tabeli
Tego typu problemy zdarzały mi się już wcześniej. Teraz zapobiegawczo, wszędzie tam gdzie daty są kluczowym elementem – zamieniam je na liczby, gdyż:
Data i czas to liczba

W tym konkretnym przypadku:

    • w kwerendzie, w której wstawiam kryteria parametryczne – dokładam dodatkową kolumnę oparta o formułę:
      =Clng(DataP)
    • taką samą konwersję wykonuję w stosunku do dat w polach formularza
Private Sub PolecenieSzukaj_Click()
Dim MojaKwerenda As String
Dim DataOD As Date
Dim DataDO As Date
Dim LDataOD As Long
Dim LDataDO As Long
DataOD=Me.TOD
DataDO=Me.TDO
LDataOD=Clng(DataOD)
LDataDO=Clng(DataDO)
MojaKwerenda = „SELECT TabelaKsiazki.NumerKatalogowy, TabelaKsiazki.Autor, TabelaKsiazki.Tytul, TabelaKsiazki.Dzial,  ” & _ „TabelaKsiazki.DataP, CLng([DATAP]) AS LDataP ” & _
„FROM TabelaKsiazki LEFT JOIN TabelaDzial ON TabelaKsiazki.Dzial = TabelaDzial.IDKat ” & _
„WHERE TabelaKsiazki.LDataP  Between ” & LDataOD &_
” AND ” &  LDataDO & „;”
Me.RecordSource = MojaKwerenda
Me.Requery
End Sub

Oczywiście – tu już nie ma znaków # przed i po zmiennych – one są tylko w stosunku do zmiennych typu Data.