Zdarzyło Ci się zapomnieć hasła do projektu VBA w arkuszu Excel lub otrzymać plik, którego kod VBA jest zabezpieczony hasłem? Taka sytuacja bywa frustrująca – zablokowany VBAProject uniemożliwia przeglądanie i edycję makr. Na szczęście istnieje metoda, która pozwala odblokować projekt VBA nawet bez znajomości hasła. W tym artykule przedstawiamy krok po kroku, jak za pomocą specjalnego kodu VBA uzyskać dostęp do zablokowanego projektu.
Uwaga: Opisana metoda służy do odzyskiwania własnych zapomnianych haseł lub odblokowania projektów za zgodą właściciela pliku. Nie należy jej wykorzystywać do nieautoryzowanego dostępu.
Instrukcja krok po kroku
Krok 1: Otwórz chroniony plik Excel. Uruchom skoroszyt Excela, który zawiera projekt VBA zabezpieczony hasłem (pliku, który chcesz odblokować). Upewnij się, że ten plik pozostaje otwarty podczas całego procesu (nie zamykaj go).
Krok 2: Utwórz nowy pusty skoroszyt i dodaj moduł z kodem. Otwórz nowy, pusty plik Excel (skoroszyt). Przejdź do edytora Visual Basic dla Aplikacji – możesz to zrobić naciskając Alt + F11 lub wybierając kartę Deweloper na wstążce, a następnie przycisk Visual Basic. W Edytorze VBA upewnij się, że aktywny jest projekt nowo utworzonego skoroszytu (powinien nazywać się np. VBAProject (Workbook.xlsx)). Dodaj nowy moduł (Menu Wstaw -> Module). Do tego modułu (automatycznie nazwanego Module1) wklej poniższy kod VBA:
' Source - https://stackoverflow.com/a
' Posted by VePe, modified by community. See post 'Timeline' for change history
' Retrieved 2025-11-20, License - CC BY-SA 4.0
Option Explicit
Private Const PAGE_EXECUTE_READWRITE = &H40
Private Declare PtrSafe Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" _
(Destination As LongPtr, Source As LongPtr, ByVal Length As LongPtr)
Private Declare PtrSafe Function VirtualProtect Lib "kernel32" (lpAddress As LongPtr, _
ByVal dwSize As LongPtr, ByVal flNewProtect As LongPtr, lpflOldProtect As LongPtr) As LongPtr
Private Declare PtrSafe Function GetModuleHandleA Lib "kernel32" (ByVal lpModuleName As String) As LongPtr
Private Declare PtrSafe Function GetProcAddress Lib "kernel32" (ByVal hModule As LongPtr, _
ByVal lpProcName As String) As LongPtr
Private Declare PtrSafe Function DialogBoxParam Lib "user32" Alias "DialogBoxParamA" (ByVal hInstance As LongPtr, _
ByVal pTemplateName As LongPtr, ByVal hWndParent As LongPtr, _
ByVal lpDialogFunc As LongPtr, ByVal dwInitParam As LongPtr) As Integer
Dim HookBytes(0 To 11) As Byte
Dim OriginBytes(0 To 11) As Byte
Dim pFunc As LongPtr
Dim Flag As Boolean
Private Function GetPtr(ByVal Value As LongPtr) As LongPtr
GetPtr = Value
End Function
Public Sub RecoverBytes()
If Flag Then MoveMemory ByVal pFunc, ByVal VarPtr(OriginBytes(0)), 12
End Sub
Public Function Hook() As Boolean
Dim TmpBytes(0 To 11) As Byte
Dim p As LongPtr, osi As Byte
Dim OriginProtect As LongPtr
Hook = False
#If Win64 Then
osi = 1
#Else
osi = 0
#End If
pFunc = GetProcAddress(GetModuleHandleA("user32.dll"), "DialogBoxParamA")
If VirtualProtect(ByVal pFunc, 12, PAGE_EXECUTE_READWRITE, OriginProtect) <> 0 Then
MoveMemory ByVal VarPtr(TmpBytes(0)), ByVal pFunc, osi + 1
If TmpBytes(osi) <> &HB8 Then
MoveMemory ByVal VarPtr(OriginBytes(0)), ByVal pFunc, 12
p = GetPtr(AddressOf MyDialogBoxParam)
If osi Then HookBytes(0) = &H48
HookBytes(osi) = &HB8
osi = osi + 1
MoveMemory ByVal VarPtr(HookBytes(osi)), ByVal VarPtr(p), 4 * osi
HookBytes(osi + 4 * osi) = &HFF
HookBytes(osi + 4 * osi + 1) = &HE0
MoveMemory ByVal pFunc, ByVal VarPtr(HookBytes(0)), 12
Flag = True
Hook = True
End If
End If
End Function
Private Function MyDialogBoxParam(ByVal hInstance As LongPtr, _
ByVal pTemplateName As LongPtr, ByVal hWndParent As LongPtr, _
ByVal lpDialogFunc As LongPtr, ByVal dwInitParam As LongPtr) As Integer
If pTemplateName = 4070 Then
MyDialogBoxParam = 1
Else
RecoverBytes
MyDialogBoxParam = DialogBoxParam(hInstance, pTemplateName, _
hWndParent, lpDialogFunc, dwInitParam)
Hook
End If
End Function
Powyższy kod jest sercem całej metody – odpowiada za przechwycenie okna dialogowego z prośbą o hasło i automatyczne jego zamknięcie/obejście. Został on pierwotnie opublikowany przez użytkownika VePe na forum Stack Overflow na licencji CC BY-SA 4.0. Działa zarówno w Excelu 32-bit, jak i 64-bit (makro uwzględnia oba przypadki w preprocesorze #If Win64).
Krok 3: Dodaj drugi moduł i kod uruchamiający odblokowanie. W tym samym skoroszycie (pustym, pomocniczym) dodaj kolejny moduł (Module2). W Module2 wklej poniższy krótki kod:
' Source - https://stackoverflow.com/a
' Posted by VePe, modified by community. See post 'Timeline' for change history
' Retrieved 2025-11-20, License - CC BY-SA 4.0
Sub unprotected()
If Hook Then
MsgBox "VBA Project is unprotected!", vbInformation, "*****"
End If
End Sub
Kod ten wywołuje wcześniej zdefiniowaną funkcję Hook() i jeśli wszystko się powiedzie – wyświetla komunikat „VBA Project is unprotected!” (co oznacza, że projekt VBA został odblokowany).
Krok 4: Uruchom makro odblokowujące. Upewnij się, że masz otwarte oba pliki Excel: (1) oryginalny zablokowany skoroszyt oraz (2) nowy skoroszyt z wklejonymi powyżej modułami. Teraz uruchom makro unprotected z Module2. Możesz to zrobić np. poprzez umieszczenie kursora w treści makra i naciśnięcie klawisza F5, kliknięcie przycisku Uruchom (▶) w edytorze VBA lub wybranie makra z menu Makra. Po uruchomieniu skryptu powinna pojawić się informacja w okienku dialogowym: „VBA Project is unprotected!”. Oznacza to, że zabezpieczony projekt VBA został pomyślnie odblokowany.
Krok 5: Sprawdź efekt i usuń hasło. Przełącz się z powrotem do Edytora VBA i rozwiń drzewo projektu VBA oryginalnego skoroszytu. Projekt powinien być już widoczny – hasło nie jest wymagane do podglądu modułów ani formularzy. Teraz zaleca się usunąć lub zmienić hasło na nowe, aby plik nie pozostał w stanie zabezpieczonym nieznanym hasłem. W tym celu w Edytorze VBA wybierz menu Tools (Narzędzia) → VBAProject Properties (Właściwości projektu VBA) → zakładka Protection (Ochrona). Odznacz opcję „Lock project for viewing” (jeśli jest zaznaczona) oraz usuń stare hasło wpisując w polu hasła cokolwiek i usuwając to (lub wpisz nowe znane hasło i potwierdź). Zatwierdź i zapisz plik. Dzięki temu przy ponownym otwarciu pliku projekt VBA będzie już dostępny normalnie (stare nieznane hasło zostanie zastąpione).
Podsumowanie i uwagi
Powyższa metoda wykorzystuje sprytny trik z użyciem API systemowych Windows do chwilowego obejścia okna dialogowego proszącego o hasło do projektu VBA. W efekcie Excel „myśli”, że poprawne hasło zostało podane, dzięki czemu projekt zostaje odblokowany. Ten sposób okazał się skuteczny w wielu wersjach Excela (potwierdzono działanie m.in. w Excel 2016 (32-bit) oraz w najnowszych kompilacjach Office 365 (64-bit)). Należy jednak podkreślić, że metoda nie usuwa oryginalnego hasła z pliku – odbezpiecza projekt tylko w bieżącej sesji programu. Aby trwale zdjąć hasło, musimy je ręcznie usunąć lub nadpisać (jak opisano w kroku 5).
Jeżeli z jakiegoś powodu opisany makro-sposób nie zadziała (niektórzy użytkownicy zgłaszali rzadkie przypadki niepowodzenia), istnieje alternatywna metoda polegająca na edycji pliku w edytorze HEX Metoda hex polega na zmianie ciągu odpowiadającego za hasło w pliku binarnym projektu VBA – jest to bardziej skomplikowane i czasochłonne, ale może służyć jako ostateczność. W praktyce jednak przedstawiony wyżej trik z makrem zwykle jest wystarczający i znacznie prostszy (omija konieczność ręcznego grzebania w pliku).
Mamy nadzieję, że ten poradnik okazał się pomocny. Dzięki niemu odblokujesz swój projekt VBA w Excelu i odzyskasz dostęp do kodu nawet bez znajomości oryginalnego hasła. Pamiętaj o ostrożności przy korzystaniu z takich narzędzi i zabezpieczaj swoje projekty hasłami, o których nie zapomnisz 😉. Powodzenia!