Tìm Kiếm Trong Data Validation Excel

Liên hệ QC

Kiều Mạnh

I don't program, I beat code into submission!!!
Tham gia
9/6/12
Bài viết
5,421
Được thích
4,033
Giới tính
Nam
Mình có viết code sau để tạo và sử dụng Data Validation trong Excel sử dụng tốt ...Tuy nhiên có 2 vấn đề phát sinh mà suy nghĩ hoài chua tìm ra cách xử lý ... Vậy úp bài nhờ các Bạn trợ giúp

1/ Vùng dữ liêu nguon() luôn luôn phát sinh nên mình sử dụng Dic để lấy duy nhất gán vào Data Validation ...nếu dữ liệu nhiều phải kéo xuống tìm mất công quá ... Vậy mình muốn hỏi có cách nào từ Sheet2.[C4] ta có thể gõ ký tự đại diện là nó tìm kiếm ra được hay không ?? .... để gán vào đó

2/ Khi mình sử dụng SendKeys ("%{Down}") để cho Data Validation nó xổ xuống cho dễ nhìn thì trên máy mình mất phím Numlock và có sử dụng Shell để bật nó lại tuy nhiên thấy nó cũng cứ nhảy link tinh à

Vậy nhờ các Bạn xem có cách nào khác xử lý tốt 2 vấn đề trên không giúp mình với
Xin cảm ơn
Mã:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Dim Nguon()
    Nguon = Sheet1.Range(Sheet1.[B3], Sheet1.[B65536].End(3)).Value
    Call Validation(Nguon, Sheet2.Range("C4"))
    ''Call ON_Numlock
End Sub

Public Sub Validation(ByVal dArr As Variant, ByVal Target As Range)
    Dim i As Long
    With CreateObject("scripting.dictionary")
        For i = 1 To UBound(dArr)
            If Not IsEmpty(dArr(i, 1)) Then
                .Item(dArr(i, 1)) = .Count
            End If
        Next
        Target.Validation.Delete
        If .Count Then Target.Validation.Add 3, , , Join(.Keys, ",")
        ''SendKeys ("%{Down}")
    End With
End Sub

Sub ON_Numlock()
    CreateObject("WScript.Shell").SendKeys "{NUMLOCK}", True
End Sub
 

File đính kèm

  • Data Validation.xlsb
    17.3 KB · Đọc: 61
Lần chỉnh sửa cuối:
Không hẳn như bạn nói, nhưng chuyện điền vào ô chọn là dễ hiểu.

Bạn nhầm lẫn 2 vấn đề: code nhập vào A1:O1, A2:O2, còn nhập vào ô chọn là do Excel nhập. Vd. bạn không dùng hook gì cả nhưng bạn chọn D9 rồi gõ "a" rồi "a" thì có thấy "aa" trong D không? Rõ ràng là có.

Tại sao tôi nói "không hẳn"? Vì bạn chỉ gõ được 1 ký tự khi có ô chọn.

Tôi đính kèm tập tin để mọi người có thể trong một phạm vi nào đó có thể hiểu được hook làm việc như thế nào. Tôi đính kèm tập tin về hook vì tôi hiểu là dhn46 muốn biết về hook.

Nhưng tôi cũng nói rõ là đó chỉ là ví dụ và muốn làm gì thì phải sửa code cho thích hợp
Tôi cũng viết rõ là trò chơi với cell ở chế độ edit là bật lửa trên thùng thuốc súng. Cũng viết rõ không phải để dùng hook giải quyết vấn đề của chủ đề này. Tóm lại: tôi trả lời câu hỏi cụ thể của dhn46. Thế thôi.

Trong tập tin của tôi có CommandButton nên khi click để cài hook thì nó active và không có cell nào được chọn. Vì thế tôi mới nạp phím vào cells (A1:O1, A2:O2, ...). Nếu khi có hook mà cell nào đó được chọn thì chỉ gõ được 1 ký tự, khi gõ ký tự 2 thì Excel chết đột ngột. Vì khi gõ xong 1 ký tự thì mọi người sẽ nhìn thấy trong cell được chọn có ký tự đầu tiên và trỏ văn bản ở sau nó. Khi gõ ký tự đầu thì cell không ở trạng thái như thế (chưa có ký tự trong cell và chưa có trỏ văn bản - caret). Vì thế khi gõ ký tự 2 thì 99,99% chắc chắn thao tác nhập text vào A2 đã xung đột với code của Excel.

Toàn bộ sẽ như thế này: Giả sử D9 đang activate. Bạn gõ "a" thì system gọi callback -> callback nhập "a" vào A1 -> sau khi system gọi hết các callback thì "tuồn" phím cho cửa sổ đang có input trong system, đó là cửa sổ Excel -> Excel nhận được phím "a" nên nó "đưa" vào D9 và hiển thị caret -> bạn gõ ký tự "a" thứ 2 -> system gọi callback -> callback nhập "a" vào A2. Chính lúc này, khi D9 đang ở chế độ Edit, thì 99,99% chắc chắn là thao tác "nhập "a" vào A2" đã xung đột với code của Excel -> Excel chết đột ngột. Rất có thể thread lúc đó đang ở trong một "critical section".

Tôi đã viết rất rõ là code chỉ để vọc cho biết hook hoạt động như thế nào. Mọi dụng ý dùng nó để thử nghiệm trên cell đang nhập liệu, tương tác vào các đối tượng của Excel thì các bạn tự nghiên cứu. Tôi sẽ không trả lời những câu hỏi về những việc đó.

Nếu ai đó muốn thử nghiệm hook cả khi có cell active, ở chế độ Edit thì thay
Mã:
Sheet1.Cells(r, c).Value = Text
bằng
Mã:
Debug.Print Text
hoặc ghi Text vào tập tin trên đĩa.
Cám ơn bạn đã nói rất chi tiết về hook keyboard. Một ví dụ rất hay!
 
Upvote 0
Đây là kết quả cuối cùng úp lên tặng cho Bạn nào cần thì cứ vậy mà xài ... code xúc tích ngắn gọn ... đơn giản ....

Và dễ hiểu kèm theo tham số của hàm InStr cho những ai mới bắt đầu VBA tìm hiểu

1/ Tại C4 bạn muốn gõ cái giống gì vào đó thì gõ xong Enter

2/ nếu Xóa trắng C4 thì nó lấy hết

3/ Quá trình xử dụng nếu có lỗi gì phát sinh vui lòng báo lại tại đây

4/ Mô tả Hàm InStr cho những Bạn mới làm quen với VBA ... Mạnh Copy từ Internet

Tên hàm:
InStr

Mô tả:
InStr([start, ]string1, string2[, compare])
Tìm chuỗi string2 trong chuỗi string1, tìm từ vị trí start

Tham số:
start
Vị trí tìm
string1
Chuỗi tìm kiếm
string2
Giá trị cần tìm
compare
Chỉ rõ kiểu dữ liệu để so sánh trong quá trình tìm kiếm

Ghi chú:
Dùng cho tham số compare
vbUseCompareOption = –1
Chế độ tùy chọn, VB sẽ tự động lựa lọai dữ liệu thích hợp
vbBinaryCompare = 0
So sánh nhị phân
vbTextCompare = 1
So sánh chuỗi
vbDatabaseCompare = 2
So sánh dữ liệu

Private Sub Form_Load()
Dim SearchString, SearchChar, MyPos
SearchString = "XXpXXpXXPXXP"' String to search in.
SearchChar = "P"' Search for "P".
' So sanh theo cua text tu vi tri 4
MyPos = InStr(4, SearchString, SearchChar, 1)' Returns 6.
' So sanh theo Binary
MyPos = InStr(1, SearchString, SearchChar, 0)' Returns 9.
' So sanh theo Binary, do mac dinh la 0
MyPos = InStr(SearchString, SearchChar)' Returns 9.
MyPos = InStr(1, SearchString, "W")' Returns 0.
End Sub

PHP:
Private Sub Worksheet_Change(ByVal Target As Range)
    Application.EnableEvents = False
        Dim Nguon()
        Nguon = Sheet1.Range(Sheet1.[B3], Sheet1.[B65536].End(3)).Value
        If Target.Address = [C4].Address Then
            If Target.Count = 1 Then
                Call GetListValidation(Nguon(), Sheet2.Range("C4"))
            End If
        End If
    Application.EnableEvents = True
End Sub

Public Sub GetListValidation(ByVal Arr As Variant, ByVal Target As Range)
    Dim Dic As Object, i As Long
    Set Dic = CreateObject("scripting.dictionary")
    For i = 1 To UBound(Arr)
        If InStr(1, UCase(Arr(i, 1)), UCase(Target.Value), 1) Then
            If Not IsEmpty(Arr(i, 1)) Then
                Dic.Item(Arr(i, 1)) = Dic.Count
            End If
        End If
    Next
    With Target.Validation
        .Delete
        If Dic.Count Then
            .Add 3, , , Join(Dic.keys, ",")
            .ShowError = False
        End If
        If Dic.Count > 1 Then
            SendKeys ("%{Down}"), True
        ElseIf Dic.Count = 1 Then
            Target.Value = Dic.keys()
        End If
        Target.Select
    End With
    Set Dic = Nothing
End Sub
Vừa nghĩ ra 1 cách bắt sự kiện nhấn phím enter
Anh xem nếu ok thì sửa lại code trên he
Nghĩ chắc là dùng được
Thêm vài trường hợp xử lý lại cho đúng với khi nhấn phím enter như bình thường là ok
Em vừa thử thì thấy ok. Enter 1 phát là sổ list ra ngay
Đang onl điện thoại (sửa cáp mạng- mất kết nối không up file được) nên ghi cái ý tưởng ra thôi.
Mã:
Sub Gan()
Application.onkey "{ENTER"}, "KeyEnter" ' enter ban phim so
Application.onkey "{RETURN}", "KeyEnter" ' enter ban phim chu
End sub
Sub KeyEnter()
If len(Activecell.value)=0 then
Activecell.offset(1,0).Activate
Else
Msgbox Activecell.value
End if
End sub
 
Lần chỉnh sửa cuối:
Upvote 0
Vừa nghĩ ra 1 cách bắt sự kiện nhấn phím enter
Anh xem nếu ok thì sửa lại code trên he
Nghĩ chắc là dùng được
Thêm vài trường hợp xử lý lại cho đúng với khi nhấn phím enter như bình thường là ok
Em vừa thử thì thấy ok. Enter 1 phát là sổ list ra ngay
Đang onl điện thoại (sửa cáp mạng- mất kết nối không up file được) nên ghi cái ý tưởng ra thôi.
Mã:
Sub Gan()
Application.onkey "{ENTER"}, "KeyEnter" ' enter ban phim so
Application.onkey "{RETURN}", "KeyEnter" ' enter ban phim chu
End sub
Sub KeyEnter()
If len(Activecell.value)=0 then
Activecell.offset(1,0).Activate
Else
Msgbox Activecell.value
End if
End sub
ok .......... Lúc nào rảnh úp file xem ... dân nghiên cứu code két mà khi có ý tưởng mới mắt sáng long lanh liền à
 
Lần chỉnh sửa cuối:
Upvote 0
Giờ Mạnh muốn mở rộng hướng ta nghiên cứu tiếp vầy các Bạn xem tình hình sao nha
1/ Vẫn sử dụng Validation thật để chơi tiếp ....??!!!

2/ Vùng dữ liệu Nguon ta sẻ mở rộng thêm 5 hay nhiều cột nữa ...vvv

3/ Khi ta gõ vào c4 chữ m và chọn nó thì sẻ lấy nguyên dòng theo dữ liệu trong Validation gán xuống dưới ...và tại c4 gán cái chọn vào đó luôn ...hay trả về 1 mãng dữ liệu xuống dưới vvv...

4/ Mặc dù trên GPE huuthang_bd Or langtuchungtinh ..... đã làm rồi ......

nhưng Sử dụng controls để làm và 1 trường hợp khác nữa cũng làm nhưng ta chỉ dòm thôi Mạnh ko tiện nói ở đây ... Vì mình là dân mê code mà chỉ dòm thôi thì ...............:D

5/ Nếu được ta sẻ làm thêm cái form khi gõ vào c4 nó sẻ lọc và Show ra Form cho dễ nhìn

6/ Ý tưởng là vậy không biết các Bạn sao ....thêm bớt gì ta sẻ từng bước điều chỉnh cuộc chơi tiếp

Xin cảm ơn
 
Lần chỉnh sửa cuối:
Upvote 0
Giờ Mạnh muốn mở rộng hướng ta nghiên cứu tiếp vầy các Bạn xem tình hình sao nha
1/ Vẫn sử dụng Validation thật để chơi tiếp ....??!!!

2/ Vùng dữ liệu Nguon ta sẻ mở rộng thêm 5 hay nhiều cột nữa ...vvv

3/ Khi ta gõ vào c4 chữ m và chọn nó thì sẻ lấy nguyên dòng theo dữ liệu trong Validation gán xuống dưới ...và tại c4 gán cái chọn vào đó luôn ...hay trả về 1 mãng dữ liệu xuống dưới vvv...

4/ Mặc dù trên GPE huuthang_bd Or langtuchungtinh ..... đã làm rồi ......

nhưng Sử dụng controls để làm và 1 trường hợp khác nữa cũng làm nhưng ta chỉ dòm thôi Mạnh ko tiện nói ở đây ... Vì mình là dân mê code mà chỉ dòm thôi thì ...............:D

5/ Nếu được ta sẻ làm thêm cái form khi gõ vào c4 nó sẻ lọc và Show ra Form cho dễ nhìn

6/ Ý tưởng là vậy không biết các Bạn sao ....thêm bớt gì ta sẻ từng bước điều chỉnh cuộc chơi tiếp

Xin cảm ơn
anh cho hỏi, khi đặt con trỏ trên cells, sau đó gọi form ShowModal = false , thì chương trình sẽ Active Form, khi đó sẽ nhấn phím sẽ không thao tác được trên sheet được nữa.
vậy code như thế nào để có thể chọn lại ô đang chọn và edit được (giống thao tác nhấn chọn ô rồi F2) tức là khi gọi form xong thì lập tức sẽ Active Sheet lại để thao tác gõ chữ ngay chứ không mất công nhấn chuột lại vào Sheet thì mới thao tác được
chỉ cần làm được công việc trên thì sẽ giúp ích được cho việc phát triển ở mục 5 mà anh nói.
 

File đính kèm

  • List Search_Validation.xlsb
    23 KB · Đọc: 16
Upvote 0
anh cho hỏi, khi đặt con trỏ trên cells, sau đó gọi form ShowModal = false , thì chương trình sẽ Active Form, khi đó sẽ nhấn phím sẽ không thao tác được trên sheet được nữa.
vậy code như thế nào để có thể chọn lại ô đang chọn và edit được (giống thao tác nhấn chọn ô rồi F2) tức là khi gọi form xong thì lập tức sẽ Active Sheet lại để thao tác gõ chữ ngay chứ không mất công nhấn chuột lại vào Sheet thì mới thao tác được
chỉ cần làm được công việc trên thì sẽ giúp ích được cho việc phát triển ở mục 5 mà anh nói.
Nói chung ok ... nhưng dài dòng và dòng này có tác dụng gì Application.SendKeys "{F2}"
 
Upvote 0
Ta lại thử bỏ hết mấy cái If trong Sub KeyEnter ..... đi ...xong xóa trắng c4 đi xem sao .............Tịt :D:eek:
vẫn pình xường
Mã:
Sub KeyEnter()
    Application.ScreenUpdating = False
    If ActiveCell.Address(0, 0) <> "C4" Then GoTo Thoat
    Application.EnableEvents = False
    Dim Nguon()
    Nguon = Sheet1.Range(Sheet1.[B3], Sheet1.[B65536].End(3)).Value
    Call GetListValidation(Nguon(), ActiveCell)
    Application.EnableEvents = True
    Beep
Thoat:
    Application.ScreenUpdating = True
End Sub
 
Upvote 0
vẫn pình xường
Mã:
Sub KeyEnter()
    Application.ScreenUpdating = False
    If ActiveCell.Address(0, 0) <> "C4" Then GoTo Thoat
    Application.EnableEvents = False
    Dim Nguon()
    Nguon = Sheet1.Range(Sheet1.[B3], Sheet1.[B65536].End(3)).Value
    Call GetListValidation(Nguon(), ActiveCell)
    Application.EnableEvents = True
    Beep
Thoat:
    Application.ScreenUpdating = True
End Sub
Ko biết bên đó là thử Run chưa vậy ...???
 
Upvote 0
Ko biết bên đó là thử Run chưa vậy ...???
bên đây thử rồi anh, không có dữ liệu nó sổ ra danh sách đầy đủ.
mặc định khi mở file là gán phím enter để chạy code, đóng file thì khôi phục lại chức năng phím enter.
test thì chỉnh vậy thôi, đi vào thực tế thì lúc đó dùng class để gán lệnh cho phím enter.
 
Upvote 0
bên đây thử rồi anh, không có dữ liệu nó sổ ra danh sách đầy đủ.
mặc định khi mở file là gán phím enter để chạy code, đóng file thì khôi phục lại chức năng phím enter.
test thì chỉnh vậy thôi, đi vào thực tế thì lúc đó dùng class để gán lệnh cho phím enter.
sao máy mạnh ko được ... thôi bỏ qua vụ này ....Ta chuyển qua bài 66 ... ý sao .... nếu tạm ok ta cho vào class
ta nghiên cứu từng bước 1 sai tới đâu sửa tới đó .............. Nghiên cứu mà sợ chi sai ???!!!
 
Upvote 0
sao máy mạnh ko được ... thôi bỏ qua vụ này ....Ta chuyển qua bài 66 ... ý sao .... nếu tạm ok ta cho vào class
ta nghiên cứu từng bước 1 sai tới đâu sửa tới đó .............. Nghiên cứu mà sợ chi sai ???!!!
cho vào sự kiện class thì chắc làm được, còn việc tổ chức để có thể cài đặt làm sao cho code hiểu mà làm theo đúng ý mình mới khó anh à.
đang bắt đầu tải VB2017 về tối quậy, tận 21Gb, chả biết máy chạy nổi không.
 
Upvote 0
Delphi.PNG
cho vào sự kiện class thì chắc làm được, còn việc tổ chức để có thể cài đặt làm sao cho code hiểu mà làm theo đúng ý mình mới khó anh à.
đang bắt đầu tải VB2017 về tối quậy, tận 21Gb, chả biết máy chạy nổi không.
vb2017 gì vậy mà tới 21G dữ vậy .... học thôi kiếm bản nào nhẹ xài đã khi kiến thức khá chơi sau ok mà mạnh đang xài delphi2010 có 403 MB sau khi setup chay ngọt lắm ... rất nhẹ hổ trợ Unicode vvv.....
 
Upvote 0
vb2017 gì vậy mà tới 21G dữ vậy .... học thôi kiếm bản nào nhẹ xài đã khi kiến thức khá chơi sau ok mà mạnh đang xài delphi2010 có 403 MB sau khi setup chay ngọt lắm ... rất nhẹ hổ trợ Unicode vvv.....
upload_2017-7-21_18-19-4.png
vậy cho em xin link đi, tìm hoài mà chả có bản nào nhẹ cả.
 
Upvote 0
Web KT
Back
Top Bottom