Chỉ cho phép nhập số trong TextBox

Liên hệ QC

doanhhoang79

Thành viên hoạt động
Tham gia
31/3/08
Bài viết
142
Được thích
18
Chào các anh chị trên diễn đàn.

Tôi tìm thấy trên diễn đàn có một file (không nhớ tên tác giả) với nội dung chỉ cho phép nhập ký tự số và ký tự ".". Tuy nhiên khi tôi gõ liên tiếp 2 ký tự "o", 2 ký tự "d",...thì nó lại xuất hiện trong textbox (gõ theo kiểu Telex). Tôi không biết nguyên nhân lỗi này. Mong các anh chị kiểm tra giúp và thêm, sửa code để khi gõ liên tiếp ký tự "o" 2 lần nó không xuất hiện trong textbox nữa.

Tôi gửi file đính kèm

Xin cảm ơn.
 

File đính kèm

  • So trong Textbox.xls
    31 KB · Đọc: 171
Chào các anh chị trên diễn đàn.

Tôi tìm thấy trên diễn đàn có một file (không nhớ tên tác giả) với nội dung chỉ cho phép nhập ký tự số và ký tự ".". Tuy nhiên khi tôi gõ liên tiếp 2 ký tự "o", 2 ký tự "d",...thì nó lại xuất hiện trong textbox (gõ theo kiểu Telex). Tôi không biết nguyên nhân lỗi này. Mong các anh chị kiểm tra giúp và thêm, sửa code để khi gõ liên tiếp ký tự "o" 2 lần nó không xuất hiện trong textbox nữa.

Tôi gửi file đính kèm

Xin cảm ơn.
Tôi test thấy bình thường mà bạn!
Có điều nếu chỉ cần cho phép nhập ký tự số và dấu chấm thì tôi nghĩ code đâu dài thế
PHP:
Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
 If InStr("1234567890." + Chr$(vbKeyBack), Chr$(KeyAscii)) = 0 Then
  KeyAscii = 0
 End If
End Sub
 
Upvote 0
Tôi test thấy bình thường mà bạn!
Có điều nếu chỉ cần cho phép nhập ký tự số và dấu chấm thì tôi nghĩ code đâu dài thế
PHP:
Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
 If InStr("1234567890." + Chr$(vbKeyBack), Chr$(KeyAscii)) = 0 Then
  KeyAscii = 0
 End If
End Sub
Với code này thì sẽ xảy ra hiện tượng nhập nhiều dấu chấm vẫn chấp nhận, chính vì thế tác giả phải đưa thêm 1 số tình huống để xét.
Bạn nói là test bình thường nhưng không biết bạn dùng bảng mã nào, kiểu gõ nào, nếu dùng Unicode và Telex thì sẽ bị lôi Chr$(KeyAscii) khi nhập 2 chữ d hoặc 2 chữ o vì lúc đó sẽ là đ và ô
Tôi đổi Chr$(KeyAscii) thành ChrW(KeyAscii) thì không bị lỗi và không hiển thị lên ký tự nhập vào nữa nhưng nó lại xóa luôn ký tự đứng trước, kỳ thật.
Kể ra cũng hơi đau đầu.
 
Upvote 0
Với code này thì sẽ xảy ra hiện tượng nhập nhiều dấu chấm vẫn chấp nhận, chính vì thế tác giả phải đưa thêm 1 số tình huống để xét.
Bạn nói là test bình thường nhưng không biết bạn dùng bảng mã nào, kiểu gõ nào, nếu dùng Unicode và Telex thì sẽ bị lôi Chr$(KeyAscii) khi nhập 2 chữ d hoặc 2 chữ o vì lúc đó sẽ là đ và ô
Tôi đổi Chr$(KeyAscii) thành ChrW(KeyAscii) thì không bị lỗi và không hiển thị lên ký tự nhập vào nữa nhưng nó lại xóa luôn ký tự đứng trước, kỳ thật.
Kể ra cũng hơi đau đầu.

Đúng đấy, lỗi xảy ra đúng y như bạn nói. Tôi cũng đã tim đủ mọi cánh nhưng chăng ăn thua gì. Chẳng lẽ lại botay.com hay sao?. Tôi nghĩ chắc chắn là phải có cách để xử lý lỗi này.

Mong mọi người tiếp tục cho cao kiến.
 
Upvote 0
Với code này thì sẽ xảy ra hiện tượng nhập nhiều dấu chấm vẫn chấp nhận, chính vì thế tác giả phải đưa thêm 1 số tình huống để xét.

Thủ tục này chỉ cho nhập duy nhất 1 dấu chấm và các chữ số.
Mã:
Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
Select Case KeyAscii
Case 46, 48 To 57
  If KeyAscii = 46 And InStr(1, TextBox1, ".") > 0 Then KeyAscii = 0
Case Else
  KeyAscii = 0
End Select
End Sub
 
Upvote 0
Đúng đấy, lỗi xảy ra đúng y như bạn nói. Tôi cũng đã tim đủ mọi cánh nhưng chăng ăn thua gì. Chẳng lẽ lại botay.com hay sao?. Tôi nghĩ chắc chắn là phải có cách để xử lý lỗi này.

Mong mọi người tiếp tục cho cao kiến.
Tôi cũng không rành lắm về Form... tôi dùng cách "củ chuối" này xem thế nào nhé:
PHP:
Private Sub TextBox1_Change()
  On Error Resume Next
  With TextBox1
    If Not IsNumeric(.Text) Then
      .Text = Left(.Text, Len(.Text) - 1): Exit Sub
    End If
  End With
End Sub
PHP:
Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
 On Error Resume Next
 If InStr("1234567890." + Chr$(vbKeyBack), Chr$(KeyAscii)) = 0 Then
  KeyAscii = 0
 End If
End Sub
 

File đính kèm

  • So trong Textbox.xls
    31 KB · Đọc: 196
Lần chỉnh sửa cuối:
Upvote 0
Cho em nhận xét tí ti:
  • Cái Textbox1Keypress của Thầy Long và của anh Ndu chạy rất tốt: chỉ cho phép nhập cái chữ số và dấu chấm.

  • Còn cái Textbox1_Change của anh Ndu thì không ổn... Nếu nhập dấu chấm, nó chỉ cho nhập 1 dấu chấm mà thôi, rồi thì cấm. Nhưng nếu nhập dấu phẩy vào đó, thì bao nhiêu dấu phẩy nó cũng OK...
 
Upvote 0
Cho em nhận xét tí ti:
  • Cái Textbox1Keypress của Thầy Long và của anh Ndu chạy rất tốt: chỉ cho phép nhập cái chữ số và dấu chấm.
  • Còn cái Textbox1_Change của anh Ndu thì không ổn... Nếu nhập dấu chấm, nó chỉ cho nhập 1 dấu chấm mà thôi, rồi thì cấm. Nhưng nếu nhập dấu phẩy vào đó, thì bao nhiêu dấu phẩy nó cũng OK...
Sao kỳ vậy ta!
Tôi test trên máy tôi đâu có vụ cho phép nhập dấu phẩy nhỉ?
Có khi nào Regional Language Options trên máy của BNTT định dạng dấu phẩy là dấu thập phân không đó?
 
Lần chỉnh sửa cuối:
Upvote 0
Em thì thường dùng thế này cho nó đơn giản :
PHP:
Private Sub H_TBDKThanhTien_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
    On Error Resume Next
    Select Case KeyAscii
    Case 48 To 57
        'Case vbKeyBack, vbKeyClear, vbKeyDelete
        'Case vbKeyLeft, vbKeyRight, vbKeyUp, vbKeyDown, vbKeyTab
    Case 96 To 105 ' For Numpad
    Case 109, 110 ' For "-", "."
    Case Else
        KeyAscii = 0
    End Select
End Sub
--CV--
 
Upvote 0
Thủ tục này chỉ cho nhập duy nhất 1 dấu chấm và các chữ số.
Mã:
Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
Select Case KeyAscii
Case 46, 48 To 57
  If KeyAscii = 46 And InStr(1, TextBox1, ".") > 0 Then KeyAscii = 0
Case Else
  KeyAscii = 0
End Select
End Sub
Cách làm nào tôi cũng thấy đúng cả nhưng vẫn không triệt để được. Cái của bác cũng vậy mà, bác cứ nhập liên tiếp 2 chữ o hoặc 2 chữ d (hoặc ký tự có dấu bất kỳ) khi TextBox1.SelStart < Len(TextBox1.Text) (nhớ là bảng mã Unicode, kiểu gõ Telext bộ gõ Unikey, bảng mã khác, kiểu gõ khác và bộ gõ khác tôi chưa test.) nó xóa luôn ký tự đứng trước.
Tôi nghĩ củ chuối nằm ở chỗ bị thằng Unikey nó hook trước, vì khi gõ chữ d đầu tiên thì bị đoạn mã trên loại bỏ, đến ký tự thứ 2 thì Unikey quét đến ký tự trước đó và xóa ký tự đó đi để truyền vào ký tự đ để thay thế lúc đó lại bị đoạn mã trên loại bỏ nên xảy ra hiện tượng này.
Nếu tắt chế độ tiếng Việt đi thì Ok luôn.
Cách giải quyết là làm sao tắt được chế độ tiếng Việt đây.
 
Upvote 0
Tôi cũng không rành lắm về Form... tôi dùng cách "củ chuối" này xem thế nào nhé:
PHP:
Private Sub TextBox1_Change()
  On Error Resume Next
  With TextBox1
    If Not IsNumeric(.Text) Then
      .Text = Left(.Text, Len(.Text) - 1): Exit Sub
    End If
  End With
End Sub
Cách này không ổn, bất đắc dĩ lắm mới đưa vào sự kiện change vì sẽ xảy ra trường hợp thủ tục chạy lòng vòng với lại đoạn mã này chỉ xét được trường hợp ký tự nhập vào ở cuối cùng thôi.
 
Upvote 0
Em thì thường dùng thế này cho nó đơn giản :
PHP:
Private Sub H_TBDKThanhTien_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
    On Error Resume Next
    Select Case KeyAscii
    Case 48 To 57
        'Case vbKeyBack, vbKeyClear, vbKeyDelete
        'Case vbKeyLeft, vbKeyRight, vbKeyUp, vbKeyDown, vbKeyTab
    Case 96 To 105 ' For Numpad
    Case 109, 110 ' For "-", "."
    Case Else
        KeyAscii = 0
    End Select
End Sub
--CV--
Kỳ thật, tôi test thử thấy tất cả các ký tự đều nhận hết.
 
Upvote 0
Sao kỳ vậy ta!
Tôi test trên máy tôi đâu có vụ cho phép nhập dấu phẩy nhỉ?
Có khi nào Regional Language Options trên máy của BNTT định dạng dấu phẩy là dấu thập phân không đó?
Hông... Em vẫn xài định dạng số kiểu Mỹ thì hồi nảo hồi nao.
Vả lại, em copy cả 2 cái code của anh, dán chung vào một chỗ, sau đó em test từng cái một (chạy cái này thì đánh dấu ' vào cái kia, không sợ chuyện 2 cái đụng nhau). Nếu như cái Change mà sai thì cái Keypress cũng sai chứ? Đằng này, cái Keypress chạy rất ngon (không thể nhập dấu phẩy vào trong textbox), chỉ có cái Change là bị trục trặc thôi.
 
Upvote 0
Hông... Em vẫn xài định dạng số kiểu Mỹ thì hồi nảo hồi nao.
Vả lại, em copy cả 2 cái code của anh, dán chung vào một chỗ, sau đó em test từng cái một (chạy cái này thì đánh dấu ' vào cái kia, không sợ chuyện 2 cái đụng nhau). Nếu như cái Change mà sai thì cái Keypress cũng sai chứ? Đằng này, cái Keypress chạy rất ngon (không thể nhập dấu phẩy vào trong textbox), chỉ có cái Change là bị trục trặc thôi.
Ah... không! 2 code phải chạy cùng lúc BNTT à!
 
Upvote 0
Với code này:
PHP:
Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
  Select Case KeyAscii
    Case 48 To 57
    Case 45
      If InStr(1, Me.TextBox1.Text, "-") > 0 Or Me.TextBox1.SelStart > 0 Then KeyAscii = 0
    Case 46
      If InStr(1, Me.TextBox1.Text, ".") > 0 Then KeyAscii = 0
    Case Else
      KeyAscii = 0
  End Select
End Sub
Chạy From lần thứ nhất sẽ bị lổi gõ 2 chử d hoặc 2 chử o
Nhưng nếu đóng Form rồi chạy lại lần nữa thì... hết bị...
Kỳ lạ thật!
----------------
Ủa... mà sao bây giờ test lại không lổi nữa ta?
Các bạn test dùng file đính kèm này với!
 

File đính kèm

  • Allow_Number_Only_01.xls
    29 KB · Đọc: 68
Lần chỉnh sửa cuối:
Upvote 0
Vẫn chết đứ đừ, lúc được lúc không có nghĩa là vẫn chưa được triệt để.
Tóm lại nếu nhập ký tự có dấu bằng các bộ gõ thông thường thì đều bị chết khi gõ ký tự có dấu, không riêng gì d hay o. Như bài trên tôi đã nói, nguyên nhân chính là do bị bộ gõ đã tiến hành hook bàn phím trước, nên các sự kiện khác đều phụ thuộc vào chế độ hook của bộ gõ.
về code thì cái nào tôi cũng thấy đúng dù là chr(keycode) hay chrw(keycode) hay chr$(keyascii).. select case, instr(...) thì cũng thế bản chất đều như nhau là kiểm tra mã ký tự xuất hiện.
Theo tôi, vấn đề ở đây là làm thế nào để tắt chế độ nhập TV của bộ gõ, còn nếu ai đó đưa ra được thủ pháp không cần tắt chế độ nhập TV mà vẫn đảm bảo được các tình huống thì đó mới là tối ưu.
 
Upvote 0
Vẫn chết đứ đừ, lúc được lúc không có nghĩa là vẫn chưa được triệt để.
Tóm lại nếu nhập ký tự có dấu bằng các bộ gõ thông thường thì đều bị chết khi gõ ký tự có dấu, không riêng gì d hay o. Như bài trên tôi đã nói, nguyên nhân chính là do bị bộ gõ đã tiến hành hook bàn phím trước, nên các sự kiện khác đều phụ thuộc vào chế độ hook của bộ gõ.
về code thì cái nào tôi cũng thấy đúng dù là chr(keycode) hay chrw(keycode) hay chr$(keyascii).. select case, instr(...) thì cũng thế bản chất đều như nhau là kiểm tra mã ký tự xuất hiện.
Theo tôi, vấn đề ở đây là làm thế nào để tắt chế độ nhập TV của bộ gõ, còn nếu ai đó đưa ra được thủ pháp không cần tắt chế độ nhập TV mà vẫn đảm bảo được các tình huống thì đó mới là tối ưu.
Vậy theo tôi, tối ưu nhất có lẽ là nên cho nhập thoải mái... dù gì đến lúc xử lý dử liệu mới cần kiểm tra... Khi ấy sẽ "tính" vẫn chưa muộn!
 
Upvote 0
Vâng, đúng thế, đó là cái cuối cùng ta cần. Khổ nỗi nhiều khi người thiết kế muốn chuẩn hóa ngay nên mới đau đầu. Tôi cũng làm nhiều về cái này nhưng hạn chế được chừng nào thì hạn chế, còn cuối cùng khi động đến dữ liệu đó hoặc khi exit textbox ta mới xét.
 
Upvote 0
Cách làm nào tôi cũng thấy đúng cả nhưng vẫn không triệt để được. Cái của bác cũng vậy mà, bác cứ nhập liên tiếp 2 chữ o hoặc 2 chữ d (hoặc ký tự có dấu bất kỳ) khi TextBox1.SelStart < Len(TextBox1.Text) (nhớ là bảng mã Unicode, kiểu gõ Telext bộ gõ Unikey, bảng mã khác, kiểu gõ khác và bộ gõ khác tôi chưa test.) nó xóa luôn ký tự đứng trước.
Tôi nghĩ củ chuối nằm ở chỗ bị thằng Unikey nó hook trước, vì khi gõ chữ d đầu tiên thì bị đoạn mã trên loại bỏ, đến ký tự thứ 2 thì Unikey quét đến ký tự trước đó và xóa ký tự đó đi để truyền vào ký tự đ để thay thế lúc đó lại bị đoạn mã trên loại bỏ nên xảy ra hiện tượng này.
Nếu tắt chế độ tiếng Việt đi thì Ok luôn.
Cách giải quyết là làm sao tắt được chế độ tiếng Việt đây.

Đau đầu thật, không ngờ lại có tình huống này. Nhập oo hay dd lại ra lệnh xóa ký tự bên trái (<--). Xử lý bằng cách vô hiệu hóa phím <--
Mã:
Private Sub TextBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
If KeyCode = 8 Then KeyCode = 0
End Sub
Cách này chỉ đối phó, vì phím <-- rất cần cho việc chỉnh dữ liệu nhập vào textbox
 
Upvote 0
Web KT

Bài viết mới nhất

Back
Top Bottom