I have a couple of userforms for my excel spreadsheet and I need to setup an admin panel for certain tasks that I don't want most people to access.
The problem I have is that I can setup a simple password protection form however the text is always visible. I want to try and encrypt it so if anyone is looking over my should or one of the other admins shoulders then they cannot see the password.
Is there anyway to have the text appear as **** or something similar?
Thanks
Al
Private Sub CommandButton1_Click()
Dim MyValue As Variant
MyValue = InputBox("Enter Password")
If MyValue = "lemonade" Then 'lemonade being the password
Application.Visible = True
Else
MsgBox ("Password Incorrect")
End If
End Sub
Edit - I have amended it to follow your suggestion as I had it to bring up an input box instead of creating my own userform.
If Pword2.Value = "lemonade" Then
AddPick1.Hide
Report1.Hide
Unload Me
Admin1.Show vbModal
Else
MsgBox ("Password Incorrect")
End If
When the password is incorrect it gives the incorrect password error however when it is correct it gives me the following error (Must close of hide topmost modal form first) However I have it to set to hide all other forms before loading the Admin1 form?
In the TextBox properties there is a property called PasswordChar. Enter your preferred 'hidden' character in here.
You can also add a button to your form to reveal the password if you wish using the Mouse-Up and Mouse
_Down events. MouseDown would look like the following on a textbox called TextBox1 and using a button called CommandButton1:
Private Sub CommandButton1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
TextBox1.PasswordChar = vbNullChar
End Sub
I'll leave you to code the Mouse_Up event.
This link will give you the usage but you will find plenty of examples with a Google search.
Related
I have a message box that asks for user input, Yes or No, but need to give the user a chance to cross check another tab if their guess is correct, e.g.
answer = MsgBox("Confirm Deletion?", vbYesNo + vbQuestion)
If answer = vbNo Then
Exit Sub
End If
The messagebox blocks everything and doesnt allow the user to change tabs or click anything else. I also tried creating a UserForm instead and setting its ShowModal to False. This allows the user to interact with the spreadsheet while the form is displayed, but then it also allows code execution to continue while it is still displayed/without waiting for an answer, e.g in code below the message box is shown immediately after the UserForm is shown.
UserForm.Show
MsgBox("Step 2")
I need the messagebox to only show when the userform is exited. How can I achieve this?
Finally found a solution. Once the Userform is displayed you can enable window interaction again using the windows api. The form's ShowModal property should initially be True, which is the default anyways.
Then in the Userform code window you include this code at the top that gets triggered when the form shows.
Private Declare PtrSafe Function EnableWindow Lib "user32.dll" (ByVal Hwnd As Long, ByVal fEnable As Long) As Long
Private Sub UserForm_Activate()
EnableWindow Application.Hwnd, 1
End Sub
On running the code below, this allows the user to still click and move around the spreadsheet while the form is shown, but wont allow any editing of cells, which is perfectly ideal. Code execution only continues to the message box after the form is closed
UserForm.Show
MsgBox("Step 2")
Not an exact solution, but you can replace the Msgbox with an Inputbox and sort of stop code from further execution until an input is received from user. The below code deletes the sheet, of which the user has selected a cell.
Sub AlowDeletion()
On Error Resume Next
Set rng = Application.InputBox( _
Title:="Range Selector", _
Prompt:="Select any cell in the sheet you want to delete", _
Type:=8)
Application.DisplayAlerts = False
ActiveWorkbook.Sheets(rng.Parent.Name).Delete
Application.DisplayAlerts = True
On Error GoTo 0
End Sub
My intention is to open "birthdate" userform when textbox "bdayBox" is entered. And also want to be able to open "birthdate" userform again, if it was closed, by clicking with mouse inside the box, but only if textbox "bdayBox" is currently active.
My problem is, that if the textbox in not active and i click it with mouse, _Enter is executed before _MouseDown. This opens "birthdate" userform twice.
Is there a way to execute _MouseDown before _Enter or any other way to do, what i want without double openings?
*EDIT Before the user even gets to the put in birth date, they select how many people should be added. The form 'birthdate' should only show up, if there are more than 1 person to be added and it should appear automatically, when user is entering the 'bdayBox' textbox. If there is only 1 person, no extra form will appear and user enters birth date in the textbox itself. I want to take the decision from the user away to open the 'birthdate' form or not.
Current code
Public bdayBoxAct As Boolean
Public Sub bdayBox_Enter()
birthdate.Show
bdayBoxAct = True
End Sub
Public Sub bdayBox_Exit(ByVal Cancel As MSForms.ReturnBoolean)
bdayBoxAct = False
End Sub
Private Sub bdayBox_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
If bdayBoxAct = True Then
birthdate.Show
End If
End Sub
Public Sub UserForm_Initialize()
bdayBoxAct = False
End Sub
I feel this approach is not intuitive for the user, and suffers from the symptoms you are experiencing. My suggestion is to place a button next to the bdayBox textbox, with an appropriate caption telling the user what the button will do, which they can press whenever they need to form to appear. The button replaces the MouseDown logic. Your code then becomes:
Option Explicit
Private Sub bdayBox_Enter()
birthdate.Show
End Sub
Private Sub ShowBirthdate_Click()
birthdate.Show
End Sub
I want to prevent the user from closing the form and editing the spreadsheet if they don't know the password. I can get the Userform to stay open but I cannot figure out how to initialize the form so all of the command buttons still function.
I have tried using an if statement as described below. The userform stays open but isn't initialized so the user is unable to enter a password or run the userform at all.
Private Sub UserForm_Terminate()
Password = InputBox("Enter Password")
If Password = "syntax" Then
UserForm1.Hide
ElseIf Password <> "syntax" Then
UserForm1.Show
End If
End
End Sub
There aren't any error messages, but if the VBA editor window isn't open the user has to close Excel completely. Any advice on what to try next is appreciated. Thanks in advance
You can use UserForm_QueryClose to intercept all 'close' actions on a userform. This code would go in the userform itself.
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
Dim password As String
password = InputBox("Enter Password")
If password = "syntax" Then
Cancel = False 'If password is correct, allow close event to proceed
ElseIf password <> "syntax" Then
Cancel = True 'If password is incorrect, cancel the close event
End If
End Sub
Like K.Dᴀᴠɪs pointed out, this still won't prevent anyone from pausing the code execution and manually closing the form (Excel just doesn't provide that level of security).
Problem: I am building a Userform that has a 'Submit' and 'Cancel' button. I want the entire form to clear any entered data and close the form if the user hits the 'Cancel' button but I also am trying to build in the same functionality if the user hits the red 'X' in the top right corner. I'm unclear where I need to unload the form. I currently have it placed within the btnCancel_Click() method and I'm able to launch the form, enter some data and hit Cancel and it will close the form down.
But when I try to re-launch the form a 2nd time I get an error (I attached a picture of that message) that says
"Run-Time error '-2177418105 (80010007): Automation Error - The Callee (server [not server application]) is not available and disappeared; all connections are invalid. The call may have executed.
If I remove Unload Me from btnCancel_Click() then the form can close and re-open just fine, but any data I entered the first time will still be on the form and isn't cleared properly. I'm wondering if this is an Unload Me error or do I need to reset all form controls when I initialize the form?
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
' how was the form closed?
' vbFormControlMenu = X in corner of title bar
If CloseMode = vbFormControlMenu Then
' cancel normal X button behavior
Cancel = True
' run code for click of Cancel button
btnCancel_Click
End If
End Sub
'******************************************************************
Private Sub btnCancel_Click()
mbCancel = True
Me.Hide
Unload Me
End Sub
'*********************************************************************
Private Sub UserForm_Initialize()
'Populate values for 2 combo boxes
lastEmp = Sheets("Form_Ref").Cells(Rows.Count, 1).End(xlUp).Row
Me.cmbBoxEmpName.List = Sheets("Form_Ref").Range("A2:A" & lastEmp).Value
lastBld = Sheets("Form_Ref").Cells(Rows.Count, 2).End(xlUp).Row
Me.cmbBoxBuildingName.List = Sheets("Form_Ref").Range("B2:B" & lastBld).Value
End Sub
'******************************************************************
Public form As New CheckOutForm
Sub testFormOptions()
'Button pressed within Excel will start program and show the userform
form.Show
End Sub
This is the easiest quick and dirty solution:
Delete Public form As New CheckOutForm from the code. Then add it in the testFormOptions():
Sub testFormOptions()
Dim form As New CheckOutForm
form.Show
End Sub
Some not-that-good VBA books/tutorials would even go a bit like this, but this is brutal:
Sub testFormOptions()
CheckOutForm.Show
End Sub
Anyway, now the problem with the predefined values in the form is solved.
For the clean and not-so-easy solution, consider writing a MVC framework around the form:
https://codereview.stackexchange.com/questions/154401/handling-dialog-closure-in-a-vba-user-form
this blogpost (disclaimer - mine!), which pretty much says what the above link proposes, but it does not have the errors from the question.
the old StackOverflow tutorial for UserForms
If you execute Unload, you destroy the form object. With other words, your (global) variable form gets invalid and if you issue a new form.show, you get the runtime error.
When, on the other hand, you just unhide the form, the form-object stays valid (it's just currently not visible) and all controls keep their value.
Either you do some housekeeping by resetting all controls when a form is displayed (use the UserForm_Activate-event), or you have to create a new form-object every time you want to display it (I would strongly advice not to use the name form as variable name to avoid confusion).
Sub testFormOptions()
dim myForm as CheckOutForm
myForm.Show
End Sub
I am writing a script for a UserForm through which users can register to gain access to a Database. The UserForm has three fields, Username, Password and Confirm Password.
I have made it so that, after the user chooses a username, the script runs a VLookUp through the existing usernames to check if the username chosen already exists. If so, a MsgBox pops up, advising the selection of another username. In this case, all three fields of the UserForm are cleared. I would like to make the cursor be positioned in the Username field so that the user can straight away fill in a different username. However, after all fields are cleared, the password filed is the one selected instead. How can I solve this? Thank you for your help.
This is the code I have written:
Private Sub usernameinput_AfterUpdate()
Dim username As String
username = usernameinput.Text
Dim temp As String
On Error Resume Next
temp = WorksheetFunction.VLookup(Me.usernameinput.Value, Range("Usernames"), 1, 0)
If username = temp Then
MsgBox ("The username chosen already exists. Please chose a different username."), vbOKOnly + vbInformation, "Existing Username"
Err.Clear
temp = ""
Me.usernameinput.Value = ""
Me.passwordinput.Value = ""
Me.passwordconfirm.Value = ""
Me.usernameinput.SetFocus
On Error GoTo 0
End If
End Sub
you could act like follows:
in your UserForm code pane:
declare a userform scoped variable
Dim reset As Boolean
insert this Sub
Private Sub HandleReset()
If reset Then
Me.usernameinput.SetFocus
reset = False
End If
End Sub
add all other UserForm controls Enter event handler to call HandleReset() like follows:
Private Sub passwordconfirm_Enter()
HandleReset
End Sub
Private Sub passwordinput_Enter()
HandleReset
End Sub