Ý tưởng Sort bằng Array (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

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,725
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

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

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
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).
Nếu sort trên sheet thì sao gọi là Ý TƯỞNG SORT BẰNG ARRAY?
Mai nay bạn định sort trên ListBox bằng cách nào? Đừng nói là copy toàn bộ ra sheet, sort xong cho vô ListBox trở lại nha! Mà cứ cho là tạm chấp nhận phương án ấy đi, vậy code của ta chỉ hoạt động trên Excel thôi à?
Tôi thì không nghĩ thế! Nếu đã viết code, tôi sẽ tính đến việc code ấy có thể hoạt động trên mọi môi trường
 
Upvote 0
Nếu sort trên sheet thì sao gọi là Ý TƯỞNG SORT BẰNG ARRAY?
Mai nay bạn định sort trên ListBox bằng cách nào? Đừng nói là copy toàn bộ ra sheet, sort xong cho vô ListBox trở lại nha! Mà cứ cho là tạm chấp nhận phương án ấy đi, vậy code của ta chỉ hoạt động trên Excel thôi à?
Tôi thì không nghĩ thế! Nếu đã viết code, tôi sẽ tính đến việc code ấy có thể hoạt động trên mọi môi trường

Bởi vậy em mới đưa ra nhiều hướng giải quyết cho nhiều phương pháp, nếu có hướng đi đúng biết đâu người có thuật toán cao siêu sẽ rút từ đâu đó những bài mà chúng ta cùng thảo luận thì có thể người đó sẽ làm được việc đó.

Hy vọng người đó là Thầy đấy!
 
Upvote 0
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).

Tôi nghĩ rằng ta chỉ cần thuật toán. Chuyện tập ký tự như thế nào là đủ thì vô cùng. Nhưng nếu ta làm được với một tập ký tự chọn trước thì việc thêm ký tự vào tập cho đầy đủ hơn chả có gì là khó. Ta chỉ cần xếp "tay" lại thứ tự các ký tự trong tập.
Tôi cũng thử làm cho tập ký tự chứa tất cả các ký tự Việt, các chữ số, và các ký tự khác (như + - *, :, ? ...) mà code >= 32 và <= 127. Cho tập này thì tôi mã mỗi ký tự bằng 2 ký tự từ tập A = "0..9" + "abcdef". Tức tôi sắp xếp tập ký tự theo dãy tăng dần và gán cho chúng giá trị từ 0 tới ... nhưng được viết trong hệ 16, như vậy mỗi ký tự được mã bằng 2 ký tự của tập A.
Hàm Sort2DArray nhận mảng đã mã hóa ở các cột cần Sort hoặc không cần mã nếu chúng chỉ chứa các ký tư có code trong khoảng 32..127
Như vậy việc mã hóa là do Caller làm, hàm chỉ làm nhiệm vụ Sort mà thôi. Cũng có thể "đùn" cho hàm chuyện mã hóa bằng cách truyền thông số là cột này chứa Unicode, cột kia Vni ... nhưng như thế không đảm bảo vì có thể người dùng có nhiều loại phông chữ khác nhau trong toàn Sheet. Cũng có thể "đùn" cho hàm chuyện mã hóa mà không truyền thông số, lúc đó hàm tự phải "nhận dạng", "đoán" ký tự. Nhưng như vậy hàm có lẽ phải gọi là "Doan_va_Ma_Hoa thì đúng hơn. Hàm Sort thì như theo tên gọi nó được sinh ra để Sort.
Tôi chọn tập ký tự như đã nói, nhưng nếu ta chọn thêm hàng trăm ký tự khác mà vẫn giữ cách mã như tôi nói thì lúc đó mỗi ký tự cần mã bằng 3 ký tự từ tập A. Việc sắp xếp tập ký tự và gán bộ 3 ký tự ta làm bằng tay. Ta chỉ cung cấp cho người dùng hàm để mã hóa
Hàm Sort trong file đính kèm trả về mảng đã sắp xếp hoàn chỉnh và có thể dùng ngay nếu ta truyền cho hàm mảng không mã hóa (do chứa các ký tự có code 32..127) hoặc trả về mảng "vô giá trị" vì có trả về thì mảng chứa các cột mã hóa nên người dùng phải giải mã. Nhưng khi ta gọi hàm thì ta truyền thêm một mảng 1 chiều chứa thứ tự các dòng. Khi hàm trở về thì mảng này chứa lần lượt chỉ số dòng cần có trong mảng sắp xếp. Có được thứ tự này thì ta xếp được mảng nguồn.
Tôi đã thử test qua thì thấy việc mã hóa chiếm nhiều thời gian. Riêng việc sắp xếp mảng trong Sort2DArray thì "trong nháy mắt". Khi mã hóa thì tôi không kiểm tra phông chữ của từng ký tự vì như thế mất rất nhiều thời gian. Cũng không làm như nhiều người là kiểm tra ký tự đầu trong Sheet rồi coi đó là phông chữ trong toàn Sheet. Tôi kiểm tra từng cell. Vì có thể trong sheet người ta chuyển phông chữ nhiều lần nhưng hiếm ai trong cùng một cell chuyển phông chữ.
Nói tóm lại: việc mã hóa do người dùng làm, ta cung cấp cho người dùng hàm để mã hóa + hàm để sort

Link: http://www.mediafire.com/download.php?cjpwiucm6sj67ww
 
Lần chỉnh sửa cuối:
Upvote 0
Tôi nghĩ rằng ta chỉ cần thuật toán.


Trong tập tin gửi lên vd. dùng để test hàm Sort2DArray có lỗi.
Hàm Sort2DArray trước tiên kiểm tra tính đúng đắn của dữ liệu đầu vào và có dòng:
Mã:
If (UBound(arr_index) - LBound(arr_index) <> UBound(tmpArr, 1) - LBound(tmpArr, 1)) Or _
       (col1 < LBound(tmpArr, 2)) Or (col1 > UBound(tmpArr, 2)) Or _
       (col1 = col2) Or (col1 = col3) Or (col2 = col3) Then GoTo end_
Tức là phải có ít nhất 1 cột có chỉ số nằm trong giới hạn của mảng và 3 cột là khác nhau từng đôi một. Trong khi đó vd. để test hàm có code:
Mã:
Select Case i
            Case 1:
                col1 = CDbl(cot) - Cotdau + 1: col2 = -1: col3 = col2
            Case 2:
                col2 = CDbl(cot) - Cotdau + 1
            Case 3:
                col3 = CDbl(cot) - Cotdau + 1
End Select
tức nếu ta chỉ chọn 1 cột thì col2 = -1 = col3 nên trong hàm Sort2DArray có GoTo end_, và như vậy không sắp xếp được 1 cột. Có thể sửa lại code vd. nhưng tốt hơn là sửa code kiểm tra dữ liệu trong hàm Sort, tức thay
Mã:
If (UBound(arr_index) - LBound(arr_index) <> UBound(tmpArr, 1) - LBound(tmpArr, 1)) Or _
       (col1 < LBound(tmpArr, 2)) Or (col1 > UBound(tmpArr, 2)) Or _
       (col1 = col2) Or (col1 = col3) Or (col2 = col3) Then GoTo end_
bằng
Mã:
    If (UBound(arr_index) - LBound(arr_index) <> UBound(tmpArr, 1) - LBound(tmpArr, 1)) Or _
       (col1 < LBound(tmpArr, 2)) Or (col1 > UBound(tmpArr, 2)) Then GoTo end_
    If col1 = col2 Then
        col2 = LBound(tmpArr, 2) - 1
    ElseIf col1 = col3 Then
        col3 = LBound(tmpArr, 2) - 1
    ElseIf col2 = col3 Then
        col3 = LBound(tmpArr, 2) - 1
    End If

Tất nhiên đó mới chỉ là ý tưởng và bước đầu "cụ thể hóa" ý tưởng đó. Code được viết nhanh "trên đầu gối" nên có thể phải chỉnh sửa để hoàn hảo. Cụ thể mọi người cho ý kiến về chọn "tập ký tự cần thiết". Hiện tôi chọn ký tự Việt và các ký tự khác có code >= 32 và <= 127. Tổng cộng có 212 ký tự được chọn (< 255 nên mỗi ký tự được mã bằng 2 ký tự của tập A). Nếu ai đó thêm ký tự "đặc biệt" thì đề nghị cũng thêm luôn đề xuất xếp nó ở vị trí nào trong tập. Vd. mọi ký tự khác chữ cái được xếp trước. Nhưng thứ tự các ký tự "dấu cách", +, -, *, : {, }, "đặc biệt", ... như thế nào? Cái mấu chốt là thống nhất với nhau về tập ký tự lựa chọn và thứ tự sắp xếp chúng - đại loại là TCGPE giống như TCVN, chứ chuyện mã hóa dữ liệu theo tiêu chuẩn đó không khó.
Như tôi đã nói mọi tập dù có lớn bao nhiêu cũng không thể bao hàm được mọi trường hợp ứng dụng. Vấn đề là chọn sao cho có thể thỏa mãn nhu cầu trong "đa số" (99 %, 90 %, 80 % ...?) các trường hợp. Không có "hàm vạn năng", "tập đầy đủ" ...
 
Lần chỉnh sửa cuối:
Upvote 0
Trong tập tin gửi lên vd. dùng để test hàm Sort2DArray có lỗi.
Hàm Sort2DArray trước tiên kiểm tra tính đúng đắn của dữ liệu đầu vào và có dòng:
Mã:
If (UBound(arr_index) - LBound(arr_index) <> UBound(tmpArr, 1) - LBound(tmpArr, 1)) Or _
       (col1 < LBound(tmpArr, 2)) Or (col1 > UBound(tmpArr, 2)) Or _
       (col1 = col2) Or (col1 = col3) Or (col2 = col3) Then GoTo end_
Tức là phải có ít nhất 1 cột có chỉ số nằm trong giới hạn của mảng và 3 cột là khác nhau từng đôi một. Trong khi đó vd. để test hàm có code:
Mã:
Select Case i
            Case 1:
                col1 = CDbl(cot) - Cotdau + 1: col2 = -1: col3 = col2
            Case 2:
                col2 = CDbl(cot) - Cotdau + 1
            Case 3:
                col3 = CDbl(cot) - Cotdau + 1
End Select
tức nếu ta chỉ chọn 1 cột thì col2 = -1 = col3 nên trong hàm Sort2DArray có GoTo end_, và như vậy không sắp xếp được 1 cột. Có thể sửa lại code vd. nhưng tốt hơn là sửa code kiểm tra dữ liệu trong hàm Sort, tức thay
Mã:
If (UBound(arr_index) - LBound(arr_index) <> UBound(tmpArr, 1) - LBound(tmpArr, 1)) Or _
       (col1 < LBound(tmpArr, 2)) Or (col1 > UBound(tmpArr, 2)) Or _
       (col1 = col2) Or (col1 = col3) Or (col2 = col3) Then GoTo end_
bằng
Mã:
    If (UBound(arr_index) - LBound(arr_index) <> UBound(tmpArr, 1) - LBound(tmpArr, 1)) Or _
       (col1 < LBound(tmpArr, 2)) Or (col1 > UBound(tmpArr, 2)) Then GoTo end_
    If col1 = col2 Then
        col2 = LBound(tmpArr, 2) - 1
    ElseIf col1 = col3 Then
        col3 = LBound(tmpArr, 2) - 1
    ElseIf col2 = col3 Then
        col3 = LBound(tmpArr, 2) - 1
    End If

Tất nhiên đó mới chỉ là ý tưởng và bước đầu "cụ thể hóa" ý tưởng đó. Code được viết nhanh "trên đầu gối" nên có thể phải chỉnh sửa để hoàn hảo. Cụ thể mọi người cho ý kiến về chọn "tập ký tự cần thiết". Hiện tôi chọn ký tự Việt và các ký tự khác có code >= 32 và <= 127. Tổng cộng có 212 ký tự được chọn (< 255 nên mỗi ký tự được mã bằng 2 ký tự của tập A). Nếu ai đó thêm ký tự "đặc biệt" thì đề nghị cũng thêm luôn đề xuất xếp nó ở vị trí nào trong tập. Vd. mọi ký tự khác chữ cái được xếp trước. Nhưng thứ tự các ký tự "dấu cách", +, -, *, : {, }, "đặc biệt", ... như thế nào? Cái mấu chốt là thống nhất với nhau về tập ký tự lựa chọn và thứ tự sắp xếp chúng - đại loại là TCGPE giống như TCVN, chứ chuyện mã hóa dữ liệu theo tiêu chuẩn đó không khó.
Như tôi đã nói mọi tập dù có lớn bao nhiêu cũng không thể bao hàm được mọi trường hợp ứng dụng. Vấn đề là chọn sao cho có thể thỏa mãn nhu cầu trong "đa số" (99 %, 90 %, 80 % ...?) các trường hợp. Không có "hàm vạn năng", "tập đầy đủ" ...


Hàm của bạn rất hay! Hy vọng bạn mở rộng hơn với các mã khác, chẳng hạn VNI hay ABC, như vậy nó tương đối tổng quát hơn.

Cám ơn bạn rất nhiều!
 
Upvote 0
Hàm của bạn rất hay! Hy vọng bạn mở rộng hơn với các mã khác, chẳng hạn VNI hay ABC, như vậy nó tương đối tổng quát hơn.

Cám ơn bạn rất nhiều!

Trong module tôi gọi hàm "ma_hoa_chuoi" để mã hóa dữ liệu ví dụ. Và tôi coi chuỗi là unicode vì tôi biết dữ liệu của tôi là unicode. Làm như thế để test cho nhanh vì mục đích của tôi là test xem code hoạt động như thế nào. Trong thực tế thì phải mã hóa dữ liệu. Hàm "ma_hoa_chuoi" mã hóa dữ liệu với phông chữ cho trước, cả VN3, VNI chứ đâu chỉ unicode. Ngoài ra còn hàm "ma_hoa_cell" nữa. Cũng nằm cùng "chỗ" với Sort2DArray.
Tôi đã giải thích rất nhiều và rõ ràng trong code rồi mà
 
Lần chỉnh sửa cuối:
Upvote 0
Trong module tôi gọi hàm "ma_hoa_chuoi" để mã hóa dữ liệu ví dụ. Và tôi coi chuỗi là unicode vì tôi biết dữ liệu của tôi là unicode. Làm như thế để test cho nhanh vì mục đích của tôi là test xem code hoạt động như thế nào. Trong thực tế thì phải mã hóa dữ liệu. Hàm "ma_hoa_chuoi" mã hóa dữ liệu với phông chữ cho trước, cả VN3, VNI chứ đâu chỉ unicode. Ngoài ra còn hàm "ma_hoa_cell" nữa. Cũng nằm cùng "chỗ" với Sort2DArray.
Tôi đã giải thích rất nhiều và rõ ràng trong code rồi mà

ý tưởng rất hay, nhưng chưa thực dụng,
song, cũng rất cảm ơn bản dù sao cũng làm cho cái topic này không đi lạc chủ đề,
 
Upvote 0
ý tưởng rất hay, nhưng chưa thực dụng,
song, cũng rất cảm ơn bản dù sao cũng làm cho cái topic này không đi lạc chủ đề,

Vấn đề ở đây là mọi người hãy cùng đưa ra ý tưởng, dù hay dù dở nhưng trong mỗi ý tưởng có thể có một vài khía cạnh hay, bổ ích. Cùng chung sức như thế có thể rồi chúng ta sẽ có một kết quả cụ thể. Chứ mãi mãi chúng ta chỉ dừng ở giai đoạn tranh luận: hướng như thế chưa được đâu, không dễ đâu ... thì bao giờ mới có được code cụ thể?

Ngồi buồn kiểm tra lại code tôi phát hiện là trong hàm Sort2DArray có vài chỗ gõ thiếu hoặc nhầm.
Cần phải sửa
Mã:
QuickSort tmpArr, tmp_arr_index, LBound(tmpArr, 1), UBound(tmpArr, 1), col1, col2, col3, [COLOR=#ff0000]1[/COLOR], sortAtoZ1
thành
QuickSort tmpArr, tmp_arr_index, LBound(tmpArr, 1), UBound(tmpArr, 1), col1, col2, col3, [COLOR=#ff0000]col1[/COLOR], sortAtoZ1

Mã:
QuickSort tmpArr, tmp_arr_index, start, finish, col1, col2, col3, [COLOR=#ff0000]2[/COLOR], sortAtoZ2
thành
QuickSort tmpArr, tmp_arr_index, start, finish, col1, col2, col3, [COLOR=#ff0000]col2[/COLOR], sortAtoZ2

Mã:
QuickSort tmpArr, tmp_arr_index, start, finish, col1, col2, col3, [COLOR=#ff0000]3[/COLOR], sortAtoZ3
thành
QuickSort tmpArr, tmp_arr_index, start, finish, col1, col2, col3, [COLOR=#ff0000]col3[/COLOR], sortAtoZ3

Mã:
If [COLOR=#ff0000]U[/COLOR]Bound(tmpArr, 2) <= col3 Then
thành
If [COLOR=#ff0000]L[/COLOR]Bound(tmpArr, 2) <= col3 Then


Tập tin đã sửa có thể tải tại:
Link http://www.mediafire.com/download.php?cjpwiucm6sj67ww
 
Lần chỉnh sửa cuối:
Upvote 0
Không biết là ý tưởng này có kết quả chưa, có thể sort mọi thứ giống như Excel sort?
 
Upvote 0

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

Back
Top Bottom