VBA大十六进制到整数

时间:2016-08-22 13:03:37

标签: vba excel-vba excel

我正在尝试将十六进制的大整数转换为十进制并且VBA不断返回不正确的值。

VBA中,当我期望"&H0A1000043"时,字符串-1593835453会返回2701131843。我尝试了CDblCLngVal函数,它们都返回了错误的负值。

Excel HEX2DEC确实返回了正确的值。我认为这是VBA函数中的错误我错了吗?

5 个答案:

答案 0 :(得分:6)

这里的实际核心问题是VBA Long数据类型的有限长度以及VBA数字类型(几乎)全部签名的事实。因此,当您尝试CLng("&H0A1000043")之类的内容时,您试图将该数字解释为带符号的32位整数。在这种情况下,-1593835453是正确的值。您可以检查像this one这样的十六进制转换器(确保将“二进制类型”设置为带符号的32位。

为了正确地完成此转换,您必须使用更大的数字类型,例如LongLong(仅在64位Office中可用)。例如。 CLngLng("&H0A1000043^")

Hex2Dec成功失败的原因是因为Hex2Dec可能直接转换为字符串,而不必经过数字的中间内部表示,这是它被解释为正在签署。

答案 1 :(得分:2)

您需要从字符串

开始
Sub BigHexToDecimal()
    Dim N As String

    N = "A1000043"
    MsgBox Application.WorksheetFunction.Hex2Dec(N)
End Sub

enter image description here

答案 2 :(得分:1)

尝试添加&到Hex-String的末尾并使用Val函数: MS Documentation

答案 3 :(得分:0)

感谢您直接获取有关位数的信息。我键入了#34; VBA"到一个搜索引擎,它给了我一个Visual Basic的表,不一样。一个人必须阅读文本。 " Application.WorksheetFunction.Hex2Dec(N)"  返回一个字符串,但我做了那个工作。我从来没有找到任何正确处理64位整数的东西,但字符串消除了它的需要。

答案 4 :(得分:0)

我编写了一个快速函数,允许将大数从十进制转换为十六进制以及从十六进制转换为十进制。我没有对传递的参数进行任何验证,但如果无效,我建议添加它并抛出错误。 我也确信有一种更好、更有效的方法来做到这一点,但为了快速和肮脏,我的解决方案将在紧要关头发挥作用。

要添加代码,请在 Excel Visual Basic 中打开并创建新模块,然后粘贴下面的代码。确保转到“工具”,单击“参考”并添加“Microsoft Scripting Runtime”以启用 Scripting.Dictionary 变量创建。

Function Hex2Dec64(rngRef As Range) As Double
Dim dict As Scripting.Dictionary
Set dict = New Scripting.Dictionary

dict.Add "0", 0
dict.Add "1", 1
dict.Add "2", 2
dict.Add "3", 3
dict.Add "4", 4
dict.Add "5", 5
dict.Add "6", 6
dict.Add "7", 7
dict.Add "8", 8
dict.Add "9", 9
dict.Add "A", 10
dict.Add "B", 11
dict.Add "C", 12
dict.Add "D", 13
dict.Add "E", 14
dict.Add "F", 15

Dim val As String
Dim dec As Double
val = rngRef.Value

For n = 0 To Len(val) - 1
    dec = dec + dict(Mid(val, Len(val) - n, 1)) * (16 ^ n)
Next n
    
Hex2Dec64 = dec

End Function

Function Dec2Hex64(rngRef As Range) As String
Dim hex As String
Dim n As Double
n = rngRef.Value

Dim dict As Scripting.Dictionary
Set dict = New Scripting.Dictionary

dict.Add 0, "0"
dict.Add 1, "1"
dict.Add 2, "2"
dict.Add 3, "3"
dict.Add 4, "4"
dict.Add 5, "5"
dict.Add 6, "6"
dict.Add 7, "7"
dict.Add 8, "8"
dict.Add 9, "9"
dict.Add 10, "A"
dict.Add 11, "B"
dict.Add 12, "C"
dict.Add 13, "D"
dict.Add 14, "E"
dict.Add 15, "F"

While (n <> 0)
    Dim tmp As Double
    tmp = 0
    tmp = Modulus(n, 16)
            
    hex = dict(tmp) & hex
    tmp = n / 16
    
    If InStr(1, CStr(tmp), ".") > 0 Then
        n = CDbl(Left(CStr(tmp), InStr(1, CStr(tmp), ".") - 1))
    Else
        n = tmp
    End If
Wend

Dec2Hex64 = hex

End Function

Function Modulus(int1 As Double, int2 As Double) As Double
Dim myInt As Double
myInt = int1 / int2

If InStr(1, CStr(myInt), ".") > 0 Then
    myInt = CDbl("0." & Right(CStr(myInt), Len(CStr(myInt)) - InStr(1, CStr(myInt), ".")))
Else
    myInt = 0
End If
Modulus = myInt * int2
End Function