Все функции преобразования чисел в VBA осведомлены о локали, поэтому они будут игнорировать как разделители тысяч, так и символы валют.Функция IsNumeric
ведет себя так же:
Public Sub Example()
'en-US locale
Debug.Print IsNumeric("$1,1,1,1,1,") 'True
Debug.Print CLng("$1,1,1,1,1,") '11111
End Sub
Единственный обходной путь, не связанный с хостом, о котором я знаю (если не считать сохранение чисел в виде данных String
), этополностью обходить встроенные приведения VBA и вызывать базовые функции преобразования в oleaut32.dll напрямую с жестко заданным идентификатором локали.Например, чтобы получить Double
из локализованной строки в США:
Public Declare PtrSafe Function VarR8FromStr Lib "oleaut32" _
(ByVal strIn As LongPtr, ByVal lcid As Long, ByVal dwFlags As Long, ByRef pdblOut As Double) As Long
Public Const EN_US As Long = 1033
Public Function DoubleFromEnUsString(converting As String) As Double
Dim converted As Double, result As Long
result = VarR8FromStr(StrPtr(converting), EN_US, 0, converted)
If (result = 0) Then
DoubleFromEnUsString = converted
Else
Err.Raise 5
End If
End Function
... или Long
:
Public Declare PtrSafe Function VarI4FromStr Lib "oleaut32" _
(ByVal strIn As LongPtr, ByVal lcid As Long, ByVal dwFlags As Long, ByRef plOut As Long) As Long
Public Const EN_US As Long = 1033
Public Function LongFromEnUsString(converting As String) As Long
Dim converted As Long, result As Long
result = VarI4FromStr(StrPtr(converting), EN_US, 0, converted)
If (result = 0) Then
LongFromEnUsString = converted
Else
Err.Raise 5
End If
End Function
Пример использования:
Public Sub Sample()
Debug.Print LongFromEnUsString("12.34") '12
Debug.Print DoubleFromEnUsString("12.34") '12.34
End Sub