Excel 跨列唯一
Excel UNIQUE Across Columns
新函数 UNIQUE
是否可以跨多个列使用并将输出溢出到单个列中?
期望的输出是基于 Columns: A, B, & C
中存在的所有值的单个列中的 UNIQUE
个值(示例中的红色重复项)
- 如果我只使用
UNIQUE(A7:C7)
,我会得到一个跨列的溢出范围(这甚至不提供跨列的唯一值,这出乎意料)
- 我也试过
UNIQUE(A2:A6) & UNIQUE(B5:B10) & UNIQUE(C2:C5)
但这只是连接了值(也出乎意料但不相关)
可能有更好的方法,但这里是使用 TEXTJOIN 和 FILTERXML 创建一个数组,您可以在以下位置调用 UNIQUE:
=SORT(UNIQUE(FILTERXML("<t><s>"&TEXTJOIN("</s><s>",TRUE,A1:C6)&"</s></t>","//s")))
TEXTJOIN 确实有字符限制。我们可以使用 INDEX、SEQUENCE 和 FILTER 来解决这个问题:
=SORT(UNIQUE(FILTER(INDEX(A1:C6,MOD(SEQUENCE(COLUMNS(A1:C6)*ROWS(A1:C6),,0),MAX(ROW(A1:C6)))+1,INT(SEQUENCE(COLUMNS(A1:C6)*ROWS(A1:C6),,0)/(MAX(ROW(A1:C6))))+1),INDEX(A1:C6,MOD(SEQUENCE(COLUMNS(A1:C6)*ROWS(A1:C6),,0),MAX(ROW(A1:C6)))+1,INT(SEQUENCE(COLUMNS(A1:C6)*ROWS(A1:C6),,0)/(MAX(ROW(A1:C6))))+1)&""<>"")))
INDEX 创建一个垂直数组,可以先传递给 FILTER 以去除空白,然后传递给 UNIQUE。
不过,这比较复杂,没有字符数限制。
我正在回答此 question,因为它被标记为与此线程重复。您可以直接从 FILTERXML()
公式中获取唯一值,而无需 UNIQUE
函数。因此,您可以将此函数用于非 O365
仅具有 TEXTJOIN()
和 FILTERXML()
函数的情况,例如:Excel2019
.
FILTERXML()
可能会以最佳方式给出您想要的结果。试试下面的公式-
=FILTERXML("<t><s>"&TEXTJOIN("</s><s>",TRUE,B4:D10)&"</s></t>","//s[not(preceding::*=.)]")
Textjoin()
with delimeter </s><s>
将连接指定范围内的所有非空单元格以构造有效的 XML
字符串。
"<t><s>"&TEXTJOIN("</s><s>",TRUE,B4:D10)&"</s></t>"
将构造 XML
字符串以通过 FILTERXML()
公式处理。
XPath
参数 //s
将 return 所有节点,其中 [not(preceding::*=.)]
将仅过滤唯一节点。
- 您可以为将来的数据输入调整范围
B4:D10
,这样无论何时您输入任何文本,它都会自动出现在结果列中。
这里有 JvdV 关于 FILTERXML()
的诊断文章
新答案:
Ms365 的新数组整形函数会有用:
=UNIQUE(TOCOL(A2:C7,3,1))
TOCOL()
会 return 一个包含除错误值或每列 (1) 为空 (3) 值以外的所有值的向量。
旧答案:
使用 Microsoft365 访问 LET()
,您可以使用:
E2
中的公式:
=LET(X,A2:C7,Y,SEQUENCE(ROWS(X)*COLUMNS(X)),Z,INDEX(IF(X="","",X),1+MOD(Y,ROWS(X)),ROUNDUP(Y/ROWS(X),0)),SORT(UNIQUE(FILTER(Z,Z<>""))))
这样,公式就变得很容易 re-usable 因为我们唯一需要更改的参数是对“X”的引用。
就其价值而言,它也可以通过 PowerQuery A.K.A 完成。 Get&Transform,从 Excel2013 年或 add-in 到 Excel 2010 年免费提供。
- Select 您的数据(包括 headers)。转到功能区 > 数据 >“来自 Table/Range”。
- 确认您的数据有 headers 并且 PowerQuery 应该打开。
- 在 PowerQuery 中 select 所有列。转到变换>“转置”。
- Select 再次显示所有列。转到转换>“逆透视列”。
以上也将处理空值。现在:
- Select 属性列并将其删除。
- 对剩余的列进行排序并删除重复项(right-click header >“删除重复项”)。
- 关闭 PowerQuery 并保存更改。
结果table:
M-Code:
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"A Values", Int64.Type}, {"B Values", Int64.Type}, {"C Values", Int64.Type}}),
#"Transposed Table" = Table.Transpose(#"Changed Type"),
#"Unpivoted Columns" = Table.UnpivotOtherColumns(#"Transposed Table", {}, "Attribute", "Value"),
#"Removed Columns" = Table.RemoveColumns(#"Unpivoted Columns",{"Attribute"}),
#"Sorted Rows" = Table.Sort(#"Removed Columns",{{"Value", Order.Ascending}}),
#"Removed Duplicates" = Table.Distinct(#"Sorted Rows")
in
#"Removed Duplicates"
您可以使用我存储库中的 DM_ARRAY
函数:VBA-ArrayTools。有一个演示工作簿可用,您会发现每个用户定义函数 (UDF) 都有一个专用工作表。对于 DM_ARRAY
,第一个参数是您想要作为输出的列数,然后您可以根据需要传递任意数量的范围。在您的情况下,您可以使用 =UNIQUE(DM_ARRAY(1,A2:A6,B5:B10,C2:C5))
.
获得预期的结果
新函数 UNIQUE
是否可以跨多个列使用并将输出溢出到单个列中?
期望的输出是基于 Columns: A, B, & C
中存在的所有值的单个列中的 UNIQUE
个值(示例中的红色重复项)
- 如果我只使用
UNIQUE(A7:C7)
,我会得到一个跨列的溢出范围(这甚至不提供跨列的唯一值,这出乎意料) - 我也试过
UNIQUE(A2:A6) & UNIQUE(B5:B10) & UNIQUE(C2:C5)
但这只是连接了值(也出乎意料但不相关)
可能有更好的方法,但这里是使用 TEXTJOIN 和 FILTERXML 创建一个数组,您可以在以下位置调用 UNIQUE:
=SORT(UNIQUE(FILTERXML("<t><s>"&TEXTJOIN("</s><s>",TRUE,A1:C6)&"</s></t>","//s")))
TEXTJOIN 确实有字符限制。我们可以使用 INDEX、SEQUENCE 和 FILTER 来解决这个问题:
=SORT(UNIQUE(FILTER(INDEX(A1:C6,MOD(SEQUENCE(COLUMNS(A1:C6)*ROWS(A1:C6),,0),MAX(ROW(A1:C6)))+1,INT(SEQUENCE(COLUMNS(A1:C6)*ROWS(A1:C6),,0)/(MAX(ROW(A1:C6))))+1),INDEX(A1:C6,MOD(SEQUENCE(COLUMNS(A1:C6)*ROWS(A1:C6),,0),MAX(ROW(A1:C6)))+1,INT(SEQUENCE(COLUMNS(A1:C6)*ROWS(A1:C6),,0)/(MAX(ROW(A1:C6))))+1)&""<>"")))
INDEX 创建一个垂直数组,可以先传递给 FILTER 以去除空白,然后传递给 UNIQUE。
不过,这比较复杂,没有字符数限制。
我正在回答此 question,因为它被标记为与此线程重复。您可以直接从 FILTERXML()
公式中获取唯一值,而无需 UNIQUE
函数。因此,您可以将此函数用于非 O365
仅具有 TEXTJOIN()
和 FILTERXML()
函数的情况,例如:Excel2019
.
FILTERXML()
可能会以最佳方式给出您想要的结果。试试下面的公式-
=FILTERXML("<t><s>"&TEXTJOIN("</s><s>",TRUE,B4:D10)&"</s></t>","//s[not(preceding::*=.)]")
Textjoin()
with delimeter</s><s>
将连接指定范围内的所有非空单元格以构造有效的XML
字符串。"<t><s>"&TEXTJOIN("</s><s>",TRUE,B4:D10)&"</s></t>"
将构造XML
字符串以通过FILTERXML()
公式处理。XPath
参数//s
将 return 所有节点,其中[not(preceding::*=.)]
将仅过滤唯一节点。- 您可以为将来的数据输入调整范围
B4:D10
,这样无论何时您输入任何文本,它都会自动出现在结果列中。
这里有 JvdV 关于 FILTERXML()
的诊断文章
新答案:
Ms365 的新数组整形函数会有用:
=UNIQUE(TOCOL(A2:C7,3,1))
TOCOL()
会 return 一个包含除错误值或每列 (1) 为空 (3) 值以外的所有值的向量。
旧答案:
使用 Microsoft365 访问 LET()
,您可以使用:
E2
中的公式:
=LET(X,A2:C7,Y,SEQUENCE(ROWS(X)*COLUMNS(X)),Z,INDEX(IF(X="","",X),1+MOD(Y,ROWS(X)),ROUNDUP(Y/ROWS(X),0)),SORT(UNIQUE(FILTER(Z,Z<>""))))
这样,公式就变得很容易 re-usable 因为我们唯一需要更改的参数是对“X”的引用。
就其价值而言,它也可以通过 PowerQuery A.K.A 完成。 Get&Transform,从 Excel2013 年或 add-in 到 Excel 2010 年免费提供。
- Select 您的数据(包括 headers)。转到功能区 > 数据 >“来自 Table/Range”。
- 确认您的数据有 headers 并且 PowerQuery 应该打开。
- 在 PowerQuery 中 select 所有列。转到变换>“转置”。
- Select 再次显示所有列。转到转换>“逆透视列”。
以上也将处理空值。现在:
- Select 属性列并将其删除。
- 对剩余的列进行排序并删除重复项(right-click header >“删除重复项”)。
- 关闭 PowerQuery 并保存更改。
结果table:
M-Code:
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"A Values", Int64.Type}, {"B Values", Int64.Type}, {"C Values", Int64.Type}}),
#"Transposed Table" = Table.Transpose(#"Changed Type"),
#"Unpivoted Columns" = Table.UnpivotOtherColumns(#"Transposed Table", {}, "Attribute", "Value"),
#"Removed Columns" = Table.RemoveColumns(#"Unpivoted Columns",{"Attribute"}),
#"Sorted Rows" = Table.Sort(#"Removed Columns",{{"Value", Order.Ascending}}),
#"Removed Duplicates" = Table.Distinct(#"Sorted Rows")
in
#"Removed Duplicates"
您可以使用我存储库中的 DM_ARRAY
函数:VBA-ArrayTools。有一个演示工作簿可用,您会发现每个用户定义函数 (UDF) 都有一个专用工作表。对于 DM_ARRAY
,第一个参数是您想要作为输出的列数,然后您可以根据需要传递任意数量的范围。在您的情况下,您可以使用 =UNIQUE(DM_ARRAY(1,A2:A6,B5:B10,C2:C5))
.