等待通过事件事件在标准模块中起作用,但在用户窗体中不起作用

时间:2018-08-27 21:06:00

标签: excel-vba

背景/问题:我创建了一个用户窗体,以便在特定单元格中输入低于$ 250的值时,该用户窗体提示用户输入密码。然后由主管提供密码以允许该值。问题在于用户输入的值将是一个猜测。这些用户将值弄乱,直到输入的值使他们得到所需的数字(单独的公式取决于250美元的低额金额)。因此,在用户尝试输入第一个号码之后,他们可能需要输入最多10次的密码。当前,每次更改值时,用户表单都将要求主管输入密码。我希望编辑我的代码,以便A)如果您将在一定时间范围内将密码“保留”,或者B)允许有机会在不使用用户名的情况下输入低于设定值250美元的金额每次发射。我最初尝试了该号码尝试,但未成功。老实说,最好选择时间,以便希望有人可以提供帮助。我尝试了多种等待方式(application.wait),使用lib kernel32进行睡眠以及一些其他的do事件。从我收集到的信息来看,做事件可能是我最好的选择,因为我需要做的是允许用户更改值,而没有PC阻止用户工作(尽管我认为用户仍然可以更改所述值)执行其他操作。)

我尝试将不同的不同wait / sleep / loop子对象放入标准模块中并调用它们,但是我也尝试将它们直接放入forms模块中,但两种方法均无效。如果该子程序位于标准模块中,则Excel不允许用户执行任何操作(它充当application.wait),但是如果我在表单模块中执行该操作,则它允许用户选择单元格,但直到循环时才对其进行编辑/ userform子项已完成。在这方面都没有错误,只是不允许用户以低于250美元的价格进行多次尝试。最后一个花絮……我可以在标准模块上运行Wait子级,并在继续触发时在工作簿中工作;只是无法使其与用户表单一起使用。谢谢!

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

1 个答案:

答案 0 :(得分:0)

好吧,你的马,

我有一个可行的解决方案,但并不是您希望的那样,我会告诉您为什么它不应该像您希望的那样工作。

首先解决:

将此代码放在“ ThisWorkbook”模块中:

Option Explicit
Public Endt

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

此处的旁注:您可能要使用另一个事件,然后是Workbook_SheetChange,但这在这里为我完成了工作。缺点是它还会触发其他所有更改工作表的事件。

然后将此代码放入模块1:

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

最后在用户表单中:

Private Sub CommandButton1_Click()
Me.Hide
End Sub

现在是解释,以及为什么不应该将所有内容放入用户表单。

公共变量Endt在此工作簿中,并将保存在其中(除非有错误!)。一旦事件被触发(在我们的案例中为workbook_SheetChange),该模块将被调用。这是整个逻辑,这很好。因为您不想制作“ smartUI”,所以用户窗体中的逻辑问题在于几乎不可能维护和调整更改。我很难相信我。.我不是这个主题的专家,但是请阅读以下链接

  1. Smart UI
  2. Model View Presenter替代智能UI

然后,Sub TimeBeforeReentry会检查时间并相应显示用户表单。如果输入密码,则设置Endt,并且如果在Endt中触发了下一个事件,则不必重新输入密码。否则,将需要重新输入密码。 该用户窗体只是一个数据交换设备,它与逻辑无关,它只是保存数据并传递数据。这就是UI的目的!

我希望它对项目有帮助!