繁体   English   中英

如何修复#SPILL? 仅显示第二个值出错?

[英]How to fix the #SPILL! Error by displaying only the second value?

我有一个列,其中显示了一些信息:

产品信息
我是2020年的第三个产品
我创建于 1995 年,我于 2021 年上市
我不确定我是否来自 2019 2020 2021

我有一个公式可以在上面的列中提取年份,即:

=IFERROR(FILTERXML("<k><m>"&SUBSTITUTE([@[Product Name]]," ","</m><m>")&"</m></k>","//m[.=number() and string-length()=4]"),"")

这个公式的问题在于它适用于第一种情况,但它给了我一个#SPILL。 其他两种情况的错误:我理想的 output 是:

产品信息
我是2020年的第三个产品 2020
我创建于 1995 年,我于 2021 年上市 2021年
我不确定我是否来自 2019 2020 2021
  • 基本上,对于第一种情况,只需返回 4 位数字。 每次我只有一个 4 位数字序列时,我都想返回该序列。
  • 对于第二种情况,我只想返回第二年。 每次我有 2 个 4 位数字序列时,我只想返回第二年。
  • 对于第三种情况,我什么都不想返回。 每次我有超过 2 个 4 位数字序列时,我都想返回空白。

我试图添加的最后一件事是position()>5 ,这将切断第二个示例中的 1995,但我会继续在第三个示例中出现错误。 此外,我的列表非常庞大,我不确定position()>5是否适用于属于同一个第二个示例的所有产品。

我对 XPATH 不是很了解,所以如果有任何帮助,我们将不胜感激。 谢谢!

只需添加一个简单的子句来确定返回的数量,例如使用ROWS (因为默认情况下FILTERXML返回一个垂直数组):

=LET(
    ζ, FILTERXML(
        "<k><m>" &
            SUBSTITUTE(
                [@[Product Name]],
                " ",
                "</m><m>"
            ) & "</m></k>",
        "//m[.=number() and string-length()=4]"
    ),
    ξ, ROWS(ζ),
    IF(ξ > 2, "", INDEX(ζ, ξ))
)

编辑:我可能更愿意在这里避免FILTERXML

=LET(
    ζ, TEXTSPLIT([@[Product Name]], " "),
    ξ, -(ζ & "**0"),
    IF(COUNT(ξ) > 2, "", IFERROR(-LOOKUP(1, FILTER(ξ, LEN(ζ) = 4)), ""))
)

免责声明:以下解决方案是基于以下假设编写的:当“年数 < 3”时,返回最后给定的年份。 如果 'count >= 3' 则仅在年份成对出现时才返回最后一年。 因此使用“模数 2 == 0”。


如果您愿意,可以肯定地扩展 xpath。 但是,我会稍微重写它。 每个谓词,左方括号和右方括号之间的结构,是给定节点列表的过滤器。 写多个这样的结构实际上就是and ing这样的谓词。 为了更好地了解最常见的 xpath 1.0 函数可以在FILTERXML()中做什么,我想将您重定向到这篇文章。

因此,要编写连续的谓词模式,我会选择:

  • [.*0=0] - 首先返回一个过滤后的所有数字的节点列表,其中节点乘以零等于零;
  • [string-length()=4] - 然后只返回 4 个字符长的那些‡‡ ;
  • [position() = last() and (position() = 1 or position() mod 2 = 0)] - 第三个也是最后一个谓词对于您的查询来说是最棘手的。 这是通过首先检查position() = last()来完成的,这意味着该节点需要是步骤 2 的过滤节点列表中的最后一个节点,并且(position() = 1 or position() mod 2 = 0)意味着我们想要检查此节点是否也在第一个索引处索引 position 的模数 2 等于 0 ‡‡‡

在此处输入图像描述

B2中的公式:

=IFERROR(FILTERXML("<t><s>"&SUBSTITUTE(A2," ","</s><s>")&"</s></t>","//s[.*0=0][string-length()=4][position() = last() and (position() = 1 or position() mod 2 = 0)]"),"")

虽然以上内容适用于 Excel 2013 及更高版本‡‡‡‡ ,但您确实在谈论溢出行为。 如果您碰巧在 ms365 中使用当前频道,您也可以尝试:

=LET(x,TEXTSPLIT(A2," "),y,--FILTER(x,ISNUMBER(-(x&"**0"))*(LEN(x)=4),{1,2,3}),z,COUNT(y),IF(OR(z=1,MOD(z,2)=0),TAKE(y,,-1),""))

如果'count < 3' 如果你需要简单地返回最后一年,那么你可以使用 xpath "//s[.*0=0][string-length()=4][position()<3 and position() = last()]"或 ms365 公式=LET(x,TEXTSPLIT(A2," "),y,FILTER(x,ISNUMBER(-(x&"**0"))*(LEN(x)=4),""),IF(COUNTA(y)>2,"",TAKE(y,,-1)))

‡‡请注意,如果您希望验证年份介于 1900-2050 左右之间,则可以对此更加严格。 可以用[.*1>1899][.*1<2051]替换第一个和第二个谓词。

‡‡‡请注意,在 xpath 中的顺序或书写您的和/或陈述重要。 我们需要使用显式括号来控制优先级。 看到这个

‡‡‡‡这不适用于 Excel 在线或 Excel Mac

您可以使用TEXTAFTER function 尝试以下操作。假设您在末尾使用空格分隔年份。 如果不是这种情况,可以修改公式以进行额外检查(它是一个数字和四位数,但严格来说年份可以少于或多于 4 位数)。 让我知道之前的假设是否不适用,以便我尝试对其进行调整。 以下是数组版本,因此如果您使用 excel 个表,则可以使用整个表列:

=LET(in,A2:A4,last,TEXTAFTER(in," ",-1),
 IF(ISNUMBER(1*TEXTAFTER(SUBSTITUTE(in," "&last,"")," ",-1)),"",last))

对于超过一年的情况,去掉找到的最后一年,如果第二次查找是数字,则返回空,否则返回找到的上一年。

excel输出

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM