-bạn tham khảo code này của ndu xem sao/Cái này E sưu tầm trên GPE
Các bác sửa giúp E lại cái code lọc mảng,
phần kết quả có hàng rỗng thành danh sách duy nhất ko có hàng rỗng nhé.
Các bác xem file đính kèm![]()
Function Dsach(ByVal Rg As Range, id As Integer)
Dim cl As Range, mg(), i, j, tam
Dim DS As New Collection
Application.Volatile
On Error Resume Next
For Each cl In Rg.Cells
If Trim(cl) <> "" Then DS.Add cl.Value, CStr(cl.Value)
Next
ReDim mg(DS.Count)
For i = 1 To DS.Count: mg(i - 1) = DS(i): Next
For i = 0 To UBound(mg)
For j = i + 1 To DS.Count - 1
If mg(i) > mg(j) Then
tam = mg(i): mg(i) = mg(j): mg(j) = tam
End If: Next: Next
If id > UBound(mg) Then
Dsach = ""
Else
Dsach = mg(id - 1)
End If
End Function
Function Dsach(ByVal Rg As Range, id As Integer)
Dim cl As Range, mg(), i, j, tam
Dim DS As New Collection
On Error Resume Next
For Each cl In Rg.Cells
If Trim(cl) <> "" Then DS.Add cl.Value, CStr(cl.Value)
Next
ReDim mg(DS.Count)
For i = 1 To DS.Count: mg(i - 1) = DS(i): Next
For i = 0 To UBound(mg) - 1
For j = i + 1 To DS.Count - 1
If mg(i) > mg(j) Then
tam = mg(i): mg(i) = mg(j): mg(j) = tam
End If: Next: Next
If id > UBound(mg) Then
Dsach = ""
Else
Dsach = mg(id - 1)
End If
End Function
Cái code "hơi rối" ấy có thể lọc được vùng dữ liệu không liên tục luôn đấy anh Sealand à ---> Ngoài ra nó cũng có thể biến kết quả thành dòng hay cột tùy thích nữa đấyMình thấy code hơi rối, nên tham gia code khác. Code của mình vừa lọc vừa sắp xếp
Nếu dùng UDF thì cũng đâu cần nhiều vòng lập thế anh ơi!Đúng là mình chưa Test nhưng đã UDF rồi mà lại tiếp tục dùng bằng công thức mảng nữa nên ngại. Hơn nữa, code đó mới chuyển vùng thành cột hay hàng chứ chưa làm việc lọc DS duy nhất
Function Dsach(ByVal SrcRng As Range, id As Long)
Dim TmpArr, Item
TmpArr = SrcRng
For Each Item In TmpArr
If Trim(Item) <> "" Then
id = id - 1
If id = 0 Then
Dsach = Item
Exit Function
End If
End If
Next
End Function
{= OB(mảng_cột_1,mảng cột 2,..,mảng_cột_n)}
CT gì gì nó là cái gì? File đâu?Các bác giúp E sửa cái CT mà E sưu tầm được không ?
E muốn CT đó lọc mảng nhưng theo các cột dữ liệu ko liền nhau :
PHP:{= OB(mảng_cột_1,mảng cột 2,..,mảng_cột_n)}
Code của bạn tôi sửa thành vầy:File đó đây ạ, bác sửa giùm cái code đó loại hàng trống nhé: Sao hôm nay E vào GPE chậm rì rì vậy
Function OB(ParamArray SrcArr())
Dim TmpArr, Item, i As Long, j As Long, Arr(1 To 10000, 1 To 1)
For i = LBound(SrcArr) To UBound(SrcArr)
TmpArr = SrcArr(i)
For Each Item In TmpArr
If Trim(Item) <> "" And Item <> 0 Then
j = j + 1
Arr(j, 1) = Item
End If
Next
Next
OB = Arr
End Function
Nếu dùng UDF thì cũng đâu cần nhiều vòng lập thế anh ơi!
.....................
Cú pháp hàm cũng giống như anh đã trình bày (=DSach( SrcRng , id ))
Vâng! Nhưng em đâu nghe tác giả đề cập đến vụ LỌC DUY NHẤT... chính thể mà em không dùng Collection hay DictionaryĐúng là Ndu luôn tìm cách tối ưu code.
Nhưng đoạn Code của Ndu còn thiếu 2 phần:Chính vì vậy, nó cũng bớt đi khá số lượng vòng lặp.-Lọc Danh sách duy nhất.
-Sắp xếp lại.
Function Dsach(ByVal SrcRng As Range, id As Long)
Dim TmpArr, Item
TmpArr = SrcRng
With CreateObject("Scripting.Dictionary")
For Each Item In TmpArr
If Trim(Item) <> "" And Not .Exists(Item) Then
id = id - 1
.Add Item, ""
If id = 0 Then
Dsach = Item
Exit Function
End If
End If
Next
End With
End Function
Oh... em không đọc kỹ yêu cầu rồi...Ôi cái vụ Sort này hay quá đi mất. Mình không phát hiện ra nó có trên GPE.
À, yêu cầu duy nhất là từ bài 1 cơ.
Function OB(ParamArray SrcArr())
Dim TmpArr, Item, i As Long, j As Long, Arr(1 To 10000, 1 To 1)
With CreateObject("Scripting.Dictionary")
For i = LBound(SrcArr) To UBound(SrcArr)
TmpArr = SrcArr(i)
For Each Item In TmpArr
If Trim(Item) <> "" And Item <> 0 Then
If Not .Exists(Item) Then
j = j + 1
.Add Item, j
Arr(j, 1) = Item
End If
End If
Next
Next
OB = Arr
End With
End Function
Hi... hi... bạn làm tôi cũng... sai theo rồi nhéXin lỗi post sai chỗ! Xin Xóa dùm bài này!
Function OB(ParamArray SrcArr())
Dim TmpArr, Item, i As Long, j As Long, Arr(1 To 10000, 1 To 1)
With CreateObject("Scripting.Dictionary")
For i = LBound(SrcArr) To UBound(SrcArr)
TmpArr = SrcArr(i)
For Each Item In TmpArr
If Trim(Item) <> "" And Item <> 0 Then
If Not .Exists(Item) Then
j = j + 1
.Add Item, j
Arr(j, 1) = Item
End If
End If
Next
Next
OB = Arr
End With
End Function
Em cũng đọc thấy code về Java của Rollover và vận dụng của NDU mà cũng hú thật là chưa biết cách truyền tham số (lồng) code trên vào để sort.Tai sao mình lồng vào toàn báo lỗi nhỉ?
---------------Tai sao mình lồng vào toàn báo lỗi nhỉ?
Hi... hi... Chỉ có thể sai 1 chổ thôi, đó là hàm SortArray của rollover79 chỉ làm việc với mảng 1 chiều ---> Đối với mảng 2 chiều nó sẽ báo lỗi ngay chổ nào có dùng đến hàm JOINEm cũng đọc thấy code về Java của Rollover và vận dụng của NDU mà cũng hú thật là chưa biết cách truyền tham số (lồng) code trên vào để sort.
Mong NDU và Rollover cụ thể giúp.
Cám ơn.
Function SortArray(arr, Optional isText As Boolean = False, Optional isDESC As Boolean = False)
Dim sCommand As String
sCommand = "('" & Join(arr, vbBack) & "').split('" & vbBack & "').sort("
If isText Then
sCommand = sCommand & ")"
Else
sCommand = sCommand & "function(a,b){return (a-b)})"
End If
If isDESC Then sCommand = sCommand & ".reverse()"
sCommand = sCommand & ".join('" & vbBack & "')"
Dim objSC
Set objSC = CreateObject("MSScriptControl.ScriptControl")
objSC.Language = "JavaScript"
SortArray = Split(objSC.Eval(sCommand), vbBack)
End Function
Function OB(ParamArray SrcArr())
Dim TmpArr, Item, i As Long
With CreateObject("Scripting.Dictionary")
For i = LBound(SrcArr) To UBound(SrcArr)
TmpArr = SrcArr(i)
For Each Item In TmpArr
If Trim(Item) <> "" And Item <> 0 Then
If Not .Exists(Item) Then
.Add Item, ""
End If
End If
Next
Next
OB = WorksheetFunction.Transpose(SortArray(.Keys, True))
End With
End Function
Hôm nay em mới tìm được bài này của bác, bác có thể thêm tùy chọn chỉ lọc cho text giúp e được ko ạ.Mình hiệu chính Code 1 chút:
Mã:Function Dsach(ByVal Rg As Range, id As Integer) Dim cl As Range, mg(), i, j, tam Dim DS As New Collection On Error Resume Next For Each cl In Rg.Cells If Trim(cl) <> "" Then DS.Add cl.Value, CStr(cl.Value) Next ReDim mg(DS.Count) For i = 1 To DS.Count: mg(i - 1) = DS(i): Next For i = 0 To UBound(mg) - 1 For j = i + 1 To DS.Count - 1 If mg(i) > mg(j) Then tam = mg(i): mg(i) = mg(j): mg(j) = tam End If: Next: Next If id > UBound(mg) Then Dsach = "" Else Dsach = mg(id - 1) End If End Function
Cú pháp : = DSach( Rg , id )Trong đó:
Rg: Vùng nguồn tạo danh sách.
Id: Số phần tử của Danh sách