我做了一个转换数字的函数。例如从5到15的基数-表示除基本2、8、10、16之外的其他类型。它们基于将数字转换为10(通过使用幂),然后再从10转换为其他基数(mod,div)。 / p>
输入值A-F(十六进制是顶部)时出现问题。
这是将数字转换为10的代码的单独部分。
Function prevdeset(base As Integer, ipt As String) As String
Dim x As Integer
Dim s As Integer
Dim u As Integer
Dim p As Integer
c = Str(ipt)
x = Len(ipt)
u = 0
For i = x To 1 Step -1
If Mid(c, i, 1) = "A" Then
p = 10
ElseIf Mid(c, i, 1) = "B" Then
p = 11
ElseIf Mid(c, i, 1) = "C" Then
p = 12
ElseIf Mid(c, i, 1) = "D" Then
p = 13
ElseIf Mid(c, i, 1) = "E" Then
p = 14
ElseIf Mid(c, i, 1) = "F" Then
p = 15
Else: p = Val(Mid(c, i, 1))
End If
p = p * (base ^ (x - i))
u = u + p
Next i
prevdeset = u
End Function
该函数从右侧选择第i个字符,然后首先检查字符串值是否为A-如果不是,则为B,C,D,E,F,如果没有,则应将该字符转换为a数字(我不尝试输入其他字母作为G,H ..)。
如果输入不是字符串,则输出没有问题,完整的代码(此处未显示)可以输出字母(例如:以10为底的10将是以14为底的A)。
答案 0 :(得分:1)
由于VBA
受到Integers
的限制,您收到了溢出错误。将您的变量更改为Long
,您的代码将正常工作
| Type | Storage | Range of Values |
|---------|---------|---------------------------------|
| Byte | 1 byte | 0 to 255 |
| Integer | 2 bytes | -32,768 to 32,767 |
| Long | 4 bytes | -2,147,483,648 to 2,147,483,647 |
Option Explicit
Function prevdeset(base As Integer, ipt As String) As String
Dim x As Long, s As Long, u As Long, p As Long
Dim i As Long
Dim c As String
c = ipt
x = Len(ipt)
u = 0
For i = x To 1 Step -1
If Mid(c, i, 1) = "A" Then
p = 10
ElseIf Mid(c, i, 1) = "B" Then
p = 11
ElseIf Mid(c, i, 1) = "C" Then
p = 12
ElseIf Mid(c, i, 1) = "D" Then
p = 13
ElseIf Mid(c, i, 1) = "E" Then
p = 14
ElseIf Mid(c, i, 1) = "F" Then
p = 15
Else: p = Val(Mid(c, i, 1))
End If
p = p * (base ^ (x - i))
u = u + p
Next i
prevdeset = u
End Function
Sub test()
Dim HexVal As String
HexVal = "7B19AB"
Debug.Print CLng("&H" & HexVal)
Debug.Print prevdeset(16, HexVal)
End Sub
此外,您无需将ipt
转换为String
-您已经将ipt
声明为String
。您可以通过简单地声明c
来将其强制为字符串(应始终将所有变量声明为方便的习惯,以确保此操作确保所有模块的顶部都带有Option Explicit
)
实际上,您的代码可以简化为:
Function prevdeset(base As Integer, ipt As String) As String
Dim i As Long, u As Long
Dim p As Long
Dim HexCode As String
For i = Len(ipt) To 1 Step -1
HexCode = UCase(Mid(ipt, i, 1))
If Not IsNumeric(HexCode) Then
p = Asc(HexCode) - Asc("A") + 10
If p >= base Then Err.Raise Number:=999, Source:="prevdeset", Description:="Invalid Hex"
Else
p = Val(HexCode)
End If
p = p * (base ^ (Len(ipt) - i))
u = u + p
Next i
prevdeset = u
End Function
答案 1 :(得分:0)
下面的代码是您的简化版本和更正版本。您的代码无法正常工作的原因是使用整数而不是至少是长整数。我建议使用LongPtr。
Function Prevdeset(ByVal base As Integer, ByVal ipt As String) As LongPtr
' pass the arguments ByVal to avoid having them changed by the code
' in this way you wouldn't need the variable ipt
' Add Option Explicit at the top of your code module
' to ensure that you don't forget to declare variables
Dim u As LongPtr
Dim p As Integer
Dim x As Integer
Dim i As Integer
' the Dim statement sets all values to 0
x = Len(ipt)
For i = x To 1 Step -1
p = InStr("0123456789ABCDEF", Mid(ipt, i, 1)) - 1
If p < 0 Then
MsgBox "invalid characer " & Mid(ipt, i, 1) & "." & vbCr & _
"The returned result may not be correct."
End If
u = u + (p * (base ^ (x - i)))
Next i
Prevdeset = u
End Function
请注意,函数的返回类型必须与分配给变量u
的返回类型相同(在我的代码中为LongPtr,但至少为Long)。如果希望函数返回字符串,则可以在函数的最后一行代码中分配Prevdeset = CStr(u)
。