Cẩn trọng với Key Events (1 người xem)

  • Thread starter Thread starter jack nt
  • Ngày gửi Ngày gửi
Liên hệ QC

Người dùng đang xem chủ đề này

jack nt

Thành viên thường trực
Tham gia
23/12/07
Bài viết
304
Được thích
208
để chặn người dùng nhập trực tiếp vào combobox (chỉ cho chọn trong list), tui thường cài lệnh KeyCode = 0 trong sự kiện _KeyDown.

tuy vậy lệnh này không chặn được các phím khi gõ tiếng việt: w -> ư, [ -> ơ, ] -> ư.
các bác làm bộ gõ chặn mấy phím này mất rồi.

để xử lý tui phải xài thêm sự kiện _Change, và kiểm tra điều kiện .ListIndex = -1 (text không có trong list của combobox.

chia sẻ với ai đó dùng mấy cái events này.
 
để chặn người dùng nhập trực tiếp vào combobox (chỉ cho chọn trong list), tui thường cài lệnh KeyCode = 0 trong sự kiện _KeyDown.

tuy vậy lệnh này không chặn được các phím khi gõ tiếng việt: w -> ư, [ -> ơ, ] -> ư.
các bác làm bộ gõ chặn mấy phím này mất rồi.

để xử lý tui phải xài thêm sự kiện _Change, và kiểm tra điều kiện .ListIndex = -1 (text không có trong list của combobox.

chia sẻ với ai đó dùng mấy cái events này.
Với KeyCode = 0, tôi chặn được hầu hết các phím (trừ một số phím chức năng), cho dù tôi cài kiểu gõ VNI hay Telex. Tôi không hiểu bạn nói phải thêm gì để chặn nữa!
 
Upvote 0
Với KeyCode = 0, tôi chặn được hầu hết các phím (trừ một số phím chức năng), cho dù tôi cài kiểu gõ VNI hay Telex. Tôi không hiểu bạn nói phải thêm gì để chặn nữa!

- tui đang xài Unikey Seven, dùng chữ w thay cho ư... (túm lại là có vài phím gõ "một chạm" ra tiếng việt luôn)

- tui nhập vào phần text của combobox, đã kiểm tra với excel 2010, 2013 chưa làm với 2007, xp, 2003

- xưa nay tui cũng nghĩ vậy và làm vậy, nhưng rồi trong cái app đang viết, bị dính đòn, kiểm tra kỹ rồi mới dám đưa ra cảnh báo như trên.

- riêng với excel 2013 còn nhiều chuyện nhức đầu lắm, nhất là khi di chuyển các oleobjects. (chạy ngon trên 2007, 2010, thậm chí xp, chuyển sang 2013 là nhảy múa tá lả, rã ra mấy mảnh). nếu các bạn quan tâm tui sẽ mô tà kỹ hơn hiện tượng cũng như cách tui đã xử lý.
 
Upvote 0
để chặn người dùng nhập trực tiếp vào combobox (chỉ cho chọn trong list), tui thường cài lệnh KeyCode = 0 trong sự kiện _KeyDown.

tuy vậy lệnh này không chặn được các phím khi gõ tiếng việt: w -> ư, [ -> ơ, ] -> ư.
các bác làm bộ gõ chặn mấy phím này mất rồi.

để xử lý tui phải xài thêm sự kiện _Change, và kiểm tra điều kiện .ListIndex = -1 (text không có trong list của combobox.

chia sẻ với ai đó dùng mấy cái events này.

Tôi không biết Unikey bây giờ thế nào nhưng Unikey hồi xưa hoạt động trên cơ sở đánh tráo phím. Với mục đích đó nó dùng hook bàm phím - SetWindowsHookEx + WH_KEYBOARD
Nhưng tôi không hiểu sao bạn lại "chặn người dùng nhập trực tiếp vào combobox" rồi sau đó "phải xài thêm sự kiện _Change".
Cái ta cần là sự lựa chọn của người dùng. Sự lựa chọn đó có thể là chọn từ danh sách mà cũng có thể tự gõ. Tại sao nếu người ta gõ cái chắc chắn có trong danh sách mà lại chặn người ta?
Để kiểm tra xem có cái gì được chọn (tức từ danh sách hay tự gõ) thì kiểm tra ListIndex thôi. Cho người ta lựa chọn cách nhập dữ liệu và mình chỉ kiểm tra thôi. Sao lại chặn rồi vẫn phải kiểm tra?
Người ta luôn kiểm tra ListIndex bất kể lập trình trong ngôn ngữ nào.

Tôi có câu hỏi như thế vì bạn không miêu tả vấn đề, không nói lý do chặn.
 
Upvote 0
để chặn người dùng nhập trực tiếp vào combobox (chỉ cho chọn trong list), tui thường cài lệnh KeyCode = 0 trong sự kiện _KeyDown.

Thế sao không dùng sự kiện ComboBox_Click cho khỏe
Ngoài ra còn có thuộc tính MatchFound gì gì đó, cứ thế mà dùng thôi
 
Upvote 0
Thế sao không dùng sự kiện ComboBox_Click cho khỏe
Ngoài ra còn có thuộc tính MatchFound gì gì đó, cứ thế mà dùng thôi

khóa tại _Click không hiệu quả vì khi nhấn phím sẽ lần lượt xuất hiện các event theo thứ tự _KeyDown, _KeyUp,Key_Press, _Click

phải khóa từ event trước _KeyPress là _KeyDown hoặc _KeyUp.

@siwtom: ở đây tui chỉ bàn về việc khóa nhập bằng phím vào text của combobox thôi. còn tại sao ư? có những dữ liệu bắt buộc chỉ được phép lấy trong danh sách có sẵn (để bảo đảm tính duy nhất) mà người dùng cứ nhập khác đi thì sao? nhất là khi nhập tiếng việt lúc kiểu định sẵn, lúc kiểu tổ hợp, rồi đánh dấu kiểu òe/oè,.. thì làm sao bảo đảm là mã giống nhau. sau này query sẽ có chuyện.

(tui rành vb6 hơn là vba, thường chỉ dùng các event của excel để điều khiển chương trình, còn lại thì là vb6 và access. data lưu tại máy chủ thuận tiện hơn cho làm việc nhóm)
 
Upvote 0
@siwtom: ở đây tui chỉ bàn về việc khóa nhập bằng phím vào text của combobox thôi. còn tại sao ư? có những dữ liệu bắt buộc chỉ được phép lấy trong danh sách có sẵn (để bảo đảm tính duy nhất) mà người dùng cứ nhập khác đi thì sao? nhất là khi nhập tiếng việt lúc kiểu định sẵn, lúc kiểu tổ hợp, rồi đánh dấu kiểu òe/oè,.. thì làm sao bảo đảm là mã giống nhau. sau này query sẽ có chuyện.

(tui rành vb6 hơn là vba, thường chỉ dùng các event của excel để điều khiển chương trình, còn lại thì là vb6 và access. data lưu tại máy chủ thuận tiện hơn cho làm việc nhóm)

Người dùng mà gõ khác đi, hoặc thay vì gõ dựng sẵn mà gõ tổ hợp, tức nếu cái gõ khác "tí tẹo" thôi, tức cái gõ chắc chắn không trùng, không có trong danh sách thì 100% là ListIndex = -1
Kết luận: không cấm đoán gì. Cứ ListIndex >= 0 thì có nghĩa là cái trong TextBox của combobox chắc chắn có trong danh sách. Bất luận "nó" có được bằng cách chọn trong danh sách hay gõ thì có khác gì? Còn nếu cái trong textbox của combobox không có trong danh sách (không giống khi so sách từng bai) thì chắc chắn ListIndex = -1 và cần loại.

Cái gõ nó có (y hệt chứ không phải nhìn mắt thấy giống giống vì 1 anh là tổ hợp còn anh kia là dựng sẵn) hay không có trong danh sách thì chỉ cần kiểm tra ListIndex là lòi ra hết.

Hay tôi không hiểu được ý tưởng lớn nhỉ?
 
Upvote 0
khóa tại _Click không hiệu quả vì khi nhấn phím sẽ lần lượt xuất hiện các event theo thứ tự _KeyDown, _KeyUp,Key_Press, _Click

phải khóa từ event trước _KeyPress là _KeyDown hoặc _KeyUp.

@siwtom: ở đây tui chỉ bàn về việc khóa nhập bằng phím vào text của combobox thôi. còn tại sao ư? có những dữ liệu bắt buộc chỉ được phép lấy trong danh sách có sẵn (để bảo đảm tính duy nhất) mà người dùng cứ nhập khác đi thì sao? nhất là khi nhập tiếng việt lúc kiểu định sẵn, lúc kiểu tổ hợp, rồi đánh dấu kiểu òe/oè,.. thì làm sao bảo đảm là mã giống nhau. sau này query sẽ có chuyện.

(tui rành vb6 hơn là vba, thường chỉ dùng các event của excel để điều khiển chương trình, còn lại thì là vb6 và access. data lưu tại máy chủ thuận tiện hơn cho làm việc nhóm)
Nếu bạn ngại nhập khác những gì có trong List của ComboBox, bạn có thể dùng thuộc tính của nó. Bạn đặt thuộc tính MatchRequired là TRUE thì cho dù bạn nhập gì đi nữa cũng không sao, nhưng bạn enter hay chạm vào một control khác là nó không cho bạn dễ dàng thoát khỏi nó đâu!

Tuy nhiên, với cách trên có hạn chế của nó là dù cho bị rỗng nó cũng không cho thoát, bắt buộc nhập gì đó trong list mới cho thoát khỏi nó. Vì thế, phải dùng sự kiện để không cho nhập gì ngoài list trước khi thoát đó là dùng phương thức MatchFound cho sự kiện BeforeUpdate.

Mã:
Private Sub ComboBox2_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean)
    If ComboBox2 = "" Then Exit Sub
    If Not ComboBox2.MatchFound Then
        Cancel = True
        MsgBox "Invalid value"
    End If
End Sub

Nhập mà không đúng list thì không thoát được nó đâu!
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
cảm ơn các cao nhân đã chỉ giáo.

(p/s: tui tính bấm cảm ơn tất cả các bác phía trên, nhưng đến chỗ bác siwtom không thấy phím cảm ơn đâu cả, mà bây giờ lại có rồi. kể cũng lạ là tui đang xử lý đúng kiểu bác siwtom đề nghị, còn cách của HTN thì thú thật chưa từng biết, sẽ thử ngay.)
 
Lần chỉnh sửa cuối:
Upvote 0
Mã:
Private Sub ComboBox2[COLOR=#ff0000]_BeforeUpdate[/COLOR](ByVal Cancel As MSForms.ReturnBoolean)
    If ComboBox2 = "" Then Exit Sub
    If Not ComboBox2.MatchFound Then
        Cancel = True
        MsgBox "Invalid value"
    End If
End Sub

@HTN: tui đã kiểm tra, có điều cái ComboBox_BeforeUpdate chỉ có với ComboBox là control trên userform. tui đang xài combobox nhưng là oleobject trên sheet, không có cái _BeforeUpdate này.
thanks anyway.
 
Upvote 0
@HTN: tui đã kiểm tra, có điều cái ComboBox_BeforeUpdate chỉ có với ComboBox là control trên userform. tui đang xài combobox nhưng là oleobject trên sheet, không có cái _BeforeUpdate này.
thanks anyway.
Nếu không có thì làm cho có đi bạn!

Mã:
Private Sub ComboBox1[COLOR=#ff0000]_LostFocus[/COLOR]()
    If ComboBox1 = "" Then Exit Sub
    If Not ComboBox1.MatchFound Then
        MsgBox "Invalid value"
        ComboBox1 = ""
        ComboBox1.Activate
    End If
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
@HTN: tui đã kiểm tra, có điều cái ComboBox_BeforeUpdate chỉ có với ComboBox là control trên userform. tui đang xài combobox nhưng là oleobject trên sheet, không có cái _BeforeUpdate này.
thanks anyway.

Thế sao bạn không dùng sự kiện ComboBox_Change kết hợp với MatchFound?
 
Upvote 0
Thế sao bạn không dùng sự kiện ComboBox_Change kết hợp với MatchFound?

Nếu là em thì không dùng sự kiện Change, bởi gõ cái gì nó cũng update sự kiện, người nhập cứ phải mệt mỏi, nhất là khi gõ dấu tiếng Việt (khi chưa có dấu thì đã khác trong list, nếu dùng sự kiện này sẽ không cho thay đổi gì thêm).
 
Upvote 0
Nếu là em thì không dùng sự kiện Change, bởi gõ cái gì nó cũng update sự kiện, người nhập cứ phải mệt mỏi, nhất là khi gõ dấu tiếng Việt (khi chưa có dấu thì đã khác trong list, nếu dùng sự kiện này sẽ không cho thay đổi gì thêm).

Tôi nói rõ là dùng thêm MatchFound rồi mà: Gõ tùm lum nhưng chưa trùng gì trong list thì sao update được chứ
 
Upvote 0
Nếu không đúng với list, nó chẳng làm gì sao? Vậy nó cũng chẳng "chặn" những thứ không được nhập!

Tác giả nói rằng:
để chặn người dùng nhập trực tiếp vào combobox (chỉ cho chọn trong list)
Và tôi hiểu rằng ta phải code thế nào đó để khi nhập (hoặc chọn) đúng list thì sẽ làm 1 code khác, còn ngược lại thì thôi, không làm gì cả. Và đã không làm gì cả thì dù có nhập cái gì không thuộc list thì nó cũng chỉ nằm đó chơi, có ảnh hướng gì đâu
Mà thôi, tác giả cũng không đưa file lên nên tôi chỉ gợi ý thế thôi, áp dụng thế nào là tùy tác giả
 
Upvote 0

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

Back
Top Bottom