W Excelu często korzystamy z tzw. danych wrażliwych. Mogą to być ceny produktów, marże sprzedażowe, dane osobowe pracowników lub inne poufne informacje. Ochrona danych ma na celu zablokowanie dostępu do tych wrażliwych informacji osobom niepowołanym. W tym artykule pokażę jak stworzyć arkusz na hasło.
Budowa pliku
Plik składa się z dwóch arkuszy: Instrukcja i Ceny. Domyślnie aktywny jest pierwszy z nich, drugi zaś aktywuje się po wpisaniu prawidłowego hasła w wyskakującym okienku.
Założenie jest takie, że nie chcemy używać do tego celu arkusza głęboko ukrytego. Arkusz z cenami będzie często używany przez niektóre osoby, więc chcemy, aby pozostał widoczny. Z tego też względu ochrona danych nie będzie kuloodporna, natomiast będzie świetną bazą do stworzenia takiego narzędzia.
Idea działania formularza
Naszym celem jest stworzenie bardzo prostego, wręcz minimalistycznego formularza.
Najważniejszą kontrolką będzie pole tekstowe, do którego będziemy wpisywać hasło. Oprócz Textboxa, na formularzu powinny się znaleźć także dwa przyciski typu CommandButton – Anuluj i OK.
Ale chcemy zrobić jeszcze jedną rzecz… Chcemy pozwolić użytkownikowi na zatwierdzenie hasła klawiszem ENTER, bez konieczności klikania w przycisk OK na formularzu.
Budowa formularza
Formularz nazwiemy sobie UHaslo. W jego skład wejdą następujące kontrolki.
- txtHaslo – tutaj będziemy wpisywać hasło
- lblHaslo – etykieta ze słowem Hasło
- cmdOK – zatwierdzenie hasła
- cmdAnuluj – ukrycie formularza
Kod formularza
Zmienne prywatne i właściwości publiczne
1 2 3 4 5 6 7 8 9 |
Private Const ms_MODUL As String = "UHaslo" Option Explicit Private msHaslo As String Private mbOK As Boolean Property Get Haslo() As String: Haslo = msHaslo: End Property Property Get OK() As String: OK = mbOK: End Property |
Na samej górze umieszczamy zmienne prywatne, których zadaniem jest przechwycenie wpisanego hasła i informacji czy użytkownik kliknął w przycisk OK.
Na bazie tych zmiennych prywatnych tworzymy właściwości globalne.
Obsługa przycisków OK i Anuluj
1 2 3 4 5 6 7 8 9 10 11 |
Private Sub cmdOK_Click() mbOK = True Me.Hide End Sub Private Sub cmdAnuluj_Click() mbOK = False Me.Hide End Sub |
Przyciski ustawiają wartość zmiennej prywatnej mbOK. Jeśli użytkownik kliknie cmdOK, wówczas będzie to wartość TRUE. Jeśli kliknie cmdAnuluj będzie to wartość FALSE.
Dodatkowo, kliknięcie w jeden z przycisków ukrywa formularz.
Obsługa pola tekstowego
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
Private Sub txtHaslo_Exit(ByVal Cancel As MSForms.ReturnBoolean) msHaslo = Me.txtHaslo.Text End Sub ' Kliknięcie ENTER na klawiaturze Private Sub txtHaslo_Keydown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer) If KeyCode = 13 Then msHaslo = Me.txtHaslo.Text mbOK = True Me.Hide End If End Sub |
W tym miejscu sprawdzamy dwa istotne zdarzenia.
Zdarzenie Exit
Wyzwalane jest w momencie wyjścia z pola tekstowego txtHaslo i aktywacji innej kontrolki. W tym momencie do zmiennej prywatnej msHaslo powinno zostać przechwycone wpisane hasło.
Zdarzenie KeyDown
Wyzwalane jest w momencie wciśnięcia dowolnego klawisza na klawiaturze. Za pomocą parametru KeyCode sprawdzamy czy użytkownik kliknął przycisk ENTER (kod 13).
Jeżeli tak było wówczas:
- Przechwytujemy do zmiennej msHaslo wpisane hasło. Działa to więc tak samo jak w zdarzeniu txtHaslo_Exit.
- Przypisujemy zmiennej prywatnej mbOK wartość TRUE. Czyli postępujemy tak samo jak w przypadku kliknięcia w przycisk cmdOK.
- Ukrywamy formularz.
Ukrycie formularza
1 2 3 4 5 6 7 8 |
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer) If CloseMode = vbFormControlMenu Then Cancel = True Me.Hide End If End Sub |
Obsługujemy zdarzenie zamknięcia formularza (kliknięcia w krzyżyk). Nie chcemy formularza zamykać, tylko go ukryć, tak aby nie tracić wprowadzonych do niego informacji.
Kod arkusza Ceny
Drugi kod znajduje się w module arkusza Ceny i wywoływany jest automatycznie przy próbie jego aktywacji.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
Private Const ms_MODUL As String = "wksCeny" Option Explicit Private Sub Worksheet_Activate() Dim frmHaslo As UHaslo 'Egzemplarz formularza Dim sHaslo As String 'Wpisane hasło Dim bCzyOk As Boolean 'Czy kliknął OK 'Aktywuj inny arkusz 1 wksInstrukcja.Select 'Utwórz kopię obiektu UHaslo 2 Set frmHaslo = New UHaslo 'Wyświetl w trybie modalnym 3 frmHaslo.Show vbModal 'Zaczytaj hasło i czyOK? 4 bCzyOk = frmHaslo.OK 5 sHaslo = frmHaslo.Haslo 'Wyloguj formularz 6 Unload frmHaslo 'Pokaż ceny jeśli hasło jest prawidłowe 'i jeśli user kliknął OK lub ENTER 7 If bCzyOk Then 8 If sHaslo = "Tajne" Then 9 wksCeny.UsedRange.EntireColumn.Hidden = False 10 Application.EnableEvents = False 11 wksCeny.Select 12 Application.EnableEvents = True 13 End If 14 End If End Sub Private Sub Worksheet_Deactivate() wksCeny.UsedRange.EntireColumn.Hidden = True End Sub |
Analiza kodu
- Pierwszą rzeczą, którą robię jest aktywacja arkusza z instrukcją, czyli zablokowanie możliwości wejścia do arkusza z cenami.
- Tworzę kopię obiektu UHaslo i wyświetlam formularz w celu wprowadzenia hasła.
- Zaczytuję do zmiennych: wpisane hasło + informację czy użytkownik kliknął OK (lub ENTER na klawiaturze).
- Jeśli hasło się zgadza i zmienna bCzyOk przybiera wartość OK, wówczas zezwalam na aktywację arkusza z cenami.
- Wcześniej jednak musimy wykonać dwie rzeczy. Po pierwsze, odkryć kolumny z cenami produktów. Po drugie, wyłączyć zdarzenia aby uniknąć rekurencji. Polecenie wksCeny.Select wyzwala zdarzenie Activate, więc bez wyłączenia na chwilę zdarzeń, mielibyśmy niekończącą się pętlę.
Jest jeszcze jedna rzecz, którą robimy w momencie deaktywacji arkusza z cenami. A mianowicie, ukrywamy kolumny z cenami produktów. W przeciwnym razie ochrona danych nie zadziała. Dlaczego? O tym, dowiesz się z filmu.
Opcjonalnie możemy dodać linijkę Application.EnableEvents = True w zdarzeniu Workbook_BeforeSave lub Workbook_BeforeClose. Jest to nasze zabezpieczenie na wypadek, gdyby zdarzenia zostały przypadkowo wyłączone w pliku.