Đố vui về VBA!

Liên hệ QC

anhtuan1066

Thành viên gạo cội
Tham gia
10/3/07
Bài viết
5,802
Được thích
6,905
Nhằm cũng cố kiến thức về VBA cho các bạn mới bắt đầu và cả những bạn đang ứng dụng mà chưa hiểu nhiều về nó, tôi mở topic này với mong mõi qua những câu hỏi vui, các bạn sẽ nhận định lại sự hiểu biết cũa mình... (Kễ cã chính tôi cũng đang tập tành nên có rất nhiều cái chưa biết)
Mong rằng topic sẽ mang đến cho các bạn những khám phá thú vị với những cái tưỡng chừng như đã biết
Mong nhận dc bài viết về câu đố cũa các cao thủ! Còn các bạn mới thì đừng ngại khi đưa ra ý kiến cũa mình.. Có sai có sữa sẽ hoàn thiện!
Tôi xin mỡ màn trước bằng 1 câu hỏi đơn giãn
ANH TUẤN

CÂU HỎI 1: Tại sao biến K ko hoạt động?
Tôi muốn khi nhấn vào 1 button thì cell A1 sẽ tăng lên 1 đơn vị... Tôi đã làm như sau:
-Tạo 1 Command Button (nút nhấn thuộc thanh Control Toolbox), click phải chuột lên nút nhấn, chọn View code, rồi gõ vào đoạn code sau:
PHP:
Private Sub CommandButton1_Click()
   K = K + 1
   Range("A1").Value = K
End Sub
Ban đầu K chưa có gì, xem như =0, nhấn nút lần thứ nhất thì K dc tăng thêm 1, vậy K hiện tại sẽ bằng 1, và gán K vào cell A1 thì đương nhiên A1 sẽ =1... Nhấn nút lần 2, K lại dc tăng thêm 1 nên hiện tại K sẽ =2 và cell A1 cũng sẽ =2... vân vân.. từ đó diễn tiến tiếp...
Hi.. hi.. Điều này nghe qua có vẽ rất hợp lý, ấy thế mà khi nhấn nút nó chỉ hoạt động dc duy nhất 1 lần (A1 = 1) rồi thôi ko nhút nhít nữa...
Các bạn có thể giãi thích tại sao lại như thế ko? Tại sao những lần nhấn nút sau đó K lại ko tăng thêm tí nào (vì thực tế A1 vẫn cứ = 1 hoài) ?
ANH TUẤN
 
Pờ ro pơ ty thì phải. Không cần thuật toán, sự kiện hay thủ tục nào luôn.
Oh, kinh chưa, kinh chưa! Không phải như ComboBox đâu nha, nhưng CBB nó cho match 1 ký tự, và chỉ được nhập 1 ký tự, còn câu này em đố không hạn chế ký tự nhập vào, nhưng nếu bị kẹt phím (nhấn lâu 1 phím bất kỳ) thì sẽ chỉ cho nhảy đúng 1 ký tự, chứ không phải cho ra rất nhiều ký tự.
 
Upvote 0
Oh, kinh chưa, kinh chưa! Không phải như ComboBox đâu nha, nhưng CBB nó cho match 1 ký tự, và chỉ được nhập 1 ký tự, còn câu này em đố không hạn chế ký tự nhập vào, nhưng nếu bị kẹt phím (nhấn lâu 1 phím bất kỳ) thì sẽ chỉ cho nhảy đúng 1 ký tự, chứ không phải cho ra rất nhiều ký tự.
Cái gì mà kinh. Câu đố không rõ lắm:
"không phải gõ một ký tự mà gõ bao nhiêu cũng được" khiến cho tôi nhầm rằng gõ nhiều ký tự trên bàn phím (khác nhau). Nếu nói rõ là gõ 1 ký tự nhiều lần thì khác rồi.
Khi phần đầu nhầm thì phần sau cũng nhầm theo: "nó vẫn chỉ ra 1 ký tự mà thôi." lại hiểu là gõ những ký tự khác nhau nhưng kết quả chỉ toàn 1 ký tự giống nhau.

TB:
Gõ nhiều ký tự khác nhau nhưng chỉ ra 1 loại ký tự là như sau:

1674118458959.png
 
Upvote 0
Cái gì mà kinh. Câu đố không rõ lắm:
"không phải gõ một ký tự mà gõ bao nhiêu cũng được" khiến cho tôi nhầm rằng gõ nhiều ký tự trên bàn phím (khác nhau). Nếu nói rõ là gõ 1 ký tự nhiều lần thì khác rồi.
Khi phần đầu nhầm thì phần sau cũng nhầm theo: "nó vẫn chỉ ra 1 ký tự mà thôi." lại hiểu là gõ những ký tự khác nhau nhưng kết quả chỉ toàn 1 ký tự giống nhau.

TB:
Gõ nhiều ký tự khác nhau nhưng chỉ ra 1 loại ký tự là như sau:

View attachment 285827
Không phải kiểu gõ Password đâu, lưu ý lại là khi gõ 1 phím bất kỳ, nếu giữ lâu, thông thường nó cho ra rất nhiều ký tự đó trong 1 lần nhấn và giữ phím, câu đố ở đây là ngăn không cho điều đó xảy ra, dù cho nhấn phím liền hoặc/và giữ lâu nó cũng chỉ cho ra đúng 1 ký tự.
 
Upvote 0
Oh, kinh chưa, kinh chưa! Không phải như ComboBox đâu nha, nhưng CBB nó cho match 1 ký tự, và chỉ được nhập 1 ký tự, còn câu này em đố không hạn chế ký tự nhập vào, nhưng nếu bị kẹt phím (nhấn lâu 1 phím bất kỳ) thì sẽ chỉ cho nhảy đúng 1 ký tự, chứ không phải cho ra rất nhiều ký tự.
Có phải gán biến so sánh số lần keypress và keyup không anh nhỉ? nếu keypress > keyup thì xử lý
 
Upvote 0
Có phải gán biến so sánh số lần keypress và keyup không anh nhỉ? nếu keypress > keyup thì xử lý
Xử lý OK chưa bạn ơi. Hình như đếm nó cũng không phải là cách nhỉ?

Các thành viên khác chắc giờ đang chuẩn bị đón tết Nguyên đán nên cũng thấy ít tham gia cho vui hen.
 
Upvote 0
Mồ được đào lên, chêm câu hỏi mới.
Mình tò mò đọc thử câu hỏi đầu tiên là cái gì. Mới té ra hơn 15 năm rồi mà nó chưa được giải thích chính đáng, theo đúng ngôn ngữ VBA.
:confused::confused::confused:
 
Upvote 0
Tôi có một TextBox trên UserForm, bằng thuật toán nào, thủ tục nào, sự kiện nào để khi tôi gõ phím nó chỉ ra đúng 1 ký tự dù có nhấn lâu phím đó.

Lưu ý, không phải gõ một ký tự mà gõ bao nhiêu cũng được, nhưng mỗi lần gõ dù có bị kẹt phím (nhấn lâu) nó vẫn chỉ ra 1 ký tự mà thôi.

Bạn xem thử code này có ra đúng yêu cầu không nhé.

Rich (BB code):
Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
    Static key As Long
    Dim total As Long

    total = Len(TextBox1.Text) + 1
    If KeyAscii = key Then
        Me.TextBox1.Value = Left(Me.TextBox1.Text, total - 2)
    End If
    key = KeyAscii
End Sub
 
Upvote 0
Bạn xem thử code này có ra đúng yêu cầu không nhé.

Rich (BB code):
Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
    Static key As Long
    Dim total As Long

    total = Len(TextBox1.Text) + 1
    If KeyAscii = key Then
        Me.TextBox1.Value = Left(Me.TextBox1.Text, total - 2)
    End If
    key = KeyAscii
End Sub
Tuyệt vời! Đây là một đáp án đúng, nhưng nó khá dùng công thức tính toán, thử dùng sự kiện và đơn giản hơn xem sao!
Bài đã được tự động gộp:

Mồ được đào lên, chêm câu hỏi mới.
Mình tò mò đọc thử câu hỏi đầu tiên là cái gì. Mới té ra hơn 15 năm rồi mà nó chưa được giải thích chính đáng, theo đúng ngôn ngữ VBA.
:confused::confused::confused:
Vậy anh có câu trả lời chính đáng cho bài đầu tiên hay không? Nếu có xin trả lời để anh em được học hỏi, còn không thì đừng có spam để tăng lượng bài viết lên. Số lượng bài viết thấy nhiều quá mà bài viết toàn là những bài chả ý nghĩa gì cả!
 
Lần chỉnh sửa cuối:
Upvote 0
Xử lý OK chưa bạn ơi. Hình như đếm nó cũng không phải là cách nhỉ?

Các thành viên khác chắc giờ đang chuẩn bị đón tết Nguyên đán nên cũng thấy ít tham gia cho vui hen.
Em làm theo hướng đó, nhưng thử nhập chậm thì ổn. Gõ mà nhanh thì không hiểu sao nó chưa chuẩn lắm, tết bận rộn nên cũng không có nhiều thời gian suy nghĩ:
Mã:
Private i As Long, txt As String
Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
    If i > 0 Then
        TextBox1.Text = txt
    Else
        txt = TextBox1.Text
        i = i + 1
    End If
End Sub

Private Sub TextBox1_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
    i = 0
End Sub
Cách của anh @ongke0711 lại hơi bất tiện nếu như không phải kẹt phím mà người dùng muốn nhập 2 ký tự giống nhau liên tiếp thì không được
 
Upvote 0
Upvote 0
Nếu muốn gõ yellow, success thì không được. Tiếng Việt gõ kiểu telex ee = ê, oo = ô, aa = â, dd = đ cũng không được.
Code chỉ đúng yêu cầu đề bài chứ không yêu cầu phải gõ được đúng từ vựng tiếng Anh, tiếng Việt nhé bác. vd: Boong tàu..
Còn bác nào viết được code phân biệt và cho phép gõ: 2 chữ "o" để thành "Boong" hay "bô" thì rẩt đáng khâm phục và học hỏi đó.
 
Lần chỉnh sửa cuối:
Upvote 0
Code chỉ đúng yêu cầu đề bài chứ không yêu cầu phải gõ được đúng từ vựng tiếng Anh, tiếng Việt nhé bác. vd: Boong tàu..
Còn bác nào viết được code phân biệt và cho phép gõ: 2 chữ "o" để thành "Boong" hay "bô" thì rẩt đáng khâm phục và học hỏi đó.
Code bài #1412 của Nhattanktnn làm được rồi á, tôi test rồi dù bạn đó tự nhận "chưa chuẩn lắm".

Code đó test được như sau: gõ telex oo = ô, ooo = oo

1674195101579.png

Đề bài không rõ ràng lắm (tôi cũng đã nhầm), nhưng giờ thì hiểu là chỉ "tránh việc lỡ đè phím ra nhiều ký tự" thôi, nhấn riêng rẽ phải được như bình thường.
Tôi không phân biệt tiếng Anh và tiếng Việt gì trong thí dụ ở trên, chỉ là "gõ riêng rẽ 2 ký tự giống nhau liền kề".
 
Upvote 0
Nếu muốn gõ yellow, success thì không được. Tiếng Việt gõ kiểu telex ee = ê, oo = ô, aa = â, dd = đ cũng không được.
Cái này anh chỉ việc nhấn 2 lần phím L với Yellow và 2 lần phím C, S với Success thôi, ý là cứ mỗi chữ mình chỉ được gõ 1 lần thôi, nếu có bị kẹt phím, nhấn và giữ lâu nó cũng vẫn cho ra 1 ký tự chứ không phải chữ đó mà ra một dãy luôn.
 
Upvote 0
Cái này anh chỉ việc nhấn 2 lần phím L với Yellow và 2 lần phím C, S với Success thôi, ý là cứ mỗi chữ mình chỉ được gõ 1 lần thôi, nếu có bị kẹt phím, nhấn và giữ lâu nó cũng vẫn cho ra 1 ký tự chứ không phải chữ đó mà ra một dãy luôn.
Đó chính là điều mà tôi nói ở bài 1415, nói rằng bài 1412 đã làm được. Còn gõ không được là nói về code bài 1409.
 
Upvote 0
Đó chính là điều mà tôi nói ở bài 1415, nói rằng bài 1412 đã làm được. Còn gõ không được là nói về code bài 1409.
Bài đó, đã đạt yêu cầu, không sai vào đâu được. Nhưng nếu ngắn gọn hơn nữa mới thật sự là đáp án của em.
 
Upvote 0
Em làm theo hướng đó, nhưng thử nhập chậm thì ổn. Gõ mà nhanh thì không hiểu sao nó chưa chuẩn lắm, tết bận rộn nên cũng không có nhiều thời gian suy nghĩ:
Mã:
Private i As Long, txt As String
Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
    If i > 0 Then
        TextBox1.Text = txt
    Else
        txt = TextBox1.Text
        i = i + 1
    End If
End Sub

Private Sub TextBox1_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
    i = 0
End Sub
Cách của anh @ongke0711 lại hơi bất tiện nếu như không phải kẹt phím mà người dùng muốn nhập 2 ký tự giống nhau liên tiếp thì không được

Muốn nhập thêm thì bấm phím Shift, muốn bấm phím Shift để nhập thêm thì viết thêm Code cho nó..... :D
 
Upvote 0
Em làm theo hướng đó, nhưng thử nhập chậm thì ổn. Gõ mà nhanh thì không hiểu sao nó chưa chuẩn lắm, tết bận rộn nên cũng không có nhiều thời gian suy nghĩ:
Mã:
Private i As Long, txt As String
Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
    If i > 0 Then
        TextBox1.Text = txt
    Else
        txt = TextBox1.Text
        i = i + 1
    End If
End Sub

Private Sub TextBox1_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
    i = 0
End Sub
Cách của anh @ongke0711 lại hơi bất tiện nếu như không phải kẹt phím mà người dùng muốn nhập 2 ký tự giống nhau liên tiếp thì không được
Bài này về hình thức là đạt rồi nhé bạn, rất cố gắng và sáng tạo, tuy nhiên nói tối ưu thì chưa, bởi vì nếu ta gõ 4 ký tự thì có nghĩa sự kiện nó sẽ thay đổi 4 lần, nhưng mình thử thêm vào sự kiện Change thì nó bị thay đổi mấy lần nhé:

Mã:
Private Sub TextBox1_Change()
    Debug.Print "Change"
End Sub
 
Upvote 0
Hôm nay cuối năm âm lịch rồi, mình gửi đáp án luôn cho trọn vẹn nè, dưới đây là code ngăn không cho kẹt phím:
Mã:
Private priBlnOneKey As Boolean
Private Sub TextBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
    If priBlnOneKey Then KeyCode = 0
    priBlnOneKey = True
End Sub
Private Sub TextBox1_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
    priBlnOneKey = False
End Sub
''TEST:
Private Sub TextBox1_Change()
    Debug.Print "Change"
End Sub
Đơn giản nhưng hiệu quả phải không quý vị?!
 

File đính kèm

  • TextBoxOneChar.xlsm
    22.8 KB · Đọc: 4
Upvote 0
Web KT
Back
Top Bottom