Declare global variable for sheet password - vba

I have a larger Excel file with multiple sheets and modules.
In the code for each of these I need to protect or unprotect a password protected sheet temporarily in order to update certain protected parts.
So far I use one of the following lines which works but this means that the password appears multiple times throughout the code.
Is there a way I can declare this password just once like a global variable and then just refer to this variable whenever needed so that it only has to be changed once if there is need for a change ?
Also, would this reduce security on the file ?
Current code:
To protect a sheet:
ActiveSheet.Protect Password:="MyPassword", UserInterfaceOnly:=True
To unprotect a sheet:
ActiveSheet.Unprotect Password:="MyPassword"

In your VB editor, right click on the project, and then Insert > Module
Call it something useful like 'Constants'
Insert the following statement:
Public Const strPwd as String = "MyPassword"
It is optional to type the constant, so the 'as String' part is down to taste. You can use this constant in any place in your project where you would previously have used your literal password string.
Regarding security, the best thing to do would be to make sure you have protected the VB project itself with a strong password. You can explore the options here in VB IDE > Tools > VBAProject Properties > Protection tab.

You can use this code as an example
Option Explicit
Public Const g_strPASSWARD As String = "MyPassword"
' To Protect
Sub ProtectSheet(ByRef shToProtect As Worksheet)
shToProtect.Protect Password:=g_strPASSWARD, UserInterfaceonly:=True
End Sub
'To Protect
Sub UnprotectSheet(ByRef shToUnprotect As Worksheet)
shToUnprotect.Unprotect Password:=g_strPASSWARD
End Sub
' To Use
Sub MyTest()
ProtectSheet ActiveSheet
UnprotectSheet ActiveSheet
End Sub
I hope this helps.

Related

Excel VBA protect returning error

I've seen many posts on here and elsewhere about using the following code in the ThisWorkbook Object in order to protect your workbook but still allow macros to run:
Private Sub Workbook_Open()
ActiveWorkbook.Protect UserInterfaceOnly:=True
End Sub
However, the protect function tooltip that pops up only offers three arguments Protect([password], [structure], [windows]). Therefore, when I open the document I get the following error
"Compile Error: Named argument not found"
in regard to UserInterfaceOnly:=True.
Am I using the wrong protect function, or is there something else I'm missing? I want to allow users to input data into the workbook using forms/macros, but I don't want them to be able to manually change any cells.
It almost seems as if the protect function that I'm running has different arguments than many of the other protect solutions I've found. Could this be a version issue or something else?
The suggestion provided by Tim Williams worked. Protect doesn't work the same way at the workbook level, therefore I needed to write individual code for each sheet I wanted to protect. I used the following code to protect the sheets but allow forms to populate:
Private Sub Workbook_Open()
Worksheets("Sheet1").Protect UserInterfaceOnly:=True
Worksheets("Sheet2").Protect UserInterfaceOnly:=True
Worksheets("Sheet3").Protect UserInterfaceOnly:=True
End Sub

excel created a password to unprotect a sheet without me telling it to

I have a protected sheet with certain cells unlocked for editing. I have button click macros that run various processes that temporarily unprotect the sheet to allow the code to run, then protect it again when done. example:
sub macro1()
activesheet.unprotect
' code here
activesheet.protect allowsorting = true
activesheet.protect allowfilter:= true
end sub
for some reason when I run these macros now, it is asking for a password that I never put in there. the sheet should not be password protected. I ran a password breaker macro and it told me the password is "AAAAAAAABABF"
what would cause this, and how to I remove it from asking for a password?
can't seem to find any results in the forum with this issue.
thanks for your help
You have an error in the code, thus the password protection gets activated on this line activesheet.protect allowsorting = true. To avoid errors like this one, make sure that you always use Option Explicit on the top.
In general, this should be ok:
Sub Macro1()
ActiveSheet.Unprotect
'code
ActiveSheet.Protect AllowSorting:=True
ActiveSheet.Protect AllowFiltering:=True
End Sub
Concerning the AAAAAAAABABF, it is not the password you have set, but its hashed value is the same as the hashed value of your password.
If you want to see yourself, try just this code:
Sub TestMe
ActiveSheet.Unprotect AllowSorting = True
End Sub
It is a bit meaningless, but as far as you have used "AllowSorting = True" as a password, you can use it for the unprotect.

Macros not showing up in the run macro menu

I started learning VBA and I don't understand why some macros copy-pasted from the internet do not show up in the run macro menu (Alt-F8).
Below there are 2 macros, but only the second one is showing. Why? And how do I fix it?
Sub Test1(ByVal Target As Hyperlink)
'...
End Sub
Sub Test2()
'...
End Sub
Macros with arguments are not available in Macros list because they cannot be run alone instead they are called by another macro by passing the required arguments.
If a Sub declaration contains parameters it will not show there.
You cannot call macros that have parameters as you are describing. If you need to have a parameter, you can take it out and then have the user input the value.
Sub Test1()
Dim hyperLink As String
hyperLink = InputBox("Please input hyperlink", "My Parameter")
'...
End Sub
Alternatively, if the hyperlink is in your document, grab the value from your document instead.
Here are my 5 cents - if you give an optional parameter, you will be able to call the sub routine, even if it will not be shown among the ones which you can chose from.
Write aaaaTestMe and press Run.
Public Sub aaaaTestMe(Optional lngA As Long = 8)
Debug.Print lngA
End Sub
You can call an even private macro from any excel object you can assign a macro, calling it this way:
'MyWorkbook'!'MyModule.MyProcedure "MyParameter1"'
(be careful with single quotes: ' around procedure name with parameter)

Excel VBA, Get the value of a private worksheet constant

I want to retrieve the value of a worksheet-code-level private constant via VBA. I'm trying to do something similar to having "tags" on my worksheets that are accessible via VBA. I'd like to use the CodeModule in the VBAProject so that I can have a number of "tags", not just one. I just can't figure out how to grab the constant, even after reviewing much code and forums on-line. Does anyone have any insight on this? I am running Excel 2013 on a Windows 8.1 machine.
Maybe the easiest way to do this is to have a function that can the value of a private constant with a public accessor method. For instance, if you have the following code in your worksheet Sheet1:
Private Const myValue = "the answer is 42"
Public Function getSecret()
getSecret = myValue
End Function
Then you can access it from another module with
Sub test()
Dim sheetName = "Sheet1"
MsgBox "The sheet says that " & Sheets(sheetName).getSecret()
End Sub
You can make this fancier - you could create a collection of tags and index them… but I think that goes beyond the question you had. Note that you have to "fully qualify" the name of the accessor macro when it is in a worksheet; the advantage is that you can use the same function to examine the tag of different worksheets just by changing the sheetName.
I would export the code to a .BAS file. You can then read the material back in as a text file and retrieve the constant

vba private scripts

I know that even private vba scripts can be called by the user, such that making it "private" in fact only hides its name.
However, is there a way to set up a macro so it is only runnable if you are inside that particular VBA project? Not from Excel and not from any VBScript or the likes.
If you want to lock down the code you could
make the code private so the macro names areen't exposed
lock the protect, and then test that the project is actually unlocked before letting the code run
The sample code below checks that the VBA in the host workbook is not protected before running
Does this meet your needs?
Private Sub TestMe()
Dim objVB As Object
Set objVB = ThisWorkbook.VBProject
If objVB.Protection = 0 Then
Call TestSub
Else
MsgBox "Sorry sport - unauthorised", vbCritical
End If
End Sub
Private Sub TestSub()
MsgBox "Project unprotected - i've been run", vbOK
End Sub
Honestly, there is no foolproof way around it. You can have certain checks but that's all you can do.
If you are sure that a user will not have access to VBA Code then what brettdj suggested is the best way to go ahead. Protect your project. One cannot run a macro from Excel or from outside Excel if one doesn't know the macro name ;)
The basic intention of making a macro Private is not to prevent it from running but making it invisible to the user. Mostly, the only macros that needs to be private in Excel are the inbuilt Worksheet or Workbook events or macros referred by other macros which necessarily don't need to be accessed by the user. A user can still access them from outside VBA if he or she wants to.
Having said that, you can restrict (But not STOP - Not referring to disabling your macro security) the macros from running. Pass an authorization FLAG. Only when it receives an "Authorization", will it run.
For Example
Option Explicit
Private Sub Sample(Auth As Boolean)
If Auth = True Then
'~~> Your macro code goes here
End If
End Sub
Now if you want this macro to be called from VBA then you have to call it like this
Sample True
or
Call Sample(True)
This will ensure that the above macro will only run when you allow it to.
Would this method prevent user from running this from VBS?
NO. It won't. However, it won't run till the time the user specifies or gives the "Authorization"
HTH