Access

  MS Access 2010+  |  Przetwarzanie tekstu  |   VBA 7.0



• Funkcje przetwarzające tekst.

Konwersja tekstu ASCII na format UTF8.

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 Unicode na format UTF8.

Funkcja API WideCharToMultiByte (...) inaczej zadeklarowana.

Do konwersji tekstu z formatu Unicode na UTF8 skorzystam z funkcji WideCharToMultiByte(...), której opis znajduje się na stronie WideCharToMultiByte(...). Funkcja ta konwertuje ciąg znaków z formatu Unicode na ciąg znaków zgodny z określoną stroną kodową ASCII, w tym także na format wielobajtowy np. UTF8.
Na stronie tej pisałem, że:

...nie za bardzo udało mi się zastosować funkcję WideCharToMultiByte(...) zadeklarowaną w sposób przedstawiony na stronie Funkcja API WideCharToMultiByte(...)

Po zmianie typów dwóch argumentów

Znak Informacja dodatkowa • argument lpWideCharStr As String deklarujemy jako typ Long
• argument lpDefaultChar As String deklarujemy jako typ Long

i zadeklarowaniu funkcji WideCharToMultiByte(...) w poniższy sposób:

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 String, _
	ByVal cchMultiByte As Long, _
	ByVal lpDefaultChar As Long, _
	ByVal lpUsedDefaultChar As Long) As Long
   udało mi się stworzyć funkcję konwertującą tekst z formatu ASCII na format UTF8.

Funkcja konwertująca tekst z formatu ASCII na format UTF8.

⊗ Funkcja tekstAsciiToUTF8(ByVal sAscii As String) As String
  • Konwertuje ciąg znaków z formatu Unicode (aktualnej strony kodowej ASCII) na  ciąg znaków zgodny z wielobajtowym  formatem UTF8.
  • argumenty:
    • sAscii
    • wejściowy ciąg znaków do konwersji na format UTF8
  • zwraca:
  • Zwraca ciąg znaków w formacie UTF8. 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 WideCharToMultiByte Lib "kernel32" ( _
          ByVal CodePage As Long, _
          ByVal dwFlags As Long, _
          ByVal lpWideCharStr As LongPtr, _
          ByVal cchWideChar As Long, _
          ByVal lpMultiByteStr As String, _
          ByVal cchMultiByte As Long, _
          ByVal lpDefaultChar As LongPtr, _
          ByVal lpUsedDefaultChar As LongPtr) As Long
#Else
  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 String, _
          ByVal cchMultiByte As Long, _
          ByVal lpDefaultChar As Long, _
          ByVal lpUsedDefaultChar As Long) As Long
#End If
Private Const CP_UTF8 As Long = 65001


Public Function tekstAsciiToUTF8(ByVal sAscii As String) As String
Dim lLenUTF8      As Long
Const WC_ERR_INVALID_CHARS = 128
Const ERROR_INVALID_FLAGS = 1004
  
  ' pobierz wielkość potrzebnego buforu na wyjściowy ciąg znaków UTF8
  lLenUTF8 = WideCharToMultiByte(CP_UTF8, 0&, StrPtr(sAscii), Len(sAscii), 0&, 0&, 0&, 0&)
  ' przygotuj bufor na przyjęcie ciągu po konwersji na UTF8
  tekstAsciiToUTF8 = String(lLenUTF8, vbNullChar)
  ' konwertuj wejściowy ciąg na ASCII
  lLenUTF8 = WideCharToMultiByte(CP_UTF8, 0&, StrPtr(sAscii), Len(sAscii), _
                                 tekstAsciiToUTF8, lLenUTF8, 0&, 0&)

End Function

Inna postać funkcji konwertującej tekst z formatu ASCII na format UTF8

Do konwersji tekstu z formatu Unicode na UTF8 skorzystaliśmy z funkcji WideCharToMultiByte(...), której opis znajduje się na stronie WideCharToMultiByte(...). Funkcja ta konwertuje ciąg znaków z formatu Unicode na ciąg znaków zgodny z określoną stroną kodową ASCII, w tym także na format wielobajtowy np. UTF8.
Wcześniej pisałem, że:

... po zmianie typów dwóch argumentów

Znak Informacja dodatkowa • argument lpWideCharStr As String deklarujemy jako typ Long
• argument lpDefaultChar As String deklarujemy jako typ Long

udało mi się stworzyć funkcję konwertującą ciąg znaków z formatu Unicode (aktualnej strony kodowej ASCII) na format UTF8. Utrudnijmy sobie życie poprzez zmianę typów wszystkich argumentów na typ Long i wtedy spróbujmy stworzyć funkcję konwertującą tekst na format UTF8

Znak Informacja dodatkowa • argument lpWideCharStr As String deklarujemy jako typ Long
• argument lpDefaultChar As String deklarujemy jako typ Long
• argument lpMultiByteStr As String deklarujemy jako typ Long

Nowa deklaracja funkcji WideCharToMultiByte(...)

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

i trochę inna funkcja konwertująca ciąg znaków z formatu Unicode (aktualnej strony kodowej ASCII) na format UTF8.

I nowa funkcja konwertująca tekstStringToUTF8(...)

⊗ Funkcja tekstStringToUTF8(ByVal sAscii As String) As String
  • Konwertuje ciąg znaków z formatu Unicode (aktualnej strony kodowej ASCII) na  ciąg znaków zgodny z wielobajtowym  formatem UTF8.
  • argumenty:
    • sAscii
    • wejściowy ciąg znaków do konwersji na format UTF8
  • zwraca:
  • Zwraca ciąg znaków w formacie UTF8. 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 WideCharToMultiByte Lib "kernel32" ( _
          ByVal CodePage As Long, _
          ByVal dwFlags As Long, _
          ByVal lpWideCharStr As LongPtr, _
          ByVal cchWideChar As Long, _
          ByVal lpMultiByteStr As LongPtr, _
          ByVal cchMultiByte As Long, _
          ByVal lpDefaultChar As LongPtr, _
          ByVal lpUsedDefaultChar As LongPtr) As Long
#Else
  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
#End If
Private Const CP_UTF8 As Long = 65001


Public Function tekstStringToUTF8(ByVal sAscii As String) As String
Dim lLength         As Long
Dim arrCharsUTF8()  As Byte
Const WC_ERR_INVALID_CHARS = 128
Const ERROR_INVALID_FLAGS = 1004
 
  ' pobierz potrzebną długość ciągu po konwersji
  lLength = WideCharToMultiByte(CP_UTF8, 0&, StrPtr(sAscii), Len(sAscii), 0&, 0&, 0&, 0&)
  ' przygotuj tablicę na przyjęcie przekonwertowanego ciągu UTF8
  ReDim arrCharsUTF8(lLength)   
  ' konwertuj wejściowy ciąg na UTF8
  lLength = WideCharToMultiByte(CP_UTF8, 0&, StrPtr(sAscii), Len(sAscii), _
                                VarPtr(arrCharsUTF8(0)), lLength, 0&, 0&) 
  ' konwertuj zwróconą tablicę znaków UTF8 na format Unicode
  tekstStringToUTF8 = StrConv(arrCharsUTF8, vbUnicode)

End Function

Jak dla mnie, bardziej oczywista, przystępniejsza i krótsza jest funkcja tekstAsciiToUTF8.
Druga z przedstawionych funkcji tekstStringToUTF8(...), jest moim zdaniem bardziej skomplikowana. Przygotowanie tablicy na wyjściowy ciąg znaków, potem konwersja zwróconej tablicę znaków UTF8 na ciąg znaków. Zamieściłem tą funkcję, by nie przepadła w czeluściach mojego dysku . Kto wie, może kiedyś się przyda.