Czasami potrzebujemy przekonwertować liczbę całkowitą na postać heksadecymalną. Żaden problem. Od zawsze w VBA istniała funkcja do tego celu przeznaczona.
Jest nią funkcja Hex(liczba)
zwracająca wartość typu String reprezentującą heksadecymalną (szesnastkową) wartość liczby
(do ośmiu znaków szesnastkowych w środowisku 32-bitowym i szesnastu znaków w środowisku 64-bitowym. Obowiązkowy argument liczba jest dowolnym poprawnym wyrażeniem numerycznym lub wyrażeniem znakowym.
Jeżeli argument liczba nie jest liczbą całkowitą, przed obliczeniem wartości funkcji Hex(liczba)
jest ona zaokrąglana do najbliższej parzystej liczby całkowitej.
No to zróbmy mały test funkcji Hex(liczba)
:
Public Function TestHex() Dim iInt As Integer Dim lLng As Long Dim llLngLng As LongLong Debug.Print "--------------------------------------------" Debug.Print "Hex$(65535) = "; Hex$(65535) Debug.Print "Hex$(-1) = "; Hex$(-1) Debug.Print "--------------------------------------------" iInt = -1: lLng = -1: llLngLng = -1 Debug.Print "iInt=-1; lLng=-1; llLng=-1" Debug.Print "--------------------------------------------" Debug.Print "Hex$(iInt) = "; Hex$(iInt) Debug.Print "Hex$(lLng) = "; Hex$(lLng) Debug.Print "Hex$(llLngLng)= "; Hex$(llLngLng) DoCmd.RunCommand acCmdDebugWindow End Function
Na pierwszy rzut oka wyniki nie są zbyt optymistyczne.
Liczba 65535 w zapisie heksadecymalnym ma postać &HFFFF.
Liczba -1 w zapisie heksadecymalnym ma również postać &HFFFF.
Liczba -1 przypisana do zmiennej typu Integer ma postać &HFFFF.
Liczba -1 przypisana do zmiennej typu Long ma postać &HFFFFFFFF.
Liczba -1 przypisana do zmiennej typu LongLong ma postać &HFFFFFFFFFFFFFFFF.
Jeżeli chodzi o konwersję z zapisu postaci heksadecymalnej na postać dziesiętną MS Access i jego VBA nie posiada wbudowanej funkcji dokonującej takiej konwersji.
Ale w artukule Q161304 How To Convert Hexadecimal Numbers to Long Integer
możemy znaleźć rozwiązanie problemu konwersji liczby z reprezentacji heksadecymalnej, na postać dziesiętną za pomocą funkcji Val(ciąg)
.
FunkcjaVal(ciąg)
zwraca wartość liczb tworzących ciąg w postaci wartości numerycznej odpowiedniego typu. FunkcjaVal(...)
przerywa odczyt ciągu przy pierwszym znaku, który nie jest fragmentem liczby. Symbole i znaki, które często stanowią element wartości numerycznych, na przykład znak dolara ($), czy przecinek (,) nie są rozpoznawane przez funkcjęVal(...)
. Funkcja ta rozpoznaje jednak symbol podstawy &O (dla systemu ósemkowego) i &H (dla systemu szesnastkowego). Spacje, tabulatory i znaki wysuwu wiersza są pomijane. Liczby z zakresu &H80000000 (-2147483648) do &HFFFFFFFF (-1) oraz liczby z zakresu &H8000 (-32768) do &HFFFF (-1) są traktowane przez funkcjęVal(ciąg)
jako liczby ujemne.
Jak widzimy poniżej wyniki są trochę dziwne:
Val
("&HFFFF") = -1
Val
("&HFFFFFFFF") = -1
Val
("&H" & Hex$(65535)) = -1
Przedstawiona w tym artykule funkcja HexToLong(...)
Function HexToLong(ByVal sHex As String) As Long
HexToLong = Val("&H" & sHex & "&")
End Function
zwraca następujące wartości:
HexToLong
("FFFF") = 65535
HexToLong
("FFFFFFFF") = -1
HexToLong
(Hex$(65535)) = 65535
HexToLong
(Hex$(-1)) = 65535
Jak widać, zawsze jest coś nie tak. Aby ustrzec się błędów podczas konwersji z postaci heksadecymalnej na postać dziesiętną powinniśmy pilnować typów liczb, jakie powinna zwrócić funkcja konwertująca. W tym celu możemy użyć jednego ze znaków deklaracji (sufiksu).
Znak deklaracji (sufiks) | Typ danych | Przykład |
---|---|---|
% | Integer | Dim intLiczba% |
& | Long | Dim lngLiczba& |
^ | LongLong | Dim lnglngLiczba& |
@ | Currency | Dim curLiczba@ |
! | Single | Dim sngLiczba! |
# | Double | Dim dblLiczba# |
W wyniku konwersji z postaci heksadecymalnej na postać dziesiętną zawsze otrzymamy liczbę całkowitą, gdyż funkcja Hex(liczba)
zaokrągla do najbliższej parzystej liczby całkowitej, więc przydatne mogą być jedynie funkcje konwertująca na liczbę typu Integer,
Long lub LongLong (w środowisku VBA7).
Function HexToInteger(ByVal sHex As String) As Integer
HexToInteger = Val("&H" & sHex & "%")
End Function
___________________________________________________________________________________
Function HexToLongLong(ByVal sHex As String) As LongLong
HexToLongLong = Val("&H" & sHex & "^")
End Function
Moim zdaniem, zamiast używać funkcji Val(ciąg)
i sufiksów typu (%,&, ^)
w funkcjach konwertujących, możemy użyć funkcje konwersji typu według poniższego schematu:
Public Function HexToDec(ByVal sHex As String) Debug.Print "CByte", CByte("&H" & sHex) Debug.Print "CInt", CInt("&H" & sHex) Debug.Print "CLng", CLng("&H" & sHex) Debug.Print "CSng", CSng("&H" & sHex) Debug.Print "CDbl", CDbl("&H" & sHex) Debug.Print "CDec", CDec("&H" & sHex) Debug.Print "CCur", CCur("&H" & sHex) #If VBA7 Then Debug.Print "CLngLng", CLngLng("&H" & sHex) Debug.Print "CLngPtr", CLngPtr("&H" & sHex) #End If End Function
Brak komentarzy:
Prześlij komentarz