如何比较VBA中的值?

如何比较VBA中的值?,vba,comparison,Vba,Comparison,我有这个Sub。当按下用户表单上的按钮时,它会被激活,用于向上计数一个条目。我将此数据库中的条目总数存储在A1中。还有另一个按钮用于向下计数一个条目,它工作正常。它们都有检查,因此不会加载不存在的条目。不知怎么的,这个不起作用 Private Sub ButtonRight_Click() MsgBox TextBoxID.Value MsgBox Cells(1, 1).Value MsgBox (TextBoxID.Value < Cells(1, 1

我有这个Sub。当按下用户表单上的按钮时,它会被激活,用于向上计数一个条目。我将此数据库中的条目总数存储在A1中。还有另一个按钮用于向下计数一个条目,它工作正常。它们都有检查,因此不会加载不存在的条目。不知怎么的,这个不起作用

Private Sub ButtonRight_Click()
    
    MsgBox TextBoxID.Value
    MsgBox Cells(1, 1).Value
    MsgBox (TextBoxID.Value < Cells(1, 1).Value)
    If TextBoxID.Value < Cells(1, 1).Value Then
        LoadEntry (TextBoxID.Value + 1)
    End If

End Sub

问题是隐式转换

字符串作为文本进行比较,因此“10”比“2”小,因为它按字母顺序排序

文本框
控件的值始终是
字符串
;为了将其视为数值,您必须首先将其转换为数值-但前提是这样做是合法的(例如,“ABC”没有等效的数值)

此外,单元格的值是一个
变量
,它可能包含一个数字或另一个可以(将)正确但隐式转换为数值的值,但也可能是
变量/错误
(例如
#N/a
,或
#值!
错误)这将在您每次尝试将其与任何对象(而不是另一个
变量/错误
值)进行比较时引发类型不匹配错误,因此在进行比较之前,还应验证并显式转换单元格的值:

Dim rawValue As String
rawValue = TextBoxID.Value

If IsNumeric(rawValue) Then
    Dim numValue As Double
    numValue = CDbl(rawValue)

    Dim cellValue As Variant
    cellValue = ActiveSheet.Cells(1, 1).Value

    If IsNumeric(cellValue) Then
        If numValue < CDbl(cellValue) Then
            LoadEntry numValue + 1
        End If
    End If

End If
将值设置为字符串
rawValue=TextBoxID.Value
如果是数字(原始值),则
Dim numValue作为Double
numValue=CDbl(原始值)
作为变量的值
cellValue=ActiveSheet.Cells(1,1).Value
如果是数字(cellValue),则
如果numValue

注意,不合格,<代码>单元格隐式地引用活动表所发生的任何事件-如果不是意图,考虑用显式<代码>工作表对象限定成员调用,例如<代码> SHIET1.Cys[1](1, 1)< /代码>。如果是有意的,考虑用<代码> ActoSeGeTe<代码>对其进行限定,以便代码说明它所做的,并执行它所说的。

< P>问题是隐式转换。

字符串作为文本进行比较,因此“10”比“2”小,因为它按字母顺序排序

文本框
控件的值始终是
字符串
;为了将其视为数值,您必须首先将其转换为数值-但前提是这样做是合法的(例如,“ABC”没有等效的数值)

此外,单元格的值是一个
变量
,它可能包含一个数字或另一个可以(将)正确但隐式转换为数值的值,但也可能是
变量/错误
(例如
#N/a
,或
#值!
错误)这将在您每次尝试将其与任何对象(而不是另一个
变量/错误
值)进行比较时引发类型不匹配错误,因此在进行比较之前,还应验证并显式转换单元格的值:

Dim rawValue As String
rawValue = TextBoxID.Value

If IsNumeric(rawValue) Then
    Dim numValue As Double
    numValue = CDbl(rawValue)

    Dim cellValue As Variant
    cellValue = ActiveSheet.Cells(1, 1).Value

    If IsNumeric(cellValue) Then
        If numValue < CDbl(cellValue) Then
            LoadEntry numValue + 1
        End If
    End If

End If
将值设置为字符串
rawValue=TextBoxID.Value
如果是数字(原始值),则
Dim numValue作为Double
numValue=CDbl(原始值)
作为变量的值
cellValue=ActiveSheet.Cells(1,1).Value
如果是数字(cellValue),则
如果numValue

注意,不合格,<代码>单元格隐式地引用活动表所发生的任何事件-如果不是意图,考虑用显式<代码>工作表对象限定成员调用,例如<代码> SHIET1.Cys[1](1, 1)< /代码>。如果是有意的,考虑用<代码> ActoSeGeTe<代码>对其进行限定,以便代码说明它所做的,并执行它所说的。

< P>比较VBA中不同类型的值不是一个简单的任务,比较的结果取决于变量的类型,转换为一个数字的可能性,变量的比较不同于“非变量”变量。看

根据文档,TextBox对象的Value属性有一个基类型变量(请参阅)

因此,比较
Variant/String
(TextBox.Value带字符串)和
Variant/Double
(Cell.Value带数字)-TextBox.Value的结果总是大于Cell.Value:

Private Sub CommandButton1_Click()
    TextBox1.Value = "123"
    [A1].Value = 9999

    Debug.Print "TextBox1.Value = " & TextBox1.Value & ", Type is " & TypeName(TextBox1.Value)
    Debug.Print "[A1].Value = " & [A1].Value & ", Type is "; TypeName([A1].Value)
    Debug.Print "TextBox1.Value > [A1].Value : (" & TextBox1.Value & " > " & [A1].Value & ") is " & (TextBox1.Value > [A1].Value)

    Me.Hide
End Sub

'Output:  
'TextBox1.Value = 123, Type is String  
'[A1].Value = 9999, Type is Double  
'TextBox1.Value > [A1].Value : (123 > 9999) is True
因此,建议在比较之前:

  • 将比较值的类型减少为1
  • 处理类型转换错误的步骤
简单的方法是使用Val()函数

它可以通过以下方式应用:

Private Sub ButtonRight_Click()
    Dim TBV as Long, CV as Long
    TBV = getNumDef(TextBoxID.Value)    'Type conversion and error handling
    CV = getNumDef(Cells(1, 1).Value)   'Type conversion and error handling
    
    If TBV < 0 Or CV < 0 Then
        MsgBox "Some of the values are not numeric or less than 0" _
            & vbCrLf & "Check the raw data", vbCritical + vbOKOnly, "Sub ButtonRight_Click()"
    Else
        If TBV < CV Then
            'The parentheses in `LoadEntry (TextBoxID.Value + 1)` are syntax sugar,
            ' i.e. the argument `TextBoxID.Value + 1` in parentheses is passed as ByVal.
            'If the argument without (), i.e. `LoadEntry TextBoxID.Value + 1`,
            'it is passed as described in the Sub definition or the default ByRef
            
            LoadEntry TextBoxID.Value + 1
        End If
    End If
End Sub
Private子按钮右键单击()
变暗TBV为长,CV为长
TBV=getNumDef(TextBoxID.Value)'类型转换和错误处理
CV=getNumDef(单元格(1,1).Value)的类型转换和错误处理
如果TBV<0或CV<0,则
MsgBox“某些值不是数字或小于0”_
&vbCrLf&“检查原始数据”,vbCritical+vbOKOnly,“子按钮右键单击()
其他的
如果TBV
比较VBA中不同类型的值不是一项简单的任务,比较的结果取决于变量的类型、转换为数字的可能性等。变量的比较不同于“非变量”变量。看

根据文档,TextBox对象的Value属性有一个基类型变量(请参阅)

因此,比较
Variant/String
(TextBox.Value带字符串)和
Variant/Double
(Cell.Value带数字)-TextBox.Value的结果总是较大
Private Sub ButtonRight_Click()
    If Val(TextBoxID.Value) < Val(Cells(1, 1).Value) Then
        LoadEntry (TextBoxID.Value + 1)
    End If
End Sub
Function getNumDef(v As Variant, Optional defV As Long = -1) As Long
    getNumDef = defV    'inintially getNumDef set as defaul value
    On Error Resume Next
    getNumDef = CLng(v) ' if error occurs, getNumDef value remains defV
End Function
Private Sub ButtonRight_Click()
    Dim TBV as Long, CV as Long
    TBV = getNumDef(TextBoxID.Value)    'Type conversion and error handling
    CV = getNumDef(Cells(1, 1).Value)   'Type conversion and error handling
    
    If TBV < 0 Or CV < 0 Then
        MsgBox "Some of the values are not numeric or less than 0" _
            & vbCrLf & "Check the raw data", vbCritical + vbOKOnly, "Sub ButtonRight_Click()"
    Else
        If TBV < CV Then
            'The parentheses in `LoadEntry (TextBoxID.Value + 1)` are syntax sugar,
            ' i.e. the argument `TextBoxID.Value + 1` in parentheses is passed as ByVal.
            'If the argument without (), i.e. `LoadEntry TextBoxID.Value + 1`,
            'it is passed as described in the Sub definition or the default ByRef
            
            LoadEntry TextBoxID.Value + 1
        End If
    End If
End Sub