我有一个VBA脚本,用于从用户(表单)中获取产品名称,数量和价格的输入,如果一切都通过验证,那么它应该将其添加到列出产品的表的底部。
除了验证检查之外,一切似乎都很好,看看数量和价格是否是数字,它似乎总是经过这个检查。
任何帮助都会很棒。感谢
我已在下面复制了我的代码:
Order.joins(:order_reminders).where('order_reminders.date < ?', 1.month.from_now)
答案 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并填充工作表的示例,而不是每次都选择单元格(避免Select
和Activate
尽可能多可能)。正如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