ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[转帖] 看不懂系列:Table.ReplaceValue函数

[复制链接]

TA的精华主题

TA的得分主题

发表于 2022-2-15 10:15 | 显示全部楼层 |阅读模式



Clipped from: http://www.360doc.com/content/20/0823/10/13664199_931753931.shtml





看到前面有大神使用了Table.ReplaceValue的神奇用法,特意在baidu上搜索了一下,下面一个帖子,一步一步的讲解带领大家熟悉使用该函数.






一、基础介绍
Table.ReplaceValue函数实现的功能是将Table中的值替换成新值,语法翻译成汉语大致如下:
Table.ReplaceValue(要替换的Table, 要被替换的旧值oldValue, 要替换成的新值newValue, 替换规则函数, 在Table的哪列里替换)
我们首先可以通过基础操作来看一下替换效果。如下有一个Table,是不同的店仓编号对应的库存数量,要求将第一列“店仓编号”中的字母A替换成“仓库”两个字。
01.jpg
选中第一列,点击【转换】-【替换值】,第一个对话框输入A,也就是要查找A,第二个对话框中输入“仓库”,也就是要被替换成的值,点击确定后可以看到第一列中的A都被替换成了“仓库”两个字。
02.jpg
生成的函数如下:
= Table.ReplaceValue(Source,'A','仓库',Replacer.ReplaceText,{'店仓编号'})
其意思是,在Source这个Table的{'店仓编号'}里查找“A”这个字母,替换成“仓库”,替换方式为Replacer.ReplaceText,也就是替换文本。
03.jpg
因为刚才要替换的值是文本,所以替换方式为Replacer.ReplaceText,字符串中的A都被替换成“仓库”。
如果在刚才的替换界面勾选【单元格匹配】(上图中的步骤4),替换方式会变成Replacer.ReplaceValue,由于没有完全匹配的,因此替换不会成功。如果要替换的是null等非文本的,就必须要用Replacer.ReplaceValue了。如果单元格中仅有A这个字符,则可被替换为“仓库”,如下图所示:
04.jpg
如果想在多列里替换呢,在最后一个参数中添加对应的列名即可。如下图,要在第一列、第三列里都把A替换成“仓库”,最后一个参数改成{'店仓编号',  '店仓编号2'}就可以了。
05.jpg
= Table.ReplaceValue(Source,'A','仓库',Replacer.ReplaceText,{'店仓编号',  '店仓编号2'})二、基础细节进一步介绍
对基础用法了解之后,通过下面的例子介绍一些细节内容。如下图,第一列是级别,后面是不同子级别,分别为级别后面加上001、002、003等,没有的子级别为空(null)。
10.jpg
以下函数会将各个子级别中为null的替换成“无内容”字符串。替换逻辑为:第二参数被替换值为null,第三参数为要替换成的新值“无内容”这三个字。其中Table.ColumnNames(Source)获得标题名称的List,用List.Skip去掉第一个标题后获得包含所有子级别名称的List。

= Table.ReplaceValue(Source,null,'无内容',Replacer.ReplaceValue,List.Skip(Table.ColumnNames(Source)))
07.jpg

以下函数会将各个子级别中为空的替换成“级别”对应的文本。替换逻辑为:被替换值为null,要替换成的内容为each [级别](也即每一行对应的[级别]内容)。
= Table.ReplaceValue(Source,null,each [级别],Replacer.ReplaceValue,List.Skip(Table.ColumnNames(Source))) 09.jpg
将null改成each null结果和上面的一样:
= Table.ReplaceValue(Source,each null,each [级别],Replacer.ReplaceValue,List.Skip(Table.ColumnNames(Source)))
如下代码将子级别1的每个元素替换成“级别”中对应的值,相当于将级别那一列复制到子级别1的那一列。
= Table.ReplaceValue(Source,each [子级别1],each [级别],Replacer.ReplaceValue,{'子级别1'})
如下代码将子级别1的每个元素替换成“替换测试”字符串。
= Table.ReplaceValue(Source,each [子级别1],'替换测试',Replacer.ReplaceValue,{'子级别1'})
11.jpg
三、进阶内容介绍
重新回顾一下Table.ReplaceValue函数的各个参数:

Table.ReplaceValue(table as table, oldValue as any, newValue as any, replacer as function, columnsToSearch as list)
可以看到,被替换值可以是任意类型,替换的新值也可以是任意类型,并且替换规则是个函数,这样Table.ReplaceValue的函数应用就不仅仅限于替换个别字符串或文本了。

首先来看一下第四参数,上面用到的是Replacer.ReplaceValue这个函数,这个函数属于替换器函数,语法如下:
Replacer.ReplaceValue(value as any, old as any, new as any) as any
它的功能是将old值替换成新值new,将其放入Table.ReplaceValue函数后可以将Table.ReplaceValue函数改写成以下形式:
Table.ReplaceValue(table as table, oldValue as any, newValue as any, (value,old,new)=>函数表达式, columnsToSearch as list)
其中(value,old,new)=>函数表达式是一个三参数的函数,一般也写成(x,y,z)=>函数表达式,其中z代表newValue,y代表oldValue,x代表包含要被替换值的数据,下面通过一些例子来说明。
示例一:成绩表
12.jpg
有如上两次考试成绩记录,第2次考试有些人缺考,成绩处为null。
下面的代码将第2次考试中为null的改为“缺考”,有成绩的改成“参考”。代码中的y代表第二参数each [2次],也就是第2次考试中的每个值,如果y是数值(number)就返回“参考”,否则返回“缺考”(这里z代表“参考”但未引用z)。
= Table.ReplaceValue(Source,each [2次],'缺考',(x,y,z)=>if y is number then '参考' else '缺考',{'2次'}) 13.jpg
将“缺考”改成z,返回结果一样。也就是说一定条件下替换时可以不去引用所有的xyz。
14.jpg
下面的代码第2次考试中有成绩的改成999,没有成绩的改成“缺考”。其中z代表第三参数“缺考”的文本,y代表999,x代表第2次那一列(因为最后一个参数为{'2次'},代表要在2次那列里去判断,所以x就代表第2次那一列的值)每个要去判断是否要替换的值。替换逻辑是:x如果是null(也就是第2次那列是null),就返回z(“缺考”),否则返回y(999)。
= Table.ReplaceValue(Source,999,'缺考',(x,y,z)=>if x is null then z else y,{'2次'})
15.jpg
下面的代码中y=“不及格”,z=“缺考”,x代表1次、2次那两列中要判断是否替换的值。判断替换的逻辑是:如果x(第1次、2次中的值)是null就返回z(缺考)。如果不是null,如果x大于等于60就替换成“及格”,否则替换成y(不及格)。
= Table.ReplaceValue(Source,'不及格','缺考',(x,y,z)=>if x is null then z else if x >=60 then '及格' else y,{'1次','2次'}) 16.jpg
下面再看个判断是否及格的例子,再次说明可以不引用y、z。有如下成绩表,科目大于等于60的返回T,小于60不及格的返回F。
17.jpg
具体代码如下,根据x的值是否大于等于60返回T或F。T和F具体在(x,y,z)=>函数规则中作出判断,y设置成0,z设置成1,或者其他的任何值都不影响结果。同时,即使引用y、z也不必原封不动的返回y和z,因为y和z可能是List、Table等(示例二中有说明)。
= Table.ReplaceValue(Source,0,1,(x,y,z)=>if x>=60 then 'T' else 'F',List.Skip(Table.ColumnNames(Source)))
19.jpg
示例二:两个表之间内容的替换
如下图,有一个仓库编号和仓库名称的对应表如下,定义为“对应表”
20.jpg
有一个包含仓库编号、数量的表格如下,定义为“替换表”。要求将第一列的仓库编号替换成仓库名称。
21.jpg
替换代码如下:
= Table.ReplaceValue(替换表,each [店仓编号],对应表,(x,y,z)=>z[店仓名称]{List.PositionOf(z[店仓编号],x)},{'店仓编号'})这里的y代表第2参数each [店仓编号],z代表“对应表”,x代表的是替换表中的【店仓编号】列内容。替换逻辑是:分别判断x在z表的【店仓编号】列的位置,然后返回z表的【店仓名称】对应位置的值。

由于没引用到y,因此y设置成任意值,例如999等,都不影响替换结果:

示例三:将null填充为合计值
如下图,不同仓库数量有汇总行的位置,但是没有合计数,要求将【数量】列中的null替换为该仓库的合计数量。

首先,用Table.Group函数按仓库合并起来,并返回数量合计(表名定义为Group)。
= Table.Group(Source,'店仓编号',{'New',each List.Sum(_[数量])})

然后替换逻辑就和示例二中很相似了,将Group表中的数量填充到原表最后一列的null中即可,代码如下:
= Table.ReplaceValue(Source,each [店仓编号],Group,(x,y,z)=>if x is null then z[New]{List.PositionOf(z[店仓编号],y)} else x,{'数量'})

Table.ReplaceValue函数也属于一个相对强的函数了,在某些时候使用恰当的话能起到奇效。
作者:超人Clark





06.jpg
08.jpg

TA的精华主题

TA的得分主题

发表于 2022-2-16 11:15 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
学习!进阶内容还没有掌握......

TA的精华主题

TA的得分主题

 楼主| 发表于 2022-2-16 11:27 | 显示全部楼层
pxy0409 发表于 2022-2-16 11:15
学习!进阶内容还没有掌握......

跟着教程一步步 试着做了。
理解了就懂了!

TA的精华主题

TA的得分主题

发表于 2022-2-16 11:28 | 显示全部楼层
Table.ReplaceValue(table as table, oldValue as any, newValue as any, (value,old,new)=>函数表达式, columnsToSearch as list)其中(value,old,new)=>函数表达式是一个三参数的函数,一般也写成(x,y,z)=>函数表达式

顿悟了

TA的精华主题

TA的得分主题

发表于 2022-7-5 14:32 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
老厉害啦!学到了,谢谢!
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-11-16 09:37 , Processed in 0.043643 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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