分享

PQ-M及函数:将Excel的列标转成数字

 大海_Power 2021-05-22

小勤:在《单个格式表转换》里提到可以用配置映射表的方式来实现表格数据的提取,比如你以前用VBA程序导数据的那个:

但要在PQ里根据源表内容的位置提取数据的话,得首先知道Excel里表示的位置是那一行那一列啊,也就是说Excel里的列标是“A、B、C……AA、AB……XFD“这样子的,怎么能转成”1……16384“样子的数字呢?

大海:那你的配置表可以设计成直接让用户填哪一行哪一列的。呵呵。

小勤:这倒是可以,不过最好就是能直接让用户按照习惯的单元格表示方式填,然后咱们在PQ里自动转换就更好了。

大海:嗯。的确是这样。那咱们先观察一下Excel的列标有什么规律:首先是1-26个单字母,然后是26个单字母用完后用按顺序用2个字母,然后再用3个字母……

小勤:嗯。规律是比较明显,但怎么能转成数字呢?

大海:其实啊,这是一个26进制……

【已懂进制转换的朋友可略过以下内容】


小勤:26进制……什么鬼?

大海:10进制你懂吧?就是从0到9的10个数字组成,逢10进1……

小勤:这个我懂,但26进制……

大海:10进制因为太习惯了跟日常数量的关系,实际上你抽象一下,0到9也只是一个符号而已,现在的A到Z也是符号,跟0到9是一样一样的,你10个符号就逢10进1,我26个字符就逢26进1。

小勤:那接下来呢?怎么变成数字?

大海:接下来我们看看逢10进1是怎么算数的,然后照搬到26进制里面去。首先前面的0到9就是字符(数字)本身,接下来是10、11……,实际上呢就是:

10 = 1*10+0

11 = 1*10+1

12 = 1*10+2

……

123 = 12*10+3

= 1*10+2)*10+3

小勤:10进制这个还好理解。

大海:那么咱们来看26进制的,如果A代表1,B代表2……Z代表26,然后咱们来试一下:

AA = A*26+A = 1*26+1 =27

AB = A*26+B = 1*26+2 = 28

……

AAA = AA*26+A

=(A*26+A)*26+A

     =(1*26+1)*26+1 = 703

……

XFD =(X*26+F)*26+D

小勤:这就像是从第一个字符开始,乘以进制数,再加上第二个字符,然后再乘以进制数,然后再加上第三个字符……

大海:对的,这就是进制转换的基本方法。搞清楚这个转换方法后,咱们就可以嗨森地转换了。

【如果看完以上进制转换还不懂的,有兴趣的可以在网上搜一些关于二进制、八进制转换的内容来学习,应该会比我写得好。如果没兴趣的,也可以先大概了解,学会后面的代码怎么用即可,毕竟实际工作中需要用到的时候不太多。】


小勤:那首先得将列标分成A-Z的字符内容,然后将A-Z转为1-26个数字,再通过计算得到编号?

大海:对,基本就是这个过程,咱们一步步来,通过操作自己掌握每一步需要用到的函数和方法。

Step-01:数据获取到PQ里后,先将列标里的字符分开,用Text.ToList函数转成List:

=Text.ToList([列标])

Step-02:通过List.Transform函数,将列标所包含的字母的List转为对应的数字List(其中每个字母可通过函数Character.ToNumber转换为对应的编码值,及A-Z对应65-90,用该编码值减去64即可得到A-Z和1-26的对应关系)

= List.Transform(

     [拆分列标字符],

     each Character.ToNumber(_ ) - 64

 )

Step-03:用List.Accumulate函数实现累积(迭代)计算

=List.Accumulate(

    [数字转换],

    0,

    (x,y) => x*26+y

 )

结果就出来了,你检查一下对不对?

小勤:结果是对的,不过List.Transform和List.Accumulate两个函数感觉挺难理解的。

大海:嗯。这两个函数的确是有点儿难的,不过,不要急,后续我会继续专门就这2个函数给你举例子,让你学好它们。

小勤:好的,那我先试试将你分步的公式合成一个并且看看能不能理解。

大海:嗯。合成一步有利于后续转成自定义函数。先试试,有问题咱们再解决问题。



    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多