MinhKhai
Giải pháp Ếc-xào
- Tham gia
- 16/4/08
- Bài viết
- 941
- Được thích
- 574
Cấu trúc file của bạn không thể dùng AdvancedFilter để lọc, phải dùng mảng để lọc thôiXin các anh chị em hướng dẫn lại em cái advanded filter bằng VBA như file đính kèm với.
Chỉ là lọc với theo 2 chỉ tiêu và đưa danh sách kết quả ra chỗ khác mà em loay hoay mãi vẫn lỗi.
Mong được các ACE giúp đỡ để học hỏi.
Cảm ơn anh. Lần trước cũng là anh hướng dẫn về Advandced Fiter.Cấu trúc file của bạn không thể dùng AdvancedFilter để lọc, phải dùng mảng để lọc thôi
Tạo mảng nguồn và dùng vòng lặp để duyệt, nếu em nào thoả dk thì lấy thôi. Cố thử xem
Cảm ơn anh. Lần trước cũng là anh hướng dẫn về Advandced Fiter.
Anh nói cấu trúc của file không thể dùng AdvancedFilter có phải là các vị trí các cột kết quả không tuần tự như cột ở dữ liệu nguồn không ?
Mong anh giúp cho cả 2 tình huống:
1. Giả sử cấu trúc này được sắp đặt giống như nguồn thì code viết thế nào ?
2. Dùng mảng và vòng lặp để thực hiện.
Tôi đang tìm hiểu về VBA. Cũng đã đọc tài liệu nhưng nhưng nhận thấy không hiệu quả bằng xem các ví dụ cụ thể
Sub Loc()
Dim Sarr(), Darr(), I, J, ngay
With Sheets("BanHang")
Sarr = .Range(.[B7], .[B65536].End(3)).Resize(, 13).Value
End With
ReDim Darr(1 To UBound(Sarr), 1 To 3)
ngay = Sheets("TongKet").[C3].Value
For I = 1 To UBound(Sarr)
If Sarr(I, 1) = ngay Then
If Left(Sarr(I, 13), 2) = "Tr" Then
J = J + 1
Darr(J, 1) = Sarr(I, 5)
Darr(J, 2) = Sarr(I, 3)
Darr(J, 3) = Sarr(I, 11)
End If
End If
Next
Sheets("TongKet").[B6:D1000].ClearContents
If J Then
Sheets("TongKet").[B6].Resize(J, 3) = Darr
End If
End Sub
Bác ơi, em đưa code vào nhưng không thấy hoạt động gì cả. Không biết là em thao tác sai chỗ nào ?Code dùng vòng lặp theo file của bạn. Cột N chỉ có Trả tiền mặt là Tr thôi nha, nếu có gì mà 2 ký tự đầu giống Tr thì tèo ráng chịu
PHP:Sub Loc() Dim Sarr(), Darr(), I, J, ngay With Sheets("BanHang") Sarr = .Range(.[B7], .[B65536].End(3)).Resize(, 13).Value End With ReDim Darr(1 To UBound(Sarr), 1 To 3) ngay = Sheets("TongKet").[C3].Value For I = 1 To UBound(Sarr) If Sarr(I, 1) = ngay Then If Left(Sarr(I, 13), 2) = "Tr" Then J = J + 1 Darr(J, 1) = Sarr(I, 5) Darr(J, 2) = Sarr(I, 3) Darr(J, 3) = Sarr(I, 11) End If End If Next Sheets("TongKet").[B6:D1000].ClearContents If J Then Sheets("TongKet").[B6].Resize(J, 3) = Darr End If End Sub
AdvanceFilter chỉ có 1 dòng lệnh thôi nên bạn phải tự xử thôi.
Thử lại với file này xem saoBác ơi, em đưa code vào nhưng không thấy hoạt động gì cả. Không biết là em thao tác sai chỗ nào ?
Đúng là AdvandedFilter chỉ có 1 dòng thôi mà em không biết nhấm chỗ nào mà không ra. Em đã thử record macro để có cú pháp chuẩn nhưng record macro chỉ cho 1 tiêu chí mà ở đây mình cần lọc >2 tiêu chí
Hic, code có rồi thì cố gắng cho nó chạy đi. AdvancedFilter mà gặp dữ liệu nhiều sẽ chậm hơn dùng mảng. Và nếu thêm bớt dk thì mảng sẽ linh hoạt hơn.Bác ơi, em đưa code vào nhưng không thấy hoạt động gì cả. Không biết là em thao tác sai chỗ nào ?
Tôi nghĩ rằng sau khi lọc xong, nếu cùng số phiếu thì phải SUM thành tiền lại, đúng không?Xin các anh chị em hướng dẫn lại em cái advanded filter bằng VBA như file đính kèm với.
Chỉ là lọc với theo 2 chỉ tiêu và đưa danh sách kết quả ra chỗ khác mà em loay hoay mãi vẫn lỗi.
Mong được các ACE giúp đỡ để học hỏi.
Em chưa bao giờ sử dụng PivotTable và cũng chưa hiểu tác dụng cũng như cách dùng nó. Vừa rồi cũng chớp nhoáng đọc Ebook của bác Ptm0412 nhưng chưa hấp thụ được gì.Sau khi bạn chuẩn hóa dữ liệu rồi thì PivotTable mới là chọn lựa tốt nhất: Tốc độ nhanh nhất, dùng đơn giản nhất và khỏi code kiết gì ráo cho mệt người
Em chưa bao giờ sử dụng PivotTable và cũng chưa hiểu tác dụng cũng như cách dùng nó. Vừa rồi cũng chớp nhoáng đọc Ebook của bác Ptm0412 nhưng chưa hấp thụ được gì.
Em đã chuẩn hóa lại dữ liệu trong file đính kèm, bác có thể sử dụng PivotTable để "chế biến" file dữ liệu giúp em được không ? Qua kết quả em muốn biết PivotTable làm được gì và như thế nào thôi.
https://dl.dropboxusercontent.com/s...AHZ8ZvAfpt3JsaC9lebWz4ClWlYb8CWNcL-VwuXNOjGTA
Range("A1:B407").AdvancedFilter 2, Range("V1:V2"), Range("V10")
Sub loc()
Dim i As Long, j As Long
For i = 1 To 400
For j = 1 To 20 Step 2
Range(Cells(1, j), Cells(400, j + 1)).AdvancedFilter 2, Range(Cells(1, j + 21), Cells(2, j + 21)), Range(Cells(10, j + 21))
Next J
Next I
Cho mình hỏi lại bạn 1 chút xíu, rằng con số 2 trong câu lệnh
có nghĩa là gì vậy bạn?PHP:Range("A1:B407").AdvancedFilter 2, Range("V1:V2"), Range("V10")
& thêm 1 câu nữa:
Bạn muốn làm gì với macro này:
PHP:Sub loc() Dim i As Long, j As Long For i = 1 To 400 For j = 1 To 20 Step 2 Range(Cells(1, j), Cells(400, j + 1)).AdvancedFilter 2, Range(Cells(1, j + 21), Cells(2, j + 21)), Range(Cells(10, j + 21)) Next J Next I
Cũng không hiểu bạn định làm gì nhưng với cấu trúc dữ liệu như trong file mà dùng Advanced Filter được mới... lạ đóCác anh chị cho em hỏi về advanced filter.
1. Với Sub LocDL thì khi thay giá trị ở B1=1 là kết quả lọc sai, thay khác 1 thì lại đúng. Cho em hỏi nguyên nhân vì sao ạ.
2. E có tạo vòng lặp như code dưới, em xem mãi mà không hiểu vì sao code không chạy ạ? Chỉ em chỗ sai. Em cảm ơn nhiều.
Sub LocDL()
Range("A1:B407").AdvancedFilter 2, Range("V1:V2"), Range("V10")
End Sub
Sub loc()
Dim i As Long
Dim j As Long
For i = 1 To 400
For j = 1 To 20 Step 2
Range(Cells(1, j), Cells(400, j + 1)).AdvancedFilter 2, Range(Cells(1, j + 21), Cells(2, j + 21)), Range(Cells(10, j + 21))
Next
Next
End Sub
Dữ liệu của em đơn giản mà thầy, đây chỉ là dữ liệu e tự cho random để làm ví dụ thôi, Thực tế bài toán Advanced filter chỉ làm với 2 cột, cột đầu chỉ là giá trị "OK" và blank(), cột 2 là số ngẫu nhiên em lấy theo hàm randbetween ấy mà. Yêu cầu đặt ra là lọc theo đk nào đó (ở đây là cột 1="OK") và trả giá trị sau lọc sang bên phải. Như code ở nút Lọc chạy được rồi ạ. Nhưng em cho chạy vòng lặp để tự động lọc các cặp cột tiếp theo thì code không chạy. Em không hiểu code sai ở đâu, kính nhờ thầy và các anh chị giúp đỡ.Cũng không hiểu bạn định làm gì nhưng với cấu trúc dữ liệu như trong file mà dùng Advanced Filter được mới... lạ đó
Dữ liệu của em đơn giản mà thầy, đây chỉ là dữ liệu e tự cho random để làm ví dụ thôi, Thực tế bài toán Advanced filter chỉ làm với 2 cột, cột đầu chỉ là giá trị "OK" và blank(), cột 2 là số ngẫu nhiên em lấy theo hàm randbetween ấy mà. Yêu cầu đặt ra là lọc theo đk nào đó (ở đây là cột 1="OK") và trả giá trị sau lọc sang bên phải. Như code ở nút Lọc chạy được rồi ạ. Nhưng em cho chạy vòng lặp để tự động lọc các cặp cột tiếp theo thì code không chạy. Em không hiểu code sai ở đâu, kính nhờ thầy và các anh chị giúp đỡ.
PS. Em tô màu một chút và Add comment cho dễ hiểu hơn.
Public Sub GPE()
Dim I As Long
For I = 1 To 19 Step 2
Cells(1, I).Resize(1000, 2).AdvancedFilter Action:=xlFilterCopy, _
CriteriaRange:=Range("A1:A2").Offset(, I + 20), CopyToRange:=Range("A1:B1").Offset(9, I + 20)
Next I
End Sub
Dữ liệu của em đơn giản mà thầy, đây chỉ là dữ liệu e tự cho random để làm ví dụ thôi, Thực tế bài toán Advanced filter chỉ làm với 2 cột, cột đầu chỉ là giá trị "OK" và blank(), cột 2 là số ngẫu nhiên em lấy theo hàm randbetween ấy mà. Yêu cầu đặt ra là lọc theo đk nào đó (ở đây là cột 1="OK") và trả giá trị sau lọc sang bên phải. Như code ở nút Lọc chạy được rồi ạ. Nhưng em cho chạy vòng lặp để tự động lọc các cặp cột tiếp theo thì code không chạy. Em không hiểu code sai ở đâu, kính nhờ thầy và các anh chị giúp đỡ.
Sub LocDL()
Range("A1:B407").AdvancedFilter 2, Range("V1:V2"), Range("V10")
End Sub
. . . ..AdvancedFilter 2, Range(Cells(1, j + 21), Cells(2, j + 21)),[b] Range(Cells(10, j + 21)[/b])
For I = 1 to 400
Next I
Thử chạy SUB này xem sao.
PHP:Public Sub GPE() Dim I As Long For I = 1 To 19 Step 2 Cells(1, I).Resize(1000, 2).AdvancedFilter Action:=xlFilterCopy, _ CriteriaRange:=Range("A1:A2").Offset(, I + 20), CopyToRange:=Range("A1:B1").Offset(9, I + 20) Next I End Sub
Đúng là macro này đã chạy được:
Mình xin dịch câu lệnh này sang tiếng Việt như sau (dù bạn có biết hay chưa biết nghĩa tiếng Việt của nó)Mã:Sub LocDL() Range("A1:B407").AdvancedFilter 2, Range("V1:V2"), Range("V10") End Sub
Thực hiện fương thức lọc mở rọng từ vùng dữ liệu[A1:B407], với vùng điều kiện là [V1:V2] & kết quả lọc được được thể hiện fía dưới của ô [V10]
Giá trị đang chứa trong [V10] l1 1, ứng với iêu cầu hiễn nhiên của bạn là lọc theo cột [A]
Cần nói thêm rằng, ở bài đầu, bạn nói rằng khi sửa trị tại [B1] thì kết quả lọc thay đổi (Thay đổi, chứ không nói cái nào đúng cái nào sai!) Thì mình khẳng định là không có chuyện đó!
(*) Nói thêm rằng sẽ là thay đổi hay trở nên kỳ dị nếu tại [V10] chửa trị của [B1] & ta lại đi đổi [B1]
(**) Nếu tại [V10] bạn nhập vô trị đang có ở [B1] lúc đó thì bạn đúng.
Mình nhấn mạnh trị tại [V10] vì liên quan đến sai fạm của bạn trong macro thứ 2;
đó là câu lệnh được trích ra sau đây:
Mệnh đề mình in đậm này làm mình hiểu rằng bạn chưa thấu đáo với fương thức AdvancedFilter trong đời thường nói riêng hay trong VBA nói chungMã:. . . ..AdvancedFilter 2, Range(Cells(1, j + 21), Cells(2, j + 21)),[B] Range(Cells(10, j + 21)[/B])
Vì để macro này khỏi lạc lối, 19 ô bên fải liền kề với [V10] cần được bạn hay ai đó cho trị tương ứng.
Một sai lầm nữa là của bạn có thể là vòng lặp
PHP:For I = 1 to 400 Next I
Mình tưởng tượng là bạn cần lọc từng đôi cột từ [A].. đến [T] (20 cột) (có nghĩa chỉ 10 lần lặp chứ không fải 20 như bạn đang làm trong vòng lặp trong)
Theo mình hiểu thì bạn định lọc dữ liệu 2 cột [AB] đến dưới [V10];
Sau đó lọc [CD] cho hiện kết quả đạt dưới [W10]
(1) Nếu đúng vậy thì bạn dư vòng lặp ngoài (vì chưa thấu đáo AdvancedFilter)
(2) Các ô bên fải của [V10] cần được gán trị tương ứng [A1], [C1], . . . .[T1] bằng 1 cách nào đó
Thân ái!
Option Explicit
Sub loc()
Dim J As Long, Rws As Long
Rws = Sheets("Loc").UsedRange.Rows.Count
Columns("V:AZ").ClearContents
For J = 1 To 20 Step 2
[V1].Value = Cells(1, J).Value
[u10].Offset(, J).Value = Cells(1, J).Value
[v2].Value = [A2].Value
Cells(1, J).Resize(Rws, 2).AdvancedFilter 2, [V1:V2], Cells(10, J + 21)
Next J
End Sub
Bạn thử đọc & dịch ra tiếng Việt các câu lệnh của macro sau
PHP:Option Explicit Sub loc() Dim J As Long, Rws As Long ' Đếm số dòng dử dụng Rws = Sheets("Loc").UsedRange.Rows.Count 'Xóa dữ liệu từ cột V đến cột AZ Columns("V:AZ").ClearContents 'Vòng lặp với J bắt đầu từ 1 đến 20, nhảy 2 bước tức là vòng lặp gồm các số lẻ For J = 1 To 20 Step 2 'Range V1 có giá trị bằng giá trị của dòng 1 tại các ô lẻ [V1].Value = Cells(1, J).Value 'Range U10, sang bên J cột bằng giá trị của dòng 1 tại các ô lẻ [u10].Offset(, J).Value = Cells(1, J).Value 'Giá trị tại ô V2 bằng giá trị tại ô A2 [v2].Value = [A2].Value ' Xuống Rws dòng và sang 2 cột, copy sang vùng khác với điều kiện lọc là tại các ô Cells(1, J).Resize(Rws, 2).AdvancedFilter 2, [V1:V2], Cells(10, J + 21) Next J End Sub
[COLOR="#0000CD"]' Xuống Rws dòng và sang 2 cột, copy sang vùng khác với điều kiện lọc là tại các ô '[/COLOR]
Cells(1, J).Resize(Rws, 2).AdvancedFilter 2, [V1:V2], Cells(10, J + 21)
Next J
Chạy được ngon lành rồi thầy ạ. Có lẽ em phải nghiên cứu về mảng thôi, em đang làm quen với cells và range nên mảng hơi khoai. Cảm ơn thầy nhiều.
Public Sub GPE_2()
Dim sArr(), dArr(1 To 1000, 1 To 20), I As Long, J As Long, K As Long, R As Long
sArr = Range("A1:T1000").Value2
For J = 1 To 19 Step 2
K = 0
For I = 1 To 1000
If sArr(I, J) <> Empty Then
K = K + 1
dArr(K, J) = sArr(I, J)
dArr(K, J + 1) = sArr(I, J + 1)
End If
Next I
If K > R Then R = K
Next J
Range("V10").Resize(R, 20) = dArr
End Sub
Em đi làm rồi nên không online đk, bác Đình Phán và bác SA-DQ dịch mất rồi, em có hiểu sơ thôi, còn lại vẫn phải google hết, trc bài này e không biết cells(i,j).resize(k,l) và cells(i,j).Offset(m,n) đâu, mới đọc cũng đoán đk nhưng giờ cũng hiểu sơ sơ rồi. E cảm ơn bácBạn thử đọc & dịch ra tiếng Việt các câu lệnh của macro sau
PHP:Option Explicit Sub loc() Dim J As Long, Rws As Long Rws = Sheets("Loc").UsedRange.Rows.Count Columns("V:AZ").ClearContents For J = 1 To 20 Step 2 [V1].Value = Cells(1, J).Value [u10].Offset(, J).Value = Cells(1, J).Value [v2].Value = [A2].Value Cells(1, J).Resize(Rws, 2).AdvancedFilter 2, [V1:V2], Cells(10, J + 21) Next J End Sub
Muốn nghiên cứu mảng thì xem thử cái này, với dữ liệu như file của bạn thì xài mảng tốc độ sẽ nhanh hơn gấp 10 lần Advanced Filter như bài #18.
PHP:Public Sub GPE_2() Dim sArr(), dArr(1 To 1000, 1 To 20), I As Long, J As Long, K As Long, R As Long sArr = Range("A1:T1000").Value2 For J = 1 To 19 Step 2 K = 0 For I = 1 To 1000 If sArr(I, J) <> Empty Then K = K + 1 dArr(K, J) = sArr(I, J) dArr(K, J + 1) = sArr(I, J + 1) End If Next I If K > R Then R = K Next J Range("V10").Resize(R, 20) = dArr End Sub
Chạy ngon rồi thầy ạ. Có lẽ em phải nghiên cứu về mảng thôi, em đang làm quen với cells và range nên mảng hơi khoai. Cảm ơn thầy nhiều.
Theo mình thì bạn khoan chuyển sang "Mảng" cái đã;
Nên lật đi lật lại tất tần tật các fương án có thể của macro AdvancedFilter này trong nữa tháng nữa đã;
Ví dụ:
1./ Lọc & đếm số kết quả lọc được trong 10 cột lẻ kể từ cột [A]
2./ Trong bài trên, trong 1 cột cần lọc chỉ có 2 tiêu chí để lọc; nếu nhiều hơn 2 tiêu chí thì sẽ lọc làm sao?
3./ Có thể không cần lọc, mà chỉ cần đếm trực tiếp kết quả từng cặp cột theo điều kiện lọc được không?
. . . . .