Code để lọc theo nhiều điều kiện (1 người xem)

Liên hệ QC

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

Tôi tuân thủ nội quy khi đăng bài

LuuGiaPhúc

Thành viên hoạt động
Tham gia
28/7/21
Bài viết
126
Được thích
52
Em nhờ các anh chị sửa giúp em đoạn code này :
Em có 1 đoạn code dùng để tổng hợp nhiều file có nhiều sheet về 1 file hiện hành , trong đó, trước khi ghép thì code sẽ filter để loại bỏ ở cột A những hàng nào có 3 chữ cái đầu là ICC và BVB , code của em hiện giờ vẫn đang hoạt động tốt , đoạn code lọc đó như sau :

Set filterRange = ws.Range("A3:CK" & ws.Cells(ws.Rows.Count, "D").End(xlUp).Row)
filterRange.AutoFilter Field:=1, Criteria1:="<>ICC*", Operator:=xlAnd, Criteria2:="<>BVB*"

Bây giờ em muốn thêm 2 điều kiện nữa là loại bỏ thêm những hàng mà ở cột A có 3 chữ cái đầu là ZPC , BAN , em đã sửa code thành
Set filterRange = ws.Range("A3:CK" & ws.Cells(ws.Rows.Count, "D").End(xlUp).Row)
filterRange.AutoFilter Field:=1, Criteria1:="<>ICC*", Operator:=xlAnd, Criteria2:="<>BVB*" , Criteria3:="<>ZPC*" , Criteria4:="<>BAN*"
nhưng không hiểu sao nó không hoạt động, thậm chí bây giờ nó không lọc bất kỳ giá trị nào luôn không lẽ sau điều kiện Operator:=xlAnd, nó chỉ cho mình thêm 1 Criteria thôi hay sao ???

Data của em có dạng như sau :

1718716927816.png
 
Em nhờ các anh chị sửa giúp em đoạn code này :
Em có 1 đoạn code dùng để tổng hợp nhiều file có nhiều sheet về 1 file hiện hành , trong đó, trước khi ghép thì code sẽ filter để loại bỏ ở cột A những hàng nào có 3 chữ cái đầu là ICC và BVB , code của em hiện giờ vẫn đang hoạt động tốt , đoạn code lọc đó như sau :

Set filterRange = ws.Range("A3:CK" & ws.Cells(ws.Rows.Count, "D").End(xlUp).Row)
filterRange.AutoFilter Field:=1, Criteria1:="<>ICC*", Operator:=xlAnd, Criteria2:="<>BVB*"

Bây giờ em muốn thêm 2 điều kiện nữa là loại bỏ thêm những hàng mà ở cột A có 3 chữ cái đầu là ZPC , BAN , em đã sửa code thành
Set filterRange = ws.Range("A3:CK" & ws.Cells(ws.Rows.Count, "D").End(xlUp).Row)
filterRange.AutoFilter Field:=1, Criteria1:="<>ICC*", Operator:=xlAnd, Criteria2:="<>BVB*" , Criteria3:="<>ZPC*" , Criteria4:="<>BAN*"
nhưng không hiểu sao nó không hoạt động, thậm chí bây giờ nó không lọc bất kỳ giá trị nào luôn không lẽ sau điều kiện Operator:=xlAnd, nó chỉ cho mình thêm 1 Criteria thôi hay sao ???

Data của em có dạng như sau :

View attachment 301798
Thử so sánh chỗ điều kiện cũ với điều kiện mới thêm xem khác nhau chỗ nào, có thấy thiếu mục này không: Operator:=xlAnd
 
Thử so sánh chỗ điều kiện cũ với điều kiện mới thêm xem khác nhau chỗ nào, có thấy thiếu mục này không: Operator:=xlAnd
Em cũng có thử kiểu :
Set filterRange = ws.Range("A3:CK" & ws.Cells(ws.Rows.Count, "D").End(xlUp).Row)
filterRange.AutoFilter Field:=1, Criteria1:="<>ICC*", Operator:=xlAnd, Criteria2:="<>BVB*" , Operator:=xlAnd , Criteria3:="<>ZPC*" , Operator:=xlAnd , Criteria4:="<>BAN*" nhưng cũng không được luôn
 
Em cũng có thử kiểu :
Set filterRange = ws.Range("A3:CK" & ws.Cells(ws.Rows.Count, "D").End(xlUp).Row)
filterRange.AutoFilter Field:=1, Criteria1:="<>ICC*", Operator:=xlAnd, Criteria2:="<>BVB*" , Operator:=xlAnd , Criteria3:="<>ZPC*" , Operator:=xlAnd , Criteria4:="<>BAN*" nhưng cũng không được luôn
Bạn gửi file lên xem cụ thể thế nào.
 
Filter nhiều lần, mỗi lần 1 hoặc 2 criteria
Mõi câu lệnh filter chỉ có thể có thể chứa 1 xlAnd/Or thôi.
 
Bạn gửi file lên xem cụ thể thế nào.

Đoạn code em sửa đây ạ

1718719379762.png
Bài đã được tự động gộp:

Filter nhiều lần, mỗi lần 1 hoặc 2 criteria
Mõi câu lệnh filter chỉ có thể có thể chứa 1 xlAnd/Or thôi.
em cũng có suy luận như thế, tức là mình filter 2 lần , mỗi lần 2 criteria như sau :
Set filterRange = ws.Range("A3:CK" & ws.Cells(ws.Rows.Count, "D").End(xlUp).Row)
filterRange.AutoFilter Field:=1, Criteria1:="<>ICC*", Operator:=xlAnd, Criteria2:="<>BVB*"
filterRange.AutoFilter Field:=1, Criteria1:="<>ZPC*", Operator:=xlAnd, Criteria2:="<>BAN*"
thì nó lại chỉ lấy theo cái sau , xem như cái đầu không có tác dụng (nó bỏ ZPC và BAN , nhưng vẫn còn ICC và BVB)
chắc em còn sai chỗ nào khác nên chưa làm được
 

File đính kèm

Lần chỉnh sửa cuối:
Đoạn code em sửa đây ạ

View attachment 301802
Bài đã được tự động gộp:


em cũng có suy luận như thế, tức là mình filter 2 lần , mỗi lần 2 criteria như sau :
Set filterRange = ws.Range("A3:CK" & ws.Cells(ws.Rows.Count, "D").End(xlUp).Row)
filterRange.AutoFilter Field:=1, Criteria1:="<>ICC*", Operator:=xlAnd, Criteria2:="<>BVB*"
filterRange.AutoFilter Field:=1, Criteria1:="<>ZPC*", Operator:=xlAnd, Criteria2:="<>BAN*"
thì nó lại chỉ lấy theo cái sau , xem như cái đầu không có tác dụng (nó bỏ ZPC và BAN , nhưng vẫn còn ICC và BVB)
chắc em còn sai chỗ nào khác nên chưa làm được
Bài này có lẽ mô tả điều kiện cần lấy để viết code mới sẽ nhanh hơn mò mẫm để sửa bạn ơi.
 
Bài này có lẽ mô tả điều kiện cần lấy để viết code mới sẽ nhanh hơn mò mẫm để sửa bạn ơi.
Vâng , cảm ơn bạn rất nhiều , tại vì code cũ hiện đang chạy bình thường, chỉ là do có thêm 2 loại văn phòng mới xuất hiện nên mình muốn loại bỏ cho nó nhẹ file tổng hợp thôi , mình nghĩ đơn giản là tìm cách sửa thêm điều kiện lọc ngoài việc bỏ 2 văn phòng trước giờ là ICC* và BVB* thì giờ bỏ thêm ZPC* và BAN* nữa thôi là ổn.

Nếu không thì như bạn góp ý, bạn có thể thay đổi code mới giúp cho mình thì quá tốt rồi, mình xin liệt kê các điều kiện để tổng hợp như sau :
1. Có nhiều file Report1.xls , Report2.xlsx , Report3.xlsx.... do các bạn dưới văn phòng gởi về , mỗi file có thể có 1 sheet , cũng có thể có nhiều sheet. Yêu cầu mình sẽ tổng hợp tất cả về 1 sheet hiện hành của file 1.Data Master.
Lưu ý : do đã từng có lần bị lỗi là , trong các file mà các bạn gởi về , có thể có 1 file nào đó bị lỗi hoặc tổng cộng gom hết toàn bộ data của mọi người về có thể vượt quá 1trieu dòng (lần trước , có 2 file trong tổng số 19 file của các bạn gởi về bị lỗi , cái code cũ nó bỏ qua mà không thông báo gì hết nên dẫn đến thiếu dữ liệu mà mình không biết ==> dẫn đến báo cáo sai, nên mình rút kinh nghiệm , trong code , mình có ràng 2 điều kiện kiểm tra trước khi tổng hợp :

Set wb = Workbooks.Open(myFile(i))
If Err.Number <> 0 Then ' kiem tra xem trong so cac file da chon, có file nào bi loi khong mo duoc hay không, neu co thì phai hien thông báo cho mình biet
MsgBox "File : " & vbNewLine & Mid(myFile(i), InStrRev(myFile(i), "\") + 1) & vbNewLine & vbNewLine & " CÓ LOI KHÔNG COPY DUOC, DA BO QUA FILE NÀY, NHO KIEM TRA LAI NHÉ..", , "LUU Ý : CÓ FILE BI LOI"
Err.Clear
wb.Close False
Else
For Each ws In wb.Worksheets
totalRows = totalRows + ws.UsedRange.Rows.Count
If totalRows > 1048570 Then
MsgBox "Tong data các file da chon nhieu hon 1048570 dòng. Không import duoc."
wb.Close False
Exit Sub
End If

2. Điều kiện tổng hợp : Tổng hợp bắt đầu từ hàng thứ 4 của mỗi sheet (lấy từ Range("A4:AP") gom hết về sheet hiện hành , bắt đầu paste vào ô A3 của file chính , kết thúc mỗi sheet thì cách 1 dòng trống (để sau này dễ kiểm tra lại) . Chú ý , PasteValuesAndNumberFormats để giữ nguyên định dạng của file gốc.
- Loại bỏ những hàng mà trong cột A hoặc trong cột B có 3 chữ cái đầu là 1 trong các ký tự sau : (loại bỏ, không copy nguyên hàng đó vào file chính) : ICC* , BVB* , ZPC* , BAN* , ATD* , DTM*
- Loại bỏ những hàng mà trong cột G có chữ "dummy_collection_agent"
- loại bỏ những hàng mà trong cột I có chữ "AMD".

Sau khi đã hoàn tất việc copy , đến file cuối cùng thì copy hàng tiêu đề của file report (Range("A3:AP3").Copy) và paste nó vào hàng thứ 2 của file chính Range("A2:AP2").PasteSpecial xlPasteValuesAndNumberFormats) . Lý do là vì thỉnh thoảng các file report này sẽ bị thêm cột hoặc xóa cột nên nếu không có thao tác này để đối chiếu thì sẽ dẫn đến lệch cột ==> sai báo cáo (mình có để ở hàng 1 của file chính tiêu đề chuẩn để đối chiếu , nếu sau khi copy hàng tiêu đề từ file report và file chính mà so sánh không giống với hàng thứ 1 thì conditional Formatting sẽ tô màu cột nào bị lệch thì mình sẽ biết
 
Lần chỉnh sửa cuối:
em cũng có suy luận như thế, tức là mình filter 2 lần , mỗi lần 2 criteria như sau :
...
thì nó lại chỉ lấy theo cái sau
Có 3 cách:
Cách 1:
Dường như cột B của bạn giống y cột A. Nếu vậy thì filter cột A 2 điều kiện này, filter cột B 2 điều kiện kia
Cách 2:
Không dùng AutoFilter mà dùng Advanced filter. Vùng điều kiện đặt ở file Master. Tôi chưa thử nhưng nếu không được thì thiết lập (tạo) vùng điều kiện tại file report.
Cách 3:
Dùng mảng và lọc trong mảng ra mảng mới.
 
Có 3 cách:
Cách 1:
Dường như cột B của bạn giống y cột A. Nếu vậy thì filter cột A 2 điều kiện này, filter cột B 2 điều kiện kia
Cách 2:
Không dùng AutoFilter mà dùng Advanced filter. Vùng điều kiện đặt ở file Master. Tôi chưa thử nhưng nếu không được thì thiết lập (tạo) vùng điều kiện tại file report.
Cách 3:
Dùng mảng và lọc trong mảng ra mảng mới.
Cột A và cột B gần như 90% giống nhau , nhưng thỉnh thoảng có học viên thay đổi văn phòng (rất ít , nhưng vẫn có) nên bắt buộc phải xem như khác nhau cho an toàn ạ. Em cũng có nghĩ cách 1 như anh nói nên đã áp dụng rồi (lúc trước chỉ loại 4 văn phòng nên em đã dùng đúng như anh nói, là cho cột A lọc 2 văn phòng, cột B lọc 2 văn phòng còn lại , nhưng giờ phát sinh thêm 2 văn phòng mới nên em mới bí , vì không thể ép thêm 2 văn phòng này vào được).
Em cũng có nghĩ tới ý tưởng của cách 2 , là tạo cột phụ, liệt kê hết các văn phòng sẽ bị loại bỏ , rồi cho code so sánh nếu có xuất hiện các văn phòng trong cột phụ ở file master của mình thì loại bỏ , nhưng em làm không được , em dùng vòng lặp for để nó quét thì nó chạy lâu kinh khủng , hơn 15 phút mới load xong 19 file , nên cách đó không dùng được, còn quay về AutoFilter thì load 19 file này chỉ khoảng hơn 4 phút là xong .

Cách 3 thì em không biết làm , hiện tại em dùng mẹo : đó là cho nó tổng hợp về 1 vùng tạm (ví dụ (CA3:EP) rồi dùng hàm mảng filter kết hợp offset để lấy toàn bộ vùng data sau khi tổng hợp ở CA3:EP để lọc bỏ theo các điều kiện của mình, đưa kết quả cuối cùng về ô A3, rồi paste value vùng data sau khi có kết quả của hàm filter , bước cuối cùng là xóa vùng tạm CA3:EP . Nhưng cách này thật sự thủ công quá
1718724341542.png
 
Lần chỉnh sửa cuối:
Em nhờ các anh chị sửa giúp em đoạn code này :
Em có 1 đoạn code dùng để tổng hợp nhiều file có nhiều sheet về 1 file hiện hành , trong đó, trước khi ghép thì code sẽ filter để loại bỏ ở cột A những hàng nào có 3 chữ cái đầu là ICC và BVB , code của em hiện giờ vẫn đang hoạt động tốt , đoạn code lọc đó như sau :

Set filterRange = ws.Range("A3:CK" & ws.Cells(ws.Rows.Count, "D").End(xlUp).Row)
filterRange.AutoFilter Field:=1, Criteria1:="<>ICC*", Operator:=xlAnd, Criteria2:="<>BVB*"

Bây giờ em muốn thêm 2 điều kiện nữa là loại bỏ thêm những hàng mà ở cột A có 3 chữ cái đầu là ZPC , BAN , em đã sửa code thành
Set filterRange = ws.Range("A3:CK" & ws.Cells(ws.Rows.Count, "D").End(xlUp).Row)
filterRange.AutoFilter Field:=1, Criteria1:="<>ICC*", Operator:=xlAnd, Criteria2:="<>BVB*" , Criteria3:="<>ZPC*" , Criteria4:="<>BAN*"
nhưng không hiểu sao nó không hoạt động, thậm chí bây giờ nó không lọc bất kỳ giá trị nào luôn không lẽ sau điều kiện Operator:=xlAnd, nó chỉ cho mình thêm 1 Criteria thôi hay sao ???

Data của em có dạng như sau :

View attachment 301798
Tạo cột phụ rồi code.
Bao nhiêu điều kiện --> bấy nhiêu cột phụ --> chép cột A vào các cột phụ --> mỗi cột 1 điều kiện cho lành!
 
Cách 2 không phải như vậy mà làm như sau:
Tạo vùng điều kiện:
1718725605634.png

Code:
Mã:
    Range("A3:J4747").AdvancedFilter Action:=xlFilterInPlace, CriteriaRange:=Range _
        ("B1:E2"), Unique:=False
Cách 3 là dễ vì dùng mảng
Cách 1 là sao chép cột A vào cột Z chẳng hạn, rồi filter 2 lần 4 điều kiện ở 2 cột
 
Nếu VBA gặp * nó sẽ chuyển sang dạng filter đặc biệt.
Hình như Excel 2013~2016 có cái bug là dạng đặc biệt sẽ hoạt động không đúng với nhiều criteria.
filterRange.AutoFilter Field:=1, Criteria1:=array("ZPC*","BAN*"), Operator:=xlFilterValues
chạy ngon lành, Nhưng
filterRange.AutoFilter Field:=1, Criteria1:=array("ICC*", "BVB*", "ZPC*","BAN*"), Operator:=xlFilterValues
thì chả ra gì cả.

Cách Autofilter trong trường hợp này là:
-Tạo cột lọc (A hoặc cột cuối trong bảng cũng được.
- Code
Range("A4").Formula = "=SUM(COUNTIF(B3,{""VTU*"",""BDG*"",""ZPN*"",""BAN*""}))"
Range("A4:A"& dòng cuối).Filldown
- Fitler: filter lấy cột A, criteria = 0
Nếu muốn xóa cột phụ thì phải copy visible rồi paste lại.
 
Vâng , cảm ơn bạn rất nhiều , tại vì code cũ hiện đang chạy bình thường, chỉ là do có thêm 2 loại văn phòng mới xuất hiện nên mình muốn loại bỏ cho nó nhẹ file tổng hợp thôi , mình nghĩ đơn giản là tìm cách sửa thêm điều kiện lọc ngoài việc bỏ 2 văn phòng trước giờ là ICC* và BVB* thì giờ bỏ thêm ZPC* và BAN* nữa thôi là ổn.

Nếu không thì như bạn góp ý, bạn có thể thay đổi code mới giúp cho mình thì quá tốt rồi, mình xin liệt kê các điều kiện để tổng hợp như sau :
1. Có nhiều file Report1.xls , Report2.xlsx , Report3.xlsx.... do các bạn dưới văn phòng gởi về , mỗi file có thể có 1 sheet , cũng có thể có nhiều sheet. Yêu cầu mình sẽ tổng hợp tất cả về 1 sheet hiện hành của file 1.Data Master.
Lưu ý : do đã từng có lần bị lỗi là , trong các file mà các bạn gởi về , có thể có 1 file nào đó bị lỗi hoặc tổng cộng gom hết toàn bộ data của mọi người về có thể vượt quá 1trieu dòng (lần trước , có 2 file trong tổng số 19 file của các bạn gởi về bị lỗi , cái code cũ nó bỏ qua mà không thông báo gì hết nên dẫn đến thiếu dữ liệu mà mình không biết ==> dẫn đến báo cáo sai, nên mình rút kinh nghiệm , trong code , mình có ràng 2 điều kiện kiểm tra trước khi tổng hợp :

Set wb = Workbooks.Open(myFile(i))
If Err.Number <> 0 Then ' kiem tra xem trong so cac file da chon, có file nào bi loi khong mo duoc hay không, neu co thì phai hien thông báo cho mình biet
MsgBox "File : " & vbNewLine & Mid(myFile(i), InStrRev(myFile(i), "\") + 1) & vbNewLine & vbNewLine & " CÓ LOI KHÔNG COPY DUOC, DA BO QUA FILE NÀY, NHO KIEM TRA LAI NHÉ..", , "LUU Ý : CÓ FILE BI LOI"
Err.Clear
wb.Close False
Else
For Each ws In wb.Worksheets
totalRows = totalRows + ws.UsedRange.Rows.Count
If totalRows > 1048570 Then
MsgBox "Tong data các file da chon nhieu hon 1048570 dòng. Không import duoc."
wb.Close False
Exit Sub
End If

2. Điều kiện tổng hợp : Tổng hợp bắt đầu từ hàng thứ 4 của mỗi sheet (lấy từ Range("A4:AP") gom hết về sheet hiện hành , bắt đầu paste vào ô A3 của file chính , kết thúc mỗi sheet thì cách 1 dòng trống (để sau này dễ kiểm tra lại) . Chú ý , PasteValuesAndNumberFormats để giữ nguyên định dạng của file gốc.
- Loại bỏ những hàng mà trong cột A hoặc trong cột B có 3 chữ cái đầu là 1 trong các ký tự sau : (loại bỏ, không copy nguyên hàng đó vào file chính) : ICC* , BVB* , ZPC* , BAN* , ATD* , DTM*
- Loại bỏ những hàng mà trong cột G có chữ "dummy_collection_agent"
- loại bỏ những hàng mà trong cột I có chữ "AMD".

Sau khi đã hoàn tất việc copy , đến file cuối cùng thì copy hàng tiêu đề của file report (Range("A3:AP3").Copy) và paste nó vào hàng thứ 2 của file chính Range("A2:AP2").PasteSpecial xlPasteValuesAndNumberFormats) . Lý do là vì thỉnh thoảng các file report này sẽ bị thêm cột hoặc xóa cột nên nếu không có thao tác này để đối chiếu thì sẽ dẫn đến lệch cột ==> sai báo cáo (mình có để ở hàng 1 của file chính tiêu đề chuẩn để đối chiếu , nếu sau khi copy hàng tiêu đề từ file report và file chính mà so sánh không giống với hàng thứ 1 thì conditional Formatting sẽ tô màu cột nào bị lệch thì mình sẽ biết
Bài này của bạn có thêm một số điều kiện, để từ từ nghiên cứu thử xem thế nào.
 
Nếu VBA gặp * nó sẽ chuyển sang dạng filter đặc biệt.
Hình như Excel 2013~2016 có cái bug là dạng đặc biệt sẽ hoạt động không đúng với nhiều criteria.
filterRange.AutoFilter Field:=1, Criteria1:=array("ZPC*","BAN*"), Operator:=xlFilterValues
chạy ngon lành, Nhưng
filterRange.AutoFilter Field:=1, Criteria1:=array("ICC*", "BVB*", "ZPC*","BAN*"), Operator:=xlFilterValues
thì chả ra gì cả.

Cách Autofilter trong trường hợp này là:
-Tạo cột lọc (A hoặc cột cuối trong bảng cũng được.
- Code
Range("A4").Formula = "=SUM(COUNTIF(B3,{""VTU*"",""BDG*"",""ZPN*"",""BAN*""}))"
Range("A4:A"& dòng cuối).Filldown
- Fitler: filter lấy cột A, criteria = 0
Nếu muốn xóa cột phụ thì phải copy visible rồi paste lại.
Cảm ơn bạn rất nhiều, theo như cách bạn hướng dẫn, mình có biến tấu lại 1 chút, khi code chạy, mở file report thứ 1 lên, thì thêm 1 thao tác là copy cột A , paste vào 1 cột phụ ở cuối bảng Range("DA3 : DA" & lastrow) = Range("A3:A" & lastrow).value rồi thì mình có thể dùng lại công thức cũ hiện có của mình để autofilter cột DA này,
filterRange.AutoFilter Field:=94, Criteria1:="<>ZPC*", Operator:=xlAnd, Criteria2:="<>BAN*"
vậy là xem như mình có chỗ để filter thêm 2 điều kiện mới, cuối cùng copy kết quả sau khi filter vào file chính, tất nhiên, mình chỉ copy từ A4 đến AP và bỏ qua cột phụ này.
Để chút nữa mình sẽ thử cách này xem thời gian chạy code có hợp lý không
Cảm ơn bạn đã hướng dẫn
 
Cách 2 không phải như vậy mà làm như sau:
Tạo vùng điều kiện:
View attachment 301804

Code:
Mã:
    Range("A3:J4747").AdvancedFilter Action:=xlFilterInPlace, CriteriaRange:=Range _
        ("B1:E2"), Unique:=False
Cách 3 là dễ vì dùng mảng
Cách 1 là sao chép cột A vào cột Z chẳng hạn, rồi filter 2 lần 4 điều kiện ở 2 cột
Bác ạ, em hỏi cái, em đặt name trong Name Manager là "_bang" và "_loc". Rồi em thay thế này:
Range("_bang").AdvancedFilter Action:=xlFilterInPlace, CriteriaRange:=Range ("_loc"), Unique:=False
thì không lọc được bác ạ.
Không dùng được Name phải không bác?
 
Tôi dùng name được bình thường. Khiếp, gần 10 năm mới thấy 1 bài hỏi nghiêm túc, không tán nhảm.

View attachment 303684
Em có bài khác, chỉ giống chủ đề này là filter.
(1) Nếu advanced filter theo Name "_BANG" và "_LOC" thì: sẽ kết quả như ảnh → QUÁ CHUẨN
(2) Nếu dùng code:
Sub zzz()
Range("_BANG").AdvancedFilter Action:=xlFilterInPlace, CriteriaRange:=Range("_LOC"), Unique:=False
End Sub
thì không ra giống như (1) → SAI BÉT

Tại sao ạ???



Tóm tắt ý đồ chiến thuật: lập bảng theo dõi hàng ngày, cứ sau 7, 15, 30 ngày là phải kiểm tra vị trí
→→→ hôm nay, em muốn liệt kê các vị trí phải kiểm tra để lượn 1 vòng???
 

File đính kèm

3 dấu ? cộng với in đậm, chữ to không khiến cho câu hỏi rõ nghĩa hơn hay hỏi vì ấm ức nhiều hơn.

Sai vì dùng text. Để nguyên như vậy thì dù dùng Range("M2:H5") cũng chạy sai. Tìm nguyên nhân sai phải tìm đến nơi đến chốn chứ không được đổ thừa tại Name.

Đúng sẽ là thế này:

1725498082349.png
 
Lần chỉnh sửa cuối:
Bác thật là tâm lý.
Em đã thử thành công, tuy nhiên, em muốn ngày nó phải là dạng ngày chứ không phải số 455xx như kia.
Advance filter lọc được bằng text mà code phải dùng số.
Vậy cách xử lý sao để nó vẫn hiện ngày dạng dd/mm/yy mà code vẫn chạy bác nhỉ?
 
Advance filter lọc được bằng text mà code phải dùng số. (1)
Vậy cách xử lý sao để nó vẫn hiện ngày dạng dd/mm/yy mà code vẫn chạy bác nhỉ? (2)
(1) Code cũng advanced filter chứ là gì? Excel khác VBA, thế thôi.
(2) Tự tìm hiểu đi, và đừng đổ thừa như đổ thừa name.
 
Mã:
Sub zzz2()
Dim arr()
arr = Range("_loc").Value
For dong = LBound(arr, 1) + 1 To UBound(arr, 1)
      For Cot = LBound(arr, 2) To UBound(arr, 2)
         If arr(dong, Cot) <> "" Then
            arr(dong, Cot) = Left(arr(dong, Cot), 2) & CLng(CDate(Mid(arr(dong, Cot), 3, 10)))
         End If
      Next Cot
   Next dong
   
    Range("_BANG").AdvancedFilter Action:=xlFilterInPlace, CriteriaRange:=arr, Unique:=False
End Sub
Bác xem có cách nào để cho Điều kiện là arr mà AdvancedFilter hiểu được không ạ?
 
Thì nó là text nên em phải chuyển sang số, nhưng lại bị lỗi 1004.
Đối với dữ liệu dạng ngày:
Excel và VBA khác nhau ở việc nhận dạng dd/mm và mm/dd hoặc nhận dạng giá trị text kiểu này (bị rồi nhé)
Nhưng Excel và VBA giống nhau ở 2 điểm:
1. Nhận giá trị như nhau nếu chuyển thành số
2. Tìm tiếp
 
Lần chỉnh sửa cuối:
Đối với dữ liệu dạng ngày:
Excel và VBA khác nhau ở việc nhận dạng dd/mm và mm/dd hoặc nhận dạng giá trị text kiểu này (bị rồi nhé)
Nhưng Excel và VBA giống nhau ở 2 điểm:
1. Nhận giá trị như nhau nếu chuyển thành số
2. Tìm tiếp
1. Số thì nó lọc đúng rồi nhưng em không muốn hiển thị trên excel là số, phải là ngày cho dễ nhìn. Do đó, trong VBA thì số ngày miễn sao chạy được là được, nhưng em đang vướng cho filter nó hiểu được array so sánh lớn nhỏ thế kia.
2. Chịu luôn, em đã sử dụng hết các kỹ thuật tìm kiếm đỉnh cao.
 
Đối với dữ liệu dạng ngày:
Excel và VBA khác nhau ở việc nhận dạng dd/mm và mm/dd hoặc nhận dạng giá trị text kiểu này (bị rồi nhé)
...
Tôi có nói chuyện này rồi. Và người hỏi trên có chen vào hỏi, nhưng có lẽ không nhớ.
Hàm CDate trong VBA thuộc về nhóm hàm xác định kiểu dữ liệu và cũng như mọi hàm khác trong nhóm, chúng có khả năng ép kiểu (type coercion)
Tyoe coercion tuy rất hiệu quả nhưng cũng đi kèm theo luật của nó. Không đề phòng thì dữ liệu sai như chơi.
1725772005325.png
Như ví dụ, máy của tôi mặc định ngày theo kiểu Âu cho nên VBA sẽ chọn kiểu Âu, không được thì chọn Mẽo, nếu thất bại nữa thì Error - Type Mismacth

Hàm DateValue thì bảng tính và VBA cho ra kết quả khác nhau!
 
Dù cho chuyển thành số sẵn từ Excel cũng cóc chạy với array chứ đừng nói chuyển đổi qua số bằng code. Vấn đề là advanced filter trong VBA cóc chịu Array Criteria.
Điểm giống nhau thứ 2 của Excel và VBA khi nhận giá trị ngày từ text là text phải được định dạng yyyy/mm/dd.
Như ảnh sau thì VBA chạy tốt, kể range và name.

1725773634803.png

Mà hiển thị cái quái gì chẳng được, khi mà có thể định dạng chữ trắng để giấu đi?
 
Lần chỉnh sửa cuối:
2. Chịu luôn, em đã sử dụng hết các kỹ thuật tìm kiếm đỉnh cao.
Tìm kiếm không ra rồi tự thử không có kế hoạch. Trước khi đúc 1 cái bàn bằng sắt để thả nổi trong hồ bơi, thì tự thử quăng 1 cục sắt xuống xem nổi hay chìm. Sai ngay từ ý tưởng thì có hì hục trăm ngàn cách cũng vất đi, rồi lại đổ thừa tại cái khuôn đúc.
 
Tôi có nói chuyện này rồi. Và người hỏi trên có chen vào hỏi, nhưng có lẽ không nhớ.
Hàm CDate trong VBA thuộc về nhóm hàm xác định kiểu dữ liệu và cũng như mọi hàm khác trong nhóm, chúng có khả năng ép kiểu (type coercion)
Tyoe coercion tuy rất hiệu quả nhưng cũng đi kèm theo luật của nó. Không đề phòng thì dữ liệu sai như chơi.
View attachment 303761
Như ví dụ, máy của tôi mặc định ngày theo kiểu Âu cho nên VBA sẽ chọn kiểu Âu, không được thì chọn Mẽo, nếu thất bại nữa thì Error - Type Mismacth

Hàm DateValue thì bảng tính và VBA cho ra kết quả khác nhau!
Em có đọc bài đấy mà, em còn bảo hàm cdate nó loạn cào cào. Rồi em áp dụng hết cả dateserial, lập một cái file excel đầy màu sắc. Và cuối cùng là không đến hồi kết.

Còn bài của tôi trả lời thì không đọc, chắc là tôi tự xóa.
Hiện giờ em đang bí cái bài này. Khả năng phải đăng vào chủ đề mới nhờ các bác code cho.
 
Vậy tôi xóa bài 30 và 31
 
Vậy tôi xóa bài 30 và 31
Thực sự là giờ phải có kết quả cuối cùng thì em mới hiểu được, em chịu, không biết cách làm thế nào luôn. :wallbash::wallbash::wallbash:
Em muốn cho nó cái code để bấm 1 phát, chứ mỗi lần phải lọc advanced filter lười quá. Em đã code để siêng hơn nhưng siêng khó quá.
 
Chạy nhưng rất xấu khi mà cả đống dòng dưới nó là dmy rồi bác. Giờ làm sao để vẫn ngày tháng năm như bên ta mà advanced filter hiểu được.

Đây có thể gọi là cái vấn đề xy róp lầm. Em có x, liệu có cách y=f(x) không?
 
Đơn giản thôi mà, một vùng để hiển thị cho trực quan một vùng làm điều kiện cho Advance filter. Xã hội bây giờ cũng vậy thôi, ai cũng có ít nhất một cái mặt nạ.
Vậy tức là không có cách nào advanced filter dạng ngày Việt Nam luôn trong code hả bác? Chỉ có thể:
1 là phải dùng ngày kiểu Mỹ.
2 là phải dùng 2 bảng điều kiện.
3 là hết cách...
 
Trước mình có tìm trên diễn đàn, thấy được code xử lý lọc nhiều điều kiện như mã đơn hàng, số lượng mà mình cho là hay.
Bạn xem tham khảo thử.
 
3 là dùng kế "Thay mận đổi đào".
Ngày nay, không ai chịu chết thay ai đâu.
Bạn đổi thành "thay kép đổi đào" hợp với thời cuộc hơn.

Vậy tức là không có cách nào advanced filter dạng ngày Việt Nam luôn trong code hả bác? Chỉ có thể:
1 là phải dùng ngày kiểu Mỹ.
2 là phải dùng 2 bảng điều kiện.
3 là hết cách...
Lại cái tội đọc không kỹ. Người ta nói "mặt nạ" là ẩn ý từ "format". Format ra text tức là chụp mặt nạ cho trị.
Ngày trong Excel là dạng số. Chả cần kiểu mẽo hay âu gì để nó thay thế.
Tuy nhiên, khi so cánh ngày tháng qua format thì dùng kiểu Nhật tốt nhất:
Format(ngày, "yyyymmdd")
Nhật là chúa tể về mặt nạ mờ.
 
Xã hội bây giờ cũng vậy thôi, ai cũng có ít nhất một cái mặt nạ.
Không xái mặt nạ thì cũng còn cách khác mà mắt người ta:
Của để trưng là hàng giả, vô giá trị (với code)
Khi cần chạy code thì gắn đồ hữu dụng vào range. Chạy code xong lại gắn của giả vào.
Nói chung nếu không biết chẳng thà luồn lách chứ toàn mày mò những thứ không thể.
Phương án giấu là sau cùng, trước tiên có cách nào cho vào criteria không bác?
Vậy tức là không có cách nào advanced filter dạng ngày Việt Nam luôn trong code hả bác?
Những câu hỏi thật là không muốn trả lời chút nào. Nếu có thì người ta đã trả lời từ tám hoánh.
 
Bài 30 tôi chỉ cách này thì chê xấu
Tôi bảo giấu đi thì bảo không trực quan.
Té ra con người này sống và đánh giá lẫn nhau qua cái mẽ ngoài chứ không phải cái thực lực hiệu quả.
Vậy mà bài 39 bảo dùng mặt nạ thì ra vẻ ta đây không chịu.
 
Em tổng hợp lại 4+1 cách:

Cách 1:

Như ảnh sau thì VBA chạy tốt, kể range và name.
1725986462547.png

Cách 2:
1725986638383.png

Cách 3:
code xử lý lọc nhiều điều kiện
Code này rất hay, hiện tại đáp ứng bài này, tuy nhiên có chút tớ cảm giác chưa tối ưu và hơi khó dùng:
- 1 là ghi ra điều kiện filter dễ sai sót khi phải thật kỹ đúng quy tắc, khi cần sửa thì phải dò kỹ cũng chưa tối ưu, nếu tác giả sửa code mà dùng chính criteria của advanced filter thì nhanh chóng gọn lẹ hơn.
1725987021699.png
- 2 là như ảnh dưới:1725987184988.png

Cách 4:
Có lẽ là cách mà bác Mỹ, bác Thắng, bác Vet nhắc đến, gọi là "hoa quả" gì đó. Nó như thế này:

Mã:
Sub zzz3()
Application.DisplayAlerts = False
Application.ScreenUpdating = False
Dim arr()
Dim dong, cot
arr = Range("_LOCC4").Value
For dong = LBound(arr, 1) + 1 To UBound(arr, 1)
      For cot = LBound(arr, 2) To UBound(arr, 2)
         If arr(dong, cot) <> "" Then
            arr(dong, cot) = Left(arr(dong, cot), 2) & CLng(CDate(Mid(arr(dong, cot), 3, 10)))
         End If
      Next cot
Next dong
Sheets.Add(AFTER:=ActiveSheet).Name = "TEMP"
Sheets("TEMP").Range("a1").Resize(dong - 1, cot - 1) = arr
Sheets("C4").Range("_BANGC4").AdvancedFilter Action:=xlFilterInPlace, CriteriaRange:=Sheets("TEMP").Range("a1").CurrentRegion, Unique:=False
Sheets("TEMP").Delete
Sheets("C4").Activate
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub

Cách 5: Format(ngày, "yyyymmdd"): cái này đưa vào code em không biết làm, 2 bác đề cập đến nó có thể code giúp em không?
 

File đính kèm

Lần chỉnh sửa cuối:
Trước mình có tìm trên diễn đàn, thấy được code xử lý lọc nhiều điều kiện như mã đơn hàng, số lượng mà mình cho là hay.
Bạn xem tham khảo thử.
Cảm ơn bạn nhiều nhé, mình đã xem qua, có thể áp dụng được vào file của mình.
 
Còn 1 cách mà với người ưa cái mẽ bề ngoài gọi là xấu

1726018058686.png

Cách 3:
...

Cách 4:
Có lẽ là cách mà bác Mỹ, bác Thắng, bác Vet nhắc đến, gọi là "hoa quả" gì đó.
Cách 2: Xấu không biết giấu đi à?
Cách 3 tôi không thèm quan tâm vì cả đống code chẳng làm được gì. Chưa chắc đã làm đúng như trong link.
Cách 4: Cần quái gì cái sheet Temp
 
Còn 1 cách mà với người ưa cái mẽ bề ngoài gọi là xấu




Cách 2: Xấu không biết giấu đi à?
Cách 3 tôi không thèm quan tâm vì cả đống code chẳng làm được gì. Chưa chắc đã làm đúng như trong link.
Cách 4: Cần quái gì cái sheet Temp
Còn 1 cách mà với người ưa cái mẽ bề ngoài gọi là xấu: → Hình như bác tạo cột phụ, như thế thì không cần thiết, em chỉ muốn có từng đó cột thôi, ví dụ em cần thêm dữ liệu tầm 50 cột nữa thì lúc sai tìm cột FALSE TRUE sửa thì lâu lắm.

Cách 2: Xấu không biết giấu đi à? → giấu cũng được nhưng vẫn xấu, thậm chí cái bảng em làm cũng đang xấu, và em không muốn xấu thêm nữa.

Cách 3 tôi không thèm quan tâm vì cả đống code chẳng làm được gì. Chưa chắc đã làm đúng như trong link. → sheet KQ bên cạnh là chạy hàm khủng đó bác, hàm rất hay nhưng nếu điều kiện có thể nhập đơn giản hơn thì hợp ý em hơn. Tuy nhiên, có thể hàm nằm trong thư viện của tác giả nên phải dùng chuỗi lọc như thế. Do đó, là 1 hướng tiếp cận khác.

Cách 4: Cần quái gì cái sheet Temp → sheet mới hay sheet hiện tại thì cũng như nhau. Cái quan trọng là advanced filter của excel nó xịn hơn của VBA.

Thêm: còn ý format trong code, vẫn phải gán xuống sheet rồi filter đúng không bác?
 
Còn 1 cách mà với người ưa cái mẽ bề ngoài gọi là xấu: → Hình như bác tạo cột phụ
Cách của tôi KHÔNG dùng cột phụ.
Cách 4: Hiểu sai ý bài 44.
Ngoài ra tôi không trả lời thêm. Trừ khi tôi dùng đúng cách bài 44 và bạn chuyển cho tài khoản GPE 1 khoản tương đương với "bài khó" cho việc thiện nguyện.
Tôi xác định "khó" vì bạn làm cả 2 tuần không xong.
 
Nói không bằng làm. Hề hề không giải quyết được vấn đề.
 
"Thay mận đổi đào" chỉ cần làm vầy thôi, muốn giấu thì đưa vô name.
Mã:
    Range("H1").Value = "yyyy/mm/dd"
    'AdvancedFilter
    Range("H1").Value = "dd/mm/yyyy"
1726026578710.png
 
"Thay mận đổi đào" chỉ cần làm vầy thôi, muốn giấu thì đưa vô name.
Mã:
    Range("H1").Value = "yyyy/mm/dd"
    'AdvancedFilter
    Range("H1").Value = "dd/mm/yyyy"
View attachment 303894
Ồ, thế mà em không nghĩ ra được. Chán quá, thiệt tình tư duy mình kém quá.
Xin cảm ơn bác nhé, thiện nguyện em xin phép dành dịp khác vậy. Hề hề.
 

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

Back
Top Bottom