2.11. Klasa CLogowanie

Transkrypt

2.11. Klasa CLogowanie
110
2.11. Klasa CLogowanie
Praktycznie w każdej aplikacji biznesowej musimy rozwiązać problem logowania
uprawnionego użytkownika. Zadanie to może znakomicie ułatwić prezentowana klasa.
Wykorzystanie klasy CLogowanie wymaga, aby w skoroszycie aplikacji był
arkusz o nazwie Logowanie i strukturze (tabeli) pokazanej niżej.
W kolumnie A będzie przechowywany klucz tej tabeli, kolumna B przechowa
identyfikator użytkownika, kolumna C hasło, kolumna D datę jego utworzenia, kolumna E
status hasła (1 aktywne, 0 nieaktywne)
Obszar kolumn H:I będzie wykorzystywany jako miejsce zdefiniowania kryteriów
wyszukiwania zaawansowanego, a obszary kolumn K:L oraz N:O jako miejsce zwrócenia
wyników wyszukiwania zaawansowanego.
Klasa CLogowanie wykorzystuje formularz o nazwie frmLogowanie, który
pozwala na wybranie z pola kombo uprawnionego użytkownia, podanie hasła i ewentualną
jego zmianę, Zmiana może wynikać z decyzji użytkownika lub być wymuszona przez kod
klasy formularza w sytuacji, gdy w parametrach aplikacji określony jest niezerowy czas
ważności hasła w dniach.
2.11.1. Formularz frmLogowanie
Formularz logowania musi pracować w trybie logowania użytkownika w oparciu
o nowe hasło jak i w trybie zarejestrowania zmiany hasła, oznacza to zaprojektowanie
formularza w taki sposób, aby można było udostępniać różne jego formanty.
2.11.1.1. Projekt formularza
Na powierzchni formularza umieszczono następujące formanty:
cboLogin – formant typu ComboBox, pozwoli na wybór użytkownika;
txtHaslo – formant typu TextBox, tu będzie wpisane hasło;
txtNoweHaslo – formant typu TextBox, tu będzie wpisane nowe hasło;
txtPowtorzHaslo – TextBox, tu będzie powtórzenie nowego hasła;
chbZmiana – formant typu CheckBox, jego zaznaczenie wymusi zmianę hasła;
ukryte pole tekstowe txtKto – tu będą dane użytkownika wybranego w polu
cboLogin;
etykieta błędu lblError – wykorzystamy ją do zgłoszenia komunikatu o błędzie;
cmdZaloguj – przycisk polecenia uruchamiający procedurę logowania;
cmdAnuluj – przycisk polecenia anulującego proces logowania użytkownika;
111
cztery etykiety opisujące pole kombi i trzy pola tekstowe o nazwach odpowiednio
lblKto, lblHaslo, lblNoweHaslo i lblPowtorzHaslo.
2.11.1.2. Kod klasy formularza
W kodzie klasy formularza frmLogowanie, w jego sekcji deklaracji
zadeklarowano zmienne publiczne, które pozwolą na komunikację z kodem klasy
CLogowanie (przekazanie do nich wartości zmiennych prywatnych klasy jak i odebranie
identyfikatora zalogowanego użutkownika).
Public myRange As Range, pDayForPass As Integer, pPassD As _
String, pPassForArk As String, pMinD As Integer, _
pMaxD As Integer, pCzasP As Integer, pHistoriaP As _
Integer, pIleProb As Integer
W tej samej sekcji zadeklarowano także kilka pomocniczych zmiennych, które będą
wykorzystywane do wymiany informacji między prywatnymi procedurami formularza.
Dim pass As String, iPozStara As Integer, ileProb As Integer, _
dataZ As Date, fChange As Boolean
Procedura Activate formularza odpowiada za jego przygotowanie do pracy,
w tym za zbudowanie źródła danych dla formantu cboLogin i dostosowanie formantów
formularza i jego wymiarów do aktualnych potrzeb (do zalogowania bez zmiany hasła).
W tym miejscu formanty txtHaslo, chbZmien i cmdZapisz zostaną ustawione
jako niedostępne, a zmienne ileProb i fChange zainicjowane. Inicjowane będą także
trzy zmienne publiczne zadeklarowane w jednym z modułów standardowych. Zmienne te
wykorzystamy do przekazania do instancji klasy CLogowanie informacji o przebiegu
procesu logowania.
Private Sub UserForm_Activate()
DajDaneDoCboLogin
FormantyStandard
ileProb = 1
fChange = True
112
' inicjalizacja zmiennych publicznych klasy CLogowanie
DaneUsera = vbNullString
ZmianaHasla = False
IdUsera = -1
Me.txtHaslo.Enabled = False
Me.cmdZapisz.Enabled = False
Me.chbZmiana.Enabled = False
End Sub
Prywatna procedura DajDaneDoCboLogin odpowiada za zbudowanie
dwukolumnowego źródła danych dla pola cboLogin na podstawie danych obszaru
wskazanego zmienną obszarową myRange.
Private Sub DajDaneDoCboLogin()
Dim i As Integer, V() As Variant, t As String, t1 As String
ReDim V(myRange.Rows.Count, 1)
V(0, 0) = 0
V(0, 1) = "Administrator"
For i = 1 To myRange.Rows.Count
V(i, 0) = myRange.Cells(i, 1)
t = ""
For j = 2 To myRange.Columns.Count
If j = 2 Then
t = t & myRange.Cells(i, j) & " "
Else
t = t & myRange.Cells(i, j) & ", "
End If
Next j
V(i, 1) = Left(t, Len(t) - 2)
Next i
Me.cboLogin.List = V
Me.cboLogin.ListIndex = -1
End Sub
Procedury FormantyStandard oraz FormantyDoZmiany odpowiadają za
dostowanie formularza do jednego z dwóch trybów pracy.
Private Sub FormantyStandard()
Me.lblPowtorz.Visible = False
Me.txtPowtorzHaslo.Visible = False
Me.txtNoweHaslo.Visible = False
Me.lblNowe.Visible = False
UstawJedenC Me.chbZmiana, 6, 66
UstawJedenC Me.cmdZapisz, 222, 43
UstawJedenC Me.cmdAnuluj, 222, 82
UstawJedenC Me.lblError, 6, 90
Me.Height = 133
Me.Width = 295
End Sub
113
Private Sub FormantyDoZmiany()
Me.lblPowtorz.Visible = True
Me.txtPowtorzHaslo.Visible = True
Me.txtNoweHaslo.Visible = True
Me.lblNowe.Visible = True
UstawFormantC Me.txtNoweHaslo, 78, 66, Me.lblNowe, 30, 67
UstawFormantC Me.txtPowtorzHaslo, 78, 90, Me.lblPowtorz, 18, 91
UstawJedenC Me.chbZmiana, 6, 108
UstawJedenC Me.cmdZapisz, 222, 66
UstawJedenC Me.cmdAnuluj, 222, 114
UstawJedenC Me.lblError, 6, 126
Me.Height = 166.5
Me.Width = 295
End Sub
Z uwagi na zamiar wykorzystywania klasy CLogowanie jako klasy publicznej
(oferowanej jako oddzielny skoroszyt) musimy utworzyć prywatne wersje pomoczniczych
procedur UstawJedenC i UstawFormantC.
Private Sub UstawJedenC(ByRef ctrl As MSForms.Control, _
ByVal L As Integer, ByVal t As Integer)
ctrl.Left = L
ctrl.Top = t
End Sub
Private Sub UstawFormantC(ByRef ctl1 As MSForms.Control, ByVal L1 _
As Integer, ByVal t1 As Integer, ByRef ctl2 As _
MSForms.Control, L2 As Integer, ByVal t2 As Integer)
UstawJedenC ctl1, L1, t1
UstawJedenC ctl2, L2, t2
End Sub
Procedura cboLogin_Change po wyborze użytkownika ustala, czy ma on
zdefiniowane hasło, jeżeli nie, to przekazuje stosowną inforamcję do instancji klasy
CLogowanie i kończy swoją pracę.
Private Sub cboLogin_Change()
Dim d As Integer, ip As Integer
If Me.cboLogin.ListIndex > -1 Then
' zapisanie identyfikatora i danych usera
IdUsera = Me.cboLogin.Value
DaneUsera = Me.cboLogin.List(Me.cboLogin.ListIndex, 1)
' pobranie aktualnego hasła z arkusza Logowanie
pass = DajHaslo(Me.cboLogin.Value)
If pass = vbNullString Then
Unload Me
' przypisanie danych do zmiennych publicznych
' w celu przekazania ich do instancji klasy CLogowanie
IdUsera = -3
114
Unload Me
End If
Me.txtHaslo.Enabled = True
End If
End Sub
Funkcja DajHaslo odpowiada za pobranie z arkusza Logowanie aktualnego
hasła na podstawie identyfikatora użytkownika.
Private Function DajHaslo(ByVal idu As Integer) As String
Dim ile As Integer, ark As String
ark = "Logowanie"
With Worksheets(ark)
.Unprotect pPassForArk
ile = Application.WorksheetFunction.CountA(.Range("a:a")) - 1
If ile = 0 Then
DajHaslo = vbNullString : iPozStara = 0
Else
.Range("h2") = ido
.Range("i2") = 1
.Range("k2").Resize(ile, 2).ClearContents
' filtrowanie
.Range(.Range("A1").Resize(ile + 1, 5).Address). _
AdvancedFilter Action:=xlFilterCopy, _
CriteriaRange:=.Range("h1:i2"), _
CopyToRange:=.Range(.Range("k1").Resize(ile + 1, 2). _
Address), Unique:=True
DajHaslo = .Range("k2")
iPozStara = .Range("l2")
If iPozStara > 0 Then
dataZ = CDate(Application.WorksheetFunction.VLookup( _
iPozStara, .Range("a2").Resize(ile, 5), 4, False))
End If
End If
.Protect DrawingObjects:=True, Contents:=True, _
Scenarios:=True, Password:=pPassForArk
End With
End Function
Procedura chbZmiana_Change odpowiada za dostowanie formularza do jednego
z dwóch trybów pracy zależnie od zaznaczenia lub nie pola wyboru chbZmiana.
Private Sub chbZmiana_Change()
If Me.chbZmiana.Value = True Then
FormantyDoZmiany
fChange = False ' blokada obsługi zdarzenia Exit
Me.txtNoweHaslo.SetFocus
fChange = True ' usunięcie blokady zdarzenia Exit
Me.chbZmiana.Enabled = False
Else
115
FormantyStandard
End If
End Sub
Dla pól tekstowych txtHaslo, txtNoweHaslo i txtPowtorzHaslo
tworzymy procedury obsługujące zdarzenia KeyPress.
Private Sub txtHaslo_KeyPress(ByVal KeyAscii As _
MSForms.ReturnInteger)
HelpKyePress KeyAscii
End Sub
Private Sub txtNoweHaslo_KeyPress(ByVal KeyAscii As _
MSForms.ReturnInteger)
HelpKyePress KeyAscii
End Sub
Private Sub txtPowtorzHaslo_KeyPress(ByVal KeyAscii As _
MSForms.ReturnInteger)
HelpKyePress KeyAscii
End Sub
Procedura HelpKeyPress ogranicza wprowadzany znak do dopuszczalnych dla
hasła.
Private Sub HelpKyePress(ByVal KeyAscii As MSForms.ReturnInteger)
Select Case KeyAscii
Case 48 To 57, 65 To 90, 97 To 122 'cyfry
Me.lblError.Caption = vbNullString
Case 33, 35 To 38, 94 To 95
Me.lblError.Caption = vbNullString
Case Else
Beep
Me.lblError.Caption = _
"Znaki dopuszczalne: 0-9, a-z, A-Z, #,$, %,^,&,!"
KeyAscii = 0
End Select
End Sub
Procedura zdarzenia Exit pola tekstowego txtHaslo odpowiada za sprawdzenie
poprawności wprowadzonego hasła w kontekście jego długości, ważności i unikalności,
jeżeli aktywna jest historia haseł.
Private Sub txtHaslo_Exit(ByVal Cancel As MSForms.ReturnBoolean)
If Not fChange Then Exit Sub
Dim bf As Boolean
If Me.txtHaslo.Text = vbNullString Then
Cancel = False
Exit Sub
End If
116
' sprawdzenie długości hasła
If Len(Me.txtHaslo.Text) >= pMinD And _
Len(Me.txtHaslo.Text) <= pMaxD Then bf = False Else bf = True
If bf Then
Beep
Me.lblError.Caption = _
"Zła długość wprowadzonego hasła, popraw!"
Cancel = True ' zła długość
Exit Sub
Else
' czy dobre hasło?
If Not pass = Me.txtHaslo.Text Then
If ileProb = pIleProb Then
IdUsera = -1 ' wyczerpana liczba prób, brak logowania
Unload Me
Else
ileProb = ileProb + 1
Beep
Me.lblError.Caption = "Niepoprawne hasło.
Masz jeszcze " IleProbJeszcze()
Me.txtHaslo.SelStart = 0 ' punktu początkowy zaznaczenia
Me.txtHaslo.SelLength = Len(Me.txtHaslo.Text) ' długość
Cancel = True
End If
Else
Me.chbZmiana.Enabled = True
Me.cmdZapisz.Enabled = True
If pass = pPassD Then
Me.chbZmiana.Value = True
End If
End If
End If
End Sub
Funkcja IleProbJeszcze zwraca informację o tym, ile prób logowania jeszcze
pozostało.
Private Function IleProbJeszcze()
Dim t As String
Select Case pIleProb - ileProb + 1
Case 1
t = " jedną próbę"
Case 2
t = "dwie próby"
Case 3
t = "trzy próby"
Case 4
t = "cztery próby"
Case Else
117
t = "kilka prób (więcej niż 4)"
End Select
IleProbJeszcze = t
End Function
Procedury zdarzeń Change pól tekstowych txtHaslo, txtNoweHaslo
i txtPowtorzHaslo usuwają ewentualny komunikat o błędzie wyświetlony w etykiecie lblError. Zadanie to realizowane jest przy wykorzystaniu pomocniczej procedury
PomocDoChange.
Private Sub PomocDoChange()
If Not fChange Then Exit Sub
If Not Me.lblError.Caption = _
vbNullString Then Me.lblError.Caption = vbNullString
End Sub
Private Sub txtHaslo_Change()
PomocDoChange
Me.cmdZapisz.Enabled = True
End Sub
Private Sub txtNoweHaslo_Change()
PomocDoChange
End Sub
Private Sub txtPowtorzHaslo_Change()
PomocDoChange
End Sub
Procedura zdarzenia Exit pola tekstowego txtNoweHaslo odpowiada za
sprawdzenie nowego hasła w zakresie jego długości oraz unikalności, jeżeli historia haseł
jest aktywna.
Private Sub txtNoweHaslo_Exit(ByVal Cancel As MSForms.ReturnBoolean)
If SprawdzDlugosc(Me.txtNoweHaslo, _
"Zła długość wprowadzonego nowego hasła, popraw!") Then
Cancel = True
ElseIf SprawdzHistorie() Then
Cancel = True
Else
Me.cmdZapisz.Enabled = True
Cancel = False
End If
End Sub
Pomocnicza funkcja SparwdzDlugosc odpowiada za sprawdzenie wprowadzonego hasła co do formalnych wymogów odnośnie jego długości.
Private Function SprawdzDlugosc(ByVal txt As MSForms.TextBox, _
ByVal kom As String) As Boolean
Dim bf As Boolean
118
If Not fChange Then
bf = False ' nie ma sprawdzianu
ElseIf Me.txtNoweHaslo.Text = vbNullString Then
bf = False ' nie wprowadzono żadnego tekstu
ElseIf Len(txt.Text) < pMinD Or Len(txt.Text) > pMaxD Then
bf = True ' zła długość, blokada wyjścia z pola tekstowego
Else
bf = False ' hasło spełnia wymogi długości
End If
SprawdzDlugosc = bf
If bf Then
Beep
Me.lblError.Caption = kom
txt.SelStart = 0 ' początek zaznaczenia
txt.SelLength = Len(txt.Text) ' długość zaznaczenia
Else
Me.lblError.Caption = vbNullString ' kasujemy komunikat błędu
End If
End Function
Pomocnicza funkcja SprawdzHistorie odpowiada za sprawdzenie, przy
niezerowej wartości zmiennej pHistoriaP unikalności nowego hasła.
Private Function SprawdzHistorie() As Boolean
Dim bf As Boolean
If pHistoriaP = 0 Then
bf = False
Else
Dim ark As String, ile As Integer, tp As Variant, _
ip As Integer
ark = "Logowanie"
With Worksheets(ark)
.Unprotect pPassForArk
ile = _
Application.WorksheetFunction.CountA(.Range("a:a")) - 1
.Range("h2") = Me.cboLogin.Value
.Range("i2") = 0
.Range("n2").Resize(ile, 2).ClearContents
.Range(.Range("A1").Resize(ile + 1, 5).Address). _
AdvancedFilter Action:=xlFilterCopy, _
CriteriaRange:=.Range("h1:i2"), _
CopyToRange:=.Range(.Range("n1").Resize(ile + 1, 2). _
Address), Unique:=True
ile = _
Application.WorksheetFunction.CountA(.Range("n:n")) - 1
tp = Me.txtNoweHaslo.Text
' sortujemy hasła po dacie malejąco
.Range("N2").Resize(ile, 2).Sort Key1:=.Range("o2"), _
Order1:=xlDescending, Header:=xlGuess, _
119
OrderCustom:=1, MatchCase:=False, _
Orientation:=xlTopToBottom, DataOption1:=xlSortNormal, _
DataOption2:=xlSortNormal, DataOption3:=xlSortNormal
' na potrzeby funkcji VLookup
On Error Resume Next
x = Application.WorksheetFunction.VLookup(tp, _
.Range("n2").Resize(IIf(ile < pHistoriaP, ile, _
pHistoriaP), 1), 1, False)
If x = Empty Then
Me.cmdZapisz.Enabled = True
bf = False
Else
Beep
Me.lblError.Caption = "Nowe hasło jest na liście ostatnio
używanych haseł, proszę podać inne"
Me.txtNoweHaslo.SelStart = 0 ' początek zaznaczenia
Me.txtNoweHaslo.SelLength = _
Len(Me.txtHaslo.Text) ' długość zaznaczenia
bf = True
End If
ZmianaHasla = True
End With
End If
SprawdzHistorie = bf
End Function
Procedura zdarzenia Exit pola tekstowego txtPowtorzHaslo odpowiada za
sprawdzenie powtórzenego hasła w kontekście jego długości oraz zgodności z hasłem
wpisanym w polu txtNoweHaslo.
Private Sub txtPowtorzHaslo_Exit(ByVal Cancel _
As MSForms.ReturnBoolean)
If SprawdzDlugosc(Me.txtPowtorzHaslo, _
"Zła długość wprowadzonego powtórzenia hasła, popraw!") Then
Cancel = True
ElseIf Not Me.txtNoweHaslo.Text = Me.txtPowtorzHaslo.Text Then
Beep
Me.lblError.Caption = _
"Powtórzenia hasła jest inne niż nowe hasło, popraw!"
Me.txtPowtorzHaslo.SelStart = 0
Me.txtPowtorzHaslo.SelLength = Len(Me.txtPowtorzHaslo)
Cancel = True
Else
Me.lblError.Caption = vbNullString
End If
End Sub
120
Funkcja SprawdzFormanty odpowiada za sprawdzenie wypełnienia pola
txtHaslo, a w przypadku zmiany hasła także pól txtNoweHaslo oraz
txtPowtorzHaslo.
Private Function SprawdzFormanty() As Boolean
Dim bf As Boolean
SprawdzFormanty = HelpForCancel(Me.txtHaslo, _
"Pole 'Hasło' musi być wypełnione")
If SprawdzFormanty Then Exit Function
If Me.chbZmiana.Value Then
SprawdzFormanty = HelpForCancel(Me.txtNoweHaslo, _
"Pole 'Nowe hasło' musi być wypełnione")
If SprawdzFormanty Then Exit Function
SprawdzFormanty = HelpForCancel(Me.txtPowtorzHaslo, _
"Pole 'Powtórz hasło' musi być wypełnione")
If SprawdzFormanty Then Exit Function
End If
If Not Me.txtNoweHaslo.Text = Me.txtPowtorzHaslo.Text Then
Beep
Me.lblError.Caption = _
"Powtórzenie hasła jest inne niż nowe hasło, popraw!"
SprawdzFormanty = True
Else
Me.lblError.Caption = vbNullString
SprawdzFormanty = False
End If
End Function
Funkcja HelpForCancel upraszcza kod funkcji SprawdzFormanty.
Private Function HelpForCancel(ByVal txt As MSForms.TextBox, _
ByVal kom As String) As Boolean
If txt.Text = vbNullString Then
Beep
Me.lblError.Caption = kom
HelpForCancel = True
Else
HelpForCancel = False
End If
End Function
Procedura cmdZapisz_Click odpowiada za sprawdzenie, czy wszystkie
wymagane informacje do zalogowania użytkownika zostały podane. Jeżeli tak, to
w arkuszu Logowanie zostanie utworzony nowy rekord w przypadku, gdy była zmiana
hasła z jednoczesną zmianą statusu hasła dotychczasowego. Procedura przekazuje także do
zmiennych publicznych identyfikator zalogowanego użytkownika oraz jego dane.
121
Private Sub cmdZapisz_Click()
If SprawdzFormanty() Then Exit Sub
Dim i As Integer, x As Integer, ile As Integer, _
nr As Integer, myD As Range
' jeżeli była zmiana hasła
If Me.chbZmiana.Value = True Then
With Worksheets("Logowanie")
.Unprotect pPassForArk
ile = _
Application.WorksheetFunction.CountA(.Range("a:a")) - 1
' ustalamy wartość identyfikatora
nr = Application.WorksheetFunction.max(.Range("a2"). _
Resize(ile, 1)) + 1
Set myD = .Range("a2").Offset(ile, 0)
myD.Offset(0, 0) = nr
myD.Offset(0, 1) = x
myD.Offset(0, 2) = Me.txtHaslo.Text
myD.Offset(0, 3) = format(Now(), "yyyy-mm-dd")
myD.Offset(0, 4) = 1
If iPozStara > 0 Then
.Range("e1").Offset(iPozStara, 0) = 0
End If
.Protect DrawingObjects:=True, Contents:=True, _
Scenarios:=True, Password:=pPassForArk
End With
End If
Unload Me
End Sub
Procedura UserForm_QueryClose blokuje możliwość zamknięcia formularza
z pomocą przyciski „X”, jest to konieczne, jeżeli chcemy kontrolować kto anuluje proces
logowania do aplikacji.
Private Sub UserForm_QueryClose(Cancel As Integer, _
CloseMode As Integer)
If CloseMode = vbFormControlMenu Then
Beep
Me.lblError.Caption = _
"Proszę użyć do zamknięcia formularza przycisku Anuluj"
Cancel = True
End If
End Sub
Porcedura obsługująca zdarzenie Click przycisku cmdAnuluj sprawdza, czy
użytkownik rzeczywiście ma zamiar przerwać proces logowania. Jeżeli tak, to zmienna
publiczna IdUsera jest ustawiana na wartość -2, która będzie oznaczać przerwanie
logowania przez użytkownika.
122
Private Sub cmdAnuluj_Click()
If MsgBox("Naprawdę chcesz anulować proces logowania?", _
vbQuestion + vbYesNo, Me.Caption) = vbYes Then
fChange = False
IdUsera = -2
Unload Me
End If
End Sub
2.11.2. Kod klasy CLogowanie
W sekcji deklaracji zadeklarowano szereg zmiennych prywatnych klasy.
Private
Private
Private
Private
Private
Private
Private
Private
Private
Private
Private
mMinLenPass As Integer ' minimalna długość hasła
mNaxLenPass As Integer ' maksymalna długość hasła
mDefaultPass As String ' hasło domyślne
mDayForPass As Integer ' czas ważności hasła w dniach
mHistoryPass As Integer ' historia haseł w dniach
mIleProb As Integer ' maksymalna liczba prób logowania
mRange As Range ' obszar danych do pola cboLogin
mPassForLogowanie As String ' hasło arkusza Logowanie
mIdUsera As Integer ' identyfikator usera
mDaneUsera As String ' dane usera
mZmianaHasla As Boolean ' True jeżeli byla zmiana hasła
Trzy procedury typu Property Get zwracające wartości zmiennych prywatnych
wykorzystywanych do opisu przebiegu procesu logowania.
Public Property Get IdKtoZalogowany() As Integer
IdKtoZalogowany = mIdUsera
End Property
Public Property Get DaneUsera() As String
DaneUsera = mDaneUsera
End Property
Public Property Get ZmianaHasla() As Boolean
DajZmianaHasla = mZmianaHasla
End Property
Metoda UruchomLogowanie odpowiada za pobranie od użytkownika wartości
argumentów przypisywanych do zmiennych prywatnych klasy, a następnie za utworzenie
instancji klasy formularza frmLogowanie z przekazaniem do niej wartości zmiennych
prywatnych.
Instacja formularza otwierana jest w trybie okna dialogowego, a po zamknięciu
formularza metoda zwraca identyfikator zalogowanego użytkownika i jego dane
(wyświetlone w polu cboLogin instancji formularza).
123
Public Sub UruchomLogowanie(ByVal pMinLen As Integer, _
ByVal pMaxLen As Integer, ByVal pHasloD As String, _
ByVal pCzas As Integer, ByVal pHistoria As Integer, _
ByVal pIleP As Integer, ByVal pPass As String, _
ByVal pRng As Range, Optional ByVal pNazwaApp As _
String = vbNullString)
mMinLenPass = pMinLen
mNaxLenPass = pMaxLen
mDefaultPass = pHasloD
mDayForPass = pCzas
mHistoryPass = pHistoria
mIleProb = pIleP
mPassForLogowanie = pPass
Set mRange = pRng
' utworzenie instancji formularza
Dim frm As New frmLogowanie
frm.Caption = "Formularz logowania do aplikacji " & pNazwaApp
' przekazanie wartości zmiennych prywatnych klasy
Set frm.myRange = mRange
frm.pDayForPass = mDayForPass
frm.pPassD = mDefaultPass
frm.pPassForArk = mPassForLogowanie
frm.pMinD = mMinLenPass
frm.pMaxD = mNaxLenPass
frm.pCzasP = mDayForPass
frm.pHistoriaP = mHistoryPass
frm.pIleProb = mIleProb
Load frm
frm.Show (1)
' odebranie identyfikatora użytkownika i jego danych
mIdUsera = IdUsera
mDaneUsera = DaneUsera
mZmianaHasla = ZmianaHasla
End Sub
2.11.3. Testowanie klasy CLogowanie
W ramach testu sprawdzimy zachowanie się tej klasy w przypadku, gdy uczynimy ją
klasą publiczną, co pozwoli na jej wykorzystywanie w innych projektach VBA bez
konieczności importowania klasy i formularza frmLogowanie do tego projektu.
Problem utworzenia klasy publicznej i jej wykorzystania był już przedstawiony
w rozdziale poświęconym wprowadzeniu do klas, tutaj ograniczymy się do pokazania
skoroszytu udostępniającego klasę CLogowanie oraz skoroszyt testowy demonstrujący
wykorzystanie tej klasy.
124
2.11.3.1. Utworzenie skoroszytu ClassProviderCLogowanie
Proces utworzenia tego skoroszytu zamyka się w kilku pokazanych niżej krokach:
1.
2.
3.
4.
Tworzymy nowy skoroszyt;
W edytorze VBA kopiujemy klasę CLogowanie i formularz
frmLogowanie;
Zmieniamy właściwość Instancing klasy CLogowanie z Private
na PublicNotCreatable;
Dodajemy standardowy moduł i tworzymy w nim funkcję udostępniającą
instancję klasy CLogowanie oraz deklarujemy zmienne publiczne:
Public DaneUsera As String, IdUsera As Integer, _
ZmianaHasla As Boolean
Public Function GetCLogowanie() As CLogowanie
Set GetCLogowanie = New CLogowanie
End Function
5.
6.
7.
Ewentualnie można zmienić nazwę tego modułu na GetClasses;
Zmieniamy nazwę projektu VBA na np. ClassProviderCLogowanie;
Zapisujemy utworzonych skoroszyt pod nazwą projektu VBA z obsługą
makropoleceń (rozszerzenie .xlsm w wersjach Excela nowyszych niż
2003).
2.11.3.2. Utworzenie skoroszytu testowego
Otwieramy nowy skoroszyt, zmieniamy nazwę jednego arkusza na Pracownicy
i tworzymy w nim pokazną niżej tabelę. Obszar A2:D5 przekażemy do metody instancji
klasy CLogowanie, zostanie wykorzystany do zbudowania źródła danych dla pola kombo
cboLogin instancji formularza frmLogowanie.
Zmieniamy nazwę kolejnego arkusza na Logowanie i tworzymy w nim pokazną
niżej tabelę oraz definujemy pola wykorzystywane w operacjach filtru zaawansowanego.
125
Otwieramy edytor VBA i z menu Tools dodajemy referencję do skoroszytu
ClassProviderCLogowanie.xlsm.
Pomyslne dodanie referencji potwierdzone jest dodaniem do właściwości projektu
obiektu References zawierającego pokazany niżej wpis.
Po utworzeniu referencji będziemy mogli się odwoływać do klasy CLogowanie
w standardowy sposób (czyli znajdziemy klasę i jej metody w okienku systemu
inteligentych podpowiedzi edytora VBA).
W edytorze VBA wstawiamy moduł standardowy i tworzmy w nim pokazaną niżej
procedurę.
126
Public Sub TestCLogowanie()
' deklaracja instancji publicznej klasy CLogowanie
Dim w As ClassProviderCLogowanie.CLogowanie
' tworzymy obiekt w z instancji publicznej klasy CLogowanie
Set w = ClassProviderCLogowanie.GetCLogowanie
' do metody NowyObiekLogowanie przekazujemy argumenty:
' minimalna długość hasła (np. 6)
' maksymalna długość hasła (np. 10)
' hasło domyślne (np. „123456”)
' czas ważności hasła (np. 20)
' historia haseł - liczba haseł unikalnych (np. 10)
' liczba prób logowania np. 3)
' hasło zabezpieczające arkusz Logowanie (np. „jg”)
' obszar danych z których będzie zbudowane źródło cboLogin
w.NowyObiektLogowane 6, 10, "123456", 20, 10, 3, "jg", _
Worksheets("Pracownicy").Range("a2:d5")
' dla testów analiza informacji odebranych z metody
Select Case w.IdKtoZalogowany
Case -3
t = "Użytkownik " & w.DajDaneUsera & _
" nie ma zdefiniowanego hasła"
Case -2
t = "Operacja logowania anulowana przez użytkownika " _
& w.DajDaneUsera
Case -1
t = "Logowanie użytkownika " & w.DajDaneUsera & _
" nieudane, wyczerpany limit prób"
Case 0
t = "Zalogowany administrator aplikacji"
If w.DajZmianaHasla Then t = t & "." & vbNewLine & _
"Po zmianie hasła."
Case Else
t = "Zalogowany użytkownik: " & w.DajDaneUsera
If w.DajZmianaHasla Then t = t & "." & vbNewLine & _
"Po zmianie hasła."
End Select
MsgBox t, vbExclamation, "Testowanie klasy CLogowanie"
End Sub
Możemy także zmienić nazwę standardowego modułu zawierającego publiczną
procedurę TestCLogowanie na np. TestKlasyPublicznejCLogowanie.
W tym samym module musimy jeszcze zadeklarować trzy zmienne publiczne,
wykorzystamy je do wymiany informacji między klasą CLogowanie a formularzem
frmLogowanie.
Public DaneUsera As String, IdUsera As Integer, _
ZmianaHasla As Boolean
127
Poniżej kilka testów sprawdzających działanie klasy CLogowanie.
Wywołując publiczną procedurę TestCLogowanie możemy
prześledzić pracę klasy CLogowanie
w różnych sytuacjach. Przykładowo
zalogowanie
administratora
z
poprawnym hasłem „admin1” skutkuje
wyświetleniem komunikatu potwierdzającego zalogowanie administratora.
Podanie zbyt krótkiego (lub za
długiego) hasła powoduje wyświetlenie
w etykiecie błędu instancji formularza
odpowiedniego
komunikatu
z
jednoczesnym zablokowaniem możliwości opuszczenia pola Hasło.
Wprowadzenie
poprawnego
hasła
użytkownika
zakończone
klawiszem
Enter
powoduje
uaktywnienie pola wyboru Zmiana
hasła, a jego zaznaczenie powoduje
zmianę
wyglądu
formularza
udostępniając dwa dodatkowe pola
tekstowe: Nowe hasło oraz Powtórz
hasło.
Podanie niezgodnych haseł w
polach Nowe hasło i Powtórz hasło
skutkuje, po kliku przycisku Zaloguj,
wyświetleniem
odpowiedniego
komunikatu w etykiecie błędu z
jednoczesnym
zablokowaniem
możliwości opuszczenia pola Powtórz
hasło.
Podanie takie samego hasła w
polach Nowe hasło i Powtórz hasło (w
tym teście było to „admin2”) skutkuje
zapisaniem nowego hasła w arkuszu
Logowanie.
128
W kolejnym teście spróbujemy
zalogować użytkownika „Kacprzak”,
dla którego w arkuszu Logowanie
nie zostało utworzone hasło domyślne.
Po wyborze tego użytkownia w polu
Login zostaje wyświetlony pokazany
obok komunikat.
Przetestujemy teraz zachowanie
klasy CLogowanie w sytuacji, gdy
podane hasło straciło swoją ważność.
Taka sytuacja będzie miała miejsce
przy
logowaniu
użytkonwika
„Burzyńskiej Hanny” z hasłem
„hanna23”. Akceptacja wprowadzonego hasła wymusi jego zmianę z
uwagi na przeterminowanie.
Po podaniu nowego hasła (np.
„hanna123” i jego powtórzeniu klik
przycisku Zaloguj kończy proces
logowania, co potwierdza pokazany
niżej komunikat.
W arkuszu Logowanie mamy
nowy wpis hasła dla identyfikatora 5
Jeżeli w trakcie procesu
logowania użytkownik wykona klik
przycisku Anuluj, to zobaczy pokazany
obok komunikat. Jeżeli był to
przypadkowy klik, to wybór odpowiedzi Nie pozwala na kontynuację
procesu logowania. Wybór opcji Tak
kończy proces logowania.
129
Pokazany obok komunikat
potwierdza
przerwanie
procedury
logowania przez danego użytkownika.
Ewentualne dalsze testy funkcjonowania klasy CLogowanie pozostawiamy
zainteresowanym Czytelnikom.