[已解决] 请教:query或pivot增加一列,用于将某列的全角字符改为半...

  [复制链接]
查看207716 | 回复166 | 2020-8-5 09:13:39 | 显示全部楼层 |阅读模式
query或pivot导入表中,有一列供应商名称列,里面既有全角字符也有半角字符,例如XX(集团 全角括号)XX公司、XX(有限半角括号)公司。而需要进行关联的另一张表(例如银行对账单)的单位的全角半角状态不同,造成不能匹配供应商。
我原来在sheet表中新建1列,通过ASC函数将所有单位名称均转换成半角后,进行匹配。但学习PQ和PP过程中,发现似乎没有ASC函数。
我觉得:似乎可以使用text.replace能够指定字符转换,但存在2个疑问:1、转换2个以上字符串的是不是需要增加多个辅助列保存前次转换结果,而我不想添加辅助列。2、使用text.replace的前提是知道要转换谁,但供应商名称可能存在许多全角字符(除汉字外,其他的字母、数字、标点符号等均可能是全角或半角状态),我甚至都意识不到,那么就无法指定字符转换。
因此请教:用什么命令或函数,能像ASC函数那样将字符串一次性转换成半角?或者一次性全部转换成全角也行。
谢谢!
回复

使用道具 举报

XYFHID | 2020-8-5 09:18:39 | 显示全部楼层
用PQ先转换一下,这个方法只是权宜之计。

全角符号对应的编码是65281-65374,所一一对应的半角符号的编码是33-126,刚好相差65248。
最小的全角符号是65281,对应"!"
但是,全角空格除外,编码是12288,对应的半角空格是32。
所以,可以变通处理一下。举例如下:
  1. = let s="??123123 ! !??!!??(有限公司).,"

  2. in List.Accumulate(Text.ToList(s),"",(s,c)=>s&Character.FromNumber(Character.ToNumber(c)-65248*Byte.From(c>="!")))
复制代码
这个应该可以处理除了全角空格之外的全角字符。有全角空格的话加if else 单独处理。
供参考。
回复

使用道具 举报

woodbine | 2020-8-5 09:24:40 | 显示全部楼层
d:\QQ图片20190116111316.png
回复

使用道具 举报

蓝精灵 | 2020-8-5 09:31:40 | 显示全部楼层
用PQ先转换一下,这个方法只是权宜之计。

全角符号对应的编码是65281-65347,所一一对应的半角符号的编 ...


非常感谢!不过我刚接触PQ和PP,也没地方系统学习M和DAX语言,只是自己摸索测试。目前只知道letin 结构的表达式在“应用的步骤”中的对应步骤的公式输入行或者启动高级编辑器中可以看到或改写。还不清楚您写的表达式怎么用,在上述地方录入后结果不是期望的。根据以往编程经验,似乎是定义了一个函数、参数为s,却没有函数名称,所以又不像;在新增列的表达式里将s改为[供应商名称]字段录入,语法是错误的。不知要在哪里录入使用?
不过,在开始菜单的转换区块有个“替换值”按钮,选中,{"供应商纯名"}的新增列后,点击按钮,用"*"替换全角左括号"("、 用"**"替换全角右括号")",倒是没用辅助列就在1列中完成2个替换。不知这个替换表达式能否结合您的思路,制作全能转换表达式?

替换的值 = Table.ReplaceValue(增加供应商纯名,"(","*",Replacer.ReplaceText,{"供应商纯名"}),
替换的值1 = Table.ReplaceValue(替换的值,")","**",Replacer.ReplaceText,{"供应商纯名"})

奇怪的是,图片传不上去,只是一样地址。
回复

使用道具 举报

lc3662018 | 2020-8-5 09:35:40 | 显示全部楼层
用PQ先转换一下,这个方法只是权宜之计。

全角符号对应的编码是65281-65347,所一一对应的半角符号的编 ...


按照你这思路我弄个半全角的列表。方便互换。
let
  s="??123123 ! !??!!??(有限公司).,",
  半角字符 = List.Transform({32..126},each Character.FromNumber(_)),
  全角字符 = {Character.FromNumber(12288)} & List.Transform({33..126},each Character.FromNumber( _ + 65248)),
  res=List.ReplaceMatchingItems(Text.ToList(s),List.Zip({全角字符,半角字符}))
in
  Text.Combine(res)
回复

使用道具 举报

cowboy | 2020-8-5 09:40:40 | 显示全部楼层
这样能看明白一点
  1. = Table.AddColumn(源,"全TO半",each List.Accumulate( Text.ToList([供应商名字]),"",(s,c)=>s&Character.FromNumber(Character.ToNumber(c)-65248*Byte.From(c>="!"))))
复制代码
9727011651151.jpg
回复

使用道具 举报

威猛凛凛 | 2020-8-5 09:43:41 | 显示全部楼层
或者,直接在那一列上处理
  1. = Table.TransformColumns(源,{"供应商名字",each List.Accumulate( Text.ToList(_),"",(s,c)=>s&Character.FromNumber(Character.ToNumber(c)-65248*Byte.From(c>="!")))})
复制代码
9727011651152.jpg
回复

使用道具 举报

笑死人 | 2020-8-5 09:50:41 | 显示全部楼层
非常感谢!不过我刚接触PQ和PP,也没地方系统学习M和DAX语言,只是自己摸索测试。目前只知道letin 结构 ...


你新建一个查询,进入高级编辑器,先清空,然后复制粘贴以下语句
运行后,看看里边的步骤,你就明白了。
因为没有数据源,里边的源是我自己编了一个table。你可以对照处理。
  1. let

  2.   源 = #table({"供应商名字"},{{"??123123 ! !??!!??(有限公司).,"}}),

  3.   全TO半 = Table.TransformColumns(源,{"供应商名字",each List.Accumulate( Text.ToList(_),"",(s,c)=>s&Character.FromNumber(Character.ToNumber(c)-65248*Byte.From(c>="!")))})

  4. in

  5.   全TO半
复制代码
回复

使用道具 举报

yuxianglin | 2020-8-5 09:54:41 | 显示全部楼层
按照你这思路我弄个半全角的列表。方便互换。
let
  s="??123123 ! !??!!??(有限公司). ...


可以可以,谢谢范佬大。
回复

使用道具 举报

车迷 | 2020-8-5 10:02:41 | 显示全部楼层
完善一下全角变半角:

  1. = let str ="??123123 ! !??!!??(有限公司).,"



  2. in List.Accumulate( Text.ToList(str),

  3.         "",

  4.        (s,c)=>s & Character.FromNumber( {32,Character.ToNumber(c)}{Byte.From(c" ")}-65248*Byte.From(c>="!") ) )
复制代码
9727011651153.jpg
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则