Access

  MS Access 2010+  |  Przetwarzanie tekstu  |   VBA 7.0



• Funkcje przetwarzające tekst.

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 MultiByteToWideChar

Po zmianie typu argumentu

Znak Informacja dodatkowa
• 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
	
   udało mi się stworzyć funkcję konwertującą tekst UTF8 na format Unicode (domyślną stronę kodową).

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

Znak Informacja dodatkowa
• 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ą).

Znak Informacja dodatkowa • 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łą przedstawiona jako pierwsza. Funkcję tekstUTF8ToString(...) zamieściłem, by nie przepadła w czeluściach mojego dysku . Kto wie, może kiedyś się przyda.