[新手需要使用countif在excell中提供vb帮助

问题描述 投票:-1回答:1

我在VB中没有太多经验,但确实可以使用一些帮助。

我有200条数据输入行,我需要知道当前单元格值(示例B6)是否与B列中的任何上述值(示例B1:B4)匹配,如果是,则在当前行上放置一个“ x”列d

当前excel公式为=IF(COUNTIF($B$5:B35,B36)>0,"x","")

excel vba countif
1个回答
1
投票

我不确定您是否需要有关公式本身或编写等效的VBA函数以执行相同功能的帮助。因此,我同时分享了这两种选择:

使用Excel的COUNTIF

让我们假设您的数据始于单元格A1并具有标题行。然后,您将必须...

  • ...放置一个与您已有的公式有点相似的公式,在单元格D2中=IF(COUNTIF(B$2:B2, B2) > 1, "x", "")
  • ...将D2中的公式向下复制到D列中的单元格,直到到达数据的最后一行

例如,在第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列的其余部分。公式将类似于以下内容:

Image of sample sheet with VBA formulas

我在使用VBA功能时看到的唯一优势是,它允许您在找到第一个重复项后中止搜索。相比之下,即使您不需要知道该数字,COUNTIF也会计算所有重复项。


使用索引/匹配(第三种选择)

[为了避免使用VBA并避免使用COUNTIF计算所有重复项,可以使用利用Excel的INDEXMATCH函数的公式。

在这种情况下,您必须将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


最新问题
© www.soinside.com 2019 - 2024. All rights reserved.