我在VB中没有太多经验,但确实可以使用一些帮助。
我有200条数据输入行,我需要知道当前单元格值(示例B6
)是否与B列中的任何上述值(示例B1:B4
)匹配,如果是,则在当前行上放置一个“ x”列d
当前excel公式为=IF(COUNTIF($B$5:B35,B36)>0,"x","")
我不确定您是否需要有关公式本身或编写等效的VBA函数以执行相同功能的帮助。因此,我同时分享了这两种选择:
使用Excel的COUNTIF
让我们假设您的数据始于单元格A1并具有标题行。然后,您将必须...
=IF(COUNTIF(B$2:B2, B2) > 1, "x", "")
例如,在第36行中使用“ B $ 2:B 36”和“> 1”的原因(与“ B $ 2:B 35”相对, “> 0”(使用它的方式)是它使您可以在标题行之后的所有行中使用公式。否则,您将必须使D2不包含任何公式,并在D3中添加第一个公式。
[B $ 2:B2“中” $“的原因是,无论您将公式复制到哪一行,它都强制公式始终从表的顶部开始搜索。
公式看起来像这样:
Image of sample sheet with COUNTIF formulas
使用VBA
如果要使用VBA函数而不是Excel的COUNTIF
(希望获得更快的结果,则可以创建如下函数:
Function ValueRepeats(ByVal valuesRange As Range)
Const headerRow = 1 'If there is no header, you can use 0 instead of 1
'Assume that the value will repeat itself
ValueRepeats = True
Dim values As Variant: values = valuesRange.Value
'If [values] is not an array, it is a single value, meaning that it cannot have a duplicate
If Not IsArray(values) Then
ValueRepeats = False
Exit Function
End If
'Get the 2-dimensional array's bounds
Dim arrLb As Long: arrLb = LBound(values, 1)
Dim arrUb As Long: arrUb = UBound(values, 1)
Dim index2 As Long: index2 = LBound(values, 2) 'In the 2nd dimension, we only
' care about the first column
'Get the value to search for (the last value in the array)
Dim lastValue As Variant: lastValue = values(arrUb, index2)
'Traverse the array and compare the elements against the last value
Dim i As Long
For i = arrLb To arrUb - 1
If ValuesMatch(lastValue, values(i, index2)) Then Exit Function
Next
ValueRepeats = False 'If we are here, no repeat value was found
End Function
Private Function ValuesMatch(ByVal v1 As Variant, ByVal v2 As Variant)
'NOTE: This function treats the string "5" and the number 5 as different values;
' also, string comparisons are case-insensitive,
' and Null, Empty, and "" are considered equivalent; all of this can be changed as needed
Dim typ1 As Integer: typ1 = VarType(v1)
'Make sure the values are of the same type (to avoid confusing numbers and dates),
' unless the values can be converted to an empty string
If typ1 <> VarType(v2) Then
ValuesMatch = (v1 & "") = (v2 & "") 'Null, Empty, and "" will match each other
Exit Function
End If
Select Case typ1
Case vbNull
ValuesMatch = True 'v1=v2 does not work if both values are null
Case vbString
ValuesMatch = StrComp(v1, v2, vbTextCompare) 'Case-insensitive string comparison
Case Else
ValuesMatch = v1 = v2
End Select
End Function
然后您将在D2中使用公式“ =IF(ValueRepeats(B$2:B2), "x", "")
”(而不是COUNTIF
公式)并将该公式复制到D列的其余部分。公式将类似于以下内容:
我在使用VBA功能时看到的唯一优势是,它允许您在找到第一个重复项后中止搜索。相比之下,即使您不需要知道该数字,COUNTIF
也会计算所有重复项。
使用索引/匹配(第三种选择)
[为了避免使用VBA并避免使用COUNTIF
计算所有重复项,可以使用利用Excel的INDEX
和MATCH
函数的公式。
在这种情况下,您必须将D2保留为空白且没有公式,然后在D3中添加如下所示的公式:
=IF(ISNA(INDEX(B$2:B2, MATCH(B3, B$2:B2, 0),1)), "", "x")
然后您将不得不将该公式复制到D列的其余部分。这些公式将如下所示:
Image of sample sheet with INDEX/MATCH formulas
为了更好地理解INDEX和MATCH,我推荐一个如下的页面:
ExcelJet.Net page explaining INDEX/MATCH