Sắp xếp thứ tự tên ?

Liên hệ QC

Nguyen Rem

Tất cả chỉ là đưa ra quyết định đúng đắn
Tham gia
23/2/22
Bài viết
211
Được thích
30
Giới tính
Nữ
Em chào các anh chị ^^
Hiện tại em đang gặp một bài như sau nhưng chưa có ý tưởng gì cho bài đó cả nhưng mà thời hạn nộp của em nó gần hết rồi . Mong các anh giúp em viết một đoạn code đơn giản , dễ hiểu (dùng vòng lặp và hàm split)) để giải quyết nó. Rồi em sẽ học hỏi nội dung code sau ạ ^^
Đề bài:
Sắp xếp cột Họ và tên theo đúng thứ tự alphabet của tiếng Việt (tên Nguyễn Văn An đứng trước Nguyễn Văn Bình; tên Nguyễn Văn Bình đứng sau Nguyễn Tất Bình, …). Kết quả lưu vào một sheet tên là xap_sep. Ví dụ sắp xếp sau đây là đúng :
  1. Nguyễn Văn An
  2. Nguyễn Tất Bình
  3. Nguyễn Văn Bình
  4. Trần Tất Bình
(cách sắp xếp alphabet tiếng Việt : ưu tiên tên đầu tiên, sau đó xét chuỗi họ và tên đệm)
 
Lần chỉnh sửa cuối:
Trường đồ tri mã lực. Tới lúc khủng hoảng rồi.
Loại bài sắp xếp theo tên này ở đây có cả đống. Chịu khó tìm.
 
Upvote 0
Trường đồ tri mã lực. Tới lúc khủng hoảng rồi.
Loại bài sắp xếp theo tên này ở đây có cả đống. Chịu khó tìm.
Vẫn Chưa... !Vẫn Đang... !Vẫn Còn... !Vẫn Kịp... ! (Một chút vui vẻ trong lúc nước đang ngập đến cổ ^^)
Em cảm ơn anh để em kiếm :)) rồi có gì em sẽ thông báo sau ạ (Em kiếm rồi nhưng phức tạp quá nên em mới nhờ)
 
Upvote 0
Vẫn Chưa... !Vẫn Đang... !Vẫn Còn... !Vẫn Kịp... ! (Một chút vui vẻ trong lúc nước đang ngập đến cổ ^^)
Em cảm ơn anh để em kiếm :)) rồi có gì em sẽ thông báo sau ạ (Em kiếm rồi nhưng phức tạp quá nên em mới nhờ)
Split hay không có nó cũng được. Dựa vào dấu cách để lấy Tên và Họ. Nếu có > 1 dấu cách thì có cả Đệm. Dấu cách đầu tìm bằng Instr, dấu cách cuối tìm bằng InstrRev. Nếu 2 dấu cách này ở 2 vị trí khác nhau thì giữa 2 vị trí đó là Đệm. Vấn đề lớn nhất là Excel sắp xếp chuỗi tiếng Việt không chuẩn. Phải tự viết code, thậm chí nhiều code. Nếu dữ liệu là unicode dựng sẵn thì còn đỡ, còn nếu có thể là unicode tổ hợp hoặc lẫn lộn thì mệt đấy. Đó không phải là bài tập cho những người cỡ như bạn.
 
Upvote 0
Giả sử danh sách họ tên bắt đầu từ B2:
PHP:
Option Explicit
Sub sapxep()
Dim lr&, i&, j&, cell As Range, arr(), pos As String, min As String
lr = Cells(Rows.Count, "B").End(xlUp).Row
ReDim arr(1 To lr - 1, 1 To 1)
    For Each cell In Range("B2:B" & lr) ' sap xep lai ho ten theo thu tu ten truoc, ho sau
        pos = InStrRev(cell, " ")
        i = i + 1
        arr(i, 1) = Mid(cell, pos + 1) & " " & Left(cell, pos - 1)
    Next
    For i = 1 To lr - 2
        For j = i + 1 To lr - 1
            If arr(j, 1) < arr(i, 1) Then ' sort theo ten - ho lot
                min = arr(j, 1)
                arr(j, 1) = arr(i, 1)
                arr(i, 1) = min
            End If
        Next
    Next
    For i = 1 To lr - 1
        pos = InStr(1, arr(i, 1), " ") ' sap xep lai ho ten theo thu tu ho truoc, ten sau
        arr(i, 1) = Mid(arr(i, 1), pos + 1) & " " & Left(arr(i, 1), pos - 1)
    Next
Worksheets("sap_xep").Range("B2").Resize(lr - 1, 1).Value = arr ' dan ket qua qua sheet "sap_xep"
End Sub
 

File đính kèm

  • sapxep.xlsm
    19 KB · Đọc: 12
Upvote 0
Vẫn Chưa... !Vẫn Đang... !Vẫn Còn... !Vẫn Kịp... ! (Một chút vui vẻ trong lúc nước đang ngập đến cổ ^^)
Em cảm ơn anh để em kiếm :)) rồi có gì em sẽ thông báo sau ạ (Em kiếm rồi nhưng phức tạp quá nên em mới nhờ)
Tôi là dân Khoa học và Toán ứng dụng. Tôi luận vấn đề theo xác suất thống kê.
Ai luận vấn đề theo Khoa học và Toán định lượng là chuyện của họ.

... chưa có ý tưởng gì cho bài đó cả nhưng mà thời hạn nộp của em nó gần hết rồi ...
 
Upvote 0
Split hay không có nó cũng được. Dựa vào dấu cách để lấy Tên và Họ. Nếu có > 1 dấu cách thì có cả Đệm. Dấu cách đầu tìm bằng Instr, dấu cách cuối tìm bằng InstrRev. Nếu 2 dấu cách này ở 2 vị trí khác nhau thì giữa 2 vị trí đó là Đệm. Vấn đề lớn nhất là Excel sắp xếp chuỗi tiếng Việt không chuẩn. Phải tự viết code, thậm chí nhiều code. Nếu dữ liệu là unicode dựng sẵn thì còn đỡ, còn nếu có thể là unicode tổ hợp hoặc lẫn lộn thì mệt đấy. Đó không phải là bài tập cho những người cỡ như bạn.
Dùng thư viện có sẵn này có đúng không anh @batman1
SortedList
ArrayList
 
Upvote 0
Giả sử danh sách họ tên bắt đầu từ B2:
PHP:
Option Explicit
Sub sapxep()
Dim lr&, i&, j&, cell As Range, arr(), pos As String, min As String
lr = Cells(Rows.Count, "B").End(xlUp).Row
ReDim arr(1 To lr - 1, 1 To 1)
    For Each cell In Range("B2:B" & lr) ' sap xep lai ho ten theo thu tu ten truoc, ho sau
        pos = InStrRev(cell, " ")
        i = i + 1
 ...

Code này của bạn sắp xếp sai, không tính đến hết các trường hợp họ tên tiếng Việt có dấu rồi.
Vd: Tôi thêm tên "Ân" là nó xếp sau cùng.

Tham khảo bài này: Sắp xếp tiếng Việt

Screen Shot 2022-05-30 at 14.24.52.png
 
Upvote 0
Upvote 0
Vấn đề:
If arr(j, 1) < arr(i, 1) Then ' sort theo ten - ho lot
Anh ơi ! Em chưa thực sự hiểu cái đoạn này nó như thế nào anh giải thích cho em với

Em có chỉnh lại code của anh (ở module 1) như sau để tiện kiểm tra:
1653946218937.png

Hình ảnh sau khi chạy code:
1653946335261.png

Em đang thắc mắc cái phần bôi vàng
1653946550969.png
ở trong module 2 em có thiết kế một cái y hệt như cách của anh làm để sắp xếp số nhưng nó không được( đúng như dự đoán ^^)
1653947451560.png
ở trong module 3 khắc phục lỗi mà ở module 2 gây ra :))

Chắc đến đây anh cũng hiểu vấn đề em phải là gì đúng không ^^ .

Câu hỏi:
Tại sao lại có sự khác biệt này ?
Em cũng biết là các ký tự trong trên bàn phím nó được gán với một số trong bảng ASCII tức là mình có thể so sánh từng ký tự một với nhau nhưng mà trong bài làm của anh(chỗ bôi vàng) thì nó so sánh cả một chuỗi với nhau . Mong anh làm rõ vấn đề này giúp em
 

File đính kèm

  • SortName.xlsm
    22.4 KB · Đọc: 5
Upvote 0
Câu hỏi:
Tại sao lại có sự khác biệt này ?
Code trong Module2 có 2 cái sai. Thứ nhất là mảng có 11 phần tử nên phải có To 10 và To 11 chứ không phải là To 8 và To 9. Sai thứ 2 là j chạy từ i+1 chứ không phải chạy từ 2. Chạy từ 2 là thuật toán sai.

Phải là

Mã:
Sub Test()
Dim i As Long, j As Long, min
Dim A As Range
Dim Arr()
    Set A = Range("A17:A27")
    Arr = A.Value
  
    For i = 1 To 10
        For j = i + 1 To 11
            If Arr(j, 1) < Arr(i, 1) Then
                min = Arr(j, 1)
                Arr(j, 1) = Arr(i, 1)
                Arr(i, 1) = min
            End If
        Next
    Next
  
    Range("B17:B27").Value = Arr
End Sub

hoặc

Sub Test()
Dim i As Long, j As Long, min
Dim A As Range
Dim Arr()
    Set A = Range("A17:A27")
    Arr = A.Value
  
    For i = 1 To UBound(Arr, 1) - 1
        For j = i + 1 To UBound(Arr, 1)
            If Arr(j, 1) < Arr(i, 1) Then
                min = Arr(j, 1)
                Arr(j, 1) = Arr(i, 1)
                Arr(i, 1) = min
            End If
        Next
    Next
  
    Range("B17:B27").Value = Arr
End Sub

Em cũng biết là các ký tự trong trên bàn phím nó được gán với một số trong bảng ASCII tức là mình có thể so sánh từng ký tự một với nhau nhưng mà trong bài làm của anh(chỗ bôi vàng) thì nó so sánh cả một chuỗi với nhau . Mong anh làm rõ vấn đề này giúp em
Trước hết ta thống nhất với nhau là chỉ xét chuỗi các ký tự có mã >= 32 (dấu cách) và <= 127. So sánh 2 chuỗi thực ra cũng là so sánh 2 ký tự lần lượt. Cụ thể như sau:
1. So sánh 2 ký tự. Ký tự nào có mã nhỏ hơn thì nhỏ hơn.

2. So sánh 2 chuỗi. Hai chuỗi a và b được so sánh như sau:
- gọi các ký tự lần lượt của chuỗi a là a1, a2, ..., an, còn các ký tự của b là b1, b2, ..., bm
- so sánh a1 và b1. Nếu a1 < b1 thì a < b và kết thúc việc so sánh. Tương tự khi a1 > b1 thì a > b. Nếu a1 = b1 thì so sánh a2 và b2. Nếu vẫn chưa kết luận được chuỗi nào lớn hơn thì cứ tiếp tục sẽ tới lúc cặp ký tự cuối cùng được so sánh là (an, bn) và an = bn. Nếu bn cũng là ký tự cuối của b, tức m = n, thì kết luận là 2 chuỗi bằng nhau, tức a = b (2 chuỗi có cùng số ký tự và tất cả các ký tự ở vị trí tương ứng đều bằng nhau) Nếu m > n thì chuỗi b > a (nói nôm na thì chuỗi a là "đoạn đầu" của chuỗi b)

Vd.
a = "Nguyễn An", b = "Nguyễn An". Trường hợp an = bn với n = 1, 2, ... -> a = b

a = "Nguyễn An", b = "Nguyễn Anh". Trường hợp an = bn với n = 1, 2, ... và m > n -> b > a

Nói nôm na thì khi so sánh 2 chuỗi ta so sánh từng cặp ký tự ở cùng vị trí cho tới khi hoặc 2 ký tự đó không bằng nhau hoặc vị trí so sánh là ở cuối của một chuỗi. Nếu đó cũng là cuối của chuỗi thứ 2 thì 2 chuỗi bằng nhau, ngược lại thì chuỗi có nhiều ký tự hơn sẽ lớn hơn.
 
Upvote 0
Em chào các anh chị ^^
Hiện tại em đang gặp một bài như sau nhưng chưa có ý tưởng gì cho bài đó cả nhưng mà thời hạn nộp của em nó gần hết rồi . Mong các anh giúp em viết một đoạn code đơn giản , dễ hiểu (dùng vòng lặp và hàm split)) để giải quyết nó. Rồi em sẽ học hỏi nội dung code sau ạ ^^
Đề bài:
Sắp xếp cột Họ và tên theo đúng thứ tự alphabet của tiếng Việt (tên Nguyễn Văn An đứng trước Nguyễn Văn Bình; tên Nguyễn Văn Bình đứng sau Nguyễn Tất Bình, …). Kết quả lưu vào một sheet tên là xap_sep. Ví dụ sắp xếp sau đây là đúng :
  1. Nguyễn Văn An
  2. Nguyễn Tất Bình
  3. Nguyễn Văn Bình
  4. Trần Tất Bình
(cách sắp xếp alphabet tiếng Việt : ưu tiên tên đầu tiên, sau đó xét chuỗi họ và tên đệm)
Nạp tất cả vào ArrayList rồi sort phát là xong.
 
Upvote 0
Nhìn hấp dẫn quá! Nhưng mà giờ em đang làm cái khác mất rồi :> Để chiều tối em có thời gian thì em đọc cẩn thận sau ạ ^^ . Em cảm ơn các anh nhiều
 
Upvote 0
Với bài này em xin dùng hàm để tách lấy tên, sau đó dùng data→sort để sắp xếp:
 

File đính kèm

  • sapxep.xlsx
    12.3 KB · Đọc: 7
Upvote 0
Cũng không đúng được với chuỗi Tiếng Việt

Với chuỗi tiếng việt mà sắp xếp thì phải có thuận toán khác cho vấn đề, thay vì chỉ thuật toán sắp xếp thường
Cụ thể có giống như trường hợp "Ân" ở bài #10 không ạ? Em thấy sort thì nó vẫn ở giữa tên có chữ bắt đầu là "A" và "B". Chính xác là đang sắp theo A→Â→B, không biết như vậy là đang đúng hay sai.
 
Upvote 0
Cụ thể có giống như trường hợp "Ân" ở bài #10 không ạ? Em thấy sort thì nó vẫn ở giữa tên có chữ bắt đầu là "A" và "B". Chính xác là đang sắp theo A→Â→B, không biết như vậy là đang đúng hay sai.
Bạn chưa đụng hết các trường hợp sắp xếp tiếng Việt rồi.
Theo hình dưới nếu cùng tên thì sắp theo Họ vậy chữ Lê phải trước Nguyễn chứ -> Hoàng - Lê - Nguyễn. "A" phải trước "Á". Đạt và Dũng: D phải trước Đ chứ. Rồi dấu thanh, bạn qui định dấu hỏi trước ngã "~" hay ngã trước -> Bão hay Bảo trước?

Bạn đọc cái bài tôi có gửi link đính kèm để xem nhu cầu sắp xếp thực tế mọi người thảo luận trong đó.


Screen Shot 2022-05-31 at 11.43.13.png
 
Lần chỉnh sửa cuối:
Upvote 0
Web KT

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

Back
Top Bottom