计算包含某些字母的单元格(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)
方法将引用被调用的Range
第iRow
行和第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 :
-
声明您的
Function
为Long
types以来:
-
你正在返回一个整数值,所以不需要使用
Double
types -
行数可以超过
Integer
typesvariables的65 k限制
-
-
声明
Dim limit As Long
自从
limit = UBound(Range(list).Value) '<--| correct use of 'list' if it's a literal 'string'
你正在给它分配一个Range的实际行数,它可能会超过
Integer
typesvariables的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表示FALSE
。 SUMPRODUCT
增加了这个数字数组来给你计数。