在一个单元格Excel中计数模式

时间:2017-08-15 21:52:46

标签: excel excel-vba excel-formula vba

我想要你的帮助,我目前正致力于提取一些数据,现在问题是我必须计算一定数量的呼叫ID,呼叫ID格式如下9129572520020000711。该模式为19个字符,以9开头,以1结尾。 我想计算这个模式出现在一个单元格中的次数

即。这是一个单元格中的值,我想计算模式出现的次数。

1912957252002000071129129545183410000711391295381628700007114912959791875000071159129597085000000711691295892838400007117912958908933000071189129452513730000711

3 个答案:

答案 0 :(得分:1)

要使用您需要知道的公式解决此问题:

  • 起始字符
  • 结束字符
  • 您的通话ID的长度

查找所有可能的呼叫ID

enter image description here

B1成为您的数字字符串,B2成为您要查找的呼叫ID(或模式)。在B5中输入公式=MID($B$2,1,1)以查找您要查找的起始字符。在B6输入=RIGHT($B$2,1)作为结束字符。在B7中输入=LEN($B$2)作为通话ID的长度。

在A栏中,我们将输入每个首发角色的位置。第一个公式是Find()B10的{​​{1}}公式=FIND($B$5,$B$1,1)。要查找其他起始字符,请在最后一个起始字符后的位置Find()开始=FIND($B$5,$B$1,$A10+1) B11。将其复制到列中几十次(或更多次)。

在B栏中,我们将查看下一个X字符(其中X是呼叫ID的长度)是否符合呼叫ID的条件:

=IF(MID($B$1,$A10+($B$7-1),1)=$B$6,TRUE,FALSE)

MID($B$1,$A10+($B$7-1),1)=$B$6检查此可能的呼叫ID末尾的字符末尾的字符是否是我们正在寻找的结束字符。 $A10+($B$7)计算可能的呼叫ID的位置,$B$6是结束字符。

在C列中,如果匹配,我们可以返回实际的呼叫ID。这不是查找计数所必需的,但以后会有用。只需检查B列中的值是否为True,如果是,则返回计算出的字符串:=IF(B10,MID($B$1,$A10,$B$7),"")

要实际计算有效呼叫ID的数量,请执行CountIf()“呼叫ID”列以检查True值的数量:=IF(B10,MID($B$1,$A10,$B$7),"")

如果您不希望所有#Values!只是将所有内容都包含在IFERROR(,"")公式中。

查找所有连续的呼叫ID

enter image description here

但是,其中一些呼叫ID重叠。假设呼叫ID不能重叠,我们只需要在找到的ID的结束字符之后开始搜索,而不是开始。插入"结束位置"列B中的列,公式为:=$A10+($C$7-1),从B11开始。将A11更改为=FIND($C$5,$C$1,$B10+1)并复制下来。不要更改A10,因为这会找到第一个起始位置,并且不依赖于原始文本以外的任何内容。

哪些有效?

我不知道,这取决于您的通话ID的其他条件。如果你连续收到它们,那么第二种方法是最好的,其他可能的方法是巧合的。如果没有,那么您必须对第一种方法应用其他一些验证标准,因此我们确定每个ID 的原因。

答案 1 :(得分:1)

您可以使用正则表达式简单地使用UDF解决此问题。

Option Explicit
Function callIDcount(S As String) As Long
    Dim RE As Object, MC As Object
    Const sPat As String = "9\d{17}1"

Set RE = CreateObject("vbscript.regexp")
With RE
    .Global = True
    .Pattern = sPat
    Set MC = .Execute(S)
    callIDcount = MC.Count
End With
End Function

使用您的示例,这将返回8

的计数

正则表达式引擎将匹配模式的所有匹配项捕获到匹配集合中。要查看有多少,我们只返回该集合的计数。

如果有必要,琐碎的修改将允许人们返回实际ID。

enter image description here

正则表达式:

9 \ d {17} 1

9\d{17}1

使用RegexBuddy

创建

编辑通过TheFizh的帖子阅读,他认为您可能希望计数包含重叠的CallID。换句话说,给定:

9129572520020000711291

我们看到包括:

9129572520020000711
9572520020000711291

第二个与第一个重叠,但都符合您的要求。

这应该是你想要的,只需改变正则表达式,使其不“消耗”匹配:

Const sPat As String = "9(?=\d{17}1)"

并且您将返回15而不是8的结果,这将是非重叠模式。

答案 2 :(得分:0)

你的意思是什么之类的东西?

Sub CallID_noPatterns()

Dim CallID As String, CallIDLen As Integer
CallID = "9#################1"
CallIDLen = Len(CallID) 'the CallID's length

'Say that you want to get the value of "A1" cell and deal with its value
Dim CellVal As String, CellLen As Integer
CellVal = CStr(Range("A1").Text) 'get its value as a string
CellLen = Len(CellVal) 'get its length

'You Have 2 options:-
'1-The value is smaller than your CallID length. (Not Applicable)
'2-The value is longer than or equal to your CallID length
'So just run your code for the 2nd option

Dim i As Integer, num_checks, num_patterns
i = 0
num_patterns = 0

'imagine both of them as 2 arrays, every array consists of sequenced elements
'and your job is to take a sub-array from your value, of a length
' equals to CallID's length
'then compare your sub-array with CallID

num_checks = CellLen - CallIDLen + 1
If CellLen >= CallIDLen Then
    For i = 0 To num_checks - 1 Step 19
        For j = i To num_checks - 1
            If Mid(CellVal, (j + 1), CallIDLen) Like CallID Then
                num_patterns = num_patterns + 1
                Exit For
            End If
        Next j
    Next i
End If

'Display your result
MsgBox "Number of Patterns: " & Str(num_patterns)

End Sub