Giúp đỡ code: Trích lọc dữ liệu có điều kiện (2 người xem)

Liên hệ QC

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

alexanderhuti

Thành viên chính thức
Tham gia
25/8/09
Bài viết
62
Được thích
6
Tôi có vấn đề này nhờ xin nhờ các anh/chị/em GPE giúp đỡ:

- Sheet "Dulieu" chứa thông tin khách hàng đã mua hàng, số tiền, mặt hàng,.....
"Dulieu" được cập nhật hàng ngày.

- Yêu cầu đặt ra là tại sheet "Trichloc": khi gõ từ khoá vào (ví dụ: coca cola) và chọn kiểu tìm kiếm (nghĩa là tìm kiếm theo tên khách hàng/ hay theo phân loại hàng/ hay theo mặt hàng/ theo trọng lượng/ theo số tiền/...)
thì chương trình sẽ lọc dữ liệu ở sheet "Dulieu" và copy vào sheet "Trichloc" theo các nội dung bắt đầu từ ô A5.

- Ghi chú: Khi tìm kiếm theo khách hàng/ hay mặt hàng thì từ khoá là kiểu tìm kiếm gần đúng. Ví dụ:
Tìm kiếm theo công ty: gõ từ khoá là "Coca"
thì cho phép lọc và copy tất cả các công ty có từ khoá này. Ví dụ: Cong ty Coca Cola 1; Company Coca Cola 2; Factory Coca Cola
Hay tìm kiếm theo tên hàng: ví dụ từ khoá là "chuot" thì cho phép lọc và copy tất cả mặt hàng: chuot logitech, chuot HP, chuot China...

Xin chân thành cảm ơn!
 

File đính kèm

Mong có thể giải quyết bài toán của bạn.

Mã:
1# Không dùng VBA

2# Lọc ngay trên sheet Dulieu

3# Đánh dấu "X" trên tiêu đề để tìm kiếm

4# Tại cột J, lọc giá trị TRUE

5# Gõ nội dung cần tìm vào ô có tên _searchTerm

6# (Trong excel 2007+) Ấn {CTRL+ALT+L} để cập nhật thay đổi

7# Các hàm sử dụng : ISNA, ISNUMBER, MATCH, SEARCH

Thân.
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Còn đây là một cách dùng VBA để tham khảo:
1. Chuẩn hóa lại Validation tại ô B2 để đảm bảo trùng khớp với tiêu đề bảng dữ liệu nguồn.
2. Sử dụng code sau cho việc tìm kiếm:
[GPECODE=vb]Sub TimKiem()
Dim TuKhoa As String, Cot As String, VT As Long, Tmp, Tmp1, Arr()
Dim i As Long, j As Long, k As Long, DK As Boolean

TuKhoa = Sheets("Trichloc").[B1]
Cot = Sheets("Trichloc").[B2]
If Len(TuKhoa) * Len(Cot) = 0 Then
MsgBox "Chua nhap du thong tin.": Exit Sub
End If
Tmp = Sheets("Dulieu").[A2:G10000]
ReDim Arr(1 To UBound(Tmp), 1 To 7)
With WorksheetFunction
Tmp1 = .Transpose(Sheets("Dulieu").[A1:G1])
VT = .Match(Cot, Tmp1, 0)
End With
For i = 1 To UBound(Tmp)
If IsEmpty(Tmp(i, 1)) Then Exit For
If VT = 2 Or VT = 5 Then
DK = InStr(1, Tmp(i, VT), TuKhoa, vbTextCompare) > 0
Else
DK = (Tmp(i, VT) = TuKhoa)
End If
If DK Then
k = k + 1
For j = 1 To 7
Arr(k, j) = Tmp(i, j)
Next
End If
Next
Sheets("Trichloc").[A5:G10000].Clear
If k > 0 Then Sheets("Trichloc").[A5:G5].Resize(k).Value = Arr
End Sub[/GPECODE]
Bạn tham khảo trong file đính kèm nhé.
 

File đính kèm

Upvote 0
Mong có thể giải quyết bài toán của bạn.

Mã:
1# Không dùng VBA

2# Lọc ngay trên sheet Dulieu

3# Đánh dấu "X" trên tiêu đề để tìm kiếm

4# Tại cột J, lọc giá trị TRUE

5# Gõ nội dung cần tìm vào ô có tên _searchTerm

6# (Trong excel 2007+) Ấn {CTRL+ALT+L} để cập nhật thay đổi

7# Các hàm sử dụng : ISNA, ISNUMBER, MATCH, SEARCH

Thân.

Cảm ơn sự giúp đỡ của bạn. Mình cũng có thể chọn lựa cách này. Nhưng mình vẫn muốn dùng VBA hơn vì sự thật bảng tính của mình rất lớn và dữ liệu phức tạp hơn nhiều (do lấy ví dụ nên có nhiều dữ liệu nhạy cảm công ty mình ko đưa lên được).
Dù sao củng cảm ơn bạn.
 
Upvote 0
Còn đây là một cách dùng VBA để tham khảo:
1. Chuẩn hóa lại Validation tại ô B2 để đảm bảo trùng khớp với tiêu đề bảng dữ liệu nguồn.
2. Sử dụng code sau cho việc tìm kiếm:
[GPECODE=vb]Sub TimKiem()
Dim TuKhoa As String, Cot As String, VT As Long, Tmp, Tmp1, Arr()
Dim i As Long, j As Long, k As Long, DK As Boolean

TuKhoa = Sheets("Trichloc").[B1]
Cot = Sheets("Trichloc").[B2]
If Len(TuKhoa) * Len(Cot) = 0 Then
MsgBox "Chua nhap du thong tin.": Exit Sub
End If
Tmp = Sheets("Dulieu").[A2:G10000]
ReDim Arr(1 To UBound(Tmp), 1 To 7)
With WorksheetFunction
Tmp1 = .Transpose(Sheets("Dulieu").[A1:G1])
VT = .Match(Cot, Tmp1, 0)
End With
For i = 1 To UBound(Tmp)
If IsEmpty(Tmp(i, 1)) Then Exit For
If VT = 2 Or VT = 5 Then
DK = InStr(1, Tmp(i, VT), TuKhoa, vbTextCompare) > 0
Else
DK = (Tmp(i, VT) = TuKhoa)
End If
If DK Then
k = k + 1
For j = 1 To 7
Arr(k, j) = Tmp(i, j)
Next
End If
Next
Sheets("Trichloc").[A5:G10000].Clear
If k > 0 Then Sheets("Trichloc").[A5:G5].Resize(k).Value = Arr
End Sub[/GPECODE]
Bạn tham khảo trong file đính kèm nhé.

Em rất chân thành cảm ơn anh Phúc. Đây đúng là code mà em cần.
Anh có thể dành chút thời gian giải thích công việc của đoạn code được không ạ. (vì em cũng chỉ mới mày mò VBA thôi, mua quyển sách của thầy Phan Tự Hướng về nghiên cứu cũng biết chút chút cơ bản).
Vì dữ liệu trong công ty em làm hàng ngày có khoảng 4 file, mỗi file là 1 năm, bắt đầu từ 2010-2014, nên em muốn hiểu rõ về đoạn code để tìm cách phát triển lọc dữ liệu của những workbook khác nhau.
 
Upvote 0
Bài toán này Dùng advance filter cũng được..record marco đi bạn
 
Upvote 0
Bài toán này Dùng advance filter cũng được..record marco đi bạn

Hi bạn,
Khi mình dùng macro ghi lại sau đó thử đoạn code lại thì bị báo lỗi: select method or range class failed

Sheets("Dulieu").Rows("1:1").Select
Selection.AutoFilter
Range("B5").Select
ActiveSheet.Range("$A$1:$G$23").AutoFilter Field:=2, Criteria1:=Sheets("Trichloc").Range("B1"), _
Operator:=xlAnd
Range("A1:G23").Select
Range("B5").Activate
Selection.Copy
Sheets("Trichloc").Select
Range("A4").Select
ActiveSheet.Paste
 
Upvote 0
Hi bạn,
Khi mình dùng macro ghi lại sau đó thử đoạn code lại thì bị báo lỗi: select method or range class failed
...
bạn có thể dùng Advanced Filter, nhưng nên cài nhiều điều kiện lọc cùng lúc để xử lý nhiều trường hợp ngoài ý muốn.
'----
bạn để ý các Header phải giống nhau (có thể đảo vị trí cột) thì mới lọc ra đúng kết quả.
Mã:
Sub GPE_loc()
    If Range("B2") <> "" Then Range("B2") = "*" & Range("B2").Value & "*"
    If Range("E2") <> "" Then Range("E2") = "*" & Range("E2").Value & "*"
    
    Sheets("Dulieu").Range("A1:G65000").AdvancedFilter Action:=xlFilterCopy, _
                                                CriteriaRange:=Range("A1:G2"), _
                                                CopyToRange:=Range("A4:G4"), _
                                                Unique:=False


End Sub

'----
file đính kèm ----> #32
 
Lần chỉnh sửa cuối:
Upvote 0
Hi bạn phucbugis,

Nếu mình có thêm một sheet nữa, ví dụ như là sheet "DuLieu2", là thông tin của khách hàng năm khác, định dạng giống như sheet "Dulieu" thì phải thêm vào đoạn code như thế nào để khi lọc thì lọc được ở cả 2 sheet và dán vào sheet "Trichloc" vậy bạn?
 
Upvote 0
Hi bạn phucbugis,

Nếu mình có thêm một sheet nữa, ví dụ như là sheet "DuLieu2", là thông tin của khách hàng năm khác, định dạng giống như sheet "Dulieu" thì phải thêm vào đoạn code như thế nào để khi lọc thì lọc được ở cả 2 sheet và dán vào sheet "Trichloc" vậy bạn?

bạn tải lại file và xem nhé, mình mới bổ sung thêm điều kiện lọc + tạo thêm 1 ô H2 để chọn tên sheet (bạn thử đổi tên sheet Dulieu -> Dulieu2 và ngược lại, rồi đưa sheet Dulieu2 vào test tiếp xem)

Mã:
Sub GPE_loc()
Dim KH As Range, tenhang As Range
Dim ws As Worksheet
'On Error GoTo Thoat 'xay ra loi~ neu Ten sheet ko tim` thay'
Set ws = ThisWorkbook.Worksheets(Range("H2").Value)
Set KH = Range("B2")
Set tenhang = Range("E2")

    If KH <> "" And Left(KH, 1) <> "*" Then KH = "*" & KH.Value & "*"
    If tenhang <> "" And Left(tenhang, 1) <> "*" Then tenhang = "*" & tenhang.Value & "*"
    
    ws.Range("A1:G65000").AdvancedFilter Action:=xlFilterCopy, _
                                                CriteriaRange:=Range("A1:G2"), _
                                                CopyToRange:=Range("A4:G4"), _
                                                Unique:=False
    
    Set ws = Nothing: Set KH = Nothing: Set tenhang = Nothing
'Thoat:
    'MsgBox (Err.Description)
End Sub

'----
file đính kèm ----> #32
 
Lần chỉnh sửa cuối:
Upvote 0
Hi bạn phucbugis,

Nếu mình có thêm một sheet nữa, ví dụ như là sheet "DuLieu2", là thông tin của khách hàng năm khác, định dạng giống như sheet "Dulieu" thì phải thêm vào đoạn code như thế nào để khi lọc thì lọc được ở cả 2 sheet và dán vào sheet "Trichloc" vậy bạn?
Sử dụng code của nghiaphuc đi, chỉnh lại 1 chút là cho bạn 100 sheet Dulieu luôn (Miễn tên sheet bắt đầu bằng chữ Dulieu)
Mượn Code và File của nghiaphuc nhé.
[GPECODE=vb]
Sub TimKiem() Dim TuKhoa As String, Cot As String, VT As Long, Tmp, Tmp1, Arr()
Dim i As Long, j As Long, k As Long, DK As Boolean, Ws As Worksheet
TuKhoa = Sheets("Trichloc").[B1]
Cot = Sheets("Trichloc").[B2]
If Len(TuKhoa) * Len(Cot) = 0 Then
MsgBox "Chua nhap du thong tin.": Exit Sub
End If
ReDim Arr(1 To 1000, 1 To 7)
For Each Ws In ThisWorkbook.Worksheets
If Ws.Name Like "Dulieu*" Then
Tmp = Ws.[A2:G10000]
With WorksheetFunction
Tmp1 = .Transpose(Ws.[A1:G1])
VT = .Match(Cot, Tmp1, 0)
End With
For i = 1 To UBound(Tmp)
If IsEmpty(Tmp(i, 1)) Then Exit For
If VT = 2 Or VT = 5 Then
DK = InStr(1, Tmp(i, VT), TuKhoa, vbTextCompare) > 0
Else
DK = (Tmp(i, VT) = TuKhoa)
End If
If DK Then
k = k + 1
For j = 1 To 7
Arr(k, j) = Tmp(i, j)
Next
End If
Next
End If
Next Ws
Sheets("Trichloc").[A5:G10000].Clear
If k > 0 Then Sheets("Trichloc").[A5:G5].Resize(k).Value = Arr
End Sub[/GPECODE]
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Hi bạn phucbugis,

Đoạn code làm việc tốt khi mình thêm vào sheet "Dulieu2".
tuy nhiên, ý mình là mình có sheet "Dulieu" là thông tin năm 2012 chẳng hạn, và "Dulieu2" là thông tin năm 2013, "Dulieu3" là thông tin năm 2014,....
Ví dụ khách hàng có tên gần đúng là coca đều có dữ liệu tại cả 3 sheet trên, giờ mình muốn lọc coca này từ cả 3 sheet và dán vào sheet trichloc để mình có thể xem lại quá khứ những lần mua hàng của coca này.
Mong bạn giúp đỡ!
 
Upvote 0
Hi bạn phucbugis,

Đoạn code làm việc tốt khi mình thêm vào sheet "Dulieu2".
tuy nhiên, ý mình là mình có sheet "Dulieu" là thông tin năm 2012 chẳng hạn, và "Dulieu2" là thông tin năm 2013, "Dulieu3" là thông tin năm 2014,....
Ví dụ khách hàng có tên gần đúng là coca đều có dữ liệu tại cả 3 sheet trên, giờ mình muốn lọc coca này từ cả 3 sheet và dán vào sheet trichloc để mình có thể xem lại quá khứ những lần mua hàng của coca này.
Mong bạn giúp đỡ!
Bạn xem lại bài ở trên của thầy Ba Tê đi, code đáp ứng được yêu cầu của bạn đấy.
 
Upvote 0
Bạn xem lại bài ở trên của thầy Ba Tê đi, code đáp ứng được yêu cầu của bạn đấy.

Vâng, em cảm ơn thầy Ba Tê và cảm ơn anh Phúc.

Cho em hỏi thêm là nếu "dulieu" của em từ cột A đến cột Z... chẳng hạn, và cho phép tìm gần đúng chỉ ở các cột B, E, G, I thì sửa lại code như thế nào ạ!?
 
Upvote 0
Hi bạn phucbugis,
Đoạn code làm việc tốt khi mình thêm vào sheet "Dulieu2".
tuy nhiên, ý mình là mình có sheet "Dulieu" là thông tin năm 2012 chẳng hạn, và "Dulieu2" là thông tin năm 2013, "Dulieu3" là thông tin năm 2014,....
Ví dụ khách hàng có tên gần đúng là coca đều có dữ liệu tại cả 3 sheet trên, giờ mình muốn lọc coca này từ cả 3 sheet và dán vào sheet trichloc để mình có thể xem lại quá khứ những lần mua hàng của coca này.
Mong bạn giúp đỡ!
ah,
thế thì rắc rối rồi, thông thường Advanced Filter chỉ lọc được từng sheet duy nhất +-+-+-+, còn áp dụng cho nhiều sheet thì mình chưa thấy ai làm bao h cả :-=
 
Upvote 0
Vâng, em cảm ơn thầy Ba Tê và cảm ơn anh Phúc.

Cho em hỏi thêm là nếu "dulieu" của em từ cột A đến cột Z... chẳng hạn, và cho phép tìm gần đúng chỉ ở các cột B, E, G, I thì sửa lại code như thế nào ạ!?
Bạn xem lại code trong bài của thầy Ba Tê:
1. Những chỗ nào địa chỉ có dạng A...:G... thì bạn sửa thành A...:Z... (chẳng hạn A1:G1 thành A1:Z1)
2. Câu lệnh If: If VT = 2 Or VT = 5 Then
bạn sửa lại thành If InStr(1,".2.5.7.9.","." & VT & ".",vbTextCompare) > 0 Then
 
Upvote 0
ah,
thế thì rắc rối rồi, thông thường Advanced Filter chỉ lọc được từng sheet duy nhất +-+-+-+, còn áp dụng cho nhiều sheet thì mình chưa thấy ai làm bao h cả :-=
Vậy thì ta copy tuốt tuồn tuột vào 1 sheet (chứa ở một vùng tạm nào đó) rồi dùng Advanced Filter một lần luôn. Sau đó thì xóa cái vùng tạm đó đi.

Bổ sung thêm một chút: Nếu không muốn xóa cái vùng tạm đó đi thì mình có thể copy tất cả từ các sheet vào vị trí chứa kết quả luôn, sau đó sử dụng Advanced Filter với Action là xlFilterInPlace
 
Lần chỉnh sửa cuối:
Upvote 0
ah,
thế thì rắc rối rồi, thông thường Advanced Filter chỉ lọc được từng sheet duy nhất +-+-+-+, còn áp dụng cho nhiều sheet thì mình chưa thấy ai làm bao h cả :-=
Thử SUB này xem sao, muốn bi nhiêu cột thì chỉ cần sửa 1 chỗ một thôi.
[GPECODE=vb]
Sub GPE_()
Dim DK1 As String, DK2 As String, C As Long, Ws As Worksheet
Dim sArr(), dArr(), I As Long, J As Long, K As Long, Tem As String, Col As Long
With Sheets("Trichloc")
DK1 = UCase(.[B1])
DK2 = UCase(.[B2])
C = 24 '<-----------Muon bi nhieu cot thi sua so nay
For J = 1 To C
If UCase(.Cells(4, J)) = DK2 Then
Col = J
Exit For
End If
Next J
End With
ReDim dArr(1 To 10000, 1 To C)
For Each Ws In ThisWorkbook.Worksheets
If Ws.Name Like "Dulieu*" Then
sArr = Ws.Range(Ws.[A2], Ws.[A65536].End(xlUp)).Resize(, C).Value2
For I = 1 To UBound(sArr, 1)
Tem = UCase(sArr(I, Col))
If Tem Like "*" & DK1 & "*" Then
K = K + 1
For J = 1 To C
dArr(K, J) = sArr(I, J)
Next J
End If
Next I
End If
Next Ws
With Sheets("Trichloc")
.[A5:A10000].Resize(, C).ClearContents
If K > 0 Then .[A5].Resize(K, C) = dArr
End With
End Sub[/GPECODE]
 
Lần chỉnh sửa cuối:
Upvote 0
Bạn xem lại code trong bài của thầy Ba Tê:
1. Những chỗ nào địa chỉ có dạng A...:G... thì bạn sửa thành A...:Z... (chẳng hạn A1:G1 thành A1:Z1)
2. Câu lệnh If: If VT = 2 Or VT = 5 Then
bạn sửa lại thành If InStr(1,".2.5.7.9.","." & VT & ".",vbTextCompare) > 0 Then

Cảm ơn a Phúc. Em đã test với file công việc của em, chạy rất tốt ạ.
Vậy anh xem giúp em trường hợp nếu có nhiều sheet Dulieu*, nhưng nằm ở các workbook khác nhau thì có lọc được không ạ. (Vì thật sự file từng năm của em dữ liệu tại mỗi sheet đã lên đến gần 50,000 dòng, mỗi file đã chứa khoảng 5 sheet, em không thể gom tất cả các sheet lại vào 1 workbook vì như vậy dung lượng file rất lớn, với lại khó theo dõi).
 
Upvote 0
Với lại các anh có thể xem giúp em đoạn code này không ạ: Khi em lọc theo cột Y (là cột cuối cùng trong dulieu) thì báo lỗi ở phần chữ màu đỏ:

Sub TimKiem()
Dim TuKhoa As String, Cot As String, VT As Long, Tmp, Tmp1, Arr()
Dim i As Long, j As Long, k As Long, DK As Boolean, Ws As Worksheet
TuKhoa = Sheets("Trichloc").[B1]
Cot = Sheets("Trichloc").[B2]
If Len(TuKhoa) * Len(Cot) = 0 Then
MsgBox "Chua nhap du thong tin.": Exit Sub
End If
ReDim Arr(1 To 1000, 1 To 25)
For Each Ws In ThisWorkbook.Worksheets
If Ws.Name Like "Dulieu*" Then
Tmp = Ws.[A3:Y10000]
With WorksheetFunction
Tmp1 = .Transpose(Ws.[A1:Y1])
VT = .Match(Cot, Tmp1, 0)
End With
For i = 1 To UBound(Tmp)
If IsEmpty(Tmp(i, 1)) Then Exit For
If VT = 21 Or VT = 22 Then
DK = InStr(1, Tmp(i, VT), TuKhoa, vbTextCompare) > 0
Else
DK = (Tmp(i, VT) = TuKhoa)
End If
If DK Then
k = k + 1
For j = 1 To 25
Arr(k, j) = Tmp(i, j)
Next
End If
Next
 
Upvote 0
Web KT

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

Back
Top Bottom