计算包含某些字母的单元格(Visual Basic)

我想在VBA中编写一个函数来计算在特定范围内包含某些字母的单元格。 我的代码到目前为止

Function letters(list As range) As Double Dim limit As Integer limit = UBound(list.Value) Dim total As Double total = 0 Dim i As Integer For i = 1 To limit If range(list).Offset(i, 2) = "PD" Then total = total + 1 End If Next i letters = total End Function 

所以我的input是=字母(A1:B6),可以说B2,B3和B5有文字“PD”。 我希望我的答案是3,但我得到了#value! 错误。 我哪里错了?

提前致谢。

您可以遍历范围内的每个单元格,并使用INSTR来查找单元格是否包含文本。 增加一个计数器,如果它,然后输出。

 Function findText(myRange As Range, toFind As String) Dim ra As Range Dim rCount As Integer rCount = 0 For i = 1 To myRange.Rows.Count If InStr(1, myRange(i, 1), toFind, vbTextCompare) Then rCount = rCount + 1 End If Next i findText = rCount End Function 

这将计数事件在单元格中的任何位置具有所需文本的单元格。 如果你想匹配整个单元格的内容,只需使用

 If myRange(i, 1) = toFind Then 

此外,该function适用​​于单栏中的范围。

回答你的问题

我哪里错了?

有一些要解决的问题:

  • 你说你打电话给你的function

      =letters(A1:B6) 

    A1:B6没有任何意义,而你有两个select:

    • 要么你调用你的函数传递一个文字string作为一个有效的Range地址

      =letters("A1:B6")

    • 或者直接调用它传递一个Range对象

      =letters(Range("A1:B6"))

  • 一旦你完成了以前的观点,你必须坚持行事,即:

    • 选项1:将文字string作为有效的Range地址传递

      那么"A1:B6" (注意围绕A2:B6的双引号)是你的范围的地址,所以你必须:

      • 更改:

         limit = UBound(list.Value) '<--| error 

        一个string没有Value属性

        至:

         limit = UBound(Range(list).Value) '<--| OK 

        Range("A1:B6")是一个有效的Range引用,所以你可以访问它的Value属性

      • 更改:

         Range(list).Offset(i, 2) '<--| this references a range as large as the one it's being called upon! 

        Offset(nRows, nColumns)方法将引用一个范围,该范围从被调用的范围“移位”到您放入参数中的行和列数量。 因此当i = 2时, Offset(i,2)调用Range("A1:B6")引用Range("C2:D7")i = 2时, Range("C3:D8")

        至:

         Range(list).Cells(i, 2) '<--| it references a single cell 

        Cells(iRow, iColumn)方法将引用被调用的RangeiRow行和第iColumn列的单元格。 所以Range("A1:B6").Cells(1,2)引用单元格“B7”

    • 选项2:传递一个Range对象

      由于list已经是一个Range对象(即Range("A1:B6") ),所以你必须:

      • 更改:

         If Range(list).Offset(i, 2) = "PD" Then '<--| error 

        您不能将Range对象作为另一个Range对象的唯一parameter passing

      至:

        If list.Cells(i, 2) = "PD" Then '<--| Ok 

      在选项1中已经讨论过使用Range对象的Cells属性

  • 那么你可能要考虑下面的miscellanea

    • 声明您的FunctionLongtypes

      以来:

      • 你正在返回一个整数值,所以不需要使用Doubletypes

      • 行数可以超过Integertypesvariables的65 k限制

    • 声明Dim limit As Long

      自从

        limit = UBound(Range(list).Value) '<--| correct use of 'list' if it's a literal 'string' 

      你正在给它分配一个Range的实际行数,它可能会超过Integertypesvariables的65k的限制


所有这一切,我认为最有效的VBA解决scheme将使用WorksheetFunction.CountIF()函数如下:

 Function letters(list As String) As Long letters = WorksheetFunction.CountIf(Range(list).Columns(2), "PD") End Sub 

在那里你可以使用Range对象的.Columns(n)属性来引用被调用的Range的第n列

并且可以通过将其参数列表扩展到search的string来更一般化

 Function letters(list As String, myLetters As String) As Long letters = WorksheetFunction.CountIf(Range(list).Columns(2), myLetters) End Sub 

你会这样称呼:

 MsgBox letters("A1:B6", "PD") 

如果你愿意,你可以通过使用下面的公式而不是使用VBA来实现这一点。

 =SUMPRODUCT(--(IFERROR(FIND("PD",A1:A25,1)>0,FALSE))) 

你需要input这个数组公式input公式并按下Ctrl Shift Enter

FIND("PD",A1:A25,1)为您提供文本位置或错误,如果没有find每个单元格的文本。

>0将数字转换为TRUE。 如果IFERROR将其转换为FALSE,则发生错误。 因此你得到一个{TRUE,FALSE,...}的数组,如{TRUE,FALSE,...}

--({...})将数组转换为1和0。 1表示TRUE ,0表示FALSESUMPRODUCT增加了这个数字数组来给你计数。