Strona kodowa ASCII i UTF8.
Strona kodowa jest zestawem znaków, który zawiera liczby, znaki interpunkcyjne i inne symbole. Różne języki i ustawienia regionalne używaja różnych stron kodowych. Na przykład strona kodowa Windows 1250 jest używana dla języka polskiego w systemie Windows. Strona kodowych Windows-1252 jest używana dla języka angielskiego i większości języków europejskich. IBM 852 jest stosowane w systemach operacyjnych MS-DOS, zaś ISO 8859-2 (Latin-2) jest zestawem znaków „środkowowschodnioeuropejskich” i „wschodnioeuropejskich”.
UTF-8 to system kodowania Unicode, wykorzystujący od 1 do 6 bajtów do zakodowania pojedynczego znaku, jest w pełni kompatybilny z ASCII. Format UTF8 zdominował cały internet. Większość stron internetowych kodowana jest w UTF8. Format ten, w porównaniu do standardu ISO 8859-2 zajmuje nieco więcej miejsca, ale daje o wiele, wiele większe możliwości prezentowania tekstu na stronach internetowych. I dlatego też, (moim skromnym zdaniem☺) niezbędna jest funkcja umożliwiająca konwersję tekstu z formatu UTF8 na format Unicode, a praktycznie na określoną stronę kodową ASCII.
Konwersja tekstu z formatu UTF8 na ASCII.
Funkcja API MultiByteToWideChar(...) (...) inaczej zadeklarowana.
By przekonwertować tekst z formatu UTF8 na Unicode (aktualną stronę kodową) możemy skorzystać z funkcji MultiByteToWideChar Funkcja ta konwertuje tekst wejściowy ze strony kodowej ASCII, (w tym i UTF8) na format Unicode (ciąg znaków UTF-16). Należy zauważyć, że konwertowany tekst wejściowy nie musi być zestawem znaków wielobajtowych. Na stronie tej pisałem też, że:
...nie za bardzo udało mi się zastosować funkcję MultiByteToWideChar(...) zadeklarowaną w sposób przedstawiony na stronie Funkcja API MultiByteToWideCharPo zmianie typu argumentu
• argument lpWideCharStr As String deklarujemy jako typ Long
i zadeklarowaniu funkcji MultiByteToWideChar(...) w poniższy sposób:
Private Declare Function MultiByteToWideChar Lib "kernel32.dll" ( _ ByVal CodePage As Long, _ ByVal dwFlags As Long, _ ByVal lpMultiByteStr As String, _ ByVal cchMultiByte As Long, _ ByVal lpWideCharStr As Long, _ ByVal cchWideChar As Long) As Long
Funkcja konwertująca tekst UTF8 na domyślną stronę kodową ASCII.
⊗ Funkcja tekstUTF8ToAscii(sUTF8 As String) As String
- Konwertuje ciąg znaków z formatu UTF8 na format Unicode (domyślną stroną kodową ASCII).
- argumenty:
- sUTF8
- ciąg znaków do konwersji na format Unicode (domyślną stroną kodową ASCII)
- zwraca:
-
Zwraca ciąg znaków w formacie Unicode (domyślnej stronie kodowej ASCII). Przy niepowodzeniu zwraca ciąg zerowej długości.
- autor: Zbigniew Bratko
- data: 22.01.2018
Option Compare Database Option Explicit #If VBA7 Then Private Declare PtrSafe Function MultiByteToWideChar Lib "kernel32" ( _ ByVal CodePage As Long, _ ByVal dwFlags As Long, _ ByVal lpMultiByteStr As String, _ ByVal cchMultiByte As Long, _ ByVal lpWideCharStr As LongPtr, _ ByVal cchWideChar As Long) As Long #Else Private Declare Function MultiByteToWideChar Lib "kernel32.dll" ( _ ByVal CodePage As Long, _ ByVal dwFlags As Long, _ ByVal lpMultiByteStr As String, _ ByVal cchMultiByte As Long, _ ByVal lpWideCharStr As Long, _ ByVal cchWideChar As Long) As Long #End If Private Const CP_UTF8 As Long = 65001 Public Function tekstUTF8ToAscii(sUTF8 As String) As String Dim lLenAscii As Long Const MB_ERR_INVALID_CHARS = 8 Const ERROR_INVALID_FLAGS = 1004 ' pobierz wielkość potrzebnego buforu na wyjściowy ciąg znaków ASCII lLenAscii = MultiByteToWideChar(CP_UTF8, 0&, sUTF8, Len(sUTF8), 0&, 0&) ' przygotuj bufor na przyjęcie ciągu po konwersji na Ascii tekstUTF8ToAscii = String$(lLenAscii, vbNullChar) ' konwertuj wejściowy ciąg na ASCII lLenAscii = MultiByteToWideChar(CP_UTF8, 0&, sUTF8, Len(sUTF8), _ StrPtr(tekstUTF8ToAscii), lLenAscii) End Function
Inna postać funkcji konwertującej tekst w formacie ASCII na format UTF8
Do konwersji tekstu z formatu UTF8 na format Unicode (domyślną stroną kodową ASCII) skorzystaliśmy z funkcji MultiByteToWideChar(...), której opis znajduje się na stronie MultiByteToWideChar. Funkcja ta konwertuje ciąg znaków z formatu UTF8 na format Unicode (domyślną stroną kodową ASCII). Wcześniej pisałem, że:
Po zmianie typu argumentu
• argument lpWideCharStr As String deklarujemy jako typ Long
udało mi się stworzyć ☺ funkcję konwertującą tekst UTF8 na format Unicode (domyślną stronę kodową).
Utrudnijmy sobie życie poprzez zmianę typów wszystkich argumentów na typ Long i wtedy spróbujmy stworzyć funkcję konwertującą tekst UTF8 na format Unicode (domyślną stronę kodową).
• argument lpWideCharStr As String deklarujemy jako typ Long
• argument lpMultiByteStr As String deklarujemy jako typ Long
Nowa deklaracja funkcji MultiByteToWideChar(...)
Private Declare Function WideCharToMultiByte Lib "kernel32.dll" ( _ ByVal CodePage As Long, _ ByVal dwFlags As Long, _ ByVal lpWideCharStr As Long, _ ByVal cchWideChar As Long, _ ByVal lpMultiByteStr As Long, _ ByVal cchMultiByte As Long, _ ByVal lpDefaultChar As Long, _ ByVal lpUsedDefaultChar As Long) As Long
Nowa deklaracja funkcji WideCharToMultiByte(...)
i trochę inna funkcja konwertująca tekst z formatu ASCII na format UTF8.
⊗ Funkcja tekstUTF8ToString(sUTF8 As String) As String
- Konwertuje ciąg znaków z formatu UTF8 na format Unicode (domyślną stroną kodową ASCII).
- argumenty:
- sUTF8
- ciąg znaków do konwersji na format Unicode (domyślną stroną kodową ASCII)
- zwraca:
-
Zwraca ciąg znaków w formacie Unicode (domyślnej stronie kodowej ASCII). Przy niepowodzeniu zwraca ciąg zerowej długości.
- autor: Zbigniew Bratko
- data: 22.01.2018
Option Compare Database Option Explicit #If VBA7 Then Private Declare PtrSafe Function MultiByteToWideChar Lib "kernel32" ( _ ByVal CodePage As Long, _ ByVal dwFlags As Long, _ ByVal lpMultiByteStr As LongPtr, _ ByVal cchMultiByte As Long, _ ByVal lpWideCharStr As LongPtr, _ ByVal cchWideChar As Long) As Long #Else Private Declare Function MultiByteToWideChar Lib "kernel32.dll" ( _ ByVal CodePage As Long, _ ByVal dwFlags As Long, _ ByVal lpMultiByteStr As Long, _ ByVal cchMultiByte As Long, _ ByVal lpWideCharStr As Long, _ ByVal cchWideChar As Long) As Long #End If Private Const CP_UTF8 As Long = 65001 Public Function tekstUTF8ToString(ByVal sUTF8 As String) As String Dim arrCharsUTF8() As Byte Dim lLength As Long Const MB_ERR_INVALID_CHARS = 8 Const ERROR_INVALID_FLAGS = 1004 ' konwertuj ciąg wejściowy na tablicę bajtów znaków UTF8 arrCharsUTF8 = StrConv(sUTF8, vbFromUnicode) ' pobierz potrzebną długość ciągu po konwersji lLength = MultiByteToWideChar(CP_UTF8, 0&, VarPtr(arrCharsUTF8(0)), Len(sUTF8), 0&, 0&) 'przygotuj bufor na przyjęcie ciągu po konwersji na Ascii tekstUTF8ToString = String$(lLength, vbNullChar) ' konwertuj wejściowy ciąg (tablicę bajtów UTF8) na Ascii lLength = MultiByteToWideChar(CP_UTF8, 0&, VarPtr(arrCharsUTF8(0)), Len(sUTF8), _ StrPtr(tekstUTF8ToString), lLength) End Function
Jak dla mnie, bardziej oczywista, przystępniejsza i krótsza jest funkcja tekstAsciiToUTF8, która została przedstawiona jako pierwsza. Funkcję tekstUTF8ToString(...) zamieściłem, by nie przepadła w czeluściach mojego dysku ☺. Kto wie, może kiedyś się przyda.