ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
楼主: shaowu459

[分享] Microsoft 365:X檔案大揭秘

  [复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2023-4-16 22:22 | 显示全部楼层
本帖已被收录到知识树中,索引项:LAMBDA
=REDUCE(初始值,A1:A20,LAMBDA(x,y,LET(s,@TAKE(x,-1),t,s=y,VSTACK(DROP(x,-t),IF(t,数组1,数组2)))))

这个公式可以说是上楼公式的变形,也是非常常见的用法之一。具体解释如下:
1)LET函数定义一个s,s是x最后一行的第一个值,也即s=@TAKE(x,-1)。
2)定义一个t,t判断s是否等于当前的y,返回TRUE或FALSE。
3)DROP(x,-t)部分,如果t是TRUE,也就意味着当前的y和X最后一行的第一个值相等,也就是连续出现,因此,就需要将X最后一行DROP掉。如果t是FALSE,则不需要DROP掉X的最后一行。
4)IF部分,判断如果t是TRUE,就返回基于X最后一行计数部分+1的结果;如果t是FALSE就返回类似HSTACK(OFFSET(y,,,,4),1)的数组。
5)最后用VSTACK函数将步骤4和步骤5生成的数组堆叠在一起。

图片.png

评分

2

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2023-4-16 22:25 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
根据实际需要,可以给X的初始值赋予0值、常量数组、引用单元格区域、结果标题行等等。

图片.jpg

TA的精华主题

TA的得分主题

 楼主| 发表于 2023-4-16 22:45 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
某些情况下,可以先直接用VSTACK函数将X和新数组堆叠在一起,是否需要删除最后一行用条件判断,并作为DROP函数的第二参数。满足条件,就DROP掉-1行,否则DROP掉0行。

图片.png

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2023-4-16 22:50 | 显示全部楼层
本帖最后由 shaowu459 于 2023-4-16 22:52 编辑

=DROP(REDUCE(T1:W2,数组,LAMBDA(x,y,…DROP(x,-1)
如果LAMBDA函数体部分设计了DROP(x,-1)部分,假设第一个y不满足条件,需要执行去掉X最后一行的时候,假设REDUCE函数第一参数只有1行,去掉最后1行后就会出错。这个时候,可以考虑给初始值X设定为一个2行的数组,这样哪怕是第一次循环时执行DROP掉最后一行的操作,也不会出错。
图片.png

更常见的一种情况是=DROP(REDUCE(0,数组,LAMBDA(x,y,…)),1),为X设定任意一个单值作为初始值,因为最后没用,所以使用DROP函数去掉第一行。

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2023-4-16 23:00 | 显示全部楼层
在循环过程中,更新X中的某个值。

例如,以下公式根据B3:C9单元格区域判断姓名出现的次数(请忽略此例子的实际意义)。
  1. =REDUCE({"姓名","次数"},B4:B9,LAMBDA(x,y,IF(OR(x=y),IF(TAKE(x,,1)=y,HSTACK(y,VLOOKUP(y,x,2,)+1),x),VSTACK(x,HSTACK(y,1)))))
复制代码
图片.png

上述公式运算过程说明(假设当前y值为姓名“A”):
1)OR(x=y)部分判断当前的人A是否在X中出现过。
2)如果A在X中出现过,则更新X中对应姓名后的次数数值。当TAKE(x,,1)=y,也就是第一列姓名=当前的姓名A时,返回{A,在X中查找A返回对应的次数值+1}的数组,否则,仍然保留X不变。这样就将X中A这个人对应的次数更新为原值+1的结果。
3)如果A在X中没有出现过,就直接在X下面堆积HSTACK(y,1)={"A",1}的结果。

评分

2

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2023-4-16 23:07 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 shaowu459 于 2023-4-16 23:08 编辑

在连续问题的统计上,使用当前的y和X最后一行的值比较,判断是否连续,以采取不同的操作。

以下公式,根据B4:C11单元格区域的值,返回连续值姓名对应金额汇总的目的(人员可以多次出现,例如B)。

  1. =REDUCE({"姓名","合计"},B4:B11,LAMBDA(x,y,IF(@TAKE(x,-1)=y,VSTACK(DROP(x,-1),HSTACK(y,SUM(TAKE(x,-1))+OFFSET(y,,1))),VSTACK(x,OFFSET(y,,,,2)))))
复制代码
图片.jpg

公式运算过程说明如下:
1)@TAKE(x,-1)=y部分判断当前姓名是否和X最后一行的人员一致。
2)如果一致,把X的最后1行DROP掉,下面堆积上HSTACK(y,SUM(TAKE(x,-1))+OFFSET(y,,1)))这个结果。HSTACK第一参数是当前人员姓名,第二参数是最后一行的数字+当前人员对应右侧的金额合计。也即实现了更新了最后一行人员对应金额的目的。
3)如果不一致,也就是不再连续了,直接在X下面堆积上当前人员姓名和右侧对应金额。

如果不需要标题,可以给REDUCE函数的X初始值设置为0,最后再将结果第一行DROP掉即可。

图片.png

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2023-4-16 23:13 | 显示全部楼层
LAMBDA函数运算体部分,可以直接对X整体进行计算或统计。

例如,以下公式可以实现将B3:C11单元格区域数据按班级将名称汇总在一个单元格,同时每个班级之前加上序号的效果。

  1. =REDUCE({"序号","班级","姓名"},UNIQUE(B4:B11),LAMBDA(x,y,VSTACK(x,HSTACK(ROWS(x),y,TEXTJOIN("、",,FILTER(C4:C11,B4:B11=y))))))
复制代码
图片.jpg


上述公式中,X初始值是标题行,行数是1,当循环到A班级时,ROWS(X)返回1,可以给A班级当编号;当循环到B班级时,此时X中有标题行和A班级的数据,是2行,因此可以给B班级当编号。后面以此类推。

除了用ROWS函数获取X行数之外,如果X中除了某列都是文本,可以直接用SUM(X)求合计值、MAX(X)求最大值、COUNTA(X)求数据总个数等等。


TA的精华主题

TA的得分主题

 楼主| 发表于 2023-4-16 23:24 | 显示全部楼层
X可以是一个随着循环持续增长或变化的单值,LAMBDA函数体每次运算时可以从X这个单值中提取部分数据来运算。例如将X按分隔符拆分后统计元素个数、提取最后一个分隔符之后的内容、提取第一个分隔符之前的内容等等。

以下公式将B列包含重复字符的字符串中的内容编号:

  1. =MID(REDUCE(0,TEXTSPLIT(B4,"-"),LAMBDA(x,y,x&"-"&y&ROWS(TEXTSPLIT(x,,y)))),3,99)
复制代码

图片.png

上述公式中,X初始值设置为0,每次循环时用X连接y值及y在X中出现的次数+1的结果。因为初始值为0,因此REDUCE函数运算完后返回类似“0-C1-A1-F1-A2-K1-C2-J1-L1”的字符串,从第3个字符开始是需要的内容,因此使用MID函数从第3个字符提取足够长的字符串即可。

同时,如果每次运算时都要用某个中间值来判断,如果不想堆叠数组,可以考虑类似“临时值|结果数据”的方法,每次把临时值都存储在分隔符的竖线左侧,在LAMBDA函数体运算时,可以使用TEXTBEFORE函数提取出临时值和当前的y值运算并更新分隔符竖线之后的结果,然后再次合并。如果是纯数字运算,也可以用“临时值数字.结果数据”的方法,X维持一个带小数点的数字,整数部分是临时值,小数部分是结果数字。这种方法仅是实际使用的一种可能,实际没有必要如此运算,堆叠数组就可以了。


评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2023-4-16 23:27 | 显示全部楼层
X可以是一个数组,并且可以在每次运算时直接更新整个数组的所有值。

下面的公式实现将B4:B6单元格区域字符串根据F:G列关键字替换列表替换值的目的。

  1. =REDUCE(B4:B6,F5:F7,LAMBDA(x,y,SUBSTITUTE(x,y,VLOOKUP(y,F5:G7,2,))))
复制代码
图片.png
公式中,REDUCE函数的第一参数X初始值是B4:B6单元格区域,LAMBDA函数体每次运算时,直接一次性将X中的3个值某个关键字一起替换掉,多次循环后,X中的关键字均被替换完毕。


评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2023-4-16 23:30 | 显示全部楼层
X的初始值可以是根据实际情况手动录入的常量数组。

以下公式返回斐波那契数列的前7项内容,每一项是前两项的合计。

  1. =REDUCE({1;1},ROW(1:5),LAMBDA(x,y,VSTACK(x,SUM(TAKE(x,-2)))))
复制代码

图片.png
公式中X初始值是数列的前两项,也即{1;1},第二参数有5个元素,因此循环5次。每次循环时使用TAKE函数提取X最后两列并求和,求和结果纵向堆叠在当前X的下方。


评分

1

查看全部评分

您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-15 14:42 , Processed in 0.051365 second(s), 6 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表