Hỏi về chiều dài của chuỗi Unicode

Liên hệ QC

leminhbb

Thành viên mới
Tham gia
31/1/09
Bài viết
13
Được thích
1
Các bạn có biết hàm nào xác định chính xác length của 1 chuỗi Unicode không? VD như mình dùng Len("Nguyễn") trả về là 6 nhưng khi mình đưa vào CSDL (Oracle) kiểu chuỗi có chiều dài là 7 thì báo lỗi vì thực chất Len("Nguyễn") phải trả về 8 thì mới đúng.
Khách hàng đưa mình file DL Excel nên mình dùng macro kiểm tra xong chuyển cho khách hàng sửa lại rồi mới đưa vào CSDL.
Mấy nay mày mò mình sưu tầm được code chuyển sang UTF-8 nhưng sau khi chuyển thì dùng hàm Len("Nguyễn") nó vẫn ra 7 hix.
Mã:
Public Function UnicodeToUTF8(UniString As String) As String
    Dim bArray() As Byte, TempB() As Byte, i As Long, k As Long
    Dim TLen As Long, b1 As Byte, b2 As Byte, UTF16 As Long
    Dim byte1 As Byte, byte2 As Byte, byte3 As Byte
    
    TLen = Len(UniString)
    If TLen = 0 Then Exit Function
    k = 0
       
    For i = 1 To TLen
        CopyMemory b1, ByVal StrPtr(UniString) + ((i - 1) * 2), 1
        CopyMemory b2, ByVal StrPtr(UniString) + ((i - 1) * 2) + 1, 1
        
        UTF16 = b2
        UTF16 = UTF16 * 256 + b1
        
        If UTF16 < &H80 Then
            UnicodeToUTF8 = UnicodeToUTF8 & Chr$(UTF16)
            ElseIf UTF16 < &H800 Then
            byte2 = &H80 + (UTF16 And &H3F)
            UTF16 = UTF16 \ &H40
            byte1 = &HC0 + (UTF16 And &H1F)
            UnicodeToUTF8 = UnicodeToUTF8 & Chr$(byte1) & Chr$(byte2)
        Else
            byte3 = &H80 + (UTF16 And &H3F)
            UTF16 = UTF16 \ &H40
            byte2 = &H80 + (UTF16 And &H3F)
            UTF16 = UTF16 \ &H40
            byte1 = &HE0 + (UTF16 And &HF)
            UnicodeToUTF8 = UnicodeToUTF8 & Chr$(byte1) & Chr$(byte2) & Chr$(byte3)
        End If
    Next
End Function

Ai có cách xin giúp mình với! **~**
 
Chỉnh sửa lần cuối bởi điều hành viên:
Lạ nhỉ, tôi cũng đã từng nghe nói về vấn đề này nhưng sao tôi không gặp trường hợp đó nhỉ vì hàm Len vẫn làm việc đúng cho dù dùng Tổ hợp hay dựng sẵn.
Ví dụ: Len("Nguyễn") = 7 'Đối với tổ hợp và Len("Nguyễn") = 6 'Đối với dựng sẵn
Theo tôi có lẽ dõ CSDL của bạn được xây dựng lẫn lộn bằng cả bảng mã tổ hợp và cả bảng mã dựng sẵn. Vì vậy để xác định được đúng nguyên nhân bạn hãy thử tự xây dựng lấy CSDL của mình bằng 1 bảng mã duy nhất rồi test xem có bị thế không.
Còn việc chuyển đổi giữa các bảng mã thì hiện nay có nhiều công cụ rất chuẩn ví dụ như Unikey, tuy nhiên nếu trong CSDL của bạn có chứa lẫn lộn từ 2 bảng mã trở lên thì nó cũng chịu vì không thể xác định được từng ký tự thuộc bảng mã nào, đây có lẽ là vấn đề đau đầu nhất của việc chuyển mã.
 
Upvote 0
Nếu làm bằng Unikey thì mình biết rồi nhưng tại mình phải dùng code kiểm tra mới được mình muốn làm sao mà chữ "Nguyễn" chẳng hạn nó có thể chuyển thành là "Nguye^~n" thì len = 8 là đúng. Bạn có cách nào làm như thế không, giúp mình với. -=.,,
 
Upvote 0
Ơ, Unikey có chức năng chuyển thành VIQR đó thôi -> O+, Unikey co' chu+'c na(ng chuye^?n tha`nh VIQR ddo' tho^i
Bạn chưa test cái đó à?
 
Upvote 0
Hix nhưng làm bằng VBA như thế nào mới quan trọng, không dùng công cụ vì đó là dữ liệu động. +-+-+-+
 
Upvote 0
Hãy sử dụng phép ánh xạ để thực hiện. Xây dựng 2 mảng chứa các ký tự có dấu của hai bảng mã rồi so sánh.
Tôi gửi bạn đoạn mã chuyển đổi giữa TCVN và UNICODE để tham khảo
PHP:
Option Explicit
Sub ToUnicode()
    ConvertStr Selection.Text, False
End Sub
Sub ToTCVN()
    ConvertStr Selection.Text, True
End Sub
Private Sub ConvertStr(Txt As String, Optional isReversed As Boolean = False)
    Dim IStr$, I%, UN, VN
    IStr = Txt
    UN = Array(225, 224, 7843, 227, 7841, 259, 7855, 7857, 7859, 7861, 7863, 226, _
    7845, 7847, 7849, 7851, 7853, 233, 232, 7867, 7869, 7865, 234, 7871, 7873, 7875, _
    7877, 7879, 237, 236, 7881, 297, 7883, 243, 242, 7887, 245, 7885, 244, 7889, 7891, _
    7893, 7895, 7897, 417, 7899, 7901, 7903, 7905, 7907, 250, 249, 7911, 361, 7909, _
    432, 7913, 7915, 7917, 7919, 7921, 253, 7923, 7927, 7929, 7925, 273, 193, 192, 195, _
    258, 194, 212, 416, 431, 272)
    VN = Array(184, 181, 182, 183, 185, 168, 190, 187, 188, 189, 198, 169, 202, 199, 200, _
    201, 203, 208, 204, 206, 207, 209, 170, 213, 210, 211, 212, 214, 221, 215, 216, 220, _
    222, 227, 223, 225, 226, 228, 171, 232, 229, 230, 231, 233, 172, 237, 234, 235, 236, _
    238, 243, 239, 241, 242, 244, 173, 248, 245, 246, 247, 249, 253, 250, 251, 252, 254, _
    174, 193, 192, 195, 161, 162, 164, 165, 166, 167)
    For I = 0 To 75
        If isReversed And InStr(Txt, ChrW(UN(I))) <> 0 Then
            IStr = Replace(IStr, ChrW(UN(I)), "[" & VN(I) & "]")
        ElseIf InStr(IStr, ChrW(VN(I))) <> 0 Then
            IStr = Replace(IStr, ChrW(VN(I)), "[" & UN(I) & "]")
        End If
    Next
    If Len(IStr) <> Len(Txt) Then
        For I = 0 To 75
            If isReversed Then
                IStr = Replace(IStr, "[" & VN(I) & "]", ChrW(VN(I)))
            Else
                IStr = Replace(IStr, "[" & UN(I) & "]", ChrW(UN(I)))
            End If
        Next
    End If
    Selection.Text = IStr
End Sub
 
Upvote 0
Liên quan đến chủ đề này,mình xin hỏi về code tính độ rộng của 1 chuỗi (có cả khỏang trống)trong 1 ô .
Cảm ơn
 
Upvote 0
Hình như đó chính là len của cell đó thôi thì phải @#!^%
 
Upvote 0
Len cho ra số ký tự , còn kích thước thì khác
Ví dụ 2 ô có cùng 10 ký tự , nhưng ô có khoảng trống thì kích thước sẽ khác
 
Upvote 0
Liên quan đến chủ đề này,mình xin hỏi về code tính độ rộng của 1 chuỗi (có cả khỏang trống)trong 1 ô .
Cảm ơn
Nếu dùng VBA thì không làm được việc này đâu, có thể sử dụng API nhưng lâu rồi tôi không dùng đến VB6 nên quên mất nó là hàm gì.
Còn trong VS.Net thì đơn giản và bây giờ có công cụ VSTO lập trình trên môi trường .Net can thiệp trực tiếp vào office nữa cũng rất hay.
 
Upvote 0
Hãy sử dụng phép ánh xạ để thực hiện. Xây dựng 2 mảng chứa các ký tự có dấu của hai bảng mã rồi so sánh.
Tôi gửi bạn đoạn mã chuyển đổi giữa TCVN và UNICODE để tham khảo
PHP:
Option Explicit
Sub ToUnicode()
    ConvertStr Selection.Text, False
End Sub
Sub ToTCVN()
    ConvertStr Selection.Text, True
End Sub
Private Sub ConvertStr(Txt As String, Optional isReversed As Boolean = False)
    Dim IStr$, I%, UN, VN
    IStr = Txt
    UN = Array(225, 224, 7843, 227, 7841, 259, 7855, 7857, 7859, 7861, 7863, 226, _
    7845, 7847, 7849, 7851, 7853, 233, 232, 7867, 7869, 7865, 234, 7871, 7873, 7875, _
    7877, 7879, 237, 236, 7881, 297, 7883, 243, 242, 7887, 245, 7885, 244, 7889, 7891, _
    7893, 7895, 7897, 417, 7899, 7901, 7903, 7905, 7907, 250, 249, 7911, 361, 7909, _
    432, 7913, 7915, 7917, 7919, 7921, 253, 7923, 7927, 7929, 7925, 273, 193, 192, 195, _
    258, 194, 212, 416, 431, 272)
    VN = Array(184, 181, 182, 183, 185, 168, 190, 187, 188, 189, 198, 169, 202, 199, 200, _
    201, 203, 208, 204, 206, 207, 209, 170, 213, 210, 211, 212, 214, 221, 215, 216, 220, _
    222, 227, 223, 225, 226, 228, 171, 232, 229, 230, 231, 233, 172, 237, 234, 235, 236, _
    238, 243, 239, 241, 242, 244, 173, 248, 245, 246, 247, 249, 253, 250, 251, 252, 254, _
    174, 193, 192, 195, 161, 162, 164, 165, 166, 167)
    For I = 0 To 75
        If isReversed And InStr(Txt, ChrW(UN(I))) <> 0 Then
            IStr = Replace(IStr, ChrW(UN(I)), "[" & VN(I) & "]")
        ElseIf InStr(IStr, ChrW(VN(I))) <> 0 Then
            IStr = Replace(IStr, ChrW(VN(I)), "[" & UN(I) & "]")
        End If
    Next
    If Len(IStr) <> Len(Txt) Then
        For I = 0 To 75
            If isReversed Then
                IStr = Replace(IStr, "[" & VN(I) & "]", ChrW(VN(I)))
            Else
                IStr = Replace(IStr, "[" & UN(I) & "]", ChrW(UN(I)))
            End If
        Next
    End If
    Selection.Text = IStr
End Sub
Hix cách này không biến đổi từ "Nguyễn" thành "Nguye^~n" được rồi. Nhưng dù sao vẫn cảm ơn bạn. Hix đau đầu quá! &&&%$R
 
Upvote 0
Nếu làm bằng Unikey thì mình biết rồi nhưng tại mình phải dùng code kiểm tra mới được mình muốn làm sao mà chữ "Nguyễn" chẳng hạn nó có thể chuyển thành là "Nguye^~n" thì len = 8 là đúng. Bạn có cách nào làm như thế không, giúp mình với. -=.,,
ễ > e^~
ể > ?
ệ > ?
ế > ?
ề > ?
...
Muốn chuyển phải có một quy định chung cho tất cả các ký tự tiếng Việt. Chứ chỉ có ễ > e^~ làm sao viết được !
 
Upvote 0
ễ > e^~
ể > ?
ệ > ?
ế > ?
ề > ?
...
Muốn chuyển phải có một quy định chung cho tất cả các ký tự tiếng Việt. Chứ chỉ có ễ > e^~ làm sao viết được !
Cám ơn bạn hoa35ktxdphamduylong chắc tại mình cứ mò kiếm lung tung riết mình quẩn luôn. Chắc phải là kiểu qui định như 2 bạn chỉ thôi. Hình như cũng đâu có bao nhiêu cái mà mình cứ loay hoay kiếm cách convert từ Unicode sang UTF8. Do lúc tìm mình dùng UTF8 Literal đánh thử từ "Nguyễn" nó len ra 8 nên mình cứ bị cuốn theo. +-+-+-+
 
Upvote 0
Hix cách này không biến đổi từ "Nguyễn" thành "Nguye^~n" được rồi. Nhưng dù sao vẫn cảm ơn bạn. Hix đau đầu quá! &&&%$R
Chán, bạn chẳng chịu đọc kỹ gì cả, tôi đã nói rõ đó là đoạn mã chuyển đổi giữa TCVN và UNICODE, bạn tham khảo cách làm đó để xây dựng các mảng tham chiếu mà làm chứ.
 
Upvote 0
Web KT

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

Back
Top Bottom