2025-11
22

用这三货做数据查询

By xrspook @ 8:02:29 归类于: 烂日记

不知道从什么时候开始,我就迷上了数据查询。

一开始只是想实现某个功能,后来发现原来实现同样东西,我用不同方法都可以做到。哪个方法更直观简便一些?我感觉Excel VBA的SQL,Power Query以及Python相比,就数据处理的方便性来说Python是碾压的,但我没有发现Python的巨大优势。问题可能在我交给Python处理的数据太少了,跟其它两个相比体现不出Python的高效。在控制Excel单元格格式方面,Python天生不如office自家的VBA。为什么我会把PQ跟VBA跟Python相比呢?是因为从Office 2019开始,PQ就算是内置的一个功能。VBA里面的SQL天生有缺陷,因为跟真正的数据库SQL相比,那就是个阉割版,有些你觉得明明可以实现的东西,在Excel VBA里好像就真没有直接的解决方案,为什么居然会这样呢?

到现在为止,我依然没有发现Excel VBA的SQL有直接的文本拼接功能。其它数据库的SQL里,那就是一个很简单的函数。Excel VBA的SQL在合并其他数据方面没问题,但一旦遇到需要进行文本拼接。我感觉除非在查询结束以后再做一个字符串的字典,否则无解。或许你会说其实我也可以直接在Excel的函数层面做这个拼接,因为用textjoin函数实际上是能实现那个功能的,但关键是如果数据比较多,既然我都在VBA里完成前面的所有,为什么最后的功能又要回归到函数呢?二者的运算速度不是一个层次的。每当我遇到文本拼接,我知道SQL是撞墙的,所以我就直接想到PQ。

PQ可以做数据分组,做文本拼接直接在高级编辑器里修改就能实现,但关键是实际上可以不用PQ,我不想用那个玩意,使用可能会有点慢还行,如果要进入到里面编写代码,那个小窗口字体无法放大,简直要逼死我这种老花。更作死的是,很多时候提醒我错误,但错误根本不发生在提醒的那个地方,不断的嵌套括号、逗号、又或者不小心带入的中文标点符号都会导致错误,找茬的过程让人挺绝望。我觉得,我还是喜欢在VBA里用SQL,其实无非就是判断加循环。在PQ里我总觉得有些很容易就能做到的事情,但是它非得用一些看上去很复杂的函数去实现。比如要根据A字段去决定B字段的数值是正数还是负数,在SQL里,一句很简单的iif就能实现,但在PQ里,你还得新建一个条件列,把条件写进去,接着把原来那个数值列删掉,再把条件列的名称改成数值列。当然你也可以直接使用replacevalue函数,但据说那个东西的执行效率反倒不如新增一列再删除一列。PQ里的函数非常多,嵌套用起来的方法更是让你眼花缭乱,也正是因为那些杂七杂八的东西太多了,反而让我觉得不如SQL简单干脆。让我很绝望的是,Access的SQL可以直接文本拼接,但Excel里的就不行,虽然二者是同一个版本的office。

当我在一个问题上钻研得越深,我就越能理解到高中时候,我的数学老师说学习数学的几个境界:不懂不会,会而不对,对而不全,全而不好。

2025-04
15

确定买断Office的版本

By xrspook @ 8:49:38 归类于: 烂日记

经过了Microsoft 365惊魂一夜之后,我意识到我不能把自己吊死在一棵树上,所以即便我要继续用 Microsoft Office软件,我也不能把所有电脑都用上365版本,主力机我可以继续用365,因为显然那个是最顺手的,如果他们能一直把服务提供下去,我也愿意一直每年都给他们一些费用。万一某一天365故障了,不让我们用了,我也得有对策,所以我的计划是所有的备用电脑全部装上proplus的版本,至于要装2019、2021还是2024,得考虑一下。2019跟2021比起来,我肯定会选2021,因为经过那么多年,其实2021也已经成熟了。之前不知道听谁说2016跟2019会在同一时间停止支持。

在我还不确定是要用2021还是2024的时候,突然间有人在ExcelHome上面问除了Microsoft 365以外,还有哪个版本的office是支持溢出函数。溢出函数是什么?ExcelHome的大神没有马上反应过来,但是我反应过来了,因为我用过那些函数,当我的设置不当的时候,在理论上应该显示正确答案的地方就会出现“溢出”两个字。溢出函数说白了就是动态数组函数。以前的数组函数,你必须要用三键结束,而且你还要把函数扩充到你想要的范围,但不知道是从2019还是2021开始就有了溢出函数这个东西,又或者准确的来说应该是动态数组函数,这些动态数组函数你只需要在一个单元格里设定,它的结果会扩充到其它的单元格,会向右向下扩充。至于扩充多少,就看你所设定的那个函数能获取到什么样的结果。正如上面我所说,如果你的函数设定是不对的,那么你就会得到溢出这两个字。如果你把单元格定位在动态数组函数非公式设定的那个单元格,会发现里面是主单元格灰色的公式,但实际上你看上去那个单元格又是有数据的。这是很方便的东西,也很奇妙,但如果你直接想把那个结果进一步使用,又很有难度。哪怕你想把那些东西建立一个超级表实际上也是做不到的,你想把那些数据作为数据透视表的元素去引用,也是不行的。所以这个动态数组函数到底用在什么地方呢?我觉得只能是最后的一步,就是你想做的那个事情的最后一步,因为那之后你已经没办法再继续操作下去了,情况就像在VBA的SQL里,把数据透视化展示就是语句的最后一步,透视处理之后的东西,你再也没办法进一步操作了。

我用过动态数组函数,但用得不多。因为我知道很多人的office还是挺低端的,可能不支持这个玩意,我看到他们看不到,文件发过去等于没用。动态数组函数我用得不多,但xlookup函数我用得挺多,基本可以这么说,在考虑怎么得出索引数据的时候,基本上我都会首先想到那个,而不是经典的那些组合,虽然实际上在某些情况下,他们得到能得到一样的结果,经典函数加上超级表的结构语言依然能得出很简便的索引公式。 Microsoft 365故障的那一天,因为电脑自动被退回到了Office 2016家庭版,然后我就见识到了自己的xlookup函数全部崩溃的那个画面。于是第二天我就把那些Excel表格公式全部改成了lookup函数,实际上也没有多大的改动,因为那不就是个多条件索引而已。 lookup函数Office 2016肯定是支持的,但是xlookup函数好像要到Office 2021才算是全体支持,至于升级到后期版本的2019是否支持,这个我还得进一步找一下资料。

为什么要高级版本的office呢?因为高级版本的office支持的Excel函数更多了,但是是否最高级的版本就最好呢?未必,因为据说Office 2024有不少bug。

综上所述,所以我把目标买断office版本初定为Office 2021proplus。以防万一,我也要把自己经常使用的那些Excel表格里面太高端的公式全部低端化,也不一定要低端到Office 2016也能支持,但如果真的能做到那样的话就更好了。

2023-08
18

蓝调了

By xrspook @ 8:24:16 归类于: 烂日记

周四的傍晚时分,我突然有点码农蓝调的感觉,因为好像无论我怎么整,前面总有无数的奇奇怪怪的问题。这些问题居然没有大路的答案。原因是Excel的SQL已经被阉割到一种没人能说得清的程度了。我就想知道到底Excel里的SQL有什么样的函数,知道有什么函数,知道函数怎用,才能以各种叠加的方式得出我的招数,但问题是人微软自己的手册都没有说清楚到底Excel里的SQL可以怎么个用法?相比之下,Access写清楚了,SQL Server也写清楚了,不同版本的函数不一样,些高版本能轻而易举函数就能实现的功能旧版本也有替代方法。但是Excel里的SQL像一个谜一样。你得不断尝试直到绝望。因为你拿着那个问题去搜索,没有结果,结果都是其它数据库的,虽然都叫做SQL,但差别真的很大。

的确用VBA+ADO+SQL搭配能解决一些小数据的问题,而且速度很快,但为什么微软在这个基础上还要继续整出 Power Query和Power Pivot,因为他们知道在操控数据方面,VBA本身真的有很多限制。当我死磕了一周以后,我发现VBA要死要活折腾半天出来的东西如果在PP里两下就搞定了,而且那还是在可视化的情况之下。至于PP,那是不允许你用不可行的方式去操控的,所以虽然三个都在考验逻辑,但是在Excel的SQL里面,我觉得对我最大的考验是,我明明知道要那么干,我明明知道用其它工具应该怎么干,但是无论如何我在这个Excel VBA里面就干不出来。

我遇到的某些问题,跟SQL没有关系,纯粹是VBA数组的问题。VBA的一元数组,如果要输出的话,它会在一行里输出,但如果你要把这个一维数组在列里面输出,你就得做个转置。我遇到的问题是,即便我已经设定了转制。系统依然说我的类型错误,最后我是怎么干的呢?明明我那个是一维数组就可以实现了,但为了可以顺畅输出,我硬是把那个东西设置为了二维数组,另外一维完全是空的。这样的话在我输出到单元格的时候只给予一列的空间也就是那空的第二维根本不用管他。经过SQL处理生成的记录集,如果要输出到数组,通常是一个二维数组,那个二维数组跟VBA自己的数组又是转置的关系的,那个记录集的数组编码是从0开始的,VBA默认的数组是从1开始的。如果在VBA里把一个字符串打断赋值给数组那又是从0开始的。在python里,默认就是从0开始,什么东西都从0开始了,所以你不需要为长度跟起始数值还有突然间又有个转置之类烦恼。

周四我遇到一个算是逻辑意外的事件。我要筛选某个表里某一字段不包含某个关键词的记录,但问题是那个字段里的东西有关键词也有空,我需要筛选出来的记录是关键词以外的其它字符以及空的。当我where 字段A not like ‘%关键词%’的时候,结果出乎我的意料。因为那个关键词是包含的关系,所以我没有办法精确控制,所以我必须在关键词的前后加上%。这句筛选的结果是字段里所有那个字段的记录都没有被筛选出来。不就是一个包含的关系吗?Excel的SQL里面允许用正则吗?最终我用的方式是在where里面用两句话,一个是not like,筛选到那个字段里没有关键词,但是有其它字符的记录,另外一个是用or的关系搭配一个isnull(字段A),这到底是什么情况呢?如果在其他地方,一个contain之类的东西就能表达出来,如果允许用正着,正则也能很好表示不包含关键词,Excel的SQL到底允许我用什么工具呢?

SQL in Excel这把刀到底应该怎么玩???

2020-10
13

Excel的高端玩法

By xrspook @ 8:43:14 归类于: 烂日记

数据本身没有问题,如果我们不能让它们确立某种关系,只是因为我们对那个东西还不够了解而已。在Excel里做一件事,你可以通过很多方法,比如说函数,比如说VBA,比如说SQL查询,又或者Power Query或Power Pivot。当然,我这里所说的,主要是针对查询,或者说数据清洗类的东西。如果纯粹是针对单元格的格式化,函数以及Power BI系列以及SQL是没办法做到的。

同样一个数据,用不同的方法都可以得出目标答案,但是哪个会更简便快捷一些呢?函数我觉得挺被动的,尤其是在处理大量数据的时候,效率非常低。因为在处理一些复杂东西的时候通常要用到数组函数,即便不需要用到数据函数本身,其实也在运用着数组函数的变体。而且函数这种东西受Excel本身版本的限制,越是低版本的Excel越是没办法轻而易举地实现某些逼格的功能。于是就出现了你不得不为了某个功能升级Excel,又或者因为你的伙伴升级了Excel,用了一些高端的函数,但是你却看不到,工作就没办法继续下去了。SQL和VBA是两个大杀器,很早以前Excel就已经支持。与其说他们是Office软件的一部分,不如说这两个东西更接近于编程语言。我对Excel里面的SQL不是十分熟悉,因为至今为止,虽然已经折腾了不少网站,但是我从未试过操作数据库。SQL在Excel可以用,但我觉得可能在Access里SQL会用得更顺手一些。比如说如果改变数据源,比如移动文件之后,SQL需要重新连接。若没有VBA的帮助,这是无解的。我不喜欢用SQL的其中一个原因是它会在硬盘的某个位置生成某个数据库。

VBA这个东西强大到任何你想到想不到的东西都可以控制,无论是数据本身还是说单元格的格式,一律通杀,它甚至可以让Excel自杀,又或者让你的系统自杀。VBA用得好不好直接决定了某个脚本的运行效率。是对初级用户来说,VBA的学习成本实在是高,除非你从来不打算要建立自己的规则而纯粹只是用别人的东西。

至于Power BI系列的Power Query和Power Pivot现在我仍然处在甚至还不能说入门的阶段,我只是稍微了解了一点这两个东西。在数据清洗和建立关系的时候,它们实在太强大了。但是要使用这两个东西,Excel的版本就必须有要求。所以这也导致了不少免费用户直接绕过这两个强大的东西。我也不知道为什么自己在使用Excel高级函数几乎还没入门的情况下,我就去折腾M语言。我觉得那个东西一定程度上颠覆了我对数据的理解。Power Query对数据的处理方式就像通过各种蹂躏就能得出你想要的东西,其间你没有修改原数据,所以实际上在写M语言的时候就像是手工编写一个宏,而那个宏要比一般的VBA简洁很多。之所以简洁,一定程度是因为那是在高级套用的前提下。Power Query里玩的数据转换实际上是在折叠、删除以及扩充,一定程度上就像是在用类似于递归或者迭代的方式。

别人把时间耗在应付考试上,我把时间耗在折腾自己上。

2020-04
14

一句秒杀一段话

By xrspook @ 19:52:09 归类于: 扮IT

还记得初中的时候数学老师跟我说初等数学比高等数学难多了,幸好,我这辈子暂时只学过高等数学,而且几乎都还给大学老师了……

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# def first(word):
#     return word[0]
# def last(word):
#     return word[-1]
# def middle(word):
#     return word[1:-1]
# def is_palindrome(word):
#     if len(word) <= 1:
#         return True
#     elif first(word) != last(word):
#         return False
#     else:
#         return is_palindrome(middle(word))
def is_palindrome(word):
    return word[::-1] == word
word = input('word is ')
print(is_palindrome(word))
# word is qwerreq
# False
# word is poiuuiop
# True
© 2004 - 2026 我的天 | Theme by xrspook | Power by WordPress