- Tham gia
- 17/8/08
- Bài viết
- 8,662
- Được thích
- 16,720
- Giới tính
- Nam
Như chúng ta đã biết nói về hàm lọc, chúng ta không khỏi không nhắc đến bậc Thầy ndu96081631 với hàm Filter2DArray (bản gốc), với hàm này tôi đã học được ở Thầy rất nhiều!
Tuy nhiên, với nguồn là dữ liệu lớn, kiểu lọc là dạng Số, dạng Ngày tháng, dạng giờ v.v... thì hàm Filter2DArray chưa đáp ứng được tốc độ.
Cấu trúc:
Filter2DArray (Vùng cần lọc, Cột cần lọc, Điều kiện lọc, Tiêu đề (True/False))
Thêm nữa nếu lọc thời gian phải làm thêm động tác phụ. Chẳng hạn, tôi muốn lọc 02/08/2012 05:30:00 thì cấu trúc hàm sẽ như sau:
1) Dùng hàm của EXCEL:
2) Dùng thêm 1 biến Double để cụ thể hóa điều kiện: (nên dùng cái này để cải thiện tốc độ)
Lý do mà hàm này chạy chậm khi so sánh dạng số là dùng hàm Evaluate. Đây là một hàm hữu dụng nhằm lắp ghép chuỗi để chuyển thành hàm. Nó rất hay và tiện dụng, tuy nhiên nó gặp rắc rối với dữ liệu lớn vì xử lý nhiều nên cho tốc độ rất chậm.
Tôi đã thử lọc dạng số với 65536 dòng, với hàm Filter2DArray cho tốc độ 2.3120 giây.
Chính vì thế, để cải thiện tốc độ tôi đã thay thế hàm Evaluate đó, bằng toán tử so sánh (cũng vì điều này mà thủ tục đã rất nhiều để loại trừ tất cả các điều kiện). Và hàm của tôi đã cho tốc độ nhanh gấp đôi cũng với dữ liệu trên: 1.078 giây.
Đây là hàm mới dựa vào ý tưởng của hàm Filter2DArray của Thầy ndu96081631, không những nó cải thiện về tốc độ, nó được nâng cao hơn là lọc 2 điều kiện ở 2 cột với điều kiện AND hoặc OR.
Hàm NewAutoFilter:
Cấu trúc:
NewAutoFilter(Vùng cần lọc, Tiêu đề (xlYes, xlNo), Cột lọc 1, Điều kiện lọc 1, [Kiểu AND/OR (xlAnd, xlOr)], [Điều kiện lọc 2], [Cột lọc 2])
Tôi sẽ cụ thể file ở bài viết sau!
Tuy nhiên, với nguồn là dữ liệu lớn, kiểu lọc là dạng Số, dạng Ngày tháng, dạng giờ v.v... thì hàm Filter2DArray chưa đáp ứng được tốc độ.
Cấu trúc:
Filter2DArray (Vùng cần lọc, Cột cần lọc, Điều kiện lọc, Tiêu đề (True/False))
Thêm nữa nếu lọc thời gian phải làm thêm động tác phụ. Chẳng hạn, tôi muốn lọc 02/08/2012 05:30:00 thì cấu trúc hàm sẽ như sau:
1) Dùng hàm của EXCEL:
PHP:
sArray = Filter2DArray([A2:F65536], 6, "=DATE(2012, 8, 2) + TIME(5,30,0)", True)
2) Dùng thêm 1 biến Double để cụ thể hóa điều kiện: (nên dùng cái này để cải thiện tốc độ)
PHP:
Dim DateAndTime As Double
DateAndTime = DateSerial(2012, 8, 2) + TimeSerial(5, 30, 0)
sArray = Filter2DArray([A2:F65536], 6, "=" & DateAndTime, True)
Lý do mà hàm này chạy chậm khi so sánh dạng số là dùng hàm Evaluate. Đây là một hàm hữu dụng nhằm lắp ghép chuỗi để chuyển thành hàm. Nó rất hay và tiện dụng, tuy nhiên nó gặp rắc rối với dữ liệu lớn vì xử lý nhiều nên cho tốc độ rất chậm.
Tôi đã thử lọc dạng số với 65536 dòng, với hàm Filter2DArray cho tốc độ 2.3120 giây.
Chính vì thế, để cải thiện tốc độ tôi đã thay thế hàm Evaluate đó, bằng toán tử so sánh (cũng vì điều này mà thủ tục đã rất nhiều để loại trừ tất cả các điều kiện). Và hàm của tôi đã cho tốc độ nhanh gấp đôi cũng với dữ liệu trên: 1.078 giây.
Đây là hàm mới dựa vào ý tưởng của hàm Filter2DArray của Thầy ndu96081631, không những nó cải thiện về tốc độ, nó được nâng cao hơn là lọc 2 điều kiện ở 2 cột với điều kiện AND hoặc OR.
Hàm NewAutoFilter:
PHP:
Function NewAutoFilter(ByVal Expression As Variant, _
ByVal Header As HeaderType, _
ByVal Field1 As Long, _
ByVal Criteria1 As Variant, _
Optional ByVal Operator As OperatorType = xlAnd, _
Optional ByVal Criteria2 As Variant, _
Optional ByVal Field2 As Variant) As Variant
''Yeu cau khi filter dang ngay thang, dau phan cach cua Criteria bat buoc _
''phai la dau (/) - VD: ">=14/9/1976" hoac "14/9/1976 05:30" v.v...
FilterDataType1 = "": FilterDataType2 = ""
FilterColumn1 = Field1: FilterColumn2 = Field2
FilterCompare1 = 0: FilterCompare2 = 0: FilterSeries = 0
SourceFilterArray = Expression: RowNumArray = Array(0)
Urow = UBound(SourceFilterArray, 1)
Lrow = LBound(SourceFilterArray, 1) - Header
Ucol = UBound(SourceFilterArray, 2)
Lcol = LBound(SourceFilterArray, 2)
Call Check_Type_Of_Criteria1(Criteria1)
Criteria1 = FilterCrit1
If IsMissing(Criteria2) Then
Call MissingCriteria2(Criteria1)
Else
If IsMissing(Field2) Then FilterColumn2 = FilterColumn1
Call Check_Type_Of_Criteria2(Criteria2)
Criteria2 = FilterCrit2
Select Case FilterCompare1
Case 1
Call FilterCompare1_Case_1(Criteria1, Criteria2, Operator)
Case 2
Call FilterCompare1_Case_2(Criteria1, Criteria2, Operator)
Case 3
Call FilterCompare1_Case_3(Criteria1, Criteria2, Operator)
Case 4
Call FilterCompare1_Case_4(Criteria1, Criteria2, Operator)
Case 5
Call FilterCompare1_Case_5(Criteria1, Criteria2, Operator)
Case Else
Call FilterCompare1_Case_Else(Criteria1, Criteria2, Operator)
End Select
End If
If FilterSeries Or Header Then
Lrow = Lrow + Header
Dim FilterArray As Variant
ReDim FilterArray(Lrow To FilterSeries - Header, Lcol To Ucol) As Variant
If Header Then
For FilterColumn = Lcol To Ucol
FilterArray(Lrow, FilterColumn) = SourceFilterArray(Lrow, FilterColumn)
Next
End If
For FilterRow = Lrow To FilterSeries
For FilterColumn = Lcol To Ucol
FilterArray(FilterRow - Header, FilterColumn) = _
SourceFilterArray(RowNumArray(FilterRow), FilterColumn)
Next
Next
NewAutoFilter = FilterArray
Erase FilterArray
Erase RowNumArray
Erase SourceFilterArray
End If
End Function
Cấu trúc:
NewAutoFilter(Vùng cần lọc, Tiêu đề (xlYes, xlNo), Cột lọc 1, Điều kiện lọc 1, [Kiểu AND/OR (xlAnd, xlOr)], [Điều kiện lọc 2], [Cột lọc 2])
Tôi sẽ cụ thể file ở bài viết sau!
Lần chỉnh sửa cuối: