Rùa Con 1080
Thành Viên Sao Chép 2
- Tham gia
- 4/5/16
- Bài viết
- 351
- Được thích
- 47
- Giới tính
- Nữ
Mình mới lượm được cái này. Bạn thử xem sao nhaChào các Anh, Chị.
Em có file này lọc không trùng tên phụ liệu rồi, giờ em nhờ các Anh, Chị chỉnh code để lấy đơn vị tính theo tên phụ liệu giúp em với.
(Sheet1.Active thì lọc_ chạy module CreatListPL)
Sub M_remove()
Dim Dic As Object, I As Long, sArr()
Set Dic = CreateObject("scripting.dictionary")
With Sheets("Sheet1")
sArr = .Range("A3", .Range("A65535").End(3)).Resize(, 2).Value
For I = 1 To UBound(sArr)
Dic.Item(sArr(I, 1)) = Application.Index(sArr, I, 0)
Next
.Range("D3:D1000").ClearContents
.Range("D3").Resize(Dic.Count, UBound(sArr, 2)) = Application.Index(Dic.Items, 0, 0)
.Range("D3:E" & .Range("D65535").End(3).Row).Sort Key1:=.[D2]
End With
End Sub
Sao bạn không add ĐVT vào Item luôn mà phải dùng Index rồi xử lý lại.Mình mới lượm được cái này. Bạn thử xem sao nha
Mã:Sub M_remove() Dim Dic As Object, I As Long, sArr() Set Dic = CreateObject("scripting.dictionary") With Sheets("Sheet1") sArr = .Range("A3", .Range("A65535").End(3)).Resize(, 2).Value For I = 1 To UBound(sArr) Dic.Item(sArr(I, 1)) = Application.Index(sArr, I, 0) Next .Range("D3:D1000").ClearContents .Range("D3").Resize(Dic.Count, UBound(sArr, 2)) = Application.Index(Dic.Items, 0, 0) .Range("D3:E" & .Range("D65535").End(3).Row).Sort Key1:=.[D2] End With End Sub
Dạ. Hôm trước em có đọc 1 bài họ dùng hàm Index nên đang làm thử thầy ạ./Excel có sẵn công cụ Remove Duplicates. Sử dụng kết hợp với Vlookup là được kết quả như ý.
Sao bạn không add ĐVT vào Item luôn mà phải dùng Index rồi xử lý lại.
Ngoài ra, Một số dòng cùng tên nhưng khác ĐVT và một số dòng khác chỉ khác chữ thường - hoa. Tùy theo nhu cầu nên kiểm tra kết hợp tên và ĐVT đồng thời cân nhắc thiết lập
CompareMode cho Dictionary.
Public Sub CreatList()
Dim sArr(), dArr(), I As Long, K As Long
Dim Dic As Object, Tem As String
Set Dic = CreateObject("Scripting.Dictionary")
With Sheet1
sArr = .Range("A3", .Range("B65536").End(3)).Value
ReDim dArr(1 To UBound(sArr, 1), 1 To 2)
For I = 1 To UBound(sArr, 1)
Tem = sArr(I, 1) & "#" & sArr(I, 2)
If Not Dic.Exists(Tem) Then
K = K + 1
Dic.Add Tem, K
dArr(K, 1) = sArr(I, 1): dArr(K, 2) = sArr(I, 2)
End If
Next I
.Range("D3:D1000").ClearContents
.Range("D3").Resize(K, 2) = dArr
.Range("D3:E" & .Range("D65535").End(3).Row).Sort Key1:=.[D2]
End With
Set Dic = Nothing
End Sub
Thì vầy thôiVậy nhờ anh huuthang_bd viết code add ĐVT vào Item cho em học hỏi với.
Sub CreatListPL()
Dim Darr(), Dic As Object, i As Long, LastR As Long
LastR = Sheet1.Range("A65500").End(xlUp).Row
If LastR > 1 Then
Darr = Sheet1.Range("A3:B" & LastR).Value
Set Dic = CreateObject("Scripting.Dictionary")
For i = 1 To UBound(Darr)
Dic(Darr(i, 1)) = Darr(i, 2)
Next
With Sheet1
.Range("D3:D1000").ClearContents
.Range("D3").Resize(Dic.Count) = Application.Transpose(Dic.keys)
.Range("E3").Resize(Dic.Count) = Application.Transpose(Dic.Items)
.Range("D3").Resize(Dic.Count, 2).Sort .[D3], 1, Header:=xlNo
End With
Set Dic = Nothing
End If
End Sub
Bạn kiểm tra file xem saoXin các Anh,Chị giúp em lần nữa:
Lọc không trùng xong, nạp vào mảng tạm, và lấy mảng tạm này làm List cho ComboBox trên UserForm có 2 cột[Tên Phụ liệu và ĐVT] thì chỉnh code làm sao để nạp vào ComboBox đó ah?
Thật ra vấn đề lọc duy nhất và sort mảng 2 chiều có đầy trên GPE rồi.Xin các Anh,Chị giúp em lần nữa:
Lọc không trùng xong, nạp vào mảng tạm, và lấy mảng tạm này làm List cho ComboBox trên UserForm có 2 cột[Tên Phụ liệu và ĐVT] thì chỉnh code làm sao để nạp vào ComboBox đó ah?
Option Compare Text
Function Sort2DArray(ByVal Source2D, ByVal ColIndex As Long, Optional ByVal Order As Boolean = False)
Dim aSrc, tmp
Dim oArrList As Object
Dim lR As Long, lC As Long, idx As Long, lPos As Long
Dim lFstRow As Long, lEndRow As Long, lFstCol As Long, lEndCol As Long
aSrc = Source2D
lFstRow = LBound(aSrc, 1): lEndRow = UBound(aSrc, 1)
lFstCol = LBound(aSrc, 2): lEndCol = UBound(aSrc, 2)
Set oArrList = CreateObject("System.Collections.ArrayList")
For lR = lFstRow To lEndRow
tmp = aSrc(lR, ColIndex)
oArrList.Add tmp
Next
oArrList.Sort
If Order Then oArrList.Reverse
ReDim aPos(oArrList.Count - 1)
ReDim aDes(lFstRow To lEndRow, lFstCol To lEndCol)
For lR = lFstRow To lEndRow
tmp = aSrc(lR, ColIndex)
idx = oArrList.IndexOf(tmp, 0)
lPos = idx + lFstRow + aPos(idx)
For lC = lFstCol To lEndCol
aDes(lPos, lC) = aSrc(lR, lC)
Next
aPos(idx) = aPos(idx) + 1
Next
Sort2DArray = aDes
End Function
Function Unique2DArray(ByVal Source2D, Optional ByVal ColIndex As Variant = 1)
Dim aSrc, aCol, tmp As String, cItem
Dim lR As Long, lC As Long, n As Long
Dim lFstRow As Long, lEndRow As Long, lFstCol As Long, lEndCol As Long
Dim oArrList As Object
Set oArrList = CreateObject("System.Collections.ArrayList")
aSrc = Source2D: aCol = ColIndex
If Not IsArray(aCol) Then aCol = Array(aCol)
lFstRow = LBound(aSrc, 1): lEndRow = UBound(aSrc, 1)
lFstCol = LBound(aSrc, 2): lEndCol = UBound(aSrc, 2)
ReDim aDes(lFstCol To lEndCol, lFstRow To lFstRow)
n = lFstRow - 1
For lR = lFstRow To lEndRow
tmp = vbNullString
If Len(CStr(aSrc(lR, lFstRow))) Then
If TypeName(aSrc(lR, lFstRow)) <> "Error" Then
For Each cItem In aCol
tmp = tmp & vbBack & UCase(aSrc(lR, cItem))
Next
If Not oArrList.Contains(tmp) Then
n = n + 1
oArrList.Add tmp
ReDim Preserve aDes(lFstCol To lEndCol, lFstRow To n)
For lC = lFstCol To lEndCol
aDes(lC, n) = aSrc(lR, lC)
Next
End If
End If
End If
Next
If n Then Unique2DArray = Transpose2DArray(aDes)
End Function
Function Transpose2DArray(ByVal Source2D)
Dim aSrc
Dim lR As Long, lC As Long
Dim lFstRow As Long, lEndRow As Long, lFstCol As Long, lEndCol As Long
aSrc = Source2D
lFstRow = LBound(aSrc, 1): lEndRow = UBound(aSrc, 1)
lFstCol = LBound(aSrc, 2): lEndCol = UBound(aSrc, 2)
ReDim aDes(lFstCol To lEndCol, lFstRow To lEndRow)
For lR = lFstRow To lEndRow
For lC = lFstCol To lEndCol
aDes(lC, lR) = aSrc(lR, lC)
Next
Next
Transpose2DArray = aDes
End Function
Private Sub UserForm_Initialize()
Dim arr1, arr2
arr1 = Unique2DArray(Sheet1.Range("A3:B1000")) ''<-- lọc duy nhất ra mảng arr1
If IsArray(arr1) Then
arr2 = Sort2DArray(arr1, 1) ''<-- sort arr1 ra thành arr2
If IsArray(arr2) Then Me.ComboBox1.List = arr2 ''<--- nạp arr2 vào combobox
End If
End Sub
Ủa? Người ta chỉ nhờ lọc duy nhất và sort thôi, bạn đưa code filter2d lên làm gì khiến người ta rối vậy?Bạn kiểm tra file xem sao
Tuy nhiên phải xem lại nha! Vì phần lọc duy nhất của bạn chưa chính xác.Em đoán bạn ấy sẽ cần cái đó nên dùng hàm của thầy ạ. Hị hì
Thật ra vấn đề lọc duy nhất và sort mảng 2 chiều có đầy trên GPE rồi.
Nếu bạn muốn lọc vào 1 mảng tạm thì buộc bạn phải viết nó thành 1 hàm.
Gửi bạn hàm tôi viết trước đây (tuy chưa hoàn hảo nhưng tạm dùng được):
1> Code trong Module:
Mã:Option Compare Text Function Sort2DArray(ByVal Source2D, ByVal ColIndex As Long, Optional ByVal Order As Boolean = False) Dim aSrc, tmp Dim oArrList As Object Dim lR As Long, lC As Long, idx As Long, lPos As Long Dim lFstRow As Long, lEndRow As Long, lFstCol As Long, lEndCol As Long aSrc = Source2D lFstRow = LBound(aSrc, 1): lEndRow = UBound(aSrc, 1) lFstCol = LBound(aSrc, 2): lEndCol = UBound(aSrc, 2) Set oArrList = CreateObject("System.Collections.ArrayList") For lR = lFstRow To lEndRow tmp = aSrc(lR, ColIndex) oArrList.Add tmp Next oArrList.Sort If Order Then oArrList.Reverse ReDim aPos(oArrList.Count - 1) ReDim aDes(lFstRow To lEndRow, lFstCol To lEndCol) For lR = lFstRow To lEndRow tmp = aSrc(lR, ColIndex) idx = oArrList.IndexOf(tmp, 0) lPos = idx + lFstRow + aPos(idx) For lC = lFstCol To lEndCol aDes(lPos, lC) = aSrc(lR, lC) Next aPos(idx) = aPos(idx) + 1 Next Sort2DArray = aDes End Function Function Unique2DArray(ByVal Source2D, Optional ByVal ColIndex As Variant = 1) Dim aSrc, aCol, tmp As String, cItem Dim lR As Long, lC As Long, n As Long Dim lFstRow As Long, lEndRow As Long, lFstCol As Long, lEndCol As Long Dim oArrList As Object Set oArrList = CreateObject("System.Collections.ArrayList") aSrc = Source2D: aCol = ColIndex If Not IsArray(aCol) Then aCol = Array(aCol) lFstRow = LBound(aSrc, 1): lEndRow = UBound(aSrc, 1) lFstCol = LBound(aSrc, 2): lEndCol = UBound(aSrc, 2) ReDim aDes(lFstCol To lEndCol, lFstRow To lFstRow) n = lFstRow - 1 For lR = lFstRow To lEndRow tmp = vbNullString If Len(CStr(aSrc(lR, lFstRow))) Then If TypeName(aSrc(lR, lFstRow)) <> "Error" Then For Each cItem In aCol tmp = tmp & vbBack & UCase(aSrc(lR, cItem)) Next If Not oArrList.Contains(tmp) Then n = n + 1 oArrList.Add tmp ReDim Preserve aDes(lFstCol To lEndCol, lFstRow To n) For lC = lFstCol To lEndCol aDes(lC, n) = aSrc(lR, lC) Next End If End If End If Next If n Then Unique2DArray = Transpose2DArray(aDes) End Function [/QUOTE]
Thực ra bạn có thể dùng Dictionary để lọc duy nhất chứ không cần phải mất thời gian với Arraylist.Thầy Tuấn, Nếu máy cài win 8/8.1/10 thì sẽ bị lỗi Automation của CreateObject("System.Collections.ArrayList"), khắc phục bằng cách cài gói tích hợp NetFramwork 2.0 + 3.5