VBA - 如何根据用户表单中文本框值的总和给出错误代码?
VBA - How can I give an error code based on the sum of my textbox values ina user form?
所以我目前有一个带有 3 个输入框和一个保存按钮的用户表单。
三个输入必须在 0.0 和 1.0 之间,这是我使用下面的代码所做的。
我现在需要这 3 个输入的总和等于 1。如果这些输入的总和不等于 1,我想在单击保存按钮时显示一条错误消息。
真的坚持这个并尝试了几种不同的方法但没有奏效。
有什么办法吗?
Private Sub CommandButton1_Click()
Dim textbox1 As Integer
Dim textbox2 As Integer
Dim textbox3 As Integer
On Error GoTo errHandler
textbox1 = CInt(UserForm1.textbox1.Value)
If textbox1 > 1 Then
MsgBox "Invalid Input, Please enter value between 0.0 and 1.0"
Else
UserForm1.Hide
End If
On Error GoTo errHandler
textbox2 = CInt(UserForm1.textbox2.Value)
If textbox2 > 1 Then
MsgBox "Invalid Input, Please enter value between 0.0 and 1.0"
Else
UserForm1.Hide
End If
Exit Sub
On Error GoTo errHandler
textbox3 = CInt(UserForm1.textbox3.Value)
If textbox3 > 1 Then
MsgBox "Invalid Input, Please enter value between 0.0 and 1.0"
Else
UserForm1.Hide
End If
Exit Sub
errHandler:
MsgBox Err.Description
End Sub
我在回答您的问题时有些随意,因为我看到了改进您的代码的机会,而不是仅仅让您找到答案。下面的代码应该更容易read/manage,我希望它能帮助你在未来写出更好的代码。先上代码,再说明过程:
Private Sub CommandButton1_Click()
Dim Inputs(1 To 3) As Variant
Dim Total As Double
' It is better to anticipate errors (check the values that could cause an error) than it is to
' use a GoTo block that catches everything.
' On Error GoTo errHandler
Inputs(1) = GetInputFromTextbox(UserForm1.textbox1)
Inputs(2) = GetInputFromTextbox(UserForm1.textbox2)
Inputs(3) = GetInputFromTextbox(UserForm1.textbox3)
' Handle the errors all in the same block (simply for readability)
If IsEmpty(Inputs(1)) Then
InvalidInput "Textbox1"
UserForm1.Hide
ElseIf IsEmpty(Inputs(2)) Then
InvalidInput "Textbox2"
UserForm1.Hide
ElseIf IsEmpty(Inputs(3)) Then
InvalidInput "Textbox3"
UserForm1.Hide
Else
' This will only execute if the three previous inputs are valid
Total = Application.WorksheetFunction.Sum(Inputs)
If Total <> 1 Then
TotalInputsInvalid Total
End If
End If
End Sub
' Define the function as a variant so it can return a null value
' This is important since the user could enter a 0 value and the default return of
' the function, if defined as a numeric type, would be 0. This would, in turn, prevent error handling.
Private Function GetInputFromTextbox(ByVal InputMember As Object) As Variant
If IsNumeric(InputMember.Value) Then
If CDbl(InputMember.Value) < 1 Then
GetInputFromTextbox = Round(CDbl(InputMember.Value), 2)
End If
End If
' Notice that, if the conditions for a valid input are not met, nothing happens.
' This allows us to handle errors within the calling routine.
End Function
' This will alert the user if the input given is invalid.
Private Sub InvalidInput(ByVal MemberName As String)
MsgBox "There is an invalid input in " & MemberName & ". Please enter value between 0.0 and 1.0."
End Sub
Private Sub TotalInputsInvalid(ByVal TotalValue As Double)
MsgBox "The total value of all inputs must equal 1. The current total is " & Round(TotalValue, 2) & ". Please adjust the inputs accordingly."
End Sub
首先,我为输入值定义了一个变量。这样做的主要好处是您的代码更清晰,更有意义。拥有 Foo1、Foo2、Foo3 等变量会使您的代码有点混乱。数组可以简化此过程,尤其是当此应用程序必须扩展以容纳更多文本框时。
另请注意,根据 YowE3k 的建议,我已将数组声明为 double
的数组,Total
也是如此。 Double
s 允许浮点精度,而 Long
s 和 Integer
s 只允许整数(旁注,永远不要使用 Integer
。养成只使用 Longs 的习惯任何你会使用 Int 的东西)。
接下来,我定义了一个从文本框中获取干净输入的函数。这是一个养成的好习惯。请记住,现在复制粘贴不可避免地意味着需要额外的 debugging/fixing 时间。在极少数情况下,在当前情况下这是不可避免的,但通常情况下,函数或 Sub 会创造奇迹。
对于我定义的函数,它首先检查数字输入(避免类型不匹配错误),然后检查以确保值不大于 1。如果这两个条件都成功,则它return 是值(四舍五入到小数点后第二位),否则 return 什么都不是。
我使用此函数获取所有三个值,然后我在同一个 If/ElseIf 块中测试所有三个值的有效性。这将确保在执行最终检查之前所有三个值都有效。
在最后的检查中,它确保总数等于 1,如果是,则什么也不会发生。如果不是,它会提醒用户输入无效。
这里的过程是用函数来return取值,然后用逻辑来处理错误。这比 GoTo 块更有效,并且它使调试代码更容易(至少根据我的经验)。
如有任何问题,欢迎提问。祝你好运!
编辑: 将 Inputs 的声明从 Double 更改为 Variant。 Double 类型自动将基值设置为 0 而不是允许 Empty
。这反过来又可以防止检查无效值与零。 Variant 类型解决了这个问题。
所以我目前有一个带有 3 个输入框和一个保存按钮的用户表单。 三个输入必须在 0.0 和 1.0 之间,这是我使用下面的代码所做的。
我现在需要这 3 个输入的总和等于 1。如果这些输入的总和不等于 1,我想在单击保存按钮时显示一条错误消息。
真的坚持这个并尝试了几种不同的方法但没有奏效。
有什么办法吗?
Private Sub CommandButton1_Click()
Dim textbox1 As Integer
Dim textbox2 As Integer
Dim textbox3 As Integer
On Error GoTo errHandler
textbox1 = CInt(UserForm1.textbox1.Value)
If textbox1 > 1 Then
MsgBox "Invalid Input, Please enter value between 0.0 and 1.0"
Else
UserForm1.Hide
End If
On Error GoTo errHandler
textbox2 = CInt(UserForm1.textbox2.Value)
If textbox2 > 1 Then
MsgBox "Invalid Input, Please enter value between 0.0 and 1.0"
Else
UserForm1.Hide
End If
Exit Sub
On Error GoTo errHandler
textbox3 = CInt(UserForm1.textbox3.Value)
If textbox3 > 1 Then
MsgBox "Invalid Input, Please enter value between 0.0 and 1.0"
Else
UserForm1.Hide
End If
Exit Sub
errHandler:
MsgBox Err.Description
End Sub
我在回答您的问题时有些随意,因为我看到了改进您的代码的机会,而不是仅仅让您找到答案。下面的代码应该更容易read/manage,我希望它能帮助你在未来写出更好的代码。先上代码,再说明过程:
Private Sub CommandButton1_Click()
Dim Inputs(1 To 3) As Variant
Dim Total As Double
' It is better to anticipate errors (check the values that could cause an error) than it is to
' use a GoTo block that catches everything.
' On Error GoTo errHandler
Inputs(1) = GetInputFromTextbox(UserForm1.textbox1)
Inputs(2) = GetInputFromTextbox(UserForm1.textbox2)
Inputs(3) = GetInputFromTextbox(UserForm1.textbox3)
' Handle the errors all in the same block (simply for readability)
If IsEmpty(Inputs(1)) Then
InvalidInput "Textbox1"
UserForm1.Hide
ElseIf IsEmpty(Inputs(2)) Then
InvalidInput "Textbox2"
UserForm1.Hide
ElseIf IsEmpty(Inputs(3)) Then
InvalidInput "Textbox3"
UserForm1.Hide
Else
' This will only execute if the three previous inputs are valid
Total = Application.WorksheetFunction.Sum(Inputs)
If Total <> 1 Then
TotalInputsInvalid Total
End If
End If
End Sub
' Define the function as a variant so it can return a null value
' This is important since the user could enter a 0 value and the default return of
' the function, if defined as a numeric type, would be 0. This would, in turn, prevent error handling.
Private Function GetInputFromTextbox(ByVal InputMember As Object) As Variant
If IsNumeric(InputMember.Value) Then
If CDbl(InputMember.Value) < 1 Then
GetInputFromTextbox = Round(CDbl(InputMember.Value), 2)
End If
End If
' Notice that, if the conditions for a valid input are not met, nothing happens.
' This allows us to handle errors within the calling routine.
End Function
' This will alert the user if the input given is invalid.
Private Sub InvalidInput(ByVal MemberName As String)
MsgBox "There is an invalid input in " & MemberName & ". Please enter value between 0.0 and 1.0."
End Sub
Private Sub TotalInputsInvalid(ByVal TotalValue As Double)
MsgBox "The total value of all inputs must equal 1. The current total is " & Round(TotalValue, 2) & ". Please adjust the inputs accordingly."
End Sub
首先,我为输入值定义了一个变量。这样做的主要好处是您的代码更清晰,更有意义。拥有 Foo1、Foo2、Foo3 等变量会使您的代码有点混乱。数组可以简化此过程,尤其是当此应用程序必须扩展以容纳更多文本框时。
另请注意,根据 YowE3k 的建议,我已将数组声明为 double
的数组,Total
也是如此。 Double
s 允许浮点精度,而 Long
s 和 Integer
s 只允许整数(旁注,永远不要使用 Integer
。养成只使用 Longs 的习惯任何你会使用 Int 的东西)。
接下来,我定义了一个从文本框中获取干净输入的函数。这是一个养成的好习惯。请记住,现在复制粘贴不可避免地意味着需要额外的 debugging/fixing 时间。在极少数情况下,在当前情况下这是不可避免的,但通常情况下,函数或 Sub 会创造奇迹。
对于我定义的函数,它首先检查数字输入(避免类型不匹配错误),然后检查以确保值不大于 1。如果这两个条件都成功,则它return 是值(四舍五入到小数点后第二位),否则 return 什么都不是。
我使用此函数获取所有三个值,然后我在同一个 If/ElseIf 块中测试所有三个值的有效性。这将确保在执行最终检查之前所有三个值都有效。
在最后的检查中,它确保总数等于 1,如果是,则什么也不会发生。如果不是,它会提醒用户输入无效。
这里的过程是用函数来return取值,然后用逻辑来处理错误。这比 GoTo 块更有效,并且它使调试代码更容易(至少根据我的经验)。
如有任何问题,欢迎提问。祝你好运!
编辑: 将 Inputs 的声明从 Double 更改为 Variant。 Double 类型自动将基值设置为 0 而不是允许 Empty
。这反过来又可以防止检查无效值与零。 Variant 类型解决了这个问题。