Unicode tiếng Việt trong VBA Excel
Unicode bây giờ phải xác định là font chính khi nhập dữ liệu. Khổ nổi có một số ứng dụng chưa hỗ trợ tốt font này, trong đó có VBA Excel. Muốn VBA gởi vào ô B1 chuỗi "Lập trình với Excel" không đơn giản chút nào vì khi nhập Cells(1,2)="Lập trình với Excel" nó lại trở thành Cells(1,2)="L?p trình v?i Excel". Những dấu ? đó là những ký tự mà mã của nó vượt ngưỡng 255.
Vấn đề này nhiều bạn đã đưa lên diễn đàn nhưng ở nhiều bài khác nhau, tôi mở chuyên mục này để chúng ta cùng tham gia để có thể sử dụng Unicode đễ dàng hơn.
Qua học hỏi từ diễn đàn và vận dụng vào lập trình VBA Excel, tôi viết Unicode tiếng Việt bằng 3 cách. Xin nêu lên và các bạn bổ sung thêm:
1. Nhập chuỗi vào 1 ô trên vào bảng tính, viết lệnh truy xuất nó. Ví dụ nhập vào ô A1 của sheet2 câu trên. Câu lệnh viết:
Cells(1, 2) = Sheets("Sheet2").Cells(1,1)
Cách này đơn giản, nhưng bảng tính phải có 1 sheet chứa các chuỗi này. Nếu có ai đó chỉnh, xóa dữ liệu thì hỏng.
2. Dùng phép nối chuỗi và hàm ChrW để viết:
Câu trên viết thành:
Cells(1,2)= L" & ChrW(7853) & "p trình v" & ChrW(7899) & "i Excel"
Cách này rắc rối vì phải biết mã ậ=7953, ớ=7899, nhưng nó được viết ngay trong module, người sử dụng khó thay đổi được (bạn tham khảo bảng mã trong tập tin CodeUnicode.xls).
3. Dùng 1 hàm tự viết để hỗ trợ cách 2 (hàm UniVba). Cách sử dụng như sau:
– Nhập chuỗi cần viết vào 1 ô trong bàng tính. Ví dụ nhập vào ô A1 chuỗi "Xử lý tiếng Việt".
– Ô B1 nhập công thức =univba(A1), hàm sẽ cho kết quả:
"X" & ChrW(7917) & " lý ti" & ChrW(7871) & "ng Vi" & ChrW(7879) & "t"
Hàm UniVba dò tìm từng ký tự trong chuỗi, nếu ký tự nào có mã > 255 sẽ chuyển thành ChrW(mã) và ghép chúng bằng phép &.
Bạn copy ô B1 và dán vào module, rất nhanh và chính xác.'=========== Function UniVba(TxtUni As String) As String If TxtUni = "" Then UniVba = """""" Else TxtUni = TxtUni & " " If AscW(Left(TxtUni, 1)) < 256 Then UniVba = """" For n = 1 To Len(TxtUni) - 1 uni1 = Mid(TxtUni, n, 1) uni2 = AscW(Mid(TxtUni, n + 1, 1)) If AscW(uni1) > 255 And uni2 > 255 Then UniVba = UniVba & "ChrW(" & AscW(uni1) & ") & " ElseIf AscW(uni1) > 255 And uni2 < 256 Then UniVba = UniVba & "ChrW(" & AscW(uni1) & ") & """ ElseIf AscW(uni1) < 256 And uni2 > 255 Then UniVba = UniVba & uni1 & """ & " Else UniVba = UniVba & uni1 End If Next If Right(UniVba, 4) = " & """ Then UniVba = Mid(UniVba, 1, Len(UniVba) - 4) Else UniVba = UniVba & """" End If End If End Function '========Các bạn tải tập tin CodeUnicode và UniVba về tham khảo.
Các phiên bản từ Excel 2000 về sau hỗ trợ tương đối tốt UniTV (UNICODE tiếng Việt) chứ không như bạn Cường nhận xét.
Có nhiều ứng dụng hỗ trợ UNI tiếng Việt cho Excel được viết hoàn toàn bằng VBA Excel (chuyển qua lại giữa các bảng mã, đọc số tiếng Việt, sắp xếp tiếng Việt,..) mà khi nó hoạt động, giao diện của nó thể hiện bằng UniTV rất đẹp không khác các ứng dụng của Windows. VNI Windows, ABC thể hiện trên Form không thể sánh bằng UniTV. Các bạn có thể tải TVEXCEL01 về để thấy việc hỗ trợ UniTV của VBA Excel.
Tuy nhiên, không phải 100% là tốt. Các đối tượng trong Form như Lable, TextBox, ListBox, ComboBox, … đều thể hiện tốt UniTV nhưng còn một vài trở ngại như: Caption của Form, không nhập được UniTV. Các thuộc tính trong Properties như Caption (của Lable, CommandButton), Value (của TextBox, ListBox), … không cho nhập trực tiếp UniTV nhưng có thể gán UniTV khi chương trình chạy bằng cách viết lệnh trong Module. Các hộp thoại của InputBox, MsgBox không thể hiện được tiếng Việt (tôi chưa biết cách làm, không biết Excel 2007 có tiến bộ hơn không vì tôi chưa sử dụng).
Một trở ngại lớn nhất là không thể viết UniTV trực tiếp trên module được (nhưng các bảng mã như VNI Windows, ABC thì được). VBA có hàm ChrW dùng để chuyển mã UNICODE sang ký tự, tôi nêu vấn đề nhằm mục đích tìm cách nào nhập UniTV trong VBA Excel thuận lợi và chính xác hơn.
Việc viết UniTV ứng dụng rất nhiều trong Excel vì bây giờ UNICODE được xem như là font chuẩn của VN. Tôi đưa 2 ví dụ nhỏ:1. Viết thủ tục để ghi vào các ô A1, A2, …, A7 các chuỗi UNICODE "Thứ hai", "Thứ ba", …, "Chủ nhật"
Sub ThuVN()
Cells(1, 1) = "Th" & ChrW(7913) & " hai"
Cells(2, 1) = "Th" & ChrW(7913) & " ba"
Cells(3, 1) = "Th" & ChrW(7913) & " t" & ChrW(432)
Cells(4, 1) = "Th" & ChrW(7913) & " n" & ChrW(259) & "m"
Cells(5, 1) = "Th" & ChrW(7913) & " sáu"
Cells(6, 1) = "Th" & ChrW(7913) & " b" & ChrW(7843) & "y"
Cells(7, 1) = "Ch" & ChrW(7911) & " nh" & ChrW(7853) & "t"
End SubThay vì nhập "Chủ nhật", phải nhập là "Ch" & ChrW(7911) & " nh" & ChrW(7853) & "t" thật rắc rối và chắc chắn phải có sai ! Hàm UniVba sẽ giúp chúng ta viết nhanh những chuỗi đó.
2. Viết hàm NGAYUNI(ngay) để chuyển 1 ngày trong ô thành thứ, ngày, tháng, năm. Ví dụ ô A10 có giá trị là ngày "2/6/2007", ô D10 nhập công thức =NGAYUNI(A10) sẽ cho kết quả:
"Thứ bảy, ngày 02 tháng 06 năm 2007" bằng UNICODE TIẾNG Việt.Function NGAYUNI(ngay)
dd = Day(ngay)
mm = Month(ngay)
yy = Year(ngay)
thu = Weekday(ngay)
Select Case thu
Case 1
thu = "Ch" & ChrW(7911) & " nh" & ChrW(7853) & "t"
Case 2
thu = "Th" & ChrW(7913) & " hai"
Case 3
thu = "Th" & ChrW(7913) & " ba"
Case 4
thu = "Th" & ChrW(7913) & " t" & ChrW(432)
Case 5
thu = "Th" & ChrW(7913) & " n" & ChrW(259) & "m"
Case 6
thu = "Th" & ChrW(7913) & " sáu"
Case 7
thu = "Th" & ChrW(7913) & " b" & ChrW(7843) & "y"
End Select
NGAYUNI = thu & ", ngày " & Format(dd, "00") & " tháng " & Format(mm, "00") & " n" & ChrW(259) & "m " & yy
End Function
'================Dưới đây là hàm NGAYVNI, NGAYABC cũng tương tự như NGAYUNI nhưng viết cho VNI Windows và ABC, cách viết đơn giản hơn nhiều.
'==============
Function NGAYVNI(ngay)
dd = Day(ngay)
mm = Month(ngay)
yy = Year(ngay)
thu = Weekday(ngay)
Select Case thu
Case 1
thu = "Chuû nhaät"
Case 2
thu = "Thöù hai"
Case 3
thu = "Thöù ba"
Case 4
thu = "Thöù tö"
Case 5
thu = "Thöù naêm"
Case 6
thu = "Thöù saùu"
Case 7
thu = "Thöù baûy"
End Select
NgayVni = thu & ", ngaøy " & Format(dd, "00") & " thaùng " & Format(mm, "00") & " naêm " & yy
End Function'====================
Function NGAYABC(ngay)
dd = Day(ngay)
mm = Month(ngay)
yy = Year(ngay)
thu = Weekday(ngay)
Select Case thu
Case 1
thu = "Chñ nhËt"
Case 2
thu = "Thø hai"
Case 3
thu = "Thø ba"
Case 4
thu = "Thø t"
Case 5
thu = "Thø n¨m"
Case 6
thu = "Thø s¸u"
Case 7
thu = "Thø b¶y"
End Select
NGAYABC = thu & ", ngµy " & Format(dd, "00") & " th¸ng " & Format(mm, "00") & " n¨m " & yy
End Function
'=============Theo tôi biết, hiện nay dân Excel vẫn còn sử dụng Vni Windows, ABC nhiều. Các bài Excel tải lên Giai phapExcel cũng vậy. Qua tìm hiểu, nguyên nhân họ không muốn chuyển qua UNICODE là vì:
– Các dữ liệu cũ còn đó, phải nhập tiếp thôi. Qua UNICODE lại rối với 2 bảng mã.
– Công cụ hỗ trợ cho UNICODE trên Excel còn quá ít, chưa tạo được động cơ để họ chuyển qua UNICODE.
Qua diễn đàn này, chúng ta cùng nhau tạo những công cụ tốt hơn cho UNICODE tiếng Việt để cư dân Excel sử dụng thống nhất UNICODE cho các bảng tính Excel.
Tôi thấy bạn Đào Việt Cường có làm 1 file về PicForm… trong file này nếu ta bấm vào dấu X thì 1 MsgBox tiếng Việt hiện ra…
Hình như là dùng các hàm Macro 4 thì phải
Tuy nhiên tôi xem hoài mà vẩn chưa am tường được điểm mấu chốt trong đó
Các bạn xem thử
Nếu có thể được nhờ bạn Đào Việt Cường hướng dẩn giúp 1 file ví dụ đơn giãn nhất về MsgBox tiếng Việt này
Cảm ơn!
Dear ndu96081631,
——————-
Sẽ là lạc đề nếu như thảo luận vấn đề anh nêu trong chủ đề này. Tuy nhiên xét thấy vấn đề cũng có liên quan một chút đến "Unicode tiếng Việt trong VBA" nên em trả lời luôn ở đây vậy:Mấu chốt là ở đây ạ:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Address <> "$G$1" Then Exit Sub
If ALERT(Evaluate(Application.Names("MsgExit").RefersToR1C1), 1) = False Then Exit Sub
txbPassword.Value = Null
ThisWorkbook.Close True
End SubAnh lưu ý ALERT là một hàm tự tạo trong Module1. Và đúng như theo dự đoán của anh, thủ tục có sử dụng lệnh ExecuteExcel4Macro để thi hành lệnh (hàm) macro4 có tên là "ALERT". Đây là hàm macro4 tương tự như hàm MsgBox trong VBA, khác là nó có hỗ trợ UNICODE. Tham số quan trọng của hàm này là sPrompt. Đây là chuỗi thông điệp UNICODE. Trong thủ tục sự kiện trên, tham số này được lấy từ name MsgExit (ấn Ctrl+F3 để xem name này).
Như vậy qua ví dụ minh họa này chúng ta cũng có thể biết thêm về cách thực thi một lệnh Macro4 thông qua VBA như thế nào, có phải không ạ!
Hơi bị cao siêu đây!
Hy vọng khi tôi bứt cở vài chục ngàn cọng tóc thì sẽ hiểu được vấn đề… +-+-+-+
Còn nữa: Có lẽ cũng hơi lạc đề khi đề cập vào topic này, nhưng hy vọng nhân tiện bạn giãi đáp luôn (hoặc chỉ tôi tài liệu có liên quan cũng được)
Đó là tôi thấy trong phần khai báo biến:
Dim sAlert$
Cái dấu $ này mang ý nghĩa gì vậy?
Mong bạn giúp!
Chân thành cảm ơn!
Unicode trong VBA giờ đây không còn là vấn đề gì to tát cả các bác ạ, có chăng là việc không gõ chuỗi Unicode trực tiếp trong VBE mà thôi, but chúng ta đã có worksheet, dùng nó để lưu chuỗi Unicode cơ mà!
Nếu các bác chịu đọc những cái em viết thì sẽ thấy Unicode hay những thứ được gọi là khó cũng bình thường thôi mà.
https://www.giaiphapexcel.com/forum/showthread.php?t=16802
Với hàm UniVBA và UniVBAT thì việc gõ chuỗi trực tiếp trên VBA cũng không còn là vấn đề khó khăn nữa. Các bạn xem UniVBA và MsgUni tại đây :
https://www.giaiphapexcel.com/forum/showthread.php?t=17469
www.giaiphapexcel.com/diendan/threads/unicode-ti%E1%BA%BFng-vi%E1%BB%87t-trong-vba-excel.2370/
Khoá học Trưởng phòng nhân sự
Nguồn nhân lực là một trong Tứ trụ kinh doanh của doanh nghiệp, có tác động tới sự tồn tại và phát triển bền...
Xem khóa học
Đưa toàn bộ phần khai báo hàm (Declare….) vô Module chứ không phải Form module thử xem.
Office bác này là 64bit, nên khai báo trên thiếu từ khóa Private.
Bác add thêm Private và trước Declare 2 dòng đó
À máy tôi Win7 32, Office 32bit 2007, chạy đoạn code của bác Tuân cũng không ra. Test với hàm API IsWindowUnicode thì ra FALSE (0), tức Ansi Window
Bạn giaiphap dùng Office gì vậy, chạy giúp tôi đoạn code này thử
Lạ ta, Office bạn ver mấy ? VBA bạn là VBA7 hay 6, file fm20.dll trong %Windows%System32 có version là bao nhiêu ? Xem giúp mình ?
Mình Office2007, VBA6, FM20.dll có ver là 12.0.4518.1014
Bạn debug giúp mình, xem kỹ là DefWindowProcW hay DefWindowProcA, code của bác Tuan đấy
Phải chỉnh lại vì Office của bạn ấy là 64bit, khai báo hwnd as Long sẽ bị báo lỗi Type mismatch. Phải là LongPtr
Sữa lại thành giống code tui vừa post
Code của bác Tuân lúc đầu cả 2 đều là DefWindowProcA
Không được bạn, mình đã thử rồi mới đăng lên đây. Máy hiện tại tại VP mình đang ngồi là Offcie 2007, 32bit, Win7
Bạn up giúp mình file FM20.dll trong thư mục Windows System32 của bạn nhé. Để tối về mình RE và compare xem sao.
Hì hì, tìm ra lý do rồi, do Theme API của Windows. Để desktop về theme Windows Classis thì sẽ không được, do Windows dùng Ansi API để xử lý các non Unicode Window. Còn có theme thì Windows dùng Theme API Unicode cho tất cả các Window.
File Caption Unicode up lần sau của bác giaiphap, các bác test giùm cu anh em đoạn code sau cái.
Nghi là do ông ClearType font của Quýnh đâu can thiệp nữa.
Cái vụ Caption UserForm này còn dài dài, nhiều chuyện để moi đây.
Làm cách nào bác Tuân biết UserForm Caption get property trả về Ansi string vậy bác ? Bác đã từng debug vào đó chưa ?
Tôi đã nói không biết bao nhiêu lần rồi. Đã dịch thì dịch đến cùng, không dịch nửa vời. Vì trên máy khác có thể không hiển thị chuẩn.
Trên máy tôi
2005
do không dịch HOÀNG.
————-
Sửa
thành
Thì nếu chỉ dành riêng cho Win 64bit và Office 64 bit thì xóa cha nó cho rồi, khỏi IF éc gì cả.