Excel vba combobox.value 读取十进制值的10倍

Excel vba combobox.value reads 10 times the decimal value

在 vba 中,我从组合框中读取值,但对于十进制值,它得到 10 倍的数量。它适用于整数并且适用于其他人的计算机,我猜我的设置有问题。有谁知道我该如何解决?

相关代码部分如下:

Dim Rt, r As Double
ComboBox3.RowSource = "Datas! B2:B11"
r = ComboBox3.Value
MsgBox ("r is equal to" & r)

value and value read

从这些单元格中获取值,单元格格式为数字。 “点”是十进制分隔符。 cells image

组合框 returns 文本值,因此使用 Val 进行转换,它始终将点作为小数点分隔符读取:

r = Val(ComboBox3.Value)

我使用这两个功能来处理您提出的问题。 NumberValue returns 一些从字符串中提取的 Double 类型,就像您在文本或组合框等表单控件中可能拥有的一样。此函数将尝试确定数字是否使用小数点或逗号,但它还需要一个参数来使用此枚举定义系统。

Enum Ndp                            ' Decimal point
    ' NIC 003 14 Sep 2020
    NdpEN = 1                       ' decimal point
    NdpDE                           ' decimal comma
End Enum

NumberText 以相反的方式工作,但只能 return 带小数点的数字,逗号作为千位分隔符。如果您需要组合框显示德语数字格式,那将很容易翻转。

Function NumberText(ByVal Number As Variant, _
                    Optional ByVal Decs As Integer, _
                    Optional Suffix As String) As String
    ' NIC 003 13 Sep 2020
    'returns an Absolute number
    
    Dim Mask    As String
    
    Mask = "#,##0"
    If Decs Then Mask = Mask & Left(".000000", Decs + 1)
    NumberText = Format(Abs(CDbl(Number)), Mask) & Suffix
End Function

Function NumberValue(ByVal Number As Variant, _
                     Optional ByVal Dp As Ndp) As Double
    ' Nic 003 14 Sep 2020
    ' dp defines the separators used in Number
    ' return Number with decimal point regardless of input
    ' removes any thousands separator
    ' in numbers with 3 decimals the separator is deemed a
    ' thousands separator if Dp isn't supplied.
    
    Dim Fun     As String
    Dim Char    As String
    Dim Sp()    As String
    Dim n       As Integer
    Dim p       As Integer
    
    If IsNumeric(Number) Then
        Fun = CStr(Number)
    Else
        For n = 1 To Len(Number)
            Char = Mid(Number, n, 1)
            If InStr("01234567890.,", Char) Then Fun = Fun & Char
        Next n
    End If
    Number = Fun
    
    If Len(Number) Then
        If Dp = 0 Then
            p = InStr(Number, ".")
            n = InStr(Number, ",")
            If p Then
                ' Number contains a period
                If n Then
                    ' both separators are present
                    Dp = IIf(n < p, NdpEN, NdpDE)
                Else
                    ' only period is present
                    Sp = Split(Number, ".")
                    Dp = IIf(Len(Sp(UBound(Sp))) = 3, NdpDE, NdpEN)
               End If
            Else
                ' Number contains no period
                If n Then
                    Sp = Split(Number, ",")
                    ' only comma is present
                    Dp = IIf(Len(Sp(UBound(Sp))) = 3, NdpEN, NdpDE)
                Else
                    Dp = NdpEN
                End If
            End If
        End If
    
        If Dp = NdpEN Then
            NumberValue = WorksheetFunction.NumberValue(Fun, ".", ",")
        Else
            NumberValue = WorksheetFunction.NumberValue(Fun, ",", ".")
        End If
    Else
        NumberValue = Val(Fun)
    End If
End Function

另一个可能对您有用的想法:我将实际数字存储在控件的 Tag 属性 中以供在表单中使用。所以...

' On Change or AfterUpdate: 
    Control.Tag = NumberValue(Control.Value)
    Control.Value = NumberText(Control.Tag, 2) - [*Suffix* is a string like unit or measure or +/-*]

' But retrieve the value with 
    Val(Control.Tag]