在一系列单元格中获取 5 个最常见的分隔子字符串

Zev*_*itz 3 excel vba

我有一个 Excel 工作表,每个单元格内都有子字符串,以#. 例如:

一种 C
F #G #H #I #J #K #L M#N#O#P A#B#C#D#E
F #G #H #I 无#O#P A#B#C##E

如何在单元格范围内找到 5 个最常见的子字符串?

示例数据的预期输出应如下所示:

子串 数数
一种 2
2
C 2
2
F 2

Jvd*_*vdV 5

如果可以访问 Microsoft365 的LET()功能,则可以使用以下功能组合来完成:

在此处输入图片说明

公式E1

=LET(X,SORT(TRIM(FILTERXML("<t><s>"&SUBSTITUTE(TEXTJOIN("#",,A1:C2),"#","</s><s>")&"</s></t>","//s[.!='']"))),INDEX(SORT(CHOOSE({1,2},UNIQUE(X),MMULT(--(UNIQUE(X)=TRANSPOSE(X)),SEQUENCE(COUNTA(X),,,0))),2,-1),{1;2;3;4;5},{1,2}))
Run Code Online (Sandbox Code Playgroud)

解释:

LET()允许在公式中使用可重复使用的变量。所以在上面我们分配了一个值数组并将其命名为“X”。数组被拉取:

=SORT(TRIM(FILTERXML("<t><s>"&SUBSTITUTE(TEXTJOIN("#",,A1:C2),"#","</s><s>")&"</s></t>","//s[.!='']")))
Run Code Online (Sandbox Code Playgroud)

在哪里:

  • "<t><s>"&SUBSTITUTE(TEXTJOIN("#",,A1:C2),"#","</s><s>")&"</s></t>" - 用于创建有效的 XML 字符串;
  • "//s[.!='']" - 检索所有非空字符串的有效 xpath。
  • TRIM()将删除任何前导和尾随空格。SORT()然后对数组进行升序排序。

如果您想了解更多关于使用 将字符串“拆分”为元素的机制FILTERXML(),您可以在此处阅读。

现在我们有了一个变量,我们可以在里面的第三个参数中使用它LET()

=INDEX(SORT(CHOOSE({1,2},UNIQUE(X),MMULT(--(UNIQUE(X)=TRANSPOSE(X)),SEQUENCE(COUNTA(X),,,0))),2,-1),{1,2,3,4,5},{1;2})
Run Code Online (Sandbox Code Playgroud)

使用INDEX()我们可以从数组中“切片”行/列,其中:

  • SORT(CHOOSE({1,2},UNIQUE(X),MMULT(--(UNIQUE(X)=TRANSPOSE(X)),SEQUENCE(COUNTA(X),,,0))),2,-1)- 有点复杂的构造,但这里的想法是CHOOSE({1,2}允许使用 2D 数组,其中第一列填充UNIQUE()来自“X”的值,第二列是总数组中每个唯一元素的计数。计数是使用MMULT()每个唯一元素针对TRANSPOSE()'d“X”进行计数的地方完成的。然后二维数组在第二列上排序。

有了上面的方法,我们可以简单地使用以下INDEX()方法检索我们需要的 5 行(和两列):

=INDEX(<TheAbove>,{1;2;3;4;5},{1,2})
Run Code Online (Sandbox Code Playgroud)