1

Background/issue: I created a userform so that when a value lower than $250 is entered in a specific cell, the userform prompts the user for a password. The password is then supplied by a supervisor to allow the value. The issue is that the value entered by the user will be a guess. These users mess with values until the value they enter gets them the number they're looking for (separate formula that's dependent upon the low $250 amount). So after the user attempts their first number, they're likely going to need to enter it up to 10ish times. Currently the userform would require the supervisor to enter the password each time the value is changed. I'm hoping to edit my code so that either A) the password can be "retained" if you will for a certain length of time or B) allow the opportunity to enter an amount lower than $250 a set amount of times without the userform launching each time. I tried the number attempt originally and was unsuccessful. Honestly a time option would be best so hopefully someone can help. I've tried multiple ways of waiting (application.wait), sleep using lib kernel32, and a few different do events. From what I've gathered, the do events might be my best option as what I need it to do is allow the user to change values and not have the PC prevent the user from working (change said value though I suppose the user could still perform other actions.)

I've tried putting different the different wait/sleep/loop subs in a standard module and call them but I've also tried putting them directly in the forms module but neither way works. If the sub is in a standard module, Excel doesn't let the user do anything (it acts as application.wait) but if I perform it in the form module, it allows the user to select cells but not edit them until the loop/userform sub is complete. No errors are given in any of this, it just doesn't let users make multiple attempts at the value under $250. One last tidbit...I can run the Wait sub on a standard module and work in the workbook while it continues firing; just can't get it to work with the userform.

Public Sub CommandButton1_Click()
Dim newTime As Date

If tbPassword.Value = "password" Then
    me.hide  'Form would stay up so I thought hiding it would fix issue but didn't
    call wait  'loop to allow an amount of time before PS has to be reentered
Else
    MsgBox "Password is incorrect."
    Sheets("Rate Calculator v8").Range("K19") = ""
    Application.Goto Sheets("Rate Calculator v8").Range("K19")
End If
Unload me
End Sub

Sub Wait()
Start = Timer
    Do While Timer < Start + 60
      DoEvents
    Loop
End Sub
Zoe
  • 27,060
  • 21
  • 118
  • 148
Craig
  • 145
  • 9
  • It seems like you may be going about this backward. I'd just store the last time that a password was validated, then skip the password prompt entirely if the maximum time hadn't elapsed yet. – Comintern Aug 27 '18 at 22:49

1 Answers1

0

I got a solution that works but not as you like it to work and I will tell you why it shouldn't work like you want it to work.

First the solution:

Put this code in "ThisWorkbook"-Module:

Option Explicit
Public Endt

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Call Modul1.TimeBeforeReentry
End Sub

Side note here: You may want to use another event then Workbook_SheetChange but it does the job for me here. The disadvantage is that it also triggers with everything else that changes the a sheet.

Then put this code in a module1:

Sub TimeBeforeReentry()

If ThisWorkbook.Endt > Timer Then
Else
UserForm1.Show
    If UserForm1.Passwordfield.Value = "password" Then
        UserForm1.Passwordfield.Value = ""
        ThisWorkbook.Endt = Timer + 60
    Else
        MsgBox "Password is incorrect."
        Worksheets(1).Range("K19") = ""
        Application.Goto Worksheets(1).Range("K19")
    End If
End If
End Sub

And finally in the userform:

Private Sub CommandButton1_Click()
Me.Hide
End Sub

And now the explanation and why you shouldn't put everything into the userform.

The public variable Endt is in thisworkbook and will be saved there (unless there is an error!). As soon as the event is triggered, in our case workbook_SheetChange, the module will be called. Here is the whole logic and this is good. Because you do not want to make "smartUI" the problem with logic in userforms is that it is nearly impossible to maintain and to adjust to changes. I learned this the hard way believe me.. I am not an expert on this topic but read these links

  1. Smart UI
  2. Model View Presenter as alternative to Smart UI

The Sub TimeBeforeReentry then checks the time and shows the userform accordingly. If the password is entered the Endt is set and if the next event is triggered within Endt then the password does not have to be reentered. Otherwise the password will be needed to reentered. The userform is just a data interchange device it has nothing to do with logic it just holds data and delivers it. That's what UI is for!

Zoe
  • 27,060
  • 21
  • 118
  • 148