数字验证在VBA中不起作用

时间:2015-10-05 02:01:56

标签: excel vba validation excel-vba numbers

我有一个VBA脚本,用于从用户(表单)中获取产品名称,数量和价格的输入,如果一切都通过验证,那么它应该将其添加到列出产品的表的底部。

除了验证检查之外,一切似乎都很好,看看数量和价格是否是数字,它似乎总是经过这个检查。

任何帮助都会很棒。感谢

我已在下面复制了我的代码:

Order.joins(:order_reminders).where('order_reminders.date < ?', 1.month.from_now)

3 个答案:

答案 0 :(得分:0)

如果需要,可以将它放在命令按钮中,但使用Textbox.change也可以节省时间,例如。

Private Sub CommandButton1_Click()
    Range("B1") = Me.TextBox1.Value
    Unload Me
End Sub

Private Sub TextBox1_Change()
    If IsNumeric(Me.TextBox1) Then
    Else
        With Me.TextBox1
            .SelStart = 0
            .SelLength = Len(.Text)
            .SetFocus
        End With
        MsgBox "Must be a number"
    End If
    If Me.TextBox1 > 0 Then
    Else
        With Me.TextBox1
            .SelStart = 0
            .SelLength = Len(.Text)
            .SetFocus
        End With
        MsgBox "Must be  > 0"
    End If
End Sub

Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    Me.TextBox1 = Format(Me.TextBox1, "$#,##0.00")
End Sub

答案 1 :(得分:0)

您应该在显示消息框后退出子或功能 如果使用Sub,则使用“Exit Sub”;如果使用Function,则使用“Exit Function”。

例如

'Validating Price

If (intResponse = 6) Then
    If (IsNumeric(intPrice)) Then
        If (intPrice > 0) Then
            'Do nothing
        Else
            MsgBox ("Price should be greater than zero")
            intResponse = 0          'Set intResponse to value different than vbYes
            Exit Sub
        End If
    Else
        MsgBox ("Price should be a number")
        Exit Sub
    End If
End If

答案 2 :(得分:0)

关于项目的最佳架构有各种各样的观点,我的意见只是个人意见。所以,FWIW,我会处理UserForm事件中的数据验证 - 这样用户不会通过输入所有数据来查找单击“Do it”按钮,他是回到第一个方向。

我想你的TextBoxes上有一些UserForm和某种“做它”按钮(称为“保存”或“输入”或类似的东西)。在验证所有数据之前禁用该按钮可能会更好,因此只需单击一下即可启动 Go for launch 。在下面的代码中有一个如何做到的例子 - 一旦输入有效,它会绘制TextBox绿色的背景,但你可以弹出消息或任何你喜欢的消息。在验证方面,我确实喜欢RegEx甚至数字字符串,因为我可以很容易地控制某些东西的小数位数(这对货币价值等有用)。然而,许多人不同意这种做法。

就您的代码而言,我粘贴了一个更简单的获取产品ID并填充工作表的示例,而不是每次都选择单元格(避免SelectActivate尽可能多可能)。正如pnuts所述,请注意您的声明 - 如果要保持对数据类型的控制,每个声明都必须有自己的类型标识符。例如,在您的代码中,看起来好像您希望quanitity为Integer,但它尚未被声明为一个。在VBA中,Strings&连接。

要使下面的代码工作,您需要引用RegEx。转到工具 - &gt;引用...并点击Microsoft VBScript Regular Expressions 5.5上的复选框。

UserForm中输入以下代码,显然会根据需要更改控件名称:

Private Const RED As Long = &HC0C0FF
Private Const GREEN As Long = &H80FF80
Private mPriceIsValid As Boolean
Private mQuantityIsValid As Boolean
Private mProductIsValid As Boolean

Private Property Let PriceIsValid(value As Boolean)
    mPriceIsValid = value
    txtPrice.BackColor = IIf(value, GREEN, RED)
    btnProcess.Enabled = mPriceIsValid And mQuantityIsValid And mProductIsValid
End Property
Private Property Let QuantityIsValid(value As Boolean)
    mQuantityIsValid = value
    txtQuantity.BackColor = IIf(value, GREEN, RED)
    btnProcess.Enabled = mPriceIsValid And mQuantityIsValid And mProductIsValid
End Property
Private Property Let ProductIsValid(value As Boolean)
    mProductIsValid = value
    txtProduct.BackColor = IIf(value, GREEN, RED)
    btnProcess.Enabled = mPriceIsValid And mQuantityIsValid And mProductIsValid
End Property

Private Sub btnProcess_Click()
    ProcessInputs txtProduct.Text, txtQuantity.Text, txtPrice.Text
    txtProduct.Text = ""
    txtPrice.Text = ""
    txtQuantity.Text = ""
End Sub

Private Sub txtPrice_Change()
    If Not IsPositiveCurrency(txtPrice.Text) Then
        PriceIsValid = False
    ElseIf val(txtPrice.Text) = 0 Then
        PriceIsValid = False
    Else
        PriceIsValid = True
    End If
End Sub

Private Sub txtProduct_Change()
    ProductIsValid = (Len(txtProduct.Text) <> 0)
End Sub

Private Sub txtQuantity_Change()
    If Not IsPositiveDecimal(txtQuantity.Text, 1) Then
        QuantityIsValid = False
    ElseIf val(txtQuantity.Text) = 0 Then
        QuantityIsValid = False
    Else
        QuantityIsValid = True
    End If

End Sub

Private Function IsPositiveCurrency(textValue As String) As Boolean
    Dim regex As New RegExp

    regex.Pattern = "^\d+(\.\d{2})?$"
    IsPositiveCurrency = regex.Test(textValue)
End Function
Private Function IsPositiveInteger(textValue As String) As Boolean
    Dim regex As New RegExp

    regex.Pattern = "^\d+$"
    IsPositiveInteger = regex.Test(textValue)
End Function
Private Function IsPositiveDecimal(textValue As String, uptoDecPlaces As Integer) As Boolean
    Dim regex As New RegExp

    regex.Pattern = "^\d+(\.\d{1," & CStr(uptoDecPlaces) & "})?$"
    IsPositiveDecimal = regex.Test(textValue)
End Function

Private Sub UserForm_Initialize()
    ProductIsValid = False
    QuantityIsValid = False
    PriceIsValid = False
End Sub

然后在Module粘贴以下代码:

Public Sub ProcessInputs(product As String, quantity As String, price As String)
    Const PRODUCT_ID_COL As String = "A"
    Const PRODUCT_ID_FIRST_ROW As Long = 2
    Dim wksInventory As Worksheet
    Dim nextRow As Range
    Dim id As Long
    Dim dialogResult As Integer

    dialogResult = MsgBox("Are you certain of the following:" & vbCrLf & vbCrLf & _
                          "Product Name: " & product & vbCrLf & _
                          "Quantity: " & quantity & vbCrLf & _
                          "Price: " & price, vbYesNo)

    If dialogResult = vbYes Then

        'Find the next blank row
        Set wksInventory = ThisWorkbook.Worksheets(2)
        Set nextRow = wksInventory.Cells(wksInventory.Rows.Count, PRODUCT_ID_COL).End(xlUp).Offset(1)

        'Acquire the next product ID
        If nextRow.Row < PRODUCT_ID_FIRST_ROW Or nextRow.Row = 1 Then
            MsgBox "Headers missing!"
            End
        ElseIf nextRow.Row = PRODUCT_ID_FIRST_ROW Then
            id = 1
        ElseIf Not IsNumeric(nextRow.Offset(-1).Value2) Then
            MsgBox "Product number corrupt!"
            End
        Else
            id = nextRow.Offset(-1).Value2 + 1
        End If

        'Populate and format the new row
        nextRow.Resize(, 4).value = Array(id, product, quantity, price)
        nextRow.Resize(, 4).HorizontalAlignment = xlCenter
        nextRow.Offset(, 3).NumberFormat = "[$$-409]#,##0.00_ ;[Red]-[$$-409]#,##0.00 "

    End If
End Sub