【问题标题】:How to count cells containing numbers in specific range with cells that contain both text and numbers如何使用包含文本和数字的单元格计算包含特定范围内数字的单元格
【发布时间】:2021-09-06 17:52:26
【问题描述】:

我以为我可以轻松解决这个问题,但我花了很长时间才解决了一半。

我有一个表格,其中连续包含 100 个数据单元格。每个单元格中的数据要么是纯文本,要么是文本和数字(见底部布局)。

我需要一个函数来计算表中有多少单元格报告N2 OR E 的值>=37。

Negative
Positive (N2: 23, E: 23)
Negative                      Function answer: 2
Positive (N2: 37, E: 26)
Positive (N2: 31, E: 38)

到目前为止,我只能使用考虑第 15 个字符的函数 [=MID(A2,15,FIND(",",A2)-15)] 提取每个 N2 数字,然后第二个函数计算提取的数字(它们已在 B 行中提取)>=37,[=COUNTIF (B2:B100, ">=37")] 但不知道如何考虑 E 值。

此外,我希望函数考虑包含 N2 值或 E 值 >=37 的单元格。

是否有机会拥有一个可以做到这一点的大功能?是否有机会不依赖 KUTools for Excel?

【问题讨论】:

  • 你可以试试这个公式:=IF(OR(--MID(A2,FIND("N2:",A2)+4,2)>=37,--MID(A2,FIND ("E:",A2)+3,2)>=37),1,0) 在 B 列中,对于最终计数,您可以使用 =COUNTIF(B2:B100,1)
  • @MarioJavierEugenioEstrada 假设 OP 添加了基本错误处理(#VALUE! 很丑),第二个公式简化为 =SUM(B2:B100)
  • @MarkBalhoff 我同意!您所说的一切都是正确的,但 SUM 不适用于#VALUE,我假设他不介意出现 VALUE 错误(因为他已经在使用没有 IFERROR 的 MID 函数)。
  • @MarioJavierEugenioEstrada,如果一个数字是 100+ 怎么办?
  • @JvdV 你可以使用这个公式:=IF(OR(--MID(A2,FIND("N2:",A2)+4,FIND("E:",A2)-FIND) ("N2:",A2)-6)>=37,--MID(A2,FIND("E:",A2)+3,FIND(")",A2)-FIND("E:",A2 )-3)>=37),1,0)

标签: python excel excel-formula


【解决方案1】:

如果您拥有最新版本的 Excel,您可以在进行一些小改动后使用FILTERXML。首先将整个范围与CONCAT 连接,然后消除所有“,”并将“)”替换为连接字符串中的空格。

例如,下面会为您提供超过 36 个的所有实例(如果您只想要次数,请将其包装在 COUNT 中):

=FILTERXML("<t><s>"&SUBSTITUTE(
SUBSTITUTE(SUBSTITUTE(CONCAT($F$2:$F$7), ")", " "), ",", ""), " ",
 "</s><s>")&"</s></t>", "//s[number()>=37]")

有关处理字符串的更多信息,请参阅here

编辑:感谢@MarkBalhoff 在公式中发现了一个缺失的空格,并且 @JvdV 为 =IFERROR(COUNT(FILTERXML("&lt;t&gt;&lt;s&gt;"&amp;SUBSTITUTE(TEXTJOIN(" ",,F2:F6)," ","&lt;/s&gt;&lt;s&gt;")&amp;"&lt;/s&gt;&lt;/t&gt;","//s[translate(.,',','')*1&gt;=37 or translate(following::*[2],')','')*1&gt;=37]")),0) 提供另一种方式@

【讨论】:

  • 这不会重复计算Positive (N2: 45, E: 51)吗?
  • 也许宁可使用=IFERROR(COUNT(FILTERXML("&lt;t&gt;&lt;s&gt;"&amp;SUBSTITUTE(TEXTJOIN(" ",,F2:F6)," ","&lt;/s&gt;&lt;s&gt;")&amp;"&lt;/s&gt;&lt;/t&gt;","//s[translate(.,',','')*1&gt;=37 or translate(following::*[2],')','')*1&gt;=37]")),0) 来反驳之前的评论?
  • @Mark Ba​​lhoff 和 JvdV 谢谢,可以通过用空格代替右括号来修复,请参阅编辑
  • 我看不出添加空格将如何解决问题,而 Excel 中的快速测试可以支持这一点。如果我将 =COUNT(&lt;yourFormula&gt;) 放在 Excel 中(由于旧版 Excel 版本将 CONCATENATE 替换为 CONCAT)针对 OP 示例数据,则将最后一行中的 31 更改为 39 会改变答案。根本问题是该函数不知道哪些数字来自同一行。
  • @Mark Ba​​lhoff 很奇怪,请检查我的图片以显示它有效。现在的图片是4,如果我把31改成39就是5。一定是版本问题
【解决方案2】:

由于您包含了 python 标记并且还引用了 KU-Tools,我假设您对 VBA 有一定的了解。

您可以使用正则表达式轻松灵活地在 Excel VBA 中实现逻辑。

对于这个函数,我允许三个参数:

  1. 要搜索的范围
  2. 值的阈值
  3. 要查找的值列表

在正则表达式中,该模式查找“searchFor”中任一字符串后面的数字。请注意,正如所写,您需要在searchFor 字符串中包含冒号,并且字符串区分大小写。 (很容易改变)

Option Explicit
Function CountVals(r As Range, Threshold As Long, ParamArray searchFor() As Variant) As Long
    Dim RE As Object, MC As Object, M As Object
    Dim counter As Long
    Dim vSrc As Variant, v As Variant
    Dim sPat As String
    
'read range into variant array for fastest processing
vSrc = r

'create Pattern
sPat = "(?:" & Join(searchFor, "|") & ")\s*(\d+)"

'initialize regex
Set RE = CreateObject("vbscript.regexp")
With RE
    .Global = True
    .ignorecase = False 'or change to true if capitalization not important
    .Pattern = sPat
    counter = 0
    
    'check each string for the values
    For Each v In vSrc
        Set MC = .Execute(v)
            For Each M In MC
                If CLng(M.submatches(0)) >= Threshold Then counter = counter + 1
            Next M
    Next v
    
CountVals = counter
        
End With
    
End Function

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-05
    • 1970-01-01
    • 1970-01-01
    • 2012-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多