Kỹ thuật lọc dữ liệu bằng AdvancedFilter.

Liên hệ QC

ThichExcel

Thành viên bị đình chỉ hoạt động
Thành viên bị đình chỉ hoạt động
Tham gia
11/10/06
Bài viết
68
Được thích
21
Xin hỏi diễn đàn 1 việc như sau : Giả sử mình có tập hợp dữ liệu mã hàng là các chuỗi ký tự (4 Ký tự chẳng hạn) và tương ứng mỗi mã hàng là các thông tin về hàng hóa. Mình muốn thực hiện 1 tao tác lọc như sau : Giả sử mình đánh 2 ký tự vào 1ô (Ví dụ là ô A1) thì ở cột B sẽ thống kê toàn bộ các hàng hóa mà 2 ký tự đầu trong chuỗi mã của chúng chính là 2 ký tự mà mình vừa đánh.(Còn nếu đánh 1 ký tự, 3 hay n ký tự thì tương tự). Các bạn giúp mình với.
 
Chỉnh sửa lần cuối bởi điều hành viên:
Để làm kiểu đó anh có thể tìm hiểu hàm VLOOKUP thử nha. Cái này không cần sử dụng lập trình. Cái đó cho phép tìm kiếm tên hàng theo mã hàng.
 
Upvote 0
Dear skyonline,
--------------
Mình thấy ThichExcel thích cả... lập trình nữa, nên trả lời của bạn có thể chưa được thoả đáng.
Theo mình đây là chủ đề rất thiết thực và hầu hết những ai sử dụng MS Excel đều có nhu cầu này. Mặt khác vấn đề được nêu trong box lập trình và cũng chưa có chủ đề tương tự nên không bị coi là phạm quy.
Theo mình nên đặt chủ đề này thành: "Kỹ thuật lọc dữ liệu bằng AdvancedFilter" với mục đích giúp nhau tìm hiểu và vận dụng linh hoạt mọi trường hợp chứ không chỉ trường hợp cụ thể như của ThichExcel.
Có rất nhiều bài viết có liên quan thuộc nhiều chủ đề và diễn đàn khác nhau, có thể các bài viết đó sẽ được gộp lại trong chủ đề này để các bạn có được cái cái nhìn toàn diện hơn.
Nói chung, để có được những code minh hoạ đơn giản, các bạn nên nhờ Macro hỗ trợ. Các bước thu một Macro xin phép không được đề cập ở đây. Điều quan trọng là bạn thấy được mã Macro được phát xinh như thế nào, cần phải chỉnh sửa ra sao cho phù hợp với nhu cầu của bạn. Một điều quan trọng nữa là bạn phải hiểu và thành thạo về Advanced Filter.
Sau đây là một đoạn code mà mình thu được từ việc lọc một bảng dữ liệu:
Mã:
[LEFT]Sub Macro1()
'
' Macro1 Macro
' Macro recorded 17/10/2006 by Cuongdv
'
'
    Range("A1:G6").AdvancedFilter Action:=xlFilterCopy, CriteriaRange:=Range( _
        "I1:O2"), CopyToRange:=Range("I4"), Unique:=False
End Sub[/LEFT]
Qua Macro này các bạn có thể nhận xét:
- AdvancedFilter là một phương thức của tập hợp Range (tạm gọi là bảng dữ liệu cơ sở)
- AdvancedFilter có một tham số bắt buộc là Action quy định phương thức biểu diễn kết quả trực tiếp trên bảng dữ liệu cơ sở hay trên một vùng khác (CopyToRange)
- Tham số tuỳ chọn Unique cho phép bạn lựa chọn có áp dụng phương thức lọc loại bỏ dữ liệu trùng hay không.
- Hầu việc lọc dữ liệu đều có nhu cầu dựa vào một hay nhiều điều kiện. Lưu ý rằng điều kiện này phải được thiết lập trên một vùng xác định chứ không phải là một chuỗi dữ kiện vì CriteriaRange có kiểu là Range. Theo kinh nghiệm, các bạn nên đặt cho mỗi vùng dữ liệu một cái tên. Việc sử dụng name cho phương thức AdvancedFilter có nhiều lợi ích, trong đó lợi ích thiết thực nhất là các bạn có thể đặt các vùng dữ liệu trên nhiều sheet khác nhau (nếu thực hiện bằng tay và không sử dụng name các bạn không thể làm được).
Cuối cùng, cần cải tiến thủ tục để việc lọc được linh hoạt cho nhiều trường hợp, nhiều bảng khác nhau. Sẽ có một lỗi phát sinh xảy ra khi bạn cố gắng lọc dữ liệu mà kết quả lần trước vẫn còn dữ nguyên. Cách xử lý là trước khi thực hiện AdvancedFilter, bạn cần "clear" kết quả lần lọc lần trước bằng phương thức ClearContents của vùng CopyToRange.
Đoạn code sau đây minh hoạ việc lọc dữ liệu một tài khoản từ sổ Nhật ký chung để lập sổ cái cho tài khoản đó:
Mã:
Sub AdvancedFilter(rgNHATKY As Range,rgCriteria As Range, rgCopyTo As Range, Optional Unique as Boolean)
rgCopyTo.CurrentRegion.ClearContents
rgNHATKY.AdvancedFilter xlFilterCopy, rgCriteria, rgCopyTo, Unique 
[COLOR=darkgreen]'Các xử lý tiếp theo của bạn ở đây[/COLOR]
End Sub
 
Upvote 0
Dear all,
--------
Vì các chủ đề liên quan tới kỹ thuật lọc dữ liệu bằng Addvanced Filter được thảo luận theo nhiều hướng khác nhau nên theo tôi không gộp các chủ đề đó lại với nhau như ý định ban đầu nữa mà chúng ta sẽ tổng hợp các bài viết đó lại trong chủ đề này:
1. Tìm hiểu về Advanced Filter (Chuyên mục Excel và Các Công Cụ Nâng Cao)
2. How to use AutoFilters in Excel VBA Macros (Chuyên mục Lập Trình với Excel)
3. Dùng Macro lọc dữ liệu bảng trong Excel (Chuyên mục Excel và Kế Toán)
4. Tự động trích ngang dữ liệu trong Excel (Chuyên mục Excel và Kế Toán)
 
Lần chỉnh sửa cuối:
Upvote 0
Tôi không biết bạn ThichExcel đã đọc phần trả lời của các bác ở trên chưa, nhưng theo tôi nghĩ bạn ThichExcel muốn đưa ra danh sách giống tương đối (chứ không phải tuyệt đối như AdvancedFilter) giá trị nhập vào.
 
Upvote 0
chibi đã viết:
Tôi không biết bạn ThichExcel đã đọc phần trả lời của các bác ở trên chưa, nhưng theo tôi nghĩ bạn ThichExcel muốn đưa ra danh sách giống tương đối (chứ không phải tuyệt đối như AdvancedFilter) giá trị nhập vào.

AdvancedFilter xài cả tuyệt đối tương đối bạn ạ (bằng việc sử dùng ký tự đại diện, công thức . . .)
VD :
Tuyệt đối : chibi
Tương đối : chi?i -> chiai; chibi; chici . . .
Tương đối : chi* -> chiabhskjds; chsdjf; chi093

Thân!
 
Upvote 0
Bạn nên cho thêm dữ liệu bên sheet tongket bạn cần gì để mọi người có thể theo dõi được.
 
Upvote 0
Bạn xem thử cái ni có đúng í chưa nha!?!

Nhập những gì bạn cần & vô 'F1'
Mã:
[B]Private Sub Worksheet_Change(ByVal Target As Range)[/B]
    If Not Intersect(Target, Range("F1")) Is Nothing Then AdvFilter
[B]End Sub[/B]
--=0 !$@!! --=0
Mã:
[B]Sub AdvFilter()[/B]
    Range("DSach").Select
    Range("DSach").AdvancedFilter Action:=xlFilterCopy, CriteriaRange:=Range( _
        "H2:J3"), CopyToRange:=Range("G6:J6"), Unique:=False
[B]End Sub[/B]
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
khoản đó:
Mã:
Sub AdvancedFilter(rgNHATKY As Range,rgCriteria As Range, rgCopyTo As Range, Optional Unique as Boolean)
rgCopyTo.CurrentRegion.ClearContents
rgNHATKY.AdvancedFilter xlFilterCopy, rgCriteria, rgCopyTo, Unique 
[COLOR=darkgreen]'Các xử lý tiếp theo của bạn ở đây[/COLOR]
End Sub
Từ các đoạn code trên net, in Help Excel và ý tưởng của bạn, tôi đã có thể dùng đoạn
code sau:
Mã:
MyRngColection.AdvancedFilter MyFilterActionCopy, MyCriteriaRange, MyCopyToRange, MyUnique

với Data, CopyToRange, Criteria nằm trong các workbooks khác nhau, xem file attached
Nếu khg muốn đọc code mà chỉ cần áp dụng.Các bạn không cần chỉnh sửa các path của file , vùng (Range) cần dùng trong VBA, chỉ
cần chỉnh trong AdFilterOnlyCode.xls! Sheet1
Cám ơn bạn nhé

máy lại treo, chưa gửi được file.Thôi chỉ có vài đoạn code nhỏ, các bạn thử đọc chay vậy
------------
Mã:
Option Explicit
    Dim WbColecRgn As Workbook, WbCopyRng As Workbook, WbCriteriaRng As Workbook
    'MyWks As Worksheet
    Dim MyRngColection As Range
    Dim iRow As Integer
    Dim tRgColecWbDir As String, tRgColecWb As String, tRgColecWks As String, tRgColec As String
    Dim MyCriteriaDir As String, MyCriteriaWb As String, MyCriteriaWk As String, MyCriteriaRng As String
    Dim MyCopyToRangeDir As String, MyCopyToRangeWb As String, MyCopyToRangeWk As String, MyCopyToRangeRng As String
    Const MyFilterActionCopy As Integer = 2
    Dim MyCriteriaRange As Variant, MyCopyToRange As Variant, MyUnique As Variant
  

Sub SetDataListToAdFilter()
Application.ScreenUpdating = False
iRow = 2
With ThisWorkbook.Worksheets("Sheet1")
    tRgColecWbDir = .Cells(iRow, 2)
    tRgColecWb = .Cells(iRow, 3)
    tRgColecWks = .Cells(iRow, 4)
    tRgColec = .Cells(iRow, 5)
    
If bIsBookOpen(.Cells(iRow, 3)) Then
        Set WbColecRgn = Workbooks(tRgColecWb)
        'Set MyWks = Worsheets(tRgColecWks)
    Else
        Set WbColecRgn = Workbooks.Open(tRgColecWbDir & tRgColecWb)
        'Set MyWks = Worsheets(tRgColecWks)
    End If
    Set MyRngColection = WbColecRgn.Worksheets(tRgColecWks).Range(tRgColec)
    
'MyFilterAction = Cells(2, 14)

End With

Call SetCriteriaAndCopyToRange
MyRngColection.AdvancedFilter MyFilterActionCopy, MyCriteriaRange, MyCopyToRange, MyUnique

Call DeleteFilterName
WbColecRgn.Close True
WbCriteriaRng.Close True

Application.ScreenUpdating = True
End Sub
Sub SetCriteriaAndCopyToRange()
Application.ScreenUpdating = False

    With ThisWorkbook.Worksheets("Sheet1")
        MyCriteriaDir = .Cells(iRow, 6)
        MyCriteriaWb = .Cells(iRow, 7)
        MyCriteriaWk = .Cells(iRow, 8)
        MyCriteriaRng = .Cells(iRow, 9)
        
        
        If bIsBookOpen(MyCriteriaWb) Then
            Set WbCriteriaRng = Workbooks(MyCriteriaWb)
        Else
            Set WbCriteriaRng = Workbooks.Open(MyCriteriaDir & MyCriteriaWb)
        End If
    
        MyCopyToRangeDir = .Cells(iRow, 10)
        MyCopyToRangeWb = .Cells(iRow, 11)
        MyCopyToRangeWk = .Cells(iRow, 12)
        MyCopyToRangeRng = .Cells(iRow, 13)
        
        If bIsBookOpen(MyCopyToRangeWb) Then
            Set WbCopyRng = Workbooks(MyCopyToRangeWb)
        Else
            Set WbCopyRng = Workbooks.Open(MyCopyToRangeDir & MyCopyToRangeWb)
        End If
        
    Set MyCriteriaRange = Workbooks(MyCriteriaWb).Worksheets(MyCriteriaWk).Range(MyCriteriaRng)
    Set MyCopyToRange = Workbooks(MyCopyToRangeWb).Worksheets(MyCopyToRangeWk).Range(MyCopyToRangeRng)
    MyUnique = .Cells(iRow, 15)


    End With
    Application.ScreenUpdating = True
  
End Sub

Sub MyAdvancedFilter(MyFilterAction As String, MyCriteriaRange As Variant, MyCopyToRange As Variant, MyUnique As Variant)
MyCollectionRange.AdvancedFilter MyFilterAction, MyCriteriaRange, MyCopyToRange, MyUnique
End Sub

Sub DeleteFilterName()
On Error Resume Next
With ActiveWorkbook
.Names("_FilterDatabase").Delete
.Names("Criteria").Delete
.Names("Extract").Delete
End With
End Sub

Function bIsBookOpen(ByRef szBookName As String) As Boolean
' Rob Bovey
    On Error Resume Next
    bIsBookOpen = Not (Application.Workbooks(szBookName) Is Nothing)
End Function

file mẫu mình đã gửi tại:
http://www.giaiphapexcel.com/forum/showthread.php?t=886&page=2
 
Upvote 0
Nhập những gì bạn cần vô 'F1'
Mã:
[B]Private Sub Worksheet_Change(ByVal Target As Range)[/B]
    If Not Intersect(Target, Range("F1")) Is Nothing Then AdvFilter
[B]End Sub[/B]
--=0 !$@!! --=0
Mã:
[B]Sub AdvFilter()[/B]
    Range("DSach").Select
    Range("DSach").AdvancedFilter Action:=xlFilterCopy, CriteriaRange:=Range( _
        "H2:J3"), CopyToRange:=Range("G6:J6"), Unique:=False
[B]End Sub[/B]

Xin Cho Tấn hỏi về vấn đề này với, nếu Tấn muốn dùng advancedFilter để lấy dữ liệu ở một sheet1 để cho qua sheet2 theo CriteriaRange và Copy ToRange ( điều nằm ở sheet2, Bạn nào biết xin chỉ cho Mình với, vì mình áp dụng đoạn code này thì không được.
Rất cảm ơn.
 

File đính kèm

Upvote 0
Xin Cho Tấn hỏi về vấn đề này với, nếu Tấn muốn dùng advancedFilter để lấy dữ liệu ở một sheet1 để cho qua sheet2 theo CriteriaRange và Copy ToRange ( điều nằm ở sheet2, Bạn nào biết xin chỉ cho Mình với, vì mình áp dụng đoạn code này thì không được.
Rất cảm ơn.
Bạn xóa hết mấy code củ, dùng code này đưa vào sheet 2 nhé:
PHP:
Private Sub Worksheet_Change(ByVal Target As Range)
   If Target.Address = "$A$1" Then
   Range("B6:E1000").Clear
    Sheet1.Range("DSach").AdvancedFilter Action:=xlFilterCopy, CriteriaRange:=Range( _
        "C2:E3"), CopyToRange:=Range("B6:E6")
   End If
End Sub
 
Upvote 0
Bạn xóa hết mấy code củ, dùng code này đưa vào sheet 2 nhé:
PHP:
Private Sub Worksheet_Change(ByVal Target As Range)
   If Target.Address = "$A$1" Then
   Range("B6:E1000").Clear
    Sheet1.Range("DSach").AdvancedFilter Action:=xlFilterCopy, CriteriaRange:=Range( _
        "C2:E3"), CopyToRange:=Range("B6:E6")
   End If
End Sub
Trước tiên cho Tấn được Cảm ơn Bạn ndu96081631 và bạn Hyen17 đã hồi thư cho Tấn, if trong quá trình làm còn vấn đề gì k hiểu thì Tấn rất mong các bạn giúp đỡ, Hy vong se còn gặp lại các bạn.
TKS
NM1000kg

Tấn đã lấy đoạn code của Bạn ndu96081631 rồi nhưng vẫn bị lỗi. Bạn có thể tạo xong rồi gửi lại cho Tấn đc k?
Rất Cảm ơn
NM1000kg
Ban có thể gửi về nguyentan1000@yahoo.com
Rất cảm ơn bạn

Hyen17 ơi, Ban đừng có cười Tấn nha!!! Bạn cho Mình code ma mình k biết áp dụng thế nào luôn, Potay chưa??? Bạn có thể chỉ mình kỹ hơn
TKS
NM1000kg
 

File đính kèm

Upvote 0
Tấn đã lấy đoạn code của Bạn ndu96081631 rồi nhưng vẫn bị lỗi. Bạn có thể tạo xong rồi gửi lại cho Tấn đc k?
Rất Cảm ơn
NM1000kg
Ban có thể gửi về nguyentan1000@yahoo.com
Rất cảm ơn bạn
Đã nói là bạn phải xóa hết code củ đi rồi mới chèn code này vào! Bạn chừa lại lên bị lổi là phải rồi!
Tôi làm luôn đây!
 

File đính kèm

Upvote 0
àh, các anh chị cho mình hỏi, sao trong file của ndu9608631 có một công thức =A1&"*", nó mang ý nghĩa gì vậy? Sao phải là dấu *? Khi mình xóa đi thì việc lọc không chính xác nữa.
Xin chân thành cám ơn!!!
 
Upvote 0
àh, các anh chị cho mình hỏi, sao trong file của ndu9608631 có một công thức =A1&"*", nó mang ý nghĩa gì vậy? Sao phải là dấu *? Khi mình xóa đi thì việc lọc không chính xác nữa.
Xin chân thành cám ơn!!!
Dấu * là ký tự đại diện... Ví dụ cell A1 là MN, vậy công thức =A1&"*" có nghĩa là lấy phần đầu là MN còn sau đó là thứ gì cũng được, chẳng hạn MN01, MN02.. vân vân... miển sao 2 ký tự đầu là MN
Ý nghĩa trong file này là: Lọc ra tất cả phần mã có 2 ký tự đầu giống với cell A1, những ký tự phía sau đó là cái gì cũng được
 
Upvote 0
Tôi thấy các bạn đưa ra các ý kiến hoàn toàn đúng, nhưng chỉ những người rành về VBA mới hiểu được các đoạn code trên. Trường hợp sử dụng macro để thực hiện từng bước như bạn Cường đã hướng dẫn sẽ xảy ra hiện tượng: chỉ đúng trên sheet đó, còn các sheets khác sẽ không đúng vì địa chỉ không tường minh, đặc biệt nếu xử dụng lệnh copy dữ liệu đã lọc qua sheet khác.
 
Upvote 0
Tôi thấy các bạn đưa ra các ý kiến hoàn toàn đúng, nhưng chỉ những người rành về VBA mới hiểu được các đoạn code trên. Trường hợp sử dụng macro để thực hiện từng bước như bạn Cường đã hướng dẫn sẽ xảy ra hiện tượng: chỉ đúng trên sheet đó, còn các sheets khác sẽ không đúng vì địa chỉ không tường minh, đặc biệt nếu xử dụng lệnh copy dữ liệu đã lọc qua sheet khác.
Tất nhiên là được chứ!
Này nhé! Dử liệu nằm ở sheet Nhap, và bạn muốn xuất ra báo cáo ra sheet Baocao... sẽ có 2 tình huống xảy ra:
- Bạn đứng tại sheet Nhap và gọi lệnh Advanced Filter thì chắc ăn sẽ bị báo lổi
- Bạn sang sheet Baocao và gọi lệnh Advanced Filter, trong khung List range bạn chỉ đến sheet Nhap thì mọi chuyện sẽ được giãi quyết
Tóm lại: Xuất dử liệu ra sheet nào thì đúng ở đó mà gọi lệnh Advanced Filter
Còn code khó hiểu uh? Không hẳn thế! Vì thật sự bạn chỉ cần record macro toàn bộ quá trình bạn thao tác là được
 
Upvote 0
Tất nhiên là được chứ!
Này nhé! Dử liệu nằm ở sheet Nhap, và bạn muốn xuất ra báo cáo ra sheet Baocao... sẽ có 2 tình huống xảy ra:
- Bạn đứng tại sheet Nhap và gọi lệnh Advanced Filter thì chắc ăn sẽ bị báo lổi
- Bạn sang sheet Baocao và gọi lệnh Advanced Filter, trong khung List range bạn chỉ đến sheet Nhap thì mọi chuyện sẽ được giãi quyết
Tóm lại: Xuất dử liệu ra sheet nào thì đúng ở đó mà gọi lệnh Advanced Filter
Còn code khó hiểu uh? Không hẳn thế! Vì thật sự bạn chỉ cần record macro toàn bộ quá trình bạn thao tác là được

Làm ơn giúp em ví dụ này nhé
em muốn lọc ra tất cả bên nợ và có của tk 111 . ( có ví dụ đính kèm đó) em cảm ơn nhiều nhé
Thanks! nhiều....nhiều....
 

File đính kèm

Upvote 0
Làm ơn giúp em ví dụ này nhé
em muốn lọc ra tất cả bên nợ và có của tk 111 . ( có ví dụ đính kèm đó) em cảm ơn nhiều nhé
Thanks! nhiều....nhiều....
Bạn nên dùng chức năng tại menu: DATA=>Filter=>Autofilter.
Còn nếu dùng code thì bạn thử File dưới đây nhé. Làm vội nên chưa gọn. Bạn tham khảo rồi tuỳ chỉnh cho phù hợp.
 

File đính kèm

Upvote 0
Web KT

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

Back
Top Bottom