Tách từng chữ trong một chuỗi nhiều trường hợp

Liên hệ QC

letienmai

Thành viên hoạt động
Tham gia
16/7/14
Bài viết
146
Được thích
45
Kính gửi: anh/chị
- Em có một bài toán về tách từng chữ có ý nghĩa trong một chuối văn bản ra nằm từng cells nhưng nghĩ mãi không ra cách vì chuỗi cần tách có cả tiếng việt, tiếng hoa, tiếng anh và số.
- Anh/chị có thể sử dụng công thức hoặc Function sử dụng code nhưng chạy được trên Office 2010.
- Rất mong anh/ chị có kinh nghiệm xem giúp em. (Vui lòng xem file đính kèm để hiểu rõ hơn)
Xin được cám ơn và hậu tạ!
 

File đính kèm

  • tachchu.xlsm
    10.8 KB · Đọc: 25
Kính gửi: anh/chị
- Em có một bài toán về tách từng chữ có ý nghĩa trong một chuối văn bản ra nằm từng cells nhưng nghĩ mãi không ra cách vì chuỗi cần tách có cả tiếng việt, tiếng hoa, tiếng anh và số.
- Anh/chị có thể sử dụng công thức hoặc Function sử dụng code nhưng chạy được trên Office 2010.
- Rất mong anh/ chị có kinh nghiệm xem giúp em. (Vui lòng xem file đính kèm để hiểu rõ hơn)
Xin được cám ơn và hậu tạ!
Mình chỉ làm được với điều kiện có dấu cách giữa các từ tiếng Hoa, bạn tham khảo nhé.
 

File đính kèm

  • tachchu.xlsm
    11.9 KB · Đọc: 25
Mình chỉ làm được với điều kiện có dấu cách giữa các từ tiếng Hoa, bạn tham khảo nhé.
- Mình xin cám ơn bạn nhé.
- Tuy nhiên nếu giữa các chữ hoa có dấu cách thì mình đã làm được.
- Rất mong nhận thêm các trợ giúp từ các anh/chị.
 
Lần chỉnh sửa cuối:
- Mình xin cám ơn bạn nhé.
- Sẽ tuyệt vời hơn nếu giữa các chữ hoa không có dấu cách, do kết cấu nghĩa của nó là không có khoảng cách.
Vì cấu trúc tiếng Hoa nhiều hay ít nét thì máy tính cũng chỉ đếm là 1 ký tự nên mình chưa nghĩ được cách để tách riêng trong một chuỗi bạn ạ.
 
Kính gửi: anh/chị
- Em có một bài toán về tách từng chữ có ý nghĩa trong một chuối văn bản ra nằm từng cells nhưng nghĩ mãi không ra cách vì chuỗi cần tách có cả tiếng việt, tiếng hoa, tiếng anh và số.
- Anh/chị có thể sử dụng công thức hoặc Function sử dụng code nhưng chạy được trên Office 2010.
- Rất mong anh/ chị có kinh nghiệm xem giúp em. (Vui lòng xem file đính kèm để hiểu rõ hơn)
Xin được cám ơn và hậu tạ!
Bạn thử code này cho file bài 1.
Tạm thời kết quả để theo hàng ngang, nếu chốt kết quả đúng thì sẽ quay thành hàng dọc
Mã:
Option Explicit

Sub Tach()
Dim nguon
Dim tam
Dim kq
Dim rws
Dim i, j, k, x, z, t
nguon = Sheet2.Range("C5:C18")
rws = UBound(nguon)
ReDim kq(1 To rws, 1 To 100)
For i = 1 To rws
    j = 0
    If nguon(i, 1) <> "" Then
        For Each tam In Split(nguon(i, 1))
            t = ""
            x = ""
            For k = 1 To Len(tam)
                x = Mid(tam, k, 1)
                If AscW(x) > 7929 Then
                    j = j + 1
                    kq(i, j) = x
                Else
                    t = t & x
                End If
            Next k
            If t <> "" Then
                j = j + 1
                kq(i, j) = t
            End If
        Next tam
    End If
    If z < j Then z = j
Next i
With Sheet2
    .Range("F5").Resize(rws, z) = kq
End With
End Sub
---
Có lẽ bạn gửi file có đầu vào nhiều dòng hơn 1 chút để test thì kết quả sẽ tốt hơn
 
Bạn thử code này cho file bài 1.
Tạm thời kết quả để theo hàng ngang, nếu chốt kết quả đúng thì sẽ quay thành hàng dọc
Mã:
Option Explicit

Sub Tach()
Dim nguon
Dim tam
Dim kq
Dim rws
Dim i, j, k, x, z, t
nguon = Sheet2.Range("C5:C18")
rws = UBound(nguon)
ReDim kq(1 To rws, 1 To 100)
For i = 1 To rws
    j = 0
    If nguon(i, 1) <> "" Then
        For Each tam In Split(nguon(i, 1))
            t = ""
            x = ""
            For k = 1 To Len(tam)
                x = Mid(tam, k, 1)
                If AscW(x) > 7929 Then
                    j = j + 1
                    kq(i, j) = x
                Else
                    t = t & x
                End If
            Next k
            If t <> "" Then
                j = j + 1
                kq(i, j) = t
            End If
        Next tam
    End If
    If z < j Then z = j
Next i
With Sheet2
    .Range("F5").Resize(rws, z) = kq
End With
End Sub
---
Có lẽ bạn gửi file có đầu vào nhiều dòng hơn 1 chút để test thì kết quả sẽ tốt hơn
Chào bạn
- Sub đã chạy đúng kết quả theo hàng ngang.
- Tuy nhiên mình mong muốn nó như một Function tham chiếu động tại vị trí ô và sheet bất kỳ, vì hiện tại nếu Run Sub thì nó cố định ô và sheet, cụ thể trong file là Sheet1.Range("F5")
- Bạn xem có thay đổi theo hướng trên mình trình bày đc không?
 
Chào bạn
- Sub đã chạy đúng kết quả theo hàng ngang.
- Tuy nhiên mình mong muốn nó như một Function tham chiếu động tại vị trí ô và sheet bất kỳ, vì hiện tại nếu Run Sub thì nó cố định ô và sheet, cụ thể trong file là Sheet1.Range("F5")
- Bạn xem có thay đổi theo hướng trên mình trình bày đc không?
Chuyển về hàm được thôi bạn, nhưng cần xác định trước là có thể file sẽ khá nặng đó nhé.
 
File mình tính chất chỉ dưới 100 dòng thôi bạn nhé.
Nếu chuyển đc về công thức là tốt nhất.
Bạn test hàm dưới đây.
Cú pháp : Tach( Chuỗi đầu vào, vị trí chuỗi con cần lấy )
Mã:
Option Explicit

Public Function Tach(ByVal dauvao As String, ByVal vitri As Integer) As String
Dim tam As Variant
Dim chuoiR As String, chuoiG As String
Dim kq
Dim i, j, k
ReDim kq(1 To Len(dauvao))
For Each tam In Split(Application.Trim(dauvao))
    chuoiG = ""
    chuoiR = ""
    For i = 1 To Len(tam)
        chuoiR = Mid(tam, i, 1)
        If AscW(chuoiR) > 7929 Then
            j = j + 1
            If j = vitri Then
                Tach = chuoiR
                Exit Function
            End If
            kq(j) = chuoiR
        Else
            chuoiG = chuoiG & chuoiR
        End If
    Next i
    If chuoiG <> "" Then
        j = j + 1
        If j = vitri Then
            Tach = chuoiG
            Exit Function
        End If
        kq(j) = chuoiG
    End If
Next tam
If vitri > j Then Exit Function
Tach = kq(vitri)
End Function
---
code bài 5 và bài này chưa tính tới trường hợp nhóm ký tự dính liền có ký tự chữ tượng hình nằm phía cuối nhóm. Việc này có lẽ bạn chủ động kiểm tra, có gì tính tiếp sau nhé
 
Bạn test hàm dưới đây.
Cú pháp : Tach( Chuỗi đầu vào, vị trí chuỗi con cần lấy )
Mã:
Option Explicit

Public Function Tach(ByVal dauvao As String, ByVal vitri As Integer) As String
Dim tam As Variant
Dim chuoiR As String, chuoiG As String
Dim kq
Dim i, j, k
ReDim kq(1 To Len(dauvao))
For Each tam In Split(Application.Trim(dauvao))
    chuoiG = ""
    chuoiR = ""
    For i = 1 To Len(tam)
        chuoiR = Mid(tam, i, 1)
        If AscW(chuoiR) > 7929 Then
            j = j + 1
            If j = vitri Then
                Tach = chuoiR
                Exit Function
            End If
            kq(j) = chuoiR
        Else
            chuoiG = chuoiG & chuoiR
        End If
    Next i
    If chuoiG <> "" Then
        j = j + 1
        If j = vitri Then
            Tach = chuoiG
            Exit Function
        End If
        kq(j) = chuoiG
    End If
Next tam
If vitri > j Then Exit Function
Tach = kq(vitri)
End Function
---
code bài 5 và bài này chưa tính tới trường hợp nhóm ký tự dính liền có ký tự chữ tượng hình nằm phía cuối nhóm. Việc này có lẽ bạn chủ động kiểm tra, có gì tính tiếp sau nhé
Chữ việt thì trả KQ đúng, chữ hoa vẫn bị đảo bạn nhé (Hình đính kèm)
Nhờ bạn xem lại giúp. Với lại bạn nhắn giùm mình stk mình gửi mời bạn cà phê thay lời cám ơn nhé.
 

File đính kèm

  • Untitled.png
    Untitled.png
    478.8 KB · Đọc: 30
Chữ việt thì trả KQ đúng, chữ hoa vẫn bị đảo bạn nhé (Hình đính kèm)
Nhờ bạn xem lại giúp. Với lại bạn nhắn giùm mình stk mình gửi mời bạn cà phê thay lời cám ơn nhé.
Tìm dòng lệnh trên, thay bằng dòng dưới.
Mã:
'If AscW(chuoiR) > 7929 Then
 If Abs(AscW(chuoiR)) > 7929 Then

---
Bài này làm chơi thôi bạn, không cần thiết cà phê cà pháo đâu bạn.
 
Tìm dòng lệnh trên, thay bằng dòng dưới.
Mã:
'If AscW(chuoiR) > 7929 Then
If Abs(AscW(chuoiR)) > 7929 Then

---
Bài này làm chơi thôi bạn, không cần thiết cà phê cà pháo đâu bạn.
Vậy mình cám ơn bạn nhiều nhé, chúc bạn nhiều sức khỏe.
 
Nếu dữ liệu không phải là 南定an giang mà là an giang南定 thì kết quả như thế nào?
Nếu dựa vào mã ký tự thì có thể không dùng vòng lặp cũng được.
 
Bạn test hàm dưới đây.
Cú pháp : Tach( Chuỗi đầu vào, vị trí chuỗi con cần lấy )
Mã:
Option Explicit

Public Function Tach(ByVal dauvao As String, ByVal vitri As Integer) As String
Dim tam As Variant
Dim chuoiR As String, chuoiG As String
Dim kq
Dim i, j, k
ReDim kq(1 To Len(dauvao))
For Each tam In Split(Application.Trim(dauvao))
    chuoiG = ""
    chuoiR = ""
    For i = 1 To Len(tam)
        chuoiR = Mid(tam, i, 1)
        If AscW(chuoiR) > 7929 Then
            j = j + 1
            If j = vitri Then
                Tach = chuoiR
                Exit Function
            End If
            kq(j) = chuoiR
        Else
            chuoiG = chuoiG & chuoiR
        End If
    Next i
    If chuoiG <> "" Then
        j = j + 1
        If j = vitri Then
            Tach = chuoiG
            Exit Function
        End If
        kq(j) = chuoiG
    End If
Next tam
If vitri > j Then Exit Function
Tach = kq(vitri)
End Function
---
code bài 5 và bài này chưa tính tới trường hợp nhóm ký tự dính liền có ký tự chữ tượng hình nằm phía cuối nhóm. Việc này có lẽ bạn chủ động kiểm tra, có gì tính tiếp sau nhé
Bạn ơi cho mình hỏi thêm với là sao có trường hợp nó không hiển thị được chữ mà chỉ hiện ô vuông, cái đó là do mã AscW đúng không bạn?
Mình có đính kèm file trường hợp này. xin cám ơn.
 

File đính kèm

  • tachchu.xlsm
    16.2 KB · Đọc: 20
Bạn ơi cho mình hỏi thêm với là sao có trường hợp nó không hiển thị được chữ mà chỉ hiện ô vuông, cái đó là do mã AscW đúng không bạn?
Mình có đính kèm file trường hợp này. xin cám ơn.
Có lẽ bạn gửi số lượng mẫu lớn hơn để test 1 lần cho xong.
 
Kính gửi: anh/chị
- Em có một bài toán về tách từng chữ có ý nghĩa trong một chuối văn bản ra nằm từng cells nhưng nghĩ mãi không ra cách vì chuỗi cần tách có cả tiếng việt, tiếng hoa, tiếng anh và số.
- Anh/chị có thể sử dụng công thức hoặc Function sử dụng code nhưng chạy được trên Office 2010.
- Rất mong anh/ chị có kinh nghiệm xem giúp em. (Vui lòng xem file đính kèm để hiểu rõ hơn)
Xin được cám ơn và hậu tạ!
Thử Function
Mã:
Function XYZ(ByVal iText As String, ByVal iIndex As Integer) As String
  Dim S_tmp, tmp, S, Res, iChr$, i&, k&
 
  S_tmp = Split(Application.Trim(iText))
  For Each tmp In S_tmp
    For i = Len(tmp) To 2 Step -1
      If (Abs(AscW(Mid(tmp, i, 1))) > 7929) <> (Abs(AscW(Mid(tmp, i - 1, 1))) > 7929) Then
        tmp = Mid(tmp, 1, i - 1) & " " & Mid(tmp, i, Len(tmp))
      End If
    Next i
    S = Split(tmp)
    For Each Res In S
      If Abs(AscW(Mid(Res, 1, 1))) > 7929 Then
        For i = 1 To Len(Res)
          iChr = Mid(Res, i, 1)
          If AscW(iChr) < 0 Then
            If i < Len(Res) Then
              If AscW(Mid(Res, i + 1, 1)) < 0 Then
                iChr = Mid(Res, i, 2)
                i = i + 1
              End If
            End If
          End If
          k = k + 1
          If k >= iIndex Then XYZ = iChr: Exit Function
        Next i
      Else
        k = k + 1
        If k = iIndex Then XYZ = Res: Exit Function
      End If
    Next Res
  Next tmp
End Function
 
1 vấn đề; 18 lần trao đổi, trong đó có 4 lần code và 6 lần góp ý.
Trình độ diễn tả vấn đè của thớt đáng nể thật :D
 
Web KT
Back
Top Bottom