在excel下表中计算最长连续“ k”数的最佳方法是什么?我不仅要计算“ k”的总数,还想计算出“ c”之间一行中“ k”的最长字符串(例如,第1行和第2行都为“ 4” )。预先感谢!
答案 0 :(得分:1)
如果您不反对使用VBA,则可以使用正则表达式。 下面的UDF允许您输入字符串或单元格范围作为参数。
它将查找ck
序列,后跟任意数量的k
,然后是c
,并返回最大长度的长度(-1表示最大长度)。匹配的前c
)个子字符串
Option Explicit
Function CountCKKC(myData) As Long
Dim RE As Object, MC As Object, M As Object
Const sPat As String = "ck{1,}(?=c)"
Dim s As String, c As Range
Dim L As Long
Select Case TypeName(myData)
Case "Range"
s = ""
For Each c In myData
s = s & c.Value2
Next c
Case "String"
s = myData
Case Else
Debug.Print TypeName(myData)
Stop
End Select
Set RE = CreateObject("vbscript.regexp")
With RE
.Pattern = sPat
.Global = True
.IgnoreCase = True
If .Test(s) = True Then
Set MC = .Execute(s)
For Each M In MC
L = IIf((M.Length - 1) > L, M.Length - 1, L)
Next M
End If
End With
CountCKKC = L
End Function
答案 1 :(得分:0)
您将需要额外的一行中间计算,但这并不那么复杂,
一个简单的if和一个计数器:
=IF(B$2="k",1,0)+A$2
哪里
A2 = 0
然后在最后一行的单元格中,将最大范围设置为
=MAX(B2:B10)
答案 2 :(得分:0)
如果在一个单元格中需要它,它将有点复杂。检查一下。
=MAX(--((COLUMN($B2:$N2)-(TRANSPOSE(COLUMN($B2:$N2)))+1)=
COUNTIF(INDIRECT("R"&ROW($B2)&"C"&TRANSPOSE(COLUMN($B2:$N2))&
":R"&ROW($B2)&"C"&COLUMN($B2:$N2),FALSE),"k"))*
(COLUMN($B2:$N2)-(TRANSPOSE(COLUMN($B2:$N2)))+1))
这是一个数组公式,因此请按 Ctrl + Shift + Enter 即可完成。成功后,您将在公式外看到{}
。
关键是:从rngA
到rngB
开始的“ k”的最大连续数目等于从rngA
到rngB
计数的像元。因此,我建立了一个n * n矩阵来检查1.细胞数和2. k数。
警告:这是一个n * n矩阵,因此,如果您输入的数据过多(例如10000列),则可能会非常慢。
答案 3 :(得分:0)
使用正则表达式的表格的udf。您要传递一个行范围作为第一个参数rng
,将要两侧的字母作为boundingLetter
,将内部字母作为targetLetter.
进行计数“ c”之间的“ k”。因此,“ k”将是targetLetter
,“ c”将是boundingLetter
。当它们作为参数传递时,您可以轻松更改它们。
Option Explicit
Public Sub Test()
Dim boundingLetter As String, targetLetter As String, rng As Range
Set rng = [C2:V2]
boundingLetter = "c"
targetLetter = "k"
Debug.Print GetMaxSequence(rng, boundingLetter, targetLetter)
End Sub
Public Function GetMaxSequence(ByVal rng As Range, ByVal boundingLetter As String, ByVal targetLetter As String) As Variant
Dim arr(), matches As Object, iMatch As Object, inputString As String, finalString As String, maxLength As Long
If rng.Count < 3 Or rng.Rows.Count > 1 Then
GetMaxSequence = CVErr(xlErrNA)
Exit Function
End If
arr = rng.Value
arr = Application.Index(arr, 1, 0)
If IsError(arr) Then
GetMaxSequence = CVErr(xlErrNA)
Exit Function
End If
inputString = Join(arr, Chr$(44))
With CreateObject("vbscript.regexp")
.Global = True
.MultiLine = True
.IgnoreCase = True
.Pattern = boundingLetter & ",(" & targetLetter & ",)+" & boundingLetter
If .Test(inputString) Then
Set matches = .Execute(inputString)
For Each iMatch In matches
If Len(iMatch) > maxLength Then
maxLength = Len(iMatch)
finalString = iMatch
End If
Next iMatch
Else
GetMaxSequence = CVErr(xlErrNA)
Exit Function
End If
.Pattern = boundingLetter & "|,"
GetMaxSequence = Len(.Replace(finalString, vbNullString))
End With
End Function
工作表中:
答案 4 :(得分:0)
好的,我错了,使用频率功能并不是那么容易。
您至少必须忽略范围两端的任何k剩余值(这些不包含在c中):
=MAX(FREQUENCY(IF(B2:M2="k",COLUMN(B2:M2)),IF(B2:M2="c",COLUMN(B2:M2)))*(ROW(A1:INDEX(A:A,COUNTIF(B2:M2,"c")+1))>1)*(ROW(A1:INDEX(A:A,COUNTIF(B2:M2,"c")+1))<=COUNTIF(B2:M2,"c")))
这是一个数组公式。
然后,如果您想忽略介于c到k之间但被其他字符(例如'u')穿插的k,则需要另一个条件:
=MAX(FREQUENCY(IF(B4:M4="k",COLUMN(B4:M4)),IF(B4:M4="c",COLUMN(B4:M4)))
*(FREQUENCY(IF(B4:M4<>"k",COLUMN(B4:M4)),IF(B4:M4="c",COLUMN(B4:M4)))=1)
*(ROW(A$1:INDEX(A:A,COUNTIF(B4:M4,"c")+1))>1)*
(ROW(A$1:INDEX(A:A,COUNTIF(B4:M4,"c")+1))<=COUNTIF(B4:M4,"c")))
公式第二行中的“ = 1”是因为<>“ k”包括“ c”,因此您总是会得到至少一个计数。