首页 > 解决方案 > 检查目标行以外的列中是否存在值

问题描述

简而言之,我的电子表格是一个数据库,其中 A 列中有项目,B 列中有序列号。没有两个序列号可以相同。一种用户表单具有包含项目和序列号的文本框。对于添加和编辑项目,使用相同的用户表单。

为了检查序列号是否对工作表唯一,我使用的代码如下:

If Application.WorksheetFunction.CountIf(WS.Range("b4:b100"), Me.Controls("serialnumber" & i)) > j Then
   MsgBox "serial number " & Me.Controls("serialnumber" & i) & " already exists in database", vbCritical, "Error"
   Me.Controls("serialnumber" & i).SetFocus
   Exit sub
End If

在添加 j 之前,我使用 0 来测试是否存在仅当我使用 Add new 时是否存在任何事件。但是,如果编辑项目,我也想检查重复项。这会在编辑时产生错误,对序列号没有任何更改,但仍会导致 countif 跳闸和 sub 退出。

我试图做的是使用以下代码来查看当前值是否已经与文本框项匹配。

IIf WS.Cells(a, 2) = Me.Controls("serialnumber" & i).Value, j = 1, j=0

“a”指的是编辑项所在的行。基本上在编辑时,列表框会填充所有项目,并从该列表索引中调用“a”

问题是即使 cell(a,2) 值和文本框值完全相同,即使与 debug.prints 显示完全相同,比较它们的 if 语句总是评估为 false。我尝试将 .value 都去掉,将 .value 添加到等式的任一侧,我什至为这两个值中的每一个声明了变量,将它们设为整数,然后比较两者,但仍然显示为 false。

可能有另一种方法可以做到这一点,但我想看看序列号的值是否存在于列中的其他位置,不包括它源自的目标行。如果我能做到这一点,那么即使添加一个新项目也将使用相同的错误检查,因为目标行将是列表末尾的第一个空行。有没有办法排除动态变化的行?

编辑:这是数据输入工作表的方式。

With WS.Cells(a, "a")
    .Offset(0, 1).Value = Me.Controls("serialnumber" & i).Value
 end with

在序列号文本框中仅输入诸如“123456”之类的数字。(没有引号)

标签: excelvbatextbox

解决方案


这是一个语法问题。尽管从技术上讲,它应该输出相同的结果,但它不会,因为语法错误。

当您尝试为工作表单元格分配值时,IIF应使用该函数返回一个值,特别是您分配给truepart参数或falsepart参数的值。

根据IIF文档语法IIf ( expr, truepart, falsepart )。所以根据expr(表达式)是真还是假,返回适当的truepart值或falsepart值。

重要的是要理解这IIF是一个函数(再次根据文档)返回两个部分之一,具体取决于表达式的评估。因为它返回值,所以您不能在函数中分配值,这不是它的用途。

IIF在您的上下文中使用,正确的语法是:

j = IIF(WS.Cells(a, 2) = Me.Controls("serialnumber" & i).Value, 1, 0)

关键区别在于我们根据评估返回 true 或 false来分配truepart值或falsepart值。j我还在函数周围包含了括号,这意味着返回值将被分配给某些东西(在这种情况下j)。如果您不包含括号,则返回值将被忽略。您可以阅读更多关于在函数中使用括号的信息(和其他事情)在代码中使用括号

If...Then...Else声明的工作方式略有不同。(文档在这里

第一行是评估,If WS.Cells(a, 2) = Me.Controls("serialnumber" & i).Value Then。到目前为止,我们评估的方式并没有任何区别,但在此之后,我们现在分配一个语句,该语句是另一行(或多行)代码来做某事

因此,要在语句中重写您的IIF函数:If...Then...Else

If WS.Cells(a, 2) = Me.Controls("serialnumber" & i).Value Then
    j = 1    'Do this if true
Else
    j = 0    'Do this if false
End if

在新Worksheet中,Workbook我使用以下两个测试子测试了上述所有语法。随意创建一个新的工作簿/工作表,以根据C5运行代码时单元格中的值在即时窗口中查看结果。

Sub TestIIFFunction()

Dim j As Long

j = IIf(Sheet1.Range("C1").Value = 1, 1, 0)

Debug.Print j

End Sub
'___________________________________________________________________________________

Sub TestIfThenElseStatement()

Dim j As Long

If Sheet1.Range("C1").Value = 1 Then
    j = 1
Else
    j = 0
End If

Debug.Print j

End Sub

Visual Basic 概念性主题有一些很好的主题可供阅读,了解代码的工作原理、它的作用以及如何使用它。

为了直观地展示我所做的测试:

Sheet1=A1在单元格中C5

单元格 C5 中带有 =A1 的 Sheet1

IIF functionIf...Then...Else语句的输出:

IIF 函数和 If...Then...Else 语句的输出


推荐阅读