Консультация № 120717
29.01.2008, 17:32
0.00 руб.
0 7 7
Добрый день! Помогите решить проблему. Написал простенькую программку на VB6, типо калькулятор - в текстовое поле вводим цыфры, нажимаем кнопочку и все считает. Проблема: если вдруг вводят не цыфры, а буквы тутже вылетает ошибка и программка закрывается. Я понимаю проблема в обработке различных типов данных. Подскажите как избежать ошибки.

Обсуждение

Неизвестный
29.01.2008, 17:48
общий
это ответ
Здравствуйте, CLov233!
Очевидно нужно проверять вводимые данные
Метод проверки зависит от того, как организуется ввод. Можно проверять каждый символ в событии "нажание кнопки" и если он не соответствует критерию (не является цифрой, точкой или математическим знаком) то запрещать его ввод.
Можно проверять значение поля на "правильность" уже после ввода всего числа. Или встроить такую проверку перед выполненинем математических действий.
Очень жалко, что вы не привели кода программы...
Неизвестный
29.01.2008, 17:49
общий
это ответ
Здравствуйте, CLov233!
попробуйте воспользоваться процедурой обработки нажатия клавиши, приведенной ниже...
должно помочь.. этот код позволяет нажимать клавиши с цифрами, и клавиши для удаления этих цифр т.е. Back Spase или Delete...
если же нажата какая либо другая клавиша, то она игнорируется.



Приложение:
Private Sub EDIT1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger) Select Case KeyAscii Case 8 ‘ если нажат Back Spase или Delete Case 48 To 57 ‘ код клафишь от 0 до 9 Case Else KeyAscii = 0 ‘ сброс значения, т.е. ничего не нажато. End SelectEnd Sub
Неизвестный
29.01.2008, 18:58
общий
это ответ
Здравствуйте, CLov233!
Если свойство CauseValidate у Text1 существует (в Вашей версии VB) и установленно в TRUE, то
Private Sub Text1_Validate(Cancel As Boolean)
If Not IsNumeric(Text1.Text) Then
MsgBox "Please enter numbers only.", vbInformation
‘можно протереть
Text1.Text = ""
Cancel = True
End If
End Sub
Неизвестный
29.01.2008, 19:19
общий
это ответ
Здравствуйте, CLov233!
В дополнение к сказанному AlexanderZh и Максим Sly.
значение поля на "правильность" проверяется проверяется примерно так:
If Not IsNumeric(Text1.Text) Then Exit Sub
А при проверке ввода при нажантии клавиши, необходимо проверять код разделителя целой и дробной части. запятая или точка, код 44 или 46, в зависимости от национальной настройки. Иначе математические операции с нецелыми числами будут невозможны.
Евгений.
Неизвестный
29.01.2008, 23:17
общий
это ответ
Здравствуйте, CLov233!
дополним ответ последнего експерта)

код проверки считалки

Try
здесь считаем
Catch ex as Exception
MsgBox("введены невреные данные")
end try
код проверки числа

после нажатия кнопки любого действия
try
Cdbl(TextBox.Text)
catch ex as Exception
MsgBox("плохие данные")
end try

И именно дабл так как Операции IsNumeric запретят вводить запятую и прочие мат знаки вообщем плохая это затея
Неизвестный
30.01.2008, 06:56
общий
это ответ
Здравствуйте, CLov233!
Ответов много, добавлю свой.
Вариантов решения несколько.
Можно просто наплевать на то, что ввел пользователь, а перед использованием, значение поля "прогнать" через Val (не забывая, что Val принимает только (.) как разделитель):
<code>
Private Sub Command1_Click()
MsgBox Val(Replace(Text1, ",", "."))
End Sub
</code>
Можно просто информировать об ошибке и все.
Эти варианты не очень уважительно относятся к пользователю.

Есть неплохой, очень эффективный вариант, вообще запретить фокус ввода для поля, а весь ввод обрабатывать в обработчиках формы(KeyPreview=True), так сделано в калькуляторе Windows(calc.exe).
что-нибудь вроде:
<code>
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
Dim t As String
Dim dec As String
t = Val(Text1)
dec = IIf(Right(Text1, 1) = ".", ".", "")
Select Case KeyCode
Case vbKey0 To vbKey9
t = t & dec & Chr(KeyCode)
Case vbKeyNumpad0 To vbKeyNumpad9
t = t & dec & Chr(KeyCode - 48)
Case vbKeyDelete
t = ""
Case vbKeyBack
If dec = "." Then
dec = ""
Else
t = Left(t, Len(t) - 1)
End If
End Select
Text1 = Val(t)

If KeyCode = vbKeyDecimal Then If dec = "" Then Text1 = Val(t) & "."
End Sub
</code>
таким образом, можно делать проверки любой сложности, перехватывать буфер обмена и т.д. и т.п.
этот вариант - мощный, но достаточно сложный для реализации.

Варианты попроще, те что уже озвучили, это проверять ввод в обработчиках поля.

OnKeyPress - очень удобный, простой, но не учитывает то, что из буфера обмена, значени можно вставлять не только нажимая Ctrl+V, а например с помощью мыши. В таком случае, данный вариант не сработает.

OnValidate - также удобный для нас, но проверка ввода происходит только в момент потери фокуса поля, что не очень удобно для пользователя.

OnChange - этот вариант еще не озвучили, но мне он нравится больше всего:
<code>
Private Sub Text1_Change()
Static OldVal As String
Dim ss As Long
Dim sl As Long
If Trim(Text1) = "" Then OldVal = "": Text1 = "": Exit Sub
If Not IsNumeric(Text1) Then
With Text1
ss = .SelStart
sl = .SelLength
.Text = OldVal
.SelStart = ss - 1
.SelLength = sl
End With
Else
OldVal = Text1
End If
End Sub
</code>
просто, удобно, не зависит от способа изменения данных, мне нравится.

Все эти способы можно комбинировать.
Вообщем, что хотел - сказал.
Успехов.
Неизвестный
30.01.2008, 17:58
общий
это ответ
Здравствуйте, CLov233!
Private Sub Text1_KeyPress(KeyAscii As Integer)
Select Case KeyAscii
Case 8, 44, 46, 48 To 57 ‘При вводе десятичных цифр (48-57) Вам понадобится точка (46) или запятая (44) - ненужное уберите
Case 13 ‘Код клавиши Enter
‘ здесь можно вставить код вычисления
Case Else
KeyAscii = 0
End Select
End Sub
Форма ответа