Ý tưởng Sort bằng Array

Liên hệ QC

Hoàng Trọng Nghĩa

Chuyên gia GPE
Thành viên BQT
Moderator
Tham gia
17/8/08
Bài viết
8,662
Được thích
16,718
Giới tính
Nam
Chắc chắn một điều rằng tôi chỉ mới "vọc" vấn đề mảng thời gian gần đây thôi nên không thể có những tư tưởng lớn như Sư phụ ptm0412, như Thầy ndu96081631, anh Sealand, v.v..., vì thế, khi thử nghiệm ý tưởng sắp xếp này cũng là "vung tay quá trán", tuy nhiên nếu có thể được phát triển bởi các Thầy, các Anh, hy vọng nó cũng là một đề tài được nhiều người bàn luận sôi nổi và có nhiều ý tưởng mới từ đề tài này:

PHP:
Sub LearnSortArr()
    Dim ArrOrg, sArray, sArr, ArrNew
    Dim I As Long, J As Long, N As Long
    
    ArrOrg = Range(Sheet1.[A2], Sheet1.[A65536].End(xlUp)).Value
    sArray = Range(Sheet1.[D2], Sheet1.[E65536].End(xlUp)).Value
    
    ReDim sArr(1 To UBound(ArrOrg), 1 To 2)
    
    N = 0
    For I = 1 To UBound(sArray)
        For J = 1 To UBound(ArrOrg)
            If sArray(I, 1) = ArrOrg(J, 1) Then
                N = N + 1
                sArr(J, 1) = ArrOrg(J, 1)
                sArr(J, 2) = sArray(I, 2)
                GoTo NextI
            End If
        Next
NextI:
    Next
    
    ReDim ArrNew(1 To N, 1 To 2)
    
    N = 0
    For I = 1 To UBound(sArr)
        If sArr(I, 1) <> "" Then
            N = N + 1
            ArrNew(N, 1) = sArr(I, 1)
            ArrNew(N, 2) = sArr(I, 2)
        End If
    Next
    
    Sheet1.[G2].Resize(N, 2).Value = ArrNew
End Sub
 

File đính kèm

  • SapXepArr.xls
    30 KB · Đọc: 46
Chắc chắn một điều rằng tôi chỉ mới "vọc" vấn đề mảng thời gian gần đây thôi nên không thể có những tư tưởng lớn như Sư phụ ptm0412, như Thầy ndu96081631, anh Sealand, v.v..., vì thế, khi thử nghiệm ý tưởng sắp xếp này cũng là "vung tay quá trán", tuy nhiên nếu có thể được phát triển bởi các Thầy, các Anh, hy vọng nó cũng là một đề tài được nhiều người bàn luận sôi nổi và có nhiều ý tưởng mới từ đề tài này:

PHP:
Sub LearnSortArr()
    Dim ArrOrg, sArray, sArr, ArrNew
    Dim I As Long, J As Long, N As Long
    
    ArrOrg = Range(Sheet1.[A2], Sheet1.[A65536].End(xlUp)).Value
    sArray = Range(Sheet1.[D2], Sheet1.[E65536].End(xlUp)).Value
    
    ReDim sArr(1 To UBound(ArrOrg), 1 To 2)
    
    N = 0
    For I = 1 To UBound(sArray)
        For J = 1 To UBound(ArrOrg)
            If sArray(I, 1) = ArrOrg(J, 1) Then
                N = N + 1
                sArr(J, 1) = ArrOrg(J, 1)
                sArr(J, 2) = sArray(I, 2)
                GoTo NextI
            End If
        Next
NextI:
    Next
    
    ReDim ArrNew(1 To N, 1 To 2)
    
    N = 0
    For I = 1 To UBound(sArr)
        If sArr(I, 1) <> "" Then
            N = N + 1
            ArrNew(N, 1) = sArr(I, 1)
            ArrNew(N, 2) = sArr(I, 2)
        End If
    Next
    
    Sheet1.[G2].Resize(N, 2).Value = ArrNew
End Sub
Đây là hướng đi đúng đắn! Tức sẽ sort dựa trên 1 thư viện có sẵn
Tôi đã từng nghĩ đến điều này rồi, nhưng vấn đề là làm sao xây dựng cái thư viện trên cho đầy đù
Nói riêng về ký tự Unicode thôi cũng có cả 1 rừng: Ký tự Alphabet không dấu, có dấu tiếng Việt, các ký tự đặc biệt, các ký tự số, các giá trị kiểu TRUE, FALSE... vân vân...
Giả định rằng ta có sẵn 1 thư viện đầy đủ, ta sẽ làm như sau:
- Quét từ ký tự trong 1 phần tử của mảng, so từng ký tự trong bảng tra, suy ra giá trị Index (STT) tương ứng ---> Ghép vào, ra được 1 số mới
- Làm như thế đối với các phần tử khác trong mảng, ra được 1 mảng mới toàn số
- Sort mảng mới này (quá dễ vì toàn là số)
- Giải mã các số trong từng phần tử của mảng đã sort để ra những chuổi nguyên gốc
--------------------
Vậy đấy! Nói chung mọi thứ dường như đã có trong đầu tôi rồi, chỉ còn vướng cái thằng TRUE, FALSE.. chẳng biết nên xử lý nó theo kiểu gì đây?
 
Upvote 0
Đây là hướng đi đúng đắn! Tức sẽ sort dựa trên 1 thư viện có sẵn
Tôi đã từng nghĩ đến điều này rồi, nhưng vấn đề là làm sao xây dựng cái thư viện trên cho đầy đù
Nói riêng về ký tự Unicode thôi cũng có cả 1 rừng: Ký tự Alphabet không dấu, có dấu tiếng Việt, các ký tự đặc biệt, các ký tự số, các giá trị kiểu TRUE, FALSE... vân vân...
Giả định rằng ta có sẵn 1 thư viện đầy đủ, ta sẽ làm như sau:
- Quét từ ký tự trong 1 phần tử của mảng, so từng ký tự trong bảng tra, suy ra giá trị Index (STT) tương ứng ---> Ghép vào, ra được 1 số mới
- Làm như thế đối với các phần tử khác trong mảng, ra được 1 mảng mới toàn số
- Sort mảng mới này (quá dễ vì toàn là số)
- Giải mã các số trong từng phần tử của mảng đã sort để ra những chuổi nguyên gốc
--------------------
Vậy đấy! Nói chung mọi thứ dường như đã có trong đầu tôi rồi, chỉ còn vướng cái thằng TRUE, FALSE.. chẳng biết nên xử lý nó theo kiểu gì đây?

Thầy thử đảo Step - 1 là thành ngược lại rồi chứ nhỉ?
 
Upvote 0
Giống như Hàm Sort2Array của Thầy, Nếu True là A>Z còn False là ngược lại, không biết em hiểu vậy có phải không? Nên đảo lại thì dùng Step - 1.

Còn Thầy nói thằng True, False nào vậy?

Hồng phải vậy!
Ý tôi muốn nói là trong dữ liệu của chúng ta có các giá trị TRUE, FALS (do công thức trả về chẳng hạn) thì sẽ sort như thế nào
 
Upvote 0
Chắc chắn một điều rằng tôi chỉ mới "vọc" vấn đề mảng thời gian gần đây thôi nên không thể có những tư tưởng lớn như Sư phụ ptm0412, như Thầy ndu96081631, anh Sealand, v.v..., vì thế, khi thử nghiệm ý tưởng sắp xếp này cũng là "vung tay quá trán", tuy nhiên nếu có thể được phát triển bởi các Thầy, các Anh, hy vọng nó cũng là một đề tài được nhiều người bàn luận sôi nổi và có nhiều ý tưởng mới từ đề tài này:

PHP:
Sub LearnSortArr()
    Dim ArrOrg, sArray, sArr, ArrNew
    Dim I As Long, J As Long, N As Long
    
    ArrOrg = Range(Sheet1.[A2], Sheet1.[A65536].End(xlUp)).Value
    sArray = Range(Sheet1.[D2], Sheet1.[E65536].End(xlUp)).Value
    
    ReDim sArr(1 To UBound(ArrOrg), 1 To 2)
    
    N = 0
    For I = 1 To UBound(sArray)
        For J = 1 To UBound(ArrOrg)
            If sArray(I, 1) = ArrOrg(J, 1) Then
                N = N + 1
                sArr(J, 1) = ArrOrg(J, 1)
                sArr(J, 2) = sArray(I, 2)
                GoTo NextI
            End If
        Next
NextI:
    Next
    
    ReDim ArrNew(1 To N, 1 To 2)
    
    N = 0
    For I = 1 To UBound(sArr)
        If sArr(I, 1) <> "" Then
            N = N + 1
            ArrNew(N, 1) = sArr(I, 1)
            ArrNew(N, 2) = sArr(I, 2)
        End If
    Next
    
    Sheet1.[G2].Resize(N, 2).Value = ArrNew
End Sub

Theo tôi đánh số như thế có lẽ không được. Tất nhiên nếu cột A mỗi dòng chỉ 1 ký tư thì không nói làm gì. Nhưng nếu trong thực tế cột chứa text thì sao đây? Lúc đó vd. 192 là gì? Là ký tự thứ 192 (ta xét nhóm hàng trăm ký tự) hay là "bá"?
Tất nhiên ta không thể xét nhóm mọi ký tự trên đời được. Nếu gặp ký tự dùng trong âm nhạc thì sắp xếp thế nào? Nếu là ký tự Ả rập, Nga, Ba Lan thì xếp thế nào? Không thể viết hàm vạn năng. Như trong Toán mỗi định lý chỉ đúng với một giả thiết nhất định thì ta viết hàm với tập ký tự "đủ" để sử dụng trong đa số trường hợp. vd. ta chọn tất cả các ký tự Việt, các ký tự có code >= 32 và <= 127 chẳng hạn (các chữ cái, chữ số, +, -, *, :, ...). Theo tôi quãng <= 255 ký tự là "đủ".
Với nhóm ký tự được chọn ta sắp xếp theo chiều tăng dần (qui tắc sắp xếp trong tiếng Việt thì vd.: các biểu tượng (dấu cách, +, -, *, :, ^ ...) xếp trước chữ cái, chữ thường trước chữ hoa ...
Bây giờ ta gán cho các ký tự lần lượt các nhóm 2 ký tự ứng với các số từ 0 tới 255 nhưng được viết trong hệ 16. Tức: "00", "01", ..., "09", "0a", "0b", "0c", "0d", "0e", "0f", "10", ....
Khi sắp xếp thì mỗi chuỗi trong mỗi ô ta mã lần lượt các ký tự. vd. "bà" --> mã của "b" + mã của "à". Nếu có trường hợp ký tự "lạ" không nằm trong nhóm của ta thì ta để nguyên.
Sau khi mã rồi thì ta Sort theo cột có mã. Vd. ta sao cột có mã sang cột 1, và chỉ số dòng sang cột 2 của mảng 2 cột. Ta Sort theo cột 1 --> trong cột 2 ta có thứ tự cần có của các dòng trong mảng nguồn.
Tất nhiên đó chỉ là ý tưởng, một phác thảo sơ sơ thôi chứ chi tiết, chọn cách Sort thì là chuyện sau.
Tất nhiên cũng còn những vấn đề như ký tự Việt chẳng hạn. Ta không thể mặc định ngầm như nhiều người là dữ liệu của người dùng hàm của mình sẽ chỉ có Unicode dựng sẵn (2 BYTE) vì có nhiều người dùng Unicode tổ hợp, hoặc lấy dữ liệu của người thứ ba có Unicode tổ hợp (4 BYTE). Đấy là nói riêng về Unicode.
Sau cùng ta nói rõ với người dùng là hàm của ta chỉ sắp xếp theo cột mà trong đó có số, chữ cái và những ký tự như 0123456789:;<=>?@[\]^_{|}~ ... Không phục vụ những cột có dữ liệu hổ lốn: số, chữ, TRUE, FALSE, công thức. Mà nếu có cột như thế thì Excel sắp xếp thế nào nhỉ? Mà về phía ta thì ta muốn thế nào nhỉ? Mà có ai đó lại nảy sinh ra ý muốn sắp xếp theo những cột hổ lốn như thế để làm gì nhỉ?
 
Upvote 0
Hình như tiêu đề topic không hợp với nội dung?

Vì đây như là bạn sort 1 ký tự chứ không phải sort về Array,
 
Upvote 0
Hình như tiêu đề topic không hợp với nội dung?

Vì đây như là bạn sort 1 ký tự chứ không phải sort về Array,

Ý tưởng là như vậy, nhưng nếu phát triển thì ta dò từng ký tự đấy qua hàm InStr (hoặc left) thì điều kiện như vậy là đủ để phát triển thêm rồi bạn.
 
Upvote 0
Bài này Nghĩa.......muốn làm cái quái gì vậy ???? Hổng hiểu, giải thích giúp tí, đọc code .....chóng mặt quá
Híc
 
Upvote 0
Bài này Nghĩa.......muốn làm cái quái gì vậy ???? Hổng hiểu, giải thích giúp tí, đọc code .....chóng mặt quá
Híc

Chẳng qua là việc sắp xếp trật tự theo A,B,C vậy thôi bác Cò ơi (cò mà chơi chuột mới ghê)

Ý tưởng có, nhưng thuật toán thì không, nên gửi lên để những người có nhiều thuật toán cùng chung tay một chút.
 
Upvote 0
Chẳng qua là việc sắp xếp trật tự theo A,B,C vậy thôi bác Cò ơi (cò mà chơi chuột mới ghê)

Ý tưởng có, nhưng thuật toán thì không, nên gửi lên để những người có nhiều thuật toán cùng chung tay một chút.
Có phải từ bảng [D2:E15] cho ra bảng [G2:H15] hay còn gì nữa ????
 
Upvote 0
Có phải từ bảng [D2:E15] cho ra bảng [G2:H15] hay còn gì nữa ????

Đúng là như vậy đó bác, ý tưởng là dựa vào Nguồn dữ liệu được sắp xếp sẳn, lấy dữ liệu cần sắp xếp so sánh với Nguồn, thỏa điều kiện thì Add vào mảng rồi trả lại giá trị được sắp xếp.
 
Upvote 0
Đúng là như vậy đó bác, ý tưởng là dựa vào Nguồn dữ liệu được sắp xếp sẳn, lấy dữ liệu cần sắp xếp so sánh với Nguồn, thỏa điều kiện thì Add vào mảng rồi trả lại giá trị được sắp xếp.
Thế vùng [A2:B35] để làm gì ???? [J2:L15] ?????
 
Upvote 0
Thế vùng [A2:B35] để làm gì ???? [J2:L15] ?????

Nguồn là [A] còn là STT để theo dõi (cũng có thể sau này mã hóa nó thành Text Index luôn), còn [J2:L15] là để so sánh, dùng thủ tục Sort tại cột [K] theo STT đương nhiên là số dễ sắp xếp hơn chữ, rồi thử lại ở cột [L] xem nó sắp xếp có đúng trật tự không, nếu đúng thì True, sai là False.

Dĩ nhiên với thủ tục này còn nhiều bất cập, ví dụ nếu dữ liệu cần sắp xếp lặp đi lặp lại nhiều hơn 2 lần là tèo (vì mới chỉ là ý tưởng và IQ giới hạn nên chỉ dừng lại ở ý tưởng mà thôi, chưa thể là sáng kiến được)
 
Lần chỉnh sửa cuối:
Upvote 0
Tạm thời bi giờ thế này nhé:
Nguồn là dữ liệu cột D & E sắp xếp xong bỏ qua cột G & H
Sử dụng code này xem sao
Mã:
Public Sub SortNgoWa()
    Dim Vung, STT, Mg, I, Kq, K, TachA, TachB, kK
    STT = Range([E2], [E10000].End(xlUp))
    Vung = Range([D2], [E10000].End(xlUp))
    ReDim Mg(Application.WorksheetFunction.Min(STT) To Application.WorksheetFunction.Max(STT), 1 To 2)
        For I = 1 To UBound(Vung)
            Mg(Vung(I, 2), 1) = Mg(Vung(I, 2), 1) & " " & Vung(I, 1): Mg(Vung(I, 2), 2) = Mg(Vung(I, 2), 2) & " " & Vung(I, 2)
        Next I
            ReDim Kq(1 To UBound(Mg), 1 To 2)
                For I = LBound(Mg) To UBound(Mg)
                    If Mg(I, 2) <> "" Then
                        TachA = Split(Mg(I, 1)): TachB = Split(Mg(I, 2))
                        For kK = 1 To UBound(TachA)
                            Kq(K + kK, 1) = TachA(kK): Kq(K + kK, 2) = TachB(kK)
                        Next kK
                            K = K + kK - 1
                    End If
        Next I
    [G2:H1000].ClearContents
    [G2].Resize(K, 2) = Kq
End Sub
Hihi, làm theo dữ liệu trong bài thôi, chứ sort một ký tự trực tiếp trong mảng đơn giản thôi mà.
Có gì bàn tiếp, không ngủ được
+-+-+-++-+-+-++-+-+-+
 
Upvote 0
Bài này Nghĩa.......muốn làm cái quái gì vậy ???? Hổng hiểu, giải thích giúp tí, đọc code .....chóng mặt quá
Híc

Nói tóm lại em nghĩ chú nghĩa muốn xây dựng hàm Sort2DArray đấy mà
Hàm này em làm rồi, có điều nó chưa sort được tiếng Việt Unicode, bây giờ mình phát triển thêm thôi
 
Upvote 0
Hôm nay, mày mò trên Sheet, thấy cách sắp xếp trên sheet cũng không đảm bảo được ký tự có dấu, cái này chắc ai cũng biết, tôi thử làm phương pháp "thư viện tạm" trên sheet và sort trên sheet (thử với Unicode và VNI) đều cho ra kết quả đúng.

Cũng hy vọng qua bài này, các cao thủ có "manh mối" để phát triển Sort trên mảng 2 chiều.

Bằng phương thức Replace trong sheet thật là lẹ, nhưng chắc chưa ai có thể viết được kiểu này, thôi thì gửi tạm file này lên để mọi người cùng nhau "xé xác, mổ xẻ" nó cho "xôm tụ".

Phương pháp của mình mã hóa ký tự thành một Text Index, sau đó chuyển về lại giá trị gốc. Tuy nhiên, để tránh trường hợp Text Index lại trùng với những ký tự có sẳn, nên buộc lòng phải thay thế những ký tự này trước, sau cùng sẽ chuyển đổi lại như cũ.

Mã:
Sub LearnSortInRangeUni()
    With Application
        .EnableEvents = False
        .ScreenUpdating = False
        .Calculation = xlCalculationManual
    End With
    
    Dim RngLibrary As Range, sRange As Range, SortRng As Range
    Dim cIndex As Range, cBackup As Range, cOrigin As Range, sRestore As Range
    
    Set RngLibrary = Range(Sheet2.[B3], Sheet2.[B65536].End(xlUp)) 'Range("UniLib")
    Sheet2.[K:K].Clear
    Range(Sheet2.[I2], Sheet2.[I65536].End(xlUp)).Copy Sheet2.[K2]
    Set sRange = Range(Sheet2.[K2], Sheet2.[K65536].End(xlUp))
    
    [COLOR=#006400]'Backup du lieu neu co bi trung voi Index:[/COLOR]
    For Each cBackup In RngLibrary.Offset(, 4)
        With sRange
            .Replace What:=cBackup.Value, Replacement:=cBackup.Offset(, 1).Value, LookAt:=xlPart, MatchCase:=True
        End With
    Next
    
  [COLOR=#006400]  'Thay the ky tu co dau tieng Viet:[/COLOR]
    For Each cIndex In RngLibrary
        With sRange
            .Replace What:=cIndex.Value, Replacement:=cIndex.Offset(, 4).Value, LookAt:=xlPart, MatchCase:=True
        End With
    Next
    
    [COLOR=#006400]'Sap xep theo chieu tang dan:[/COLOR]
    sRange.Sort Sheet2.[K2], 1, , , , , , xlYes
    
   [COLOR=#006400] 'Thay the ky tu co dau tieng Viet:[/COLOR]
    For Each cOrigin In RngLibrary.Offset(, 4)
        With sRange
            .Replace What:=cOrigin.Value, Replacement:=cOrigin.Offset(, -4).Value, LookAt:=xlPart, MatchCase:=True
        End With
    Next
    
   [COLOR=#006400] 'Restore du lieu neu co bi trung voi Index:[/COLOR]
    For Each sRestore In RngLibrary.Offset(, 5)
        With sRange
            .Replace What:=sRestore.Value, Replacement:=sRestore.Offset(, -1).Value, LookAt:=xlPart, MatchCase:=True
        End With
    Next
    
    With Application
        .Calculation = xlCalculationAutomatic
        .EnableEvents = True
        .ScreenUpdating = True
    End With
End Sub
 

File đính kèm

  • SapXepByRange.rar
    37.7 KB · Đọc: 28
Upvote 0
Hôm nay, mày mò trên Sheet, thấy cách sắp xếp trên sheet cũng không đảm bảo được ký tự có dấu, cái này chắc ai cũng biết, tôi thử làm phương pháp "thư viện tạm" trên sheet và sort trên sheet (thử với Unicode và VNI) đều cho ra kết quả đúng.

Đừng vội!
Điều đầu tiên bạn cần làm là hãy liệt kê ra 1 thư viện thật đầy đủ, chỉ cần Unicode là đủ rồi, các bảng mã khác sẽ tính sau (cũng tương tự)
Một thư viện thật đầy đủ phải là: Gồm hết tất cả các ký tự cả text, number và các ký tự đặc biệt... Tôi tính sơ sơ chắc cũng phải vài trăm em
Cuối cùng, khi đã có 1 thư viện hoàn chỉnh hãy tính tới việc viết code... Mà viết cũng nên theo phương án tổng quát: Viết hẳn thành 1 Function đàng hoàng, sort trên nền tảng Array, để chỉ? Để mai này ta có thể áp dụng nó trên cả Range và Array luôn
 
Upvote 0
Đừng vội!
Điều đầu tiên bạn cần làm là hãy liệt kê ra 1 thư viện thật đầy đủ, chỉ cần Unicode là đủ rồi, các bảng mã khác sẽ tính sau (cũng tương tự)
Một thư viện thật đầy đủ phải là: Gồm hết tất cả các ký tự cả text, number và các ký tự đặc biệt... Tôi tính sơ sơ chắc cũng phải vài trăm em
Cuối cùng, khi đã có 1 thư viện hoàn chỉnh hãy tính tới việc viết code... Mà viết cũng nên theo phương án tổng quát: Viết hẳn thành 1 Function đàng hoàng, sort trên nền tảng Array, để chỉ? Để mai này ta có thể áp dụng nó trên cả Range và Array luôn

Theo em nghĩ, chỉ cần mã hóa các chữ có dấu tiếng Việt (cả thường và hoa chỉ có 148 ký tự), phương thức Sort trong sheet sẽ làm việc với những phần còn lại, em lại nghĩ sort 2 chiều của Thầy cũng có phương thức sort, vậy thì không cần cả một thư viện ký tự làm chi? Chỉ cần mã hóa cột cần sort, còn những cột khác không cần thiết.

Cũng chẳng ai Sort cái cột có công thức (nếu có sort làm sao đây? còn duyệt luôn thì giá trị true, false cứ theo F trước T sau).
 
Upvote 0
Web KT

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

Back
Top Bottom