Вы получаете ошибку переполнения из-за ограничения 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