if 语句的多个条件

multiple criteria for an if statement

我有一个包含 3 个文本框的表单,txt_customeracc、txt_customername、txt_customercontact

这 3 个文本框是可选的,默认情况下,文本框将在表单加载时显示 "N/A",但如果用户在其中一个中输入信息,我希望他们在另外两个中输入信息盒子也。

我使用的代码如下

If txt_customername.Text <> "" Or txt_customername.Text <> "N/A" Or 
   txt_customercontact.Text <> "" Or txt_customercontact.Text <> "N/A" And
   txt_customeracc.Text = "" Or txt_customeracc.Text = "N/A" 
   Then error1 += vbNewLine & "Please enter a correct Customer Account Number"

所以从上面的代码我期望如果用户在 txt_customername 或 txt_customercontact 文本框中输入信息而不是在 txt_customeracc 框中输入信息然后警告应该出现,但当前显示警告消息,无论是否在任何框中输入信息。谁能告诉我我做错了什么?

如果您想给用户一个正确的错误消息,告诉他他错过了什么,您必须将 if 语句分成几个部分。

首先检查所有文本框是否包含任何有效数据。
如果没有,您可以直接跳过进一步检查。
如果一个文本框包含数据,请检查每个数据并相应地设置错误。

If (txt_customername.Text = "" OrElse txt_customername.Text = "N/A") AndAlso
   (txt_customercontact.Text = "" OrElse txt_customercontact.Text = "N/A") AndAlso
   (txt_customeracc.Text = "" OrElse txt_customeracc.Text = "N/A") Then

    'No Error exit sub
    Exit Sub
End If

'This part is only reached if one textbox contains data
If (txt_customername.Text = "" OrElse txt_customername.Text = "N/A") Then
    error1 += vbNewLine & "Please enter a correct Customer Name"
End If

If (txt_customercontact.Text = "" OrElse txt_customercontact.Text = "N/A") Then
    error1 += vbNewLine & "Please enter a correct Customer Contact"
End If

If (txt_customeracc.Text = "" OrElse txt_customeracc.Text = "N/A") Then
    error1 += vbNewLine & "Please enter a correct Customer Account Number"
End If

如您所见,我还建议使用短路 OrElseAndAlso,这会产生 littttttttle 性能。

您可以计算填写的字段数。

   Dim numberFilled As Integer = 0

    If txt_customername.Text <> "" And txt_customername.Text <> "N/A" Then
        numberFilled += 1
    End If

    If txt_customercontact.Text <> "" And txt_customercontact.Text <> "N/A" Then
        numberFilled += 1
    End If

    If txt_customeracc.Text <> "" And txt_customeracc.Text <> "N/A" Then
        numberFilled += 1
    End If

    If numberFilled = 1 Or numberFilled = 2 Then
        error1 += vbNewLine & "Please enter a correct Customer Account Number"
    End If

就我个人而言,我有一个函数 IsValueEmpty 可以检查:

Function IsValueEmpty(ByVal value As String) As Boolean

    If String.IsNullOrEmpty(value) Or value = "N/A" Then
        Return True
    End If

    Return False
End Function

也可以Trim.

什么是运算符优先级?

您的主要问题是 operator precedence 有问题。那是什么?

这和做计算时一样,先乘后加。那么在 VB .NET 中,And 运算符出现在 Or 之前,因此您在代码中编写的内容的计算如下:

If txt_customername.Text <> "" Or 
   txt_customername.Text <> "N/A" Or 
   txt_customercontact.Text <> "" Or 
   (txt_customercontact.Text <> "N/A" And txt_customeracc.Text = "") Or 
   txt_customeracc.Text = "N/A" 
Then 
   error1 += vbNewLine & "Please enter a correct Customer Account Number"
End If

既然这不是你真正想要的,让我们一起构建它吧:

  • if customername OR customercontact 满了

AND

  • customeracc为空

那会给我们:

if (
    (txt_customername.Text <> "" Or txt_customername.Text <> "N/A") 'CustomerName is filled up
    Or
    (txt_customercontact.Text <> "" Or txt_customercontact.Text <> "N/A") 'Customer Contact is filled up
   )
   And
   (txt_customeracc.Text = "" Or txt_customeracc.Text = "N/A") 'Customer account is empty
Then 
  'Do whatever
End If

改进一下,调用一个函数

这里的另一个问题是可读性,这段代码可能有错误,因为它很难阅读,很难调试。

我们可以做的是构建一个函数来检查文本框是否为空:

Private Function IsEmpty(Tb As Textbox) As Boolean
    'Here we return true if tb.Text is empty or contains "N/A"
    Return Tb.Text = "" Or Tb.Text = "N/A"
End Function

所以这会使它更具可读性:

if (Not IsEmpty(txt_customername) Or Not IsEmpty(txt_customercontact)) 'CustomerName or Customer Contact is filled up
   And IsEmpty(txt_customeracc) 'Customer account is empty
Then 
  'Do whatever
End If

改进(2),比较字符串

正如 zaggler 在他的评论中所说,这里我们不使用字符串比较。如果用户开始键入,然后决定将其放回 N/A 并将其写为小写 ("n/a") 怎么办?好吧,我们会犯错误,认为他确实填满了文本框,您最终会在数据库中搜索用户 "n/a",这不是一个好主意...

所以让我们compare the String,让我们的功能变得更好:

Private Function IsEmpty(Tb As Textbox) As Boolean
    'Here we return true if tb.Text is empty or contains "N/A" (or "n/a")
    Return Tb.Text = "" Or (String.Compare(Tb.Text, "N/A", True) = 0)
End Function

备注

函数的优势在这里可以看到。我写它是因为我不想改成String.Compare()六次...每当你有两次相同的代码时,它应该是一个函数...

您可以将相关的消息部分存储在每个文本框的 Tag 属性 中并使用 Linq :

Dim customerTextBoxes = {txt_customeracc, txt_customername, txt_customercontact}

Dim messages = Aggregate customerTextBox In customerTextBoxes
               Where customerTextBox.Text = "" OrElse customerTextBox.Text = "N/A" 
               Select $"Please enter a correct {customerTextBox.Tag}")
               Into ToArray

然后根据初始长度检查它的长度,如果它们不相等,则聚合消息以供显示

If customerTextBoxes.Length <> messages.Length Then error1 = String.Join(Environment.NewLine, messages)