LET/LAMBDA 方法
这需要Excel 365。公式为:
=LET( upValues, C3:N7, upHdr, C2:N2, upAttr, C1:N1,
byBody, A3:B7, byHdr, A2:B2,
attrTitle, "month",
upFields, UNIQUE( upHdr,1 ), blockSize, COUNTA( upFields ),
byC, COLUMNS( byBody ), upC, COLUMNS( upValues ),
dmxR, MIN( ROWS( upValues ), ROWS( byBody ) ),
upCells, dmxR * upC/blockSize,
tCSeq, SEQUENCE( 1, byC + 1 + blockSize ), tRSeq, SEQUENCE( upCells + 1,, 0 ), upSeq, SEQUENCE( upCells,, 0 ),
hdr, IF( tCSeq <= byC, INDEX( byHdr, , tCSeq ),
IF( tCSeq = byC + 1, attrTitle,
INDEX( upFields, 1, tCSeq - byC - 1 ) ) ),
muxBody, INDEX( byBody, SEQUENCE( upCells, byC, 0 )/byC/upC*blockSize + 1, SEQUENCE( 1, byC ) ),
muxAttr, INDEX( upAttr, MOD( SEQUENCE( upCells,, 0, blockSize ), upC ) + 1 ),
muxValues, INDEX( upValues, SEQUENCE( upCells, blockSize, 0 )/upC+1, MOD(SEQUENCE( upCells, blockSize, 0 ),upC)+1),
table, IF( tCSeq <= byC, muxBody,
IF( tCSeq = byC + 1, muxAttr,
INDEX( muxValues, upSeq + 1, tCSeq - byC - 1 ) ) ),
IF( tRSeq = 0, hdr, INDEX( table, tRSeq, tCSeq) ) )
这需要 6 个变量:
- upValues - 将在块中逆透视的数据
- upHdr - 包含 PTHC 值的标题行
- upAttr - 将取消透视的属性,即月份行
- byBody - 将反转值的值主体,即 State 和 City 值
- byHdr - byBody 的标头(标题“State”和“City”)
- attrTitle - 将取消透视的属性的可选标题
在此图中可以更好地理解这些内容:
![input table structure](https://i.stack.imgur.com/1G2Ev.png)
为了更容易理解,这里给出了测试数据和显示的结果:
![result](https://i.stack.imgur.com/dkDyX.png)
上面的输出也可以说明:
![output parts](https://i.stack.imgur.com/7blBX.png)
红色文本是用于构造结果的内部变量。
该公式由 5 个部分组成,如下所示:
![parts](https://i.stack.imgur.com/370tS.png)
测量尺寸很明显 - 它只是参数化稍后将重复使用的变量。dmxR使用 upValues 或 byBody 行的 MIN 以防用户意外输入格式错误的值和 byBody,否则会导致无意义的输出。
构建序列创建三个用于索引输入和输出的序列:
-
tCSeq(表列序列)是按列调整大小的序列,最终输出表将具有 byBody + 属性(月份)+ 值(块大小)列。
-
tRSeq(表行序列)是一个按行序列,其大小适合最终输出表,该表将具有 dmxR*upC/blocksize + 1 (hdr) 行。
-
upSeq(unpivot 序列) 是一个按行序列,其大小适合最终输出表,该表将具有 dmxR*upC/blocksize 行(无标题)。
创建数组组件使用上面的维度和序列来构造输出表的各个部分。
-
hdr(header) 是带有标签(州和城市)、属性标题(月份)和字段名称 (PTHC) 的新标题。
-
muxBody(多路复用 byBody)是跨 dmxR 行多路复用的 byBody 的重复。
-
muxAttr(多路复用的 upAttr) 是跨 dmxR 行多路复用的 upAttr 的重复。
-
mux值(多路复用的 upValues) 是按块重复,将具有 dmxR*upC/blocksize 行。
最后两行stitch零件在一起。第一的,table缝针muxBody, muxAttr and mux值在逐列积分中使用tCSeq以及使用行式多路复用upSeq.
只是因为它在心理上更容易(并且更容易测试),我将行式集成分开(使用tRSeq) 的hdr到table在最后一行。
使用 IF 语句拼接的另一种方法是使用 IFERROR(INDEX ,它会强制出现错误,然后用表的下一部分替换错误,但这很难测试和调试,即使它只是按行或按列. 把row-wise和column-wise组合起来,就是一个cauchemar。