Sort trong mảng Arr

Liên hệ QC

NguyenthiH

Thành viên mới đăng ký
Tham gia
11/12/16
Bài viết
930
Được thích
168
Giới tính
Nữ
Em có file có dữ liệu Sheet1!A2:D, Thầy Ba Tê đã giúp em code lọc không trùng bằng DIC ra Mảng Arr, rồi nạp Mảng Arr đó vào ListBox, nhưng chưa Sort tăng dần. Bây giờ em muốn mọi người giúp em Sort mảng Arr tăng dần rồi nạp vào ListBox.
Em cám ơn.
ps: click C29 của sheet!Nhap sẽ hiện Form
 

File đính kèm

  • Book1.xlsb
    26.1 KB · Đọc: 33
Em có file có dữ liệu Sheet1!A2:D, Thầy Ba Tê đã giúp em code lọc không trùng bằng DIC ra Mảng Arr, rồi nạp Mảng Arr đó vào ListBox, nhưng chưa Sort tăng dần. Bây giờ em muốn mọi người giúp em Sort mảng Arr tăng dần rồi nạp vào ListBox.
Em cám ơn.
ps: click C29 của sheet!Nhap sẽ hiện Form
Lập thớt mới thì nêu rõ yêu cầu.

Sắp xếp tăng dần như nào? điều kiện sắp xếp ở cột nào? "Tăng dần" ở đây hiểu là A-Z hay min-max?
 
Upvote 0
Dạ Sắp Xếp tăng dần cột tên hàng hóa đó Anh befaint (theo Alphabel)
 
Upvote 0
Em không rành, nhưng xếp tên hàng hóa trong Form theo thứ tự A,B,C,D...v...v.vv. đó Anh!
như Bánh -> Bột..-> Dầu.....
 
Lần chỉnh sửa cuối:
Upvote 0
(1) code lọc không trùng bằng DIC ra Mảng Arr, (2)rồi nạp Mảng Arr đó vào ListBox, nhưng chưa Sort tăng dần.
Bây giờ em muốn mọi người giúp em Sort mảng Arr tăng dần rồi nạp vào ListBox.
Trình độ như mình, thì mình làm vầy:

Sau (1), mình nạp mảng lên trang tính (1.1)

2. Sắp xếp diễn ra trên trang tính

3. Lấy vùng dữ liệu đã sắp xếp làm nguồn cho ListBox

Hay Nạp vô mảng lại để làm nguồn cho ListBox


Nếu không muốn vòng vô & thô sơ thì tìm trên diễn đàn có bài sắp xếp trong mảng.

Chúc sớm thành công.
 
Upvote 0
Đây là yêu cầu không đơn giản vì tác giả yêu cầu sort theo tên hàng bằng tiếng Việt, kể cả sort trên sheet cũng không có kết quả mong muốn.
Đã sort tiếng Việt thì nên tham khảo các đề tài có liên quan trên GPE.
 
Upvote 0
Em thấy giống hàm Filter2DArray của Thầy Ndu ở bài này.
Nhưng em chả biết làm.
Mong AC gán vào File dùm em ah!
 
Upvote 0
Em có file có dữ liệu Sheet1!A2:D, Thầy Ba Tê đã giúp em code lọc không trùng bằng DIC ra Mảng Arr, rồi nạp Mảng Arr đó vào ListBox, nhưng chưa Sort tăng dần. Bây giờ em muốn mọi người giúp em Sort mảng Arr tăng dần rồi nạp vào ListBox.
Em cám ơn.
ps: click C29 của sheet!Nhap sẽ hiện Form
tạo dùm bạn list đã sort, còn dùng thế nào thì không biết-=09=
 

File đính kèm

  • Bot.xlsb
    28.6 KB · Đọc: 73
Upvote 0
Cám Ơn Anh HieuCD, Anh đã giúp em nhiều lần.
Chúc Anh ngày Vui!
 
Upvote 0
Cám Ơn Anh HieuCD, Anh đã giúp em nhiều lần.
Chúc Anh ngày Vui!
thấy đồ ăn ngon quá nên mới tham gia, không biết có phần không --=0
dữ liệu tạo list không ổn, nếu mới nhập cho những dòng đầu thì không có những sản phẩm mới, bạn phải có chổ lưu trử toàn bộ danh sách các sản phẩm làm căn cứ tạo list
 
Upvote 0
Cám ơn Anh nhiều!
Ý Anh nói em không hiểu
dữ liệu tạo list không ổn, nếu mới nhập cho những dòng đầu thì không có những sản phẩm mới, bạn phải có chổ lưu trử toàn bộ danh sách các sản phẩm làm căn cứ tạo list
mà code Anh hay thiệt, chỉ có một dòng là Sort luôn List
Mã:
Slist.Sort
 
Lần chỉnh sửa cuối:
Upvote 0
Cám ơn Anh nhiều!
Ý Anh nói em không hiểu

mà code Anh hay thiệt, chỉ có một dòng là Sort luôn List
Mã:
Slist.Sort

Cái đó người ta dùng ArrayList và bản thân nó có chức năng này. Tuy nhiên, thấy dễ ăn vậy chứ thật ra chỉ áp dụng được bài của bạn, List đã được lọc duy nhất rồi nên sort xong còn "mò mò" ra được các phần tử ở cột khác chứ nếu để nguyên cái list chưa lọc duy nhất thì đố Arraylist mần được bài này
Mà cũng thấy lạ thật! Bạn HieuCD dùng ArrayList, bản thân nó cũng có chức năng lọc duy nhất, vậy sao phải thêm Dictionary vào chẳng hóa ra.. thừa???
----------------------
Tôi giải quyết bài toán theo hướng tổng quát: Mặc kệ danh sách có duy nhất hay không vẫn cứ sort được
1> Code trong Module:
Mã:
Function Sort2DArray(ByVal SourceArray, ByVal ColIndex As Long, ByVal Order As Boolean, ByVal HasTitle As Boolean)
  Dim tmpArr, i As Long, j As Long, SortArr, Item1, Item2, firstVal As Double
  Dim Arr, iR As Long, tmp(), n As Long, Chk As Boolean
  On Error Resume Next
  tmpArr = SourceArray: Arr = tmpArr
  ColIndex = ColIndex + LBound(tmpArr, 2) - 1
  firstVal = CDbl(tmpArr(LBound(tmpArr, 1) - HasTitle, ColIndex))
  Chk = firstVal > 0
  For i = LBound(tmpArr, 1) - HasTitle To UBound(tmpArr, 1)
    ReDim Preserve tmp(n)
    If Chk Then
      tmp(n) = CDbl(tmpArr(i, ColIndex))
    Else
      tmp(n) = CStr(tmpArr(i, ColIndex))
    End If
    n = n + 1
  Next
  SortArr = Sort1DArray(tmp, Order)
  With CreateObject("Scripting.Dictionary")
    For i = LBound(SortArr) To UBound(SortArr)
      If Chk Then
        If Not .Exists(CDbl(SortArr(i))) Then .Add CDbl(SortArr(i)), i + LBound(tmpArr, 1) - HasTitle
      Else
        If Not .Exists(CStr(SortArr(i))) Then .Add CStr(SortArr(i)), i + LBound(tmpArr, 1) - HasTitle
      End If
    Next
    For i = LBound(tmpArr, 1) - HasTitle To UBound(tmpArr, 1)
      If Chk Then
        iR = .Item(CDbl(tmpArr(i, ColIndex)))
      Else
        iR = .Item(CStr(tmpArr(i, ColIndex)))
      End If
      For j = LBound(tmpArr, 2) To UBound(tmpArr, 2)
        Arr(iR, j) = tmpArr(i, j)
      Next
      If Chk Then
        .Item(CDbl(tmpArr(i, ColIndex))) = iR + 1
      Else
        .Item(CStr(tmpArr(i, ColIndex))) = iR + 1
      End If
    Next
  End With
  Sort2DArray = Arr
End Function
Function Sort1DArray(ByVal srcArr, ByVal Order As Boolean)
  Dim Item, tmpArr, Arr1, Arr2, n As Long, m As Long
  tmpArr = srcArr
  With CreateObject("System.Collections.ArrayList")
    For Each Item In tmpArr
      .Add Item
    Next
    .Sort
    Arr1 = .ToArray
    If Order = False Then
      ReDim Arr2(LBound(Arr1) To UBound(Arr1))
      For n = .Count To 1 Step -1
        Arr2(m) = Arr1(n - 1)
        m = m + 1
      Next
      Sort1DArray = Arr2
    Else
      Sort1DArray = Arr1
    End If
  End With
End Function
Function Unique2DArray(ByVal SourceArray, Optional ByVal ColIndex As Variant = 1)
  Dim aSrc, aCol, tmp As String, cItem
  Dim lR As Long, lC As Long, lUB1 As Long, lUB2 As Long, lLB1 As Long, lLB2 As Long, n As Long
  Dim dic As Object
  Set dic = CreateObject("Scripting.Dictionary")
  aSrc = SourceArray: aCol = ColIndex
  If Not IsArray(aCol) Then aCol = Array(aCol)
  lLB1 = LBound(aSrc, 1): lLB2 = LBound(aSrc, 2)
  lUB1 = UBound(aSrc, 1): lUB2 = UBound(aSrc, 2)
  ReDim aDes(1 To lUB2 + 1 - lLB2, 1 To 1)
  For lR = lLB1 To lUB1
    tmp = vbNullString
    If Len(CStr(aSrc(lR, 1))) Then
      For Each cItem In aCol
        tmp = tmp & vbBack & aSrc(lR, cItem)
      Next
      If Not dic.Exists(tmp) Then
        n = n + 1
        dic.Add tmp, lR
        ReDim Preserve aDes(1 To lUB2 + 1 - lLB2, 1 To n)
        For lC = lLB2 To lUB2
          aDes(lC, n) = aSrc(lR, lC)
        Next
      End If
    End If
  Next
  If n Then Unique2DArray = Transpose2DArray(aDes)
End Function
Function Transpose2DArray(ByVal SourceArray)
  Dim aSrc
  Dim lR As Long, lC As Long
  aSrc = SourceArray
  ReDim aDes(LBound(aSrc, 2) To UBound(aSrc, 2), LBound(aSrc, 1) To UBound(aSrc, 1))
  For lR = LBound(aSrc, 1) To UBound(aSrc, 1)
    For lC = LBound(aSrc, 2) To UBound(aSrc, 2)
      aDes(lC, lR) = aSrc(lR, lC)
    Next
  Next
  Transpose2DArray = aDes
End Function
2> Code trong Form:
Mã:
[COLOR=#ff0000]Private Sub Label1_Click()
  Dim aDes
  Static bChk As Boolean
  bChk = Not bChk
  aDes = Me.ListBox1.List
  aDes = Sort2DArray(aDes, 1, bChk, False)
  Me.ListBox1.List = aDes
End Sub
Private Sub Label2_Click()
  Dim aDes
  Static bChk As Boolean
  bChk = Not bChk
  aDes = Me.ListBox1.List
  aDes = Sort2DArray(aDes, 2, bChk, False)
  Me.ListBox1.List = aDes
End Sub
Private Sub UserForm_Initialize()
  Dim aSrc, aDes
  aSrc = Sheets("Nhap").Range("C2:D1000").Value
  aDes = Unique2DArray(aSrc, 1)
  ListBox1.List = aDes
End Sub[/COLOR]
Code trong Module tuy dài nhưng bạn mặc kệ nó đi, chỉ cần biết áp dụng hàm vào form là đủ (xem và khai triển chỗ màu đỏ là được rồi)
Lưu ý: Ở đây tôi viết cho bạn chức năng sort theo cách bạn bấm vào Label TÊN HÀNG hoặc ĐVT thì nó sẽ sort
 

File đính kèm

  • UniqueAndSort.xlsb
    34.9 KB · Đọc: 89
Lần chỉnh sửa cuối:
Upvote 0
Cám Ơn Thầy Ndu!
Thầy có thể chỉnh dùm code để chọn trong ListBox bang phím lên xuống và nhấn enter thì nạp vào bang tính được không Thầy!
Như file này của Thầy,nhưng Enter thay vì Double Click
http://www.giaiphapexcel.com/forum/content.php?623-Tạo-ứng-dụng-form-hổ-trợ-tìm-kiếm-và-nhập-liệu

Cái nào ra cái đó! Sau khi xong topic này rồi bạn có thể hỏi vấn đề khác ở topic khác
 
Upvote 0
Topic này tới đây là hết rồi đó Thầy ndu Ơi!
Tại vì em có đọc bài "Tạo Ứng dung Form hỗ trợ tìm kiếm và nhập lieu" và em thấy trong file Thầy nạp list cho ListBox là danh sách không trùng, nên em có mở Topic "Lọc không trùng bang Dic" và được anh Hoang2013 và Thầy Ba Tê giúp.
Va Topic "Sort trong mảng Arr" và anh HieuCD và Thầy Ndu giúp.
Vậy em nhờ Thầy giúp chỉnh code để chọn trongListBox bang bàn phím (Lên Xuống) và nhấn Enter thì gán vào bang tính.
 
Lần chỉnh sửa cuối:
Upvote 0
Cái đó người ta dùng ArrayList và bản thân nó có chức năng này. Tuy nhiên, thấy dễ ăn vậy chứ thật ra chỉ áp dụng được bài của bạn, List đã được lọc duy nhất rồi nên sort xong còn "mò mò" ra được các phần tử ở cột khác chứ nếu để nguyên cái list chưa lọc duy nhất thì đố Arraylist mần được bài này
Mà cũng thấy lạ thật! Bạn HieuCD dùng ArrayList, bản thân nó cũng có chức năng lọc duy nhất, vậy sao phải thêm Dictionary vào chẳng hóa ra.. thừa???
----------------------
Tôi giải quyết bài toán theo hướng tổng quát: Mặc kệ danh sách có duy nhất hay không vẫn cứ sort được
1> Code trong Module:
Mã:
Function Sort2DArray(ByVal SourceArray, ByVal ColIndex As Long, ByVal Order As Boolean, ByVal HasTitle As Boolean)
  Dim tmpArr, i As Long, j As Long, SortArr, Item1, Item2, firstVal As Double
  Dim Arr, iR As Long, tmp(), n As Long, Chk As Boolean
  On Error Resume Next
  tmpArr = SourceArray: Arr = tmpArr
  ColIndex = ColIndex + LBound(tmpArr, 2) - 1
  firstVal = CDbl(tmpArr(LBound(tmpArr, 1) - HasTitle, ColIndex))
  Chk = firstVal > 0
  For i = LBound(tmpArr, 1) - HasTitle To UBound(tmpArr, 1)
    ReDim Preserve tmp(n)
    If Chk Then
      tmp(n) = CDbl(tmpArr(i, ColIndex))
    Else
      tmp(n) = CStr(tmpArr(i, ColIndex))
    End If
    n = n + 1
  Next
  SortArr = Sort1DArray(tmp, Order)
  With CreateObject("Scripting.Dictionary")
    For i = LBound(SortArr) To UBound(SortArr)
      If Chk Then
        If Not .Exists(CDbl(SortArr(i))) Then .Add CDbl(SortArr(i)), i + LBound(tmpArr, 1) - HasTitle
      Else
        If Not .Exists(CStr(SortArr(i))) Then .Add CStr(SortArr(i)), i + LBound(tmpArr, 1) - HasTitle
      End If
    Next
    For i = LBound(tmpArr, 1) - HasTitle To UBound(tmpArr, 1)
      If Chk Then
        iR = .Item(CDbl(tmpArr(i, ColIndex)))
      Else
        iR = .Item(CStr(tmpArr(i, ColIndex)))
      End If
      For j = LBound(tmpArr, 2) To UBound(tmpArr, 2)
        Arr(iR, j) = tmpArr(i, j)
      Next
      If Chk Then
        .Item(CDbl(tmpArr(i, ColIndex))) = iR + 1
      Else
        .Item(CStr(tmpArr(i, ColIndex))) = iR + 1
      End If
    Next
  End With
  Sort2DArray = Arr
End Function
Function Sort1DArray(ByVal srcArr, ByVal Order As Boolean)
  Dim Item, tmpArr, Arr1, Arr2, n As Long, m As Long
  tmpArr = srcArr
  With CreateObject("System.Collections.ArrayList")
    For Each Item In tmpArr
      .Add Item
    Next
    .Sort
    Arr1 = .ToArray
    If Order = False Then
      ReDim Arr2(LBound(Arr1) To UBound(Arr1))
      For n = .Count To 1 Step -1
        Arr2(m) = Arr1(n - 1)
        m = m + 1
      Next
      Sort1DArray = Arr2
    Else
      Sort1DArray = Arr1
    End If
  End With
End Function
Function Unique2DArray(ByVal SourceArray, Optional ByVal ColIndex As Variant = 1)
  Dim aSrc, aCol, tmp As String, cItem
  Dim lR As Long, lC As Long, lUB1 As Long, lUB2 As Long, lLB1 As Long, lLB2 As Long, n As Long
  Dim dic As Object
  Set dic = CreateObject("Scripting.Dictionary")
  aSrc = SourceArray: aCol = ColIndex
  If Not IsArray(aCol) Then aCol = Array(aCol)
  lLB1 = LBound(aSrc, 1): lLB2 = LBound(aSrc, 2)
  lUB1 = UBound(aSrc, 1): lUB2 = UBound(aSrc, 2)
  ReDim aDes(1 To lUB2 + 1 - lLB2, 1 To 1)
  For lR = lLB1 To lUB1
    tmp = vbNullString
    If Len(CStr(aSrc(lR, 1))) Then
      For Each cItem In aCol
        tmp = tmp & vbBack & aSrc(lR, cItem)
      Next
      If Not dic.Exists(tmp) Then
        n = n + 1
        dic.Add tmp, lR
        ReDim Preserve aDes(1 To lUB2 + 1 - lLB2, 1 To n)
        For lC = lLB2 To lUB2
          aDes(lC, n) = aSrc(lR, lC)
        Next
      End If
    End If
  Next
  If n Then Unique2DArray = Transpose2DArray(aDes)
End Function
Function Transpose2DArray(ByVal SourceArray)
  Dim aSrc
  Dim lR As Long, lC As Long
  aSrc = SourceArray
  ReDim aDes(LBound(aSrc, 2) To UBound(aSrc, 2), LBound(aSrc, 1) To UBound(aSrc, 1))
  For lR = LBound(aSrc, 1) To UBound(aSrc, 1)
    For lC = LBound(aSrc, 2) To UBound(aSrc, 2)
      aDes(lC, lR) = aSrc(lR, lC)
    Next
  Next
  Transpose2DArray = aDes
End Function
2> Code trong Form:
Mã:
[COLOR=#ff0000]Private Sub Label1_Click()
  Dim aDes
  Static bChk As Boolean
  bChk = Not bChk
  aDes = Me.ListBox1.List
  aDes = Sort2DArray(aDes, 1, bChk, False)
  Me.ListBox1.List = aDes
End Sub
Private Sub Label2_Click()
  Dim aDes
  Static bChk As Boolean
  bChk = Not bChk
  aDes = Me.ListBox1.List
  aDes = Sort2DArray(aDes, 2, bChk, False)
  Me.ListBox1.List = aDes
End Sub
Private Sub UserForm_Initialize()
  Dim aSrc, aDes
  aSrc = Sheets("Nhap").Range("C2:D1000").Value
  aDes = Unique2DArray(aSrc, 1)
  ListBox1.List = aDes
End Sub[/COLOR]
Code trong Module tuy dài nhưng bạn mặc kệ nó đi, chỉ cần biết áp dụng hàm vào form là đủ (xem và khai triển chỗ màu đỏ là được rồi)
Lưu ý: Ở đây tôi viết cho bạn chức năng sort theo cách bạn bấm vào Label TÊN HÀNG hoặc ĐVT thì nó sẽ sort

Đúng Thầy Ndu là bậc thầy, luôn luôn chỉ rõ người chưa biết hiểu 1 cách tỷ mỉ và khác người.

Trân trong.

Ngoctoan
 
Upvote 0
Web KT
Back
Top Bottom