Xuống dòng dựa vào số lượng ký tự cho trước

Liên hệ QC

nghiank09

Thành viên hoạt động
Tham gia
1/3/12
Bài viết
143
Được thích
30
Chào mọi người, em có một đoạn text lời bài hát (cột A), có cách nào để Excel sẽ nối các dòng có dữ liệu với nhau và xuống dòng theo số lượng từ cho trước (ô B1). Kết quả trả về ô C1. Em gửi kèm file ạ. Cám ơn mọi người rất nhiều.
Đây là hình ví dụ ạ:
Untitled.png
 

File đính kèm

  • xuong dong theo so luong ky tu cho truoc.xlsx
    12.3 KB · Đọc: 17
Chào mọi người, em có một đoạn text lời bài hát (cột A), có cách nào để Excel sẽ nối các dòng có dữ liệu với nhau và xuống dòng theo số lượng từ cho trước (ô B1). Kết quả trả về ô C1. Em gửi kèm file ạ. Cám ơn mọi người rất nhiều.
Đây là hình ví dụ ạ:
Lời bài hát thì nó có ý nghĩa theo từng câu sao bạn lại muốn gộp 5 chữ là 1 dòng.
 
Chào mọi người, em có một đoạn text lời bài hát (cột A), có cách nào để Excel sẽ nối các dòng có dữ liệu với nhau và xuống dòng theo số lượng từ cho trước (ô B1). Kết quả trả về ô C1. Em gửi kèm file ạ. Cám ơn mọi người rất nhiều.
Đây là hình ví dụ ạ:
View attachment 265392
Đầu tiên bạn dùng AutoFilter lọc tất cả dòng trắng (blank) sau đó xóa toàn bộ những dòng trắng này cho nó dồn hàng lên toàn bộ.
Tiếp theo tại ô B2 bạn gõ công thức: =A2
Tại ô B3 bạn gõ: =B2 & CHAR(10) & A3
Rồi, từ ô B3 bạn fill công thức xuống toàn bộ dữ liệu.
Ô cuối cùng của cột B là kết quả cuối cùng. Bạn copy ô này rồi Paste Value là ra kết quả mong muốn.
 

File đính kèm

  • xuong dong theo so luong ky tu cho truoc.xlsx
    21.5 KB · Đọc: 13
Lời bài hát thì nó có ý nghĩa theo từng câu sao bạn lại muốn gộp 5 chữ là 1 dòng.
Tại vì mình sẽ chép vào máy nghe nhạc (máy đời cũ). Máy nghe nhạc này đọc được file .txt mỗi dòng trong máy chỉ hiển thị tối đa 5 ký tự. Nếu để đoạn lyric không chỉnh sửa chép vào máy thì rất khó đọc, nên mình phải chủ động xuống dòng (mỗi dòng 5 ký tự) :)
 
Tại ô B2 bạn gõ công thức: =A2
Tại ô B3 bạn gõ: =B2 & " " & A3
Rồi, từ ô B3 bạn fill công thức xuống toàn bộ dữ liệu.
Ô cuối cùng của cột B là kết quả kế cuối cùng.
Tại ô khác viết công thức = FiveWords(ô đó). Ô này là kết quả cuối cùng
Code đơn giản cho dễ hiểu đối với người mới học:
PHP:
Function Fivewords(MyStr As String)
Dim tmp As String, Res As String, k As Long
For i = 1 To Len(MyStr)
    tmp = Mid(MyStr, i, 1)
    If tmp <> " " Then
        Res = Res & tmp
    Else
        k = k + 1
        If k Mod 5 <> 0 Then
            Res = Res & tmp
        Else
            Res = Res & Chr(10)
        End If
    End If
Next
   Fivewords = Res
End Function

1630724477883.png
 
Lần chỉnh sửa cuối:
Code đơn giản cho dễ hiểu
Này thì cho dễ hiểu. :p

PHP:
Function Fivewords2(ByVal MyStr As String) As String
    Const numWordsWrap = 5
    Dim tmp As String, Res As String, k As Long
    MyStr = WorksheetFunction.Trim(MyStr) 'de sau moi tu la 1 khoang trang '
    For i = 1 To Len(MyStr)
        tmp = Mid(MyStr, i, 1)
        If tmp <> " " Then
            Res = Res & tmp
        Else                            'tim thay khoang trang " " '
            k = k + 1                   'dem khoang trang = so tu '
            If k < numWordsWrap Then    'so khoang trang < so tu can ngat dong '
                Res = Res & tmp
            Else                        'so khoang trang = so tu can ngat dong '
                Res = Res & Chr(10)
                k = 0                   'dat lai gia tri dem ve 0, de dem tu dau '
            End If
        End If
    Next
       Fivewords2 = Res
End Function
 
Góp vui một cách khác:
PHP:
Public Function SplitTextX(ByVal rng As Range, ByVal num As Long) As String
Dim arrData, v, i&, temp$
arrData = rng.Value
For i = 1 To UBound(arrData, 1)
    If arrData(i, 1) <> "" Then temp = temp & " " & arrData(i, 1)
Next i
v = Split(Application.Trim(temp), " ")
For i = num To UBound(v) Step num
    v(i) = ChrW(10) & v(i)
Next i
SplitTextX = Join(v, " ")
End Function
Cách dùng: =SplitTextX(A1:A189,5)


.
 
Cám ơn mọi người đã hỗ trợ ạ.
 
Dân GPE ngoài thói quen thích tốc độ còn có tật mâu thuẫn với tốc độ là dùng phép cộng chuỗi & bất cứ nơi nào.

Nên nhớ chuỗi là dạng dữ liệu 'immutable', không thay đổi trị được. Để có thể thực hiện phép a = a & b, VBA phải tạo một vùng nhớ khác, chép a và b vào, và trỏ a vào vùng nhớ mới ấy.

Chỉnh code bài #7

Fivewords2 = Application.Trim(Replace(MyStr, dấu xuóng hàng, " "))
bCount = 0
xuongHang = Chr(10)
For i = 1 To Len(Fivewords2)
tmp = Mid(Fivewords2, i, 1)
If tmp = " " Then
bCount = bCount + 1
If blkCount >= 5 Then
Mid(Fivewords2, i, 1) = xuongHang
bCount = 0
End If
End If
Next i

Bài học: đã nói chuyện tốc độ thì khi cộng chuỗi phải nhớ hàm Mid.
 
Dân GPE ngoài thói quen thích tốc độ còn có tật mâu thuẫn với tốc độ là dùng phép cộng chuỗi & bất cứ nơi nào.
Trong đó có tôi 1 nửa. Nếu dữ liệu rất nhiều tôi mới quan tâm tốc độ, và tiết kiệm từng 1/1000 giây bao gồm "không nối chuỗi".
Nếu dữ liệu không nhiều, hoặc dữ liệu cục bộ cần nối chuỗi không nhiều, tôi hy sinh tốc độ để viết code đơn giản, hoặc cố tình đơn giản. Nhất là khi viết cho người mới học. Còn befaint chắc là đang trêu ghẹo tôi thôi.
For i = 1 to Len(Fivewords2)
Chỗ này chắc anh gõ nhầm. Lúc này Len(Fivewords2) = 0
 
Lần chỉnh sửa cuối:
Dân GPE ngoài thói quen thích tốc độ còn có tật mâu thuẫn với tốc độ là dùng phép cộng chuỗi & bất cứ nơi nào.
Bác Vẹt thử dùng hàm MID để thay thế cho cái ký tự & trong bài này xem:
 
Bác Vẹt thử dùng hàm MID để thay thế cho cái ký tự & trong bài này xem:
Mid không phải tìm " " lấy gì sửa " " thành thứ khác? Hai trường hợp khác nhau.
Trường hợp bài trong chủ đề này là sau khi chạy code, len không đổi, nên thay Mid 1 bằng Mid 1 (" " thay bằng ký tự 10)
Trường hợp bên kia sau khi chạy code thì len thay đổi (tăng lên). Mid tìm 1 ký tự viết hoa, thay bằng khoảng trắng & ký tự hoa đó (2 ký tự) trong khi Mid(1 ký tự) làm sao Mid này bằng mid kia được! Cố mà dùng Mid thay vào là mất ký tự viết hoa
 
Mid không phải tìm " " lấy gì sửa " " thành thứ khác? Hai trường hợp khác nhau.
Trường hợp bài trong chủ đề này là sau khi chạy code, len không đổi, nên thay Mid 1 bằng Mid 1 (" " thay bằng ký tự 10)
Trường hợp bên kia sau khi chạy code thì len thay đổi (tăng lên). Mid tìm 1 ký tự viết hoa, thay bằng khoảng trắng & ký tự hoa đó (2 ký tự) trong khi Mid(1 ký tự) làm sao Mid này bằng mid kia được! Cố mà dùng Mid thay vào là mất ký tự liền kề ký tự viết hoa
Ủa đang hỏi bác Vẹt mà bác! Do bác Vẹt nói "dùng phép cộng chuỗi & bất cứ nơi nào" nên hỏi xem bác Vẹt có cao kiến gì không.

Riêng việc xử lý chuỗi bằng Mid thì diễn đàn GPE đã xử lý nó từ rất lâu rồi!

1630752802891.png
 
Lần chỉnh sửa cuối:
Ủa đang hỏi bác Vẹt mà bác! Do bác Vẹt nói "dùng phép cộng chuỗi & bất cứ nơi nào" nên hỏi xem bác Vẹt có cao kiến gì không.
Tôi đang hiểu ngược với "bất cứ nơi nào" không có nghĩa là "không nơi nào cả", mà là "không phải bất cứ nơi nào", hoặc nghĩa là "có nơi nào đó". Trong diễn đàn này đâu có cấm việc trả lời việc hỏi đích danh?
 
Lâu quá quên luôn code rồi, phải tập lại từ đầu thôi, hihi

Mã:
Function DichChu(ByVal chu As String) As String
    Const so = 5
    Dim demso As Integer
    
    For demso = 1 To 10
        Dim Vetmini
    Next
    
    chu = WorksheetFunction.Trim(chu)
    With CreateObject("VBScript.RegExp")
        .Global = True
        .Pattern = "(\S+\s){" & so & "}"
        DichChu = .Replace(chu, "$&" & vbCrLf)
    End With
End Function
 
Trong đó có tôi 1 nửa. Nếu dữ liệu rất nhiều tôi mới quan tâm tốc độ, và tiết kiệm từng 1/1000 giây bao gồm "không nối chuỗi".
Nếu dữ liệu không nhiều, hoặc dữ liệu cục bộ cần nối chuỗi không nhiều, tôi hy sinh tốc độ để viết code đơn giản, hoặc cố tình đơn giản. Nhất là khi viết cho người mới học. Còn befaint chắc là đang trêu ghẹo tôi thôi.

Chỗ này chắc anh gõ nhầm. Lúc này Len(Fivewords2) = 0
1. Theo chuỗi ví dụ thì tương đối có thể gọi là nhiều.
1.1. Hàm Mid cũng chả có gì là không đơn giản. Tuy rằng nó là hàm duy nhất trong VBA mà có thể nằm bên trái phép gán.
Tất cả các hàm khác đều phải nằm bên phải phép gán. Khi bạn tự viết một hàm UDF có khả năng nằm bên trái phép gán như vậy thì mới là rắc rối.

2. Fivewords2 tương đương với MyStr trong code bài #7. Chỉ hơi khác chút là tôi có chuẩn chuỗi lại: loại bỏ các dấu xuống hàng bằng cách đổi chúng thành dấu cách trước khi trim.

Chú về việc ChrW hay Chr gì gì đó: code tôi đưa lên chỉ có tính chất minh hoạ thuật toán. Có thể ophair chỉnh sửa thêm khi thực sự ứng dụng.
 
Lần chỉnh sửa cuối:
1. Theo chuỗi ví dụ thì tương đối có thể gọi là nhiều.

2. Fivewords2 tương đương với MyStr trong code bài #7. Chỉ hơi khác chút là tôi có chuẩn chuỗi lại: loại bỏ các dấu xuống hàng bằng cách đổi chúng thành dấu cách trước khi trim.

Chú về việc ChrW hay Chr gì gì đó: code tôi đưa lên chỉ có tính chất minh hoạ thuật toán. Có thể ophair chỉnh sửa thêm khi thực sự ứng dụng.
Rất nhiều đối với tôi là hàng trăm ngàn dòng kết quả trở lên (những dự án khác). Còn trong bài tôi viết thì chỉ vài trăm khoảng trắng cần xử lý, vì hàm đánh cho chuỗi đã gộp nhiều cells thành 1 bằng công thức.
 
Trong đó có tôi 1 nửa. Nếu dữ liệu rất nhiều tôi mới quan tâm tốc độ, và tiết kiệm từng 1/1000 giây bao gồm "không nối chuỗi".
Anh muốn tiết kiệm ms thì đã là gì. Nhiều người chạy code VBA còn muốn tiết kiệm μs và ns kìa. :D
Chỗ này chắc anh gõ nhầm. Lúc này Len(Fivewords2) = 0

Trước đó có dòng mà
Mã:
Fivewords2 = Application.Trim(Replace(MyStr, dấu xuóng hàng, " "))
...
For i = 1 To Len(Fivewords2)
 
Web KT
Back
Top Bottom