Смена кодировки текста с UTF-8 на UTF-16 для корректного отображения кириллицы при вставке текста в ячейки Excel.
Описание проблемы
Microsoft Excel до сих пор не дружит с кодировкой UTF-8 и отображает символы в этой кодировке в виде «кракозябр». Перекодировка строки с UTF-8 на UTF-16 может понадобиться в VBA, например, при загрузке данных из CSV-файла с кодировкой UTF-8 на рабочий лист Excel.
Excel использует внутреннее представление строк, которое основано на Unicode. Начиная с Excel 2000, это представление — UTF-16LE (Little Endian). Когда мы помещаем строку в ячейку, Excel преобразует ее во внутренний формат (UTF-16LE) для хранения и отображения.
Есть такой текст в CSV-файле:
Если строка на кириллице существует в кодировке UTF-8, Excel может попытаться интерпретировать UTF-8 как ANSI (Windows-1252 или Windows-1251 для кириллицы), что приводит к «кракозябрам».
Функции для смены кодировки
Для изменение кодировки текста с UTF-8 на UTF-16 понадобятся 2 функции: функция WinApi, использующаяся для смены MultiByte-кодировок в UTF-16 и пользовательская функция FromUTF8, которая преобразует именно UTF-8 в UTF-16.
1 2 3 4 5 6 7 8 9 10 |
'Функция WinApi, использующаяся для смены мультибайтовых кодировок в UTF-16 Private Declare PtrSafe Function MultiByteToWideChar Lib "kernel32.dll" (ByVal CodePage As LongPtr, ByVal dwFlags As LongPtr, ByVal lpMultiByteStr As String, ByVal cchMultiByte As LongPtr, ByVal lpWideCharStr As LongPtr, ByVal cchWideChar As LongPtr) As LongPtr 'Пользовательская функция для смены кодировки с UTF-8 на UTF-16 Function FromUTF8(ByVal sText As String) As String Dim nRet As Double, strRet As String strRet = String(Len(sText), vbNullChar) nRet = MultiByteToWideChar(65001, &H0, sText, Len(sText), StrPtr(strRet), Len(strRet)) FromUTF8 = Left(strRet, nRet) End Function |
Преобразование кодировки UTF-8 в UTF-16
Изменение кодировки с UTF-8 на UTF-16 на примере текста из CSV-файла:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
Sub Primer() Dim num1 As Integer, a1 As String, str1 As Variant 'Выбираем файл CSV с кодировкой UTF-8 a1 = Application.GetOpenFilename("Текст с разделителями,*.csv", , "Выбор файла") If Right(a1, 4) <> ".csv" Then Exit Sub 'Открываем файл и считываем текст в переменную num1 = FreeFile Open a1 For Input As num1 str1 = Input(LOF(num1), num1) Close num1 'Меняем кодировку с UTF-8 на UTF-16 str1 = FromUTF8(str1) 'Меняем, если нужно, разделитель с (,) на (;) str1 = Replace(str1, ",", ";") 'Записываем перекодированный текст в новый файл CSV a1 = Replace(a1, ".csv", "-UTF-16.csv") num1 = FreeFile Open a1 For Output As num1 Print #num1, str1 Close num1 'Открываем файл для просмотра ThisWorkbook.FollowHyperlink (a1) ActiveWindow.ActiveSheet.Columns.AutoFit End Sub |
Результат работы кода: