Wait через Do Events работает в стандартном модуле, но не в пользовательской форме - PullRequest
0 голосов
/ 28 августа 2018

История вопроса / проблема: я создал пользовательскую форму, чтобы при вводе значения менее 250 долларов в определенную ячейку пользовательская форма запрашивала у пользователя пароль. Пароль затем предоставляется супервизором, чтобы позволить значение. Проблема заключается в том, что введенное пользователем значение будет предположительным. Эти пользователи возятся со значениями до тех пор, пока введенное ими значение не получит нужное им число (отдельная формула, зависящая от низкой суммы в 250 долларов). Поэтому после того, как пользователь попытается набрать свой первый номер, ему, вероятно, потребуется ввести его до 10 раз. В настоящее время пользовательская форма требует, чтобы супервизор вводил пароль каждый раз, когда значение изменяется. Я надеюсь отредактировать свой код так, чтобы либо A) пароль можно было «сохранить», если вы хотите в течение определенного промежутка времени, либо B) предоставили возможность вводить сумму менее 250 долларов США установленное количество раз без пользовательской формы. запускать каждый раз. Первоначально я попытался сделать попытку номера, но безуспешно. Честно говоря, вариант времени был бы лучшим, так что, надеюсь, кто-то может помочь. Я пробовал несколько способов ожидания (application.wait), сна с использованием lib kernel32 и несколько разных событий do. Из того, что я собрал, события do могут быть моим лучшим вариантом, так как мне нужно, чтобы он позволял пользователю изменять значения, а ПК не мешал работе пользователя (измените указанное значение, хотя я полагаю, что пользователь все еще может выполнять другие действия.)

Я пытался поместить разные сабы wait / sleep / loop в стандартный модуль и вызывать их, но я также пытался поместить их непосредственно в модуль формы, но ни один из способов не работает. Если подпрограмма находится в стандартном модуле, Excel не позволяет пользователю что-либо делать (он действует как application.wait), но если я выполняю это в модуле формы, он позволяет пользователю выбирать ячейки, но не редактировать их до цикла / Пользовательская форма завершена. Никаких ошибок в этом нет, просто пользователи не могут делать несколько попыток стоимостью менее 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 голосов
/ 28 августа 2018

Ок, ходи на лошадях,

У меня есть решение, которое работает, но не так, как вам нравится, и я скажу вам, почему оно не должно работать, как вы хотите, чтобы оно работало.

Первое решение:

Поместите этот код в "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 в качестве альтернативы Smart UI

Sub TimeBeforeReentry затем проверяет время и соответственно отображает форму пользователя. Если пароль введен, то Endt установлен, и если следующее событие инициируется в Endt, тогда пароль вводить не нужно. В противном случае пароль понадобится для повторного входа. Пользовательская форма - это просто устройство обмена данными, оно не имеет ничего общего с логикой, оно просто хранит данные и доставляет их. Вот для чего пользовательский интерфейс!

Надеюсь, это поможет удаче в проекте!

...