Excel VBA Textbox_Exit Обработчик событий - PullRequest
0 голосов
/ 23 января 2020

На блокпосту здесь. Простая форма пользователя с использованием трех текстовых полей, одно для идентификатора пользователя, два для ввода серийного номера с помощью ручного сканера. Пользователь загружает файл Excel, загружает userform.show, пользователь вводит идентификатор, затем выполняет простую проверку для проверки номера numberi c, затем фокусируется на первом текстовом поле, пользователь сканирует штрих-код для ввода серийного номера, снова простую проверку, чтобы убедиться, что цифры c и длина то же самое с последним текстовым полем, сканировать серийный номер, проверить, что первая запись в текстовом поле соответствует второй записи в текстовом поле.

Ручной сканер используется для ввода серийного номера, а также возвращает символ «возврат каретки»; например, нажмите кнопку ввода после сканирования серийного номера.

Использование «возврата каретки» для запуска обработчика события textbox_exit. Проблема очень прерывистая, но последовательная. Я загружаю пользовательскую форму, ввод данных, когда запись завершена, данные передаются на рабочий лист объекта. Однако при устранении неполадок я вначале открываю книгу и форму пользователя, создаю несколько записей, сохраняю и закрываю. Все работает хорошо, данные записываются и архивируются. Обычно проблема возникает, когда я загружаю книгу во второй раз, ввожу данные для одной записи, сохраняю и начинаю вторую запись. Как только серийный номер введен в первое текстовое поле, событие выхода никогда не запускается с использованием «возврата каретки». Я могу вручную перенести фокус на другие объекты; например, текстовое поле diff, но общая операция не соответствует ожидаемой.

Я попытался вставить команды application.eventhandler = true, различные обработчики событий, а также многочисленные изменения кода; например, выйти из sub в конце операторов IF, чтобы это сработало.

Я подумал, что хотел бы обратиться к сообществу за комментариями. К вашему сведению, по-прежнему возникают проблемы, если я имитирую ручной сканер, используя клавиши копирования / вставки и ввода.

Пример обработчика события выхода для первого последовательного текстового поля ниже.

Private Sub SerialIn_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    Cancel = False

If Not IsNumeric(SerialIn.Value) Then        'validate serial number is numeric

    'error msg serial number is not numeric
    Msg = "Opps, something went wrong!  Serial number was incorrect." _
        & vbNewLine & vbNewLine & "Rescan module serial number."
        MsgBox Msg, vbCritical, "Warning"           'display msg

    Cancel = True                               'stop user from changing focus

    SerialIn.SelStart = 0                       'highlight user text
    SerialIn.SelLength = Len(SerialIn.Value)    'select user text
    'Image1.Picture = LoadPicture(StopLightRed)  'display red stop light
    Exit Sub
Else
    If Not Len(SerialIn.Value) = 19 Then           'validate serial number length
        'error msg incorrect length
        Msg = "Opps, something went wrong!  Serial number was incorrect." _
            & vbNewLine & vbNewLine & "Rescan module serial number."
            MsgBox Msg, vbCritical, "Warning"

        Cancel = True                               'stop user from changing focus

        SerialIn.SelStart = 0                       'highlight user text
        SerialIn.SelLength = Len(SerialIn.Value)    'select user text
        'Image1.Picture = LoadPicture(StopLightRed)  'display red stop light
        Exit Sub
    Else
        SerialInTime.Caption = Now                      'record date and time
        'Image1.Picture = LoadPicture(StopLightYellow)   'display yellow WIP stop light
        Me.SerialOut.SetFocus
        Exit Sub
    End If

End If End Sub

Новый код:

Private Sub SerialIn_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    Cancel = ValidateSerialIn(SerialIn)
End Sub

Function ValidateSerialIn(ByVal TextBox As Object) As Boolean

If Not IsNumeric(SerialIn.Value) Then        'validate serial number is numeric
'error msg serial number is not numeric
Msg = "Opps, something went wrong!  Serial number was incorrect." _
    & vbNewLine & vbNewLine & "Rescan module serial number."
    msgbox Msg, vbCritical, "Warning"           'display msg

SerialIn.SetFocus
SerialIn.SelStart = 0                       'highlight user text
SerialIn.SelLength = Len(SerialIn.Value)    'select user text
'Image1.Picture = LoadPicture(StopLightRed)  'display red stop light

ValidateSerialIn = True

Else
    If Not Len(SerialIn.Value) = 19 Then           'validate serial number length
'error msg incorrect length
Msg = "Opps, something went wrong!  Serial number was incorrect." _
    & vbNewLine & vbNewLine & "Rescan module serial number."
msgbox Msg, vbCritical, "Warning"

'Cancel = True                               'stop user from changing focus

SerialIn.SelStart = 0                       'highlight user text
SerialIn.SelLength = Len(SerialIn.Value)    'select user text
'Image1.Picture = LoadPicture(StopLightRed)  'display red stop light

ValidateSerialIn = True
Else
    SerialInTime.Caption = Now                      'record date and time
    'Image1.Picture = LoadPicture(StopLightYellow)   'display yellow WIP stop light

    ValidateSerialIn = False
    End If
End If
End Function

Третий go с использованием решения Тима TextBox_Change:

Private Sub SerialIn_Change()
Dim v
v = ScannedValue1(SerialIn.Text)

If Len(v) > 0 Then
    If Not IsNumeric(v) Then        'validate serial number is numeric
        'error msg serial number is not numeric
        Msg = "Opps, something went wrong!  Serial number was incorrect." _
            & vbNewLine & vbNewLine & "Rescan module serial number."
        msgbox Msg, vbCritical, "Warning"           'display msg

        SerialIn.Text = vbNullString
    Else
        If Not Len(v) = 19 Then           'validate serial number length
            'error msg incorrect length
            Msg = "Opps, something went wrong!  Serial number was incorrect." _
                & vbNewLine & vbNewLine & "Rescan module serial number."
            msgbox Msg, vbCritical, "Warning"

            SerialIn.Text = vbNullString
            'Image1.Picture = LoadPicture(StopLightRed)  'display red stop light
        Else
            SerialInTime.Caption = Now                      'record date and time
            'Image1.Picture = LoadPicture(StopLightYellow)   'display yellow WIP stop light
            SerialOut.SetFocus
        End If
    End If
End If
End Sub

'check if a value ends with vbcrlf or vblf
' - if yes strip that off and return the rest
' - otherwise returns empty string
Function ScannedValue1(vIn) As String
Dim rv As String
If Right(vIn, 2) = vbCrLf Then
    ScannedValue1 = Replace(vIn, vbCrLf, "")
ElseIf Right(vIn, 1) = vbLf Then
    ScannedValue1 = Replace(vIn, vbLf, "")
End If
End Function

Ответы [ 2 ]

0 голосов
/ 23 января 2020

Если вы хотите обнаружить «Enter» со сканера, то используйте событие Change, чтобы проверить, заканчивается ли значение текстового поля vbCrLf или vbLf (в этом порядке): если это так, запустите «сканировать» действие.

Обратите внимание, что для текстового поля необходимо установить «multiline = true» и «EnterKeyBehaviour = true», чтобы событие Change захватило клавишу ввода.

Private Sub TextBox1_Change()

    Dim v

    v = ScannedValue(TextBox1.Text)

    If Len(v) > 0 Then
        TriggerScanAction v
        TextBox1.Value = ""
    End If

End Sub

'check if a value ends with vbcrlf or vblf
' - if yes strip that off and return the rest
' - otherwise returns empty string
Function ScannedValue(vIn) As String
    Dim rv As String
    If Right(vIn, 2) = vbCrLf Then
        ScannedValue = Replace(vIn, vbCrLf, "")
    ElseIf Right(vIn, 1) = vbLf Then
        ScannedValue = Replace(vIn, vbLf, "")
    End If
End Function

'execute some action triggered by a scanned value
Sub TriggerScanAction(v)
    MsgBox "You scanned " & v
End Sub
0 голосов
/ 23 января 2020

Событие Exit имеет больше, чем кажется на первый взгляд. В большинстве форм один вводит значение в текстовое поле, а затем нажимает кнопку «ОК», командную кнопку. Происходит событие Tbx.Exit. Это также происходит, если вы щелкнете где-нибудь еще, например, кнопкой, чтобы закрыть форму. В вашей системе CR также инициирует событие, и это может показаться проблемой.

Когда CR или TAB введены в ваш Tbx, последовательность нажатий формы вступает во владение. Происходит выход, за которым следует событие ввода следующего элемента управления в вашем порядке касания. (Сравните это с ручным изменением фокуса, которое происходит, когда пользователь определяет следующий элемент управления.)

Таким образом, решение должно заключаться не в использовании события Exit, а в том, чтобы CR мог инициировать изменение фокуса, используя настройка порядка касания, которая устанавливает фокус на кнопке «ОК», а затем позволяет событию Enter этой кнопки инициировать событие Click (если оно не делает этого по умолчанию).

Возможно, вам нужен цикл там где CR запускает запись на рабочем листе, и фокус возвращается к Tbx. Это еще одна причина не использовать событие Exit, потому что вы не хотите, чтобы запись, сделанная на листе, выходила из Tbx, чтобы закрыть форму.

Однако, возможно, ваша форма не имеет или не нуждается в Кнопка «ОК». В этом случае я бы порекомендовал событие BeforeUpdate Tbx. И Exit, и BeforeUpdate происходят в тесной последовательности. Последовательность не важна, однако (хотя это не причина, почему я забыл это :-)), но их природа. Используйте событие выхода в контексте управления формой, установки фокуса или реакции на изменение фокуса. BeforeUpdate очевидно относится к данным. Каждое из этих событий точно настроено на свою задачу и поэтому делает это лучше, чем другое.

...