正常来说,同一层级的数据应该存放在同一行或者同一列里面,如下截图中两个绿框所示,但实际上,我们也经常碰到一些非常不规则的情况,如红框所示,它将不同层级的数据混在同一列里面,这个时候我们往往要对它进行清洗。方法当然很多,有些网页已经介绍了一些思路,如知乎里的这篇文章:https://zhuanlan.zhihu.com/p/2059600781817522093
这个思路我也就不赘述,有兴趣的可以看一看具体的思路,除了公式比较长,思路还是很不错的,这里,我再分享一个完全不同的思路,就是将源数据中各行进行逐个分析,如果本行数据的末尾是“市”,它的下一行末尾是“省”,则用该行返回分隔符 “|”, 其它各个情况下返回分隔符 ",", 第二步就是将A列中每行的数据与上一步的分隔符进行连接,第三步就是前第二步的结果用concat()进行进行拼接,变成一个大的字符串,然后用textsplit()函数按照行分隔符"|", 以及列分隔符","进行拆分,结果大体就出来了,第四步是嵌套一个IFNA()函数,将第三步产生的错误值进行屏蔽,大功告成。当然,以上是为了方便理解 ,将一个复合函数进行拆解,实际上完全可以将它整合成一个公式,一下子输出全部结果:=LET(a,A1:A10,
b,BYROW(a,LAMBDA(x,IF(AND(ISNUMBER(FIND("市",x)),ISNUMBER(FIND("省",OFFSET(x,1,)))),x&"|",x&","))),
IFNA(TEXTSPLIT(CONCAT(b),",","|"),""))
这个公式相对比较简洁,主要就是两块,红色的就是使用byrow()函数对源数据按行进行遍历,如果符合两个条件 (本单元格的含有文本“市”,它的下一行单元格含有文本“省”),则输出它本身和"|"进行连接,否则输出它本身和","进行连接。因为这两个条件要同时符合,所以它是“与”的关系,要用函数And()来表示,如果x表示当前单元格,则offset(x,1,)表示向下偏移一个单元格。蓝色部分的就更容易理解了,它就是将上一步的结果进行拼接成一个大字符串,然后用textsplit()函数进行拆分。现在的输出结果是同一省,以及下面各市的在同一行,如果想换成另外一个格式,即同一省,以及下面各市在同一列,只需要在原有公式的基础上再嵌套一个transpose()函数即可。