Nhờ viết VBA lọc dữ liệu nhiều điều kiện (2 người xem)

Liên hệ QC

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

gianghoxaotra

Thành viên chính thức
Tham gia
6/2/13
Bài viết
53
Được thích
1
Mình có file dữ liệu mẫu, cần lọc dữ liệu từ Sheet Data sang Sheet KQ.
Mình có ghi hướng dẫn trong file.
Nhờ các cao thủ giúp viết dùm code VBA để chạy tự động cho nhanh.
Cảm ơn.
 

File đính kèm

Mình có file dữ liệu mẫu, cần lọc dữ liệu từ Sheet Data sang Sheet KQ.
Mình có ghi hướng dẫn trong file.
Nhờ các cao thủ giúp viết dùm code VBA để chạy tự động cho nhanh.
Cảm ơn.
Ở ô J6, bạn muốn lọc những Loại >= 7 ???

Mã:
Sub LocDL()
Dim Data(), i&, KQ(), k&
Data = Range(Sheet1.[A2], Sheet1.[A5000].End(3)).Resize(, 3)
ReDim KQ(1 To UBound(Data), 1 To 3)
For i = 1 To UBound(Data)
    If Data(i, 3) >= 7 Then
        k = k + 1
        KQ(k, 1) = Data(i, 1)
        KQ(k, 2) = Data(i, 2)
        KQ(k, 3) = Data(i, 3)
    End If
Next
Sheet2.[J6:L5000].ClearContents
Sheet2.[J6].Resize(k, 3) = KQ
end sub
 
Chỉnh sửa lần cuối bởi điều hành viên:
Bài này có thể dùng Advance Filter. Cách làm:
1. Thiết lập vùng điều kiện
2. Click record macro
3. Thao tác advance filter.
4. Stop record macro.
5. Mở cửa sổ vba có đoạn code.
Đây là cách tôi từng học, chúc bạn thành công.
 
Ở ô J6, bạn muốn lọc những Loại >= 7 ???

Mã:
Sub LocDL()
Dim Data(), i&, KQ(), k&
Data = Range(Sheet1.[A2], Sheet1.[A5000].End(3)).Resize(, 3)
ReDim KQ(1 To UBound(Data), 1 To 3)
For i = 1 To UBound(Data)
    If Data(i, 3) >= 7 Then
        k = k + 1
        KQ(k, 1) = Data(i, 1)
        KQ(k, 2) = Data(i, 2)
        KQ(k, 3) = Data(i, 3)
    End If
Next
Sheet2.[J6:L5000].ClearContents
Sheet2.[J6].Resize(k, 3) = KQ
Không thử nhưng biết chắc code trên không chạy được. ( Chắc là do post bài không để ý). Hehe
 
Ở ô J6, bạn muốn lọc những Loại >= 7 ???

Mã:
Sub LocDL()
Dim Data(), i&, KQ(), k&
Data = Range(Sheet1.[A2], Sheet1.[A5000].End(3)).Resize(, 3)
ReDim KQ(1 To UBound(Data), 1 To 3)
For i = 1 To UBound(Data)
    If Data(i, 3) >= 7 Then
        k = k + 1
        KQ(k, 1) = Data(i, 1)
        KQ(k, 2) = Data(i, 2)
        KQ(k, 3) = Data(i, 3)
    End If
Next
Sheet2.[J6:L5000].ClearContents
Sheet2.[J6].Resize(k, 3) = KQ
end sub

Code này chạy chưa giống ý mình muốn bạn ơi.
Ý mình là bên sheet Data,, cột A có 3 ngày được lập lại nhiều lần với trên cùng một cột tương ứng với giá trị tại cột B và C, mình muốn chuyển lọc dữ liệu qua sheet KQ, tách ra từng ngày riêng biệt được bố cục như file mẫu mình đưa lên.
Suy rộng ra, nếu cột A có nhiều ngày thì nó sẽ tự động tách ra nhiều ngày như bố cục mình đưa lên luốn.
Lưu ý là lọc theo điều kiện Loại >7 nữa nhé.
Cảm ơn bạn.
 
Code này chạy chưa giống ý mình muốn bạn ơi.
Ý mình là bên sheet Data,, cột A có 3 ngày được lập lại nhiều lần với trên cùng một cột tương ứng với giá trị tại cột B và C, mình muốn chuyển lọc dữ liệu qua sheet KQ, tách ra từng ngày riêng biệt được bố cục như file mẫu mình đưa lên.
Suy rộng ra, nếu cột A có nhiều ngày thì nó sẽ tự động tách ra nhiều ngày như bố cục mình đưa lên luốn.
Lưu ý là lọc theo điều kiện Loại >7 nữa nhé.
Cảm ơn bạn.
Có lẽ tôi chưa hiểu ý bạn. Đọc bài này cũng chư hiểu phải ra kq thế nào +-+-+-+
 
Mình gửi lại file, bạn xem sẽ dễ hiểu hơn.

làm theo yêu cầu bài #1, chưa đọc bài này...hihihiih
Mã:
Sub hehe()
Dim data, ketqua As Variant, i, j, k, n, ngay, col As Long
ReDim ketqua(1 To 60000, 1 To 3)
With Sheets("Data")
    data = .Range(.[a2], .[a2].End(4)).Resize(, 3).Value
End With
ngay = data(1, 1)

For i = 1 To UBound(data)
If data(i, 3) > 7 Then
    If data(i, 1) <> ngay Then
        n = UBound(ketqua, 2)
        ReDim Preserve ketqua(1 To 60000, 1 To n + 3)
        k = 1
        For j = 1 To 3
            ketqua(k, n + j) = data(i, j)
        Next
    Else
        k = k + 1
        If n Then col = n
        For j = 1 To 3
            ketqua(k, j + col) = data(i, j)
        Next
    End If
    ngay = data(i, 1)
End If
Next
With Sheet2
.[A6:XFD60000].ClearContents
.[A6].Resize(k, n + 3) = ketqua
End With
End Sub
========
à quên, xóa cái dòng cuối "tiếp theo......"
cột A phải có định dạng số (date), dạng text báo lổi
 
làm theo yêu cầu bài #1, chưa đọc bài này...hihihiih
Mã:
Sub hehe()
Dim data, ketqua As Variant, i, j, k, n, ngay, col As Long
ReDim ketqua(1 To 60000, 1 To 3)
With Sheets("Data")
    data = .Range(.[a2], .[a2].End(4)).Resize(, 3).Value
End With
ngay = data(1, 1)

For i = 1 To UBound(data)
If data(i, 3) > 7 Then
    If data(i, 1) <> ngay Then
        n = UBound(ketqua, 2)
        ReDim Preserve ketqua(1 To 60000, 1 To n + 3)
        k = 1
        For j = 1 To 3
            ketqua(k, n + j) = data(i, j)
        Next
    Else
        k = k + 1
        If n Then col = n
        For j = 1 To 3
            ketqua(k, j + col) = data(i, j)
        Next
    End If
    ngay = data(i, 1)
End If
Next
With Sheet2
.[A6:XFD60000].ClearContents
.[A6].Resize(k, n + 3) = ketqua
End With
End Sub
========
à quên, xóa cái dòng cuối "tiếp theo......"
cột A phải có định dạng số (date), dạng text báo lổi


Nó chạy được nhưng khi giá trị ngày cuối cùng ít dòng thì nó bị sai bạn ơi, lọc ko hết. Bạn xem lại giúp mình. Cảm ơn
 

File đính kèm

Nó chạy được nhưng khi giá trị ngày cuối cùng ít dòng thì nó bị sai bạn ơi, lọc ko hết. Bạn xem lại giúp mình. Cảm ơn

quên, k nó bị reset lại
Mã:
Sub hehe()
Dim data, ketqua As Variant, i, j, k, n, ngay, col, maxK As Long
ReDim ketqua(1 To 60000, 1 To 3)
With Sheets("Data")
    data = .Range(.[a2], .[a2].End(4)).Resize(, 3).Value
End With
ngay = data(1, 1)

For i = 1 To UBound(data)
If data(i, 3) > 7 Then
    If data(i, 1) <> ngay Then
        n = UBound(ketqua, 2)
        ReDim Preserve ketqua(1 To 60000, 1 To n + 3)
        k = 1
        For j = 1 To 3
            ketqua(k, n + j) = data(i, j)
        Next
    Else
        k = k + 1
        If k > maxK Then maxK = k
        If n Then col = n
        For j = 1 To 3
            ketqua(k, j + col) = data(i, j)
        Next
    End If
    ngay = data(i, 1)
End If
Next
With Sheet2
.[A6:XFD60000].ClearContents
.[A6].Resize(maxK, n + 3) = ketqua
End With
End Sub
 
quên, k nó bị reset lại
Mã:
Sub hehe()
Dim data, ketqua As Variant, i, j, k, n, ngay, col, maxK As Long
ReDim ketqua(1 To 60000, 1 To 3)
With Sheets("Data")
    data = .Range(.[a2], .[a2].End(4)).Resize(, 3).Value
End With
ngay = data(1, 1)

For i = 1 To UBound(data)
If data(i, 3) > 7 Then
    If data(i, 1) <> ngay Then
        n = UBound(ketqua, 2)
        ReDim Preserve ketqua(1 To 60000, 1 To n + 3)
        k = 1
        For j = 1 To 3
            ketqua(k, n + j) = data(i, j)
        Next
    Else
        k = k + 1
        If k > maxK Then maxK = k
        If n Then col = n
        For j = 1 To 3
            ketqua(k, j + col) = data(i, j)
        Next
    End If
    ngay = data(i, 1)
End If
Next
With Sheet2
.[A6:XFD60000].ClearContents
.[A6].Resize(maxK, n + 3) = ketqua
End With
End Sub



Gần đúng rồi bạn ơi, nhưng vẫn còn một lỗi nữa là nếu mình cho cột A (ngày) chạy xem kẽ thì nó lọc ko được hết.
Mình gửi file lên bạn coi dùm nhé. Mình có tô vàng ở sheet Data. Cảm ơn.
 

File đính kèm

Lần chỉnh sửa cuối:
Gần đúng rồi bạn ơi, nhưng vẫn còn một lỗi nữa là nếu mình cho cột A (ngày) chạy xem kẽ thì nó lọc ko được hết.
Mình gửi file lên bạn coi dùm nhé. Mình có tô vàng ở sheet Data. Cảm ơn.

giải thuật nó sẻ khác hoàn toàn,
cái này chắc phải xài dictionary.
=============
kiểm tra thử nha, còn nếu ko đúng thì, xài lại code cũ, chỉ cần sort lại theo cột A là được
Mã:
Option Explicit
Sub Loc_DL()
Dim data, ketqua As Variant, i, j, k, n, ngay, col, max_rw, rw As Long, dic As Object
ReDim ketqua(1 To 60000, 1 To 1)
With Sheets("Data")
    data = .Range(.[a2], .[a2].End(4)).Resize(, 3).Value
End With
Set dic = CreateObject("scripting.dictionary")
ngay = data(1, 1)

For i = 1 To UBound(data)
If data(i, 3) > 7 Then
    If Not dic.exists(data(i, 1)) Then
        n = UBound(ketqua, 2)
        k = 1
        dic.Add data(i, 1), n & "#" & k
        ReDim Preserve ketqua(1 To 60000, 1 To n + 3)
        For j = 1 To 3
            ketqua(k, n + j - 1) = data(i, j)
        Next
    Else
        rw = Split(dic.Item(data(i, 1)), "#")(1)
        col = Split(dic.Item(data(i, 1)), "#")(0)
        rw = rw + 1
        dic.Item(data(i, 1)) = col & "#" & rw
        If rw > max_rw Then max_rw = rw
        For j = 1 To 3
            ketqua(rw, j + col - 1) = data(i, j)
        Next
    End If
    ngay = data(i, 1)
End If
Next
With Sheet2
.[A6:XFD60000].ClearContents
.[A6].Resize(max_rw, n + 3) = ketqua
End With
End Sub
 
Lần chỉnh sửa cuối:
giải thuật nó sẻ khác hoàn toàn,
cái này chắc phải xài dictionary.
=============
kiểm tra thử nha, còn nếu ko đúng thì, xài lại code cũ, chỉ cần sort lại theo cột A là được
Mã:
Option Explicit
Sub Loc_DL()
Dim data, ketqua As Variant, i, j, k, n, ngay, col, max_rw, rw As Long, dic As Object
ReDim ketqua(1 To 60000, 1 To 1)
With Sheets("Data")
    data = .Range(.[a2], .[a2].End(4)).Resize(, 3).Value
End With
Set dic = CreateObject("scripting.dictionary")
ngay = data(1, 1)

For i = 1 To UBound(data)
If data(i, 3) > 7 Then
    If Not dic.exists(data(i, 1)) Then
        n = UBound(ketqua, 2)
        k = 1
        dic.Add data(i, 1), n & "#" & k
        ReDim Preserve ketqua(1 To 60000, 1 To n + 3)
        For j = 1 To 3
            ketqua(k, n + j - 1) = data(i, j)
        Next
    Else
        rw = Split(dic.Item(data(i, 1)), "#")(1)
        col = Split(dic.Item(data(i, 1)), "#")(0)
        rw = rw + 1
        dic.Item(data(i, 1)) = col & "#" & rw
        If rw > max_rw Then max_rw = rw
        For j = 1 To 3
            ketqua(rw, j + col - 1) = data(i, j)
        Next
    End If
    ngay = data(i, 1)
End If
Next
With Sheet2
.[A6:XFD60000].ClearContents
.[A6].Resize(max_rw, n + 3) = ketqua
End With
End Sub



Mình thấy code ok rồi đó bạn. Cảm ơn nhiều nhé.
Hic, thấy mọi người viết VBA hay quá mà cũng đang nghiên cứu, học lỏm mà viết hoài chưa được. Anh em nào có biết chỗ nào ở SG dạy viết VBA này ko? hay có tài liệu nào hay chỉ giúp mình với. Cảm ơn nhiều.
 
Mình thấy code ok rồi đó bạn. Cảm ơn nhiều nhé.
Hic, thấy mọi người viết VBA hay quá mà cũng đang nghiên cứu, học lỏm mà viết hoài chưa được. Anh em nào có biết chỗ nào ở SG dạy viết VBA này ko? hay có tài liệu nào hay chỉ giúp mình với. Cảm ơn nhiều.
ở SG thì ngay ổ rồi. Liên hệ thầy Tuân (bluesofts) có dạy đấy
còn sách thì đây
 
Ở SG thì liên hệ Chị Mộng Tiền __--__//////@#!^%//**/)*&^))*&^)+-+-+-+
 
For i = 1 To UBound(data)
If data(i, 3) > 7 Then
If Not dic.exists(data(i, 1)) Then
n = UBound(ketqua, 2)
k = 1
dic.Add data(i, 1), n & "#" & k
ReDim Preserve ketqua(1 To 60000, 1 To n + 3)
For j = 1 To 3
ketqua(k, n + j - 1) = data(i, j)
Next
Else
rw = Split(dic.Item(data(i, 1)), "#")(1)
col = Split(dic.Item(data(i, 1)), "#")(0)
rw = rw + 1
dic.Item(data(i, 1)) = col & "#" & rw
If rw > max_rw Then max_rw = rw
For j = 1 To 3
ketqua(rw, j + col - 1) = data(i, j)
Next
End If
ngay = data(i, 1)
End If
Next

Có ai có thể giải thích giúp mình đoạn code sau đây ko? mình đọc mà ko hiểu lắm. Xin cảm ơn.
 
Web KT

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

Back
Top Bottom