2024-08
24

office系的SQL为啥不能文本拼接?!

By xrspook @ 8:48:37 归类于: 烂日记

花了几乎一天的时间去研究什么把Access VBA里的自定义函数移植到Excel的VBA里面。大家都是VBA,大家都是 office家庭的,听上去好像没什么难度,但实际上前人已经碰壁阵亡,确定这是不可能的,我只是在做垂死的挣扎。经过这么多年office的发展,在数据格结构上,会不会只有那么一点改进呢?毕竟即便是在Excel里,如果我用的是VBA+ADO+SQL,实际上我是把数据以数据库形态进行SQL的加工。于是我就想,万一他们的数据格式是一样的,万一Excel已经进化了那么一点点呢。但现实告诉我,虽然都是VBA,虽然都是自定义函数,但是因为他们操作的是SQL,所以出来的效果完全不一样。

SQL的语法结构非常类似,无论你用的是什么类型的数据库,但在一些细节上,大家的处理是有区别的,我觉得Excel里面和Access里SQL最大区别在于因为我在Excel里面SQL用的是ADO的方式,所以这就意味着虽然我写的是SQL的语法,但实际上那是以字符串的名义存在的东西。在Excel VBA的数据格式里,我写的结构化语言全部都是字符串,但是在Access里,在SQL的查询界面里,那个东西不是字符串。我没有认真看某些单词有没有高亮,因为那是特殊字段又或者是保留字段。当我直接把Access VBA里的那个自定义模块挪到Excel VBA里,发现打开记录集的方式根本不一样,语法不一样。因为在Access里本来就是一个数据库,但在Excel VBA的ADO里是通过一些特殊的语句打开那个记录集的。

回到一开始,为什么我得这么折腾呢?因为一直以来我都发现,从来没有一个人能在Excel VBA+ADO+SQL的模式之下在分组聚合的时候把文本以某些字符去重连接成字符串。要实现这个功能,只能最后把结果输出,然后在VBA里通过字典的处理,再把那些合并好的东西与其它东西结合在一起形成一个新的数组,最后往单元格里面输出,而不能像其它SQL查询结果那样直接就在单元格里全部输出。先输出到字典,然后再用字典合数组合并的难易程度跟那个数据最终的查询结果复杂程度有关。在高端的数据库里,文本聚合连接有直接的函数可以做到,比如在MySQL里面直接group_concat就可以做到,在其它专业数据库里,那个函数的名字各有不同,但都能实现同一个效果,就是把字符聚合拼接。在Power Query里,他们没办法在窗口界面让你实现这个,但可以在高级编辑器里面通过text.combine的方式实现这种功能。在Power Pivot里,concatenatex也能实现这种文本的拼接。让人觉得非常无语的是,都到了Microsoft 365时代,Access这个东西依然是office大家族的一部分,但这种肯定有需求的东西居然没有一个官方函数实现,但你又可以通过在模块里用自定义函数的方式达成。Excel的VBA里不能秒生成这种东西,但在函数层面textjoin+unique+filter可以。为什么就不能在Excel VBA支持的SQL里面出现这个文本拼接的官方函数呢?如果他们真觉得没有必要的话,为什么Power Bi的软件就可以实现呢?我不知道Power Bi软件是一开始就能实现,还是后面慢慢进化出来实现的,反正我第1次看到Power Bi相关软件的时候,他们已经能实现了。

一整天的挣扎下来好像没什么进展,但我在这些问题上又仔细思考了一番。

2024-08
23

我还是比较喜欢VBA+ADO+SQL

By xrspook @ 8:39:59 归类于: 烂日记

我觉得编程会让人上瘾,尤其是当你实现了自己的目标以后,你就会有很多想法,比如之前我已经做过,而且已经实现了东西,能不能更进一步,再改进一些,让程序跑得更快一点?一开始的时候,只要能实现某个功能就可以了,无论用的是什么方法。在这个初级阶段,我是不会考虑别人到底行不行的,反正我行就可以,但是当自己包里面的工具越来越多以后。到底要选择什么工具,也会变成我一个纠结的地方,虽然有些工具已经很成熟了,肯定能实现我的效果,但是我还会想有没有更快捷的方式呢?

我已经不记得我是什么时候开始认识Power Query了,大概是在office2016的时候吧。那个时候我觉得那个东西可以做文本拼接太厉害了,而且厉害之处就像是跟数据透视表一样,当你的原数据发生了变动,刷新一下结果就出来了,但实际上那只是教程的效果,你完全按照教程这么干,的确能出结果。还记得几年前当我要算某些库存的时候,我用了一些很笨的方法。为了要实现区间日期里面的累计库存我用了一些非常耗费电脑的步骤。本来数据的量就不小,又外加要实现这样的效果,所以真的得算上很长时间才终于得到结果。那个很长时间意味着可能要等5分钟以上,在等待的过程中,我都怀疑自己的电脑是不是死机了。后来我也有算累计库存,但大概我已经不用一开始的那些方法了。我也有试过在VBA里计算累计库存。如果是在其它软件下的SQL里,计算累计数可以有很直接的方法,因为他们有现成的函数可以套用,但是在VBA里面的SQL,貌似至今为止,我尝试成功的也就只能硬着头皮做一个笛卡尔积。如果数据量比较大,那将是一个噩梦。噩梦归噩梦,数据还是能算出来的,如果我只是算一个月的库存,顶多就是几秒钟的事,通常情况下如果业务量不大,一秒就差不多了,但是如果要算一年的数据,那就要跑上几十秒。在VBA层面需要跑几十秒,而如果在PQ里我简直不敢想象得多久。

试过VBA,试过PQ,在PQ里我知道我要什么,它的透视和逆透视功能让我省掉很多麻烦,但这两个便捷功能也会默认带出一些意想不到的反效果,比如默认透视的是来源去向,万一筛选区间只有入没有出,但后续处理又默认有出入,这就会卡住。Excel 的SQL里,透视就是最后一步,所以如果中途要实现这种功能只能通过添加条件字段,手动添加字段的好处是不会有PQ透视法的那种透视不出来后面没法干。就可控程度来说,VBA更容易,能把多个操作在一步里秒杀实现,比如修改某个字段的数据和增加某个字段,我就可以把它们在一步里实现,外加同时搞个什么排序。这些步骤在PQ里面,如果不是高级玩家用嵌套的方式,也就只能一步一步慢慢来。我不知道,PQ里面嵌套一步到位跟一步一步慢慢来到底效率差了多少。估计这会有运行时间的差别,但到底差别了多少,这个我没有研究过,因为我还没到的那种可以混搭在一起,一步到位的水平。处理同样的数据,使用类似的步骤,PQ就是比VBA要慢,我也不知道到底慢在哪里,为什么会那么慢?其实数据量不大,但关键是PQ载入的时候很容易出错,但那个出错到底是什么,没人说得清,因为上一次刷新不行,下一次刷新可能又可以了。在VBA里,除了去年年末的某段时间,我经常出现这样那样的奇怪现象,其它时候基本上行就行,不行就是不行。不会出现同一个数据,同一个宏,前一次可以,后一次不行。在PQ里可能得转上半分钟以上的事情,在VBA里非常有可能0.5秒以内就解决了。以前做字幕的时候,我就知道人的反应时间通常是0.3秒,如果一个VBA脚本只需0.3秒就能结束战斗,对普通人来说,那就是眨眼的事而已。

以前我没想过要这么干,以前想着怎么方便怎么来,但是当VBA有点上瘾了以后,我逐渐的把之前用PQ处理的东西全部都用VBA的方式再整了一遍。出来的效果非常好,干净利落快如闪电。让我觉得舒服的是VBE界面是被我调整过的,调整过VBE的布局和颜色,但是在PQ里,那个小得要死的高级编辑器字体实在让我看得很不舒服,但通常某些高端的功能只能在那里敲代码,所以这就很痛苦。

不把某些事完成,心里总会一直念惦记着,把这些事情都干完了,我就可以好好睡觉。

2024-08
22

进一步优化和debug

By xrspook @ 8:17:44 归类于: 烂日记

又花了整整一天的时间去改进之前的两个转换程序,一个是用PQ写的,另外一个是用VBA写的。之前以现有的数据进行测试,没有发现问题,但实际上今天再去纠结,还是有个问题,就是当业务类别为轮换,出库的时候损耗的计算方式。损耗应该放在商品粮的账本,这个没有问题,之前也是这么处理的,但是商品粮的账本还有一个。储备粮油转入,这个东西就应该包含损耗和销售两方面的数据。之前只包含了销售的数据,忽略了损耗的那一部分。同样,在储备粮的账本,在转作商品粮油的数据那里也应该包含商品粮账本里面的损耗数据。这个东西平时做的时候一定会记得,因为单仓数据如果处理不到位无法清零,但是当要考虑的事情有很多的时候,就忘记了。在做这个程序的时候,我就已经考虑到这种损耗是一个很特殊的情况,但是我却没有进一步的考虑到这个东西特殊到要一变成三,通常情况下,一变二就可以了。

除了这个问题,以我现有的数据,基本上那两个程序都能运行出我想要的效果,但实际上,今年到现在为止,单位产生的那些数据还有一些业务类型没有包含进去,那些业务类型有些我可能会用到的,有些我是几乎用不到,但我用不到,不代表其他人也一定不会用到,所以从大的层面考虑,我还要把那些东西都考虑进去。

之前无论是在PQ还是VBA,某些字段的生成实际上是条件筛选,有可能是一个条件,也有可能是多个条件,那些条件里面会有很多个情况。在PQ里做条件筛选,还有个填写界面,但是在VBA里就纯粹靠iif的不断套叠。首先你得知道怎么套叠,然后当你套到一定程度的时候,自己也会被套进去,比如数着数着括号就对不上了,什么逗号双引号之类的偶尔也会制造幺蛾子。使用这种套叠可以实现我想要的效果,但是真的非常虐,而且一旦要进行数据维护,那简直就是个深渊,所以首先我想到的是要不要做另外一个索引的表,通过左外连接的方式指定某些字段必须匹配,然后就能获得我想要的新增字段。从可维护性来说,这样非常好,从代码的实现来说,这也很方便,但是后来我还是决定不在VBA里面实现这种左外的索引和直接在原始的表格里面就索引数据得出一个大表,然后再用大表进行后续的整理,因为要处理的大表其实数据不多,一年肯定不超2000条。之所以要这么干,首先是因为我考虑到可能使用这套方案的人会更容易接受这种直观生成的大表,他们可以直接核对数据,如果觉得不对,可以进行手动更改,但如果我把那个东西做在了VBA层面,程序运行不出来,或者运行出来的效果不是大家想要的,那么需要结果的那个人肯定不知道该怎么办。这种直接通过Excel的索引,先得出一个大表的方式,同样也会让PQ的程序不那么复杂,不需要搞那么多条件筛选。虽然PQ的条件筛选有界面,可以下拉选择,但需要选择的东西多了,很容易就会选错。

最后,事实证明我的这个做法是合理的,我把需要考虑的因素全部都考虑进去用全面的测试数据都模拟过以后,发现两个程序都能满足我的要求。当然了,在最终成功之前,我经历了不知道多少debug。你永远都不知道你会被什么卡住,又或者在什么地方被卡住,但被卡的次数多了,你就会觉得这很正常,继续死磕就行。

2024-08
21

Excel文件减肥

By xrspook @ 8:18:07 归类于: 烂日记

对office越是爱,就越是恶心WPS干出来的事。昨天早上把上星期还没整理完的那些账本格式调整了一下,把所有账本模板都调整到符合我的要求以后,我就把那保存下来。在我看到的范围之内,那个账本里没有任何的图片,能看到的都已经被我删掉了,而且那些工作簿里面也就几个工作表而已,数据很简单。我感觉那就大概几十KB而已,但是当我把改好的工作簿复制到我的同步文件夹的时候,发现那个东西大得恐怖。只有4个工作,工作簿居然有接近8MB大小,我赶紧把那个工作簿撤回。打开那个玩意,我的确没有看到奇怪的数据,然后F5定位,也没有找到任何对象,到底是什么原因导致那个工作簿那么大呢?是不是一些工作表被隐藏了?于是我选择了其中一个工作表,复制到一个新的工作簿里面,结果发现,虽然仅仅只有一个工作表,可视范围也很小,但是一个工作表也居然有接近1.6MB,这到底是怎么回事呢?文件的后缀是xlsx。之前看过好几回给Excel文件减肥的教程,通常第1步就是把对象全部找出来,该删掉的删掉,显然我找不到对象,所以我的终极大招就是把文件降级保存为97~2003的xls。降级保存之后,那个工作簿马上变成了不到30KB,是一个正常的大小,然后我又把那个东西重新另存为xlsx,文件大小终于正常了。所以这到底是什么情况呢?

WPS到底干了什么好事?可以肯定的是WPS至今没有64位的版本,实际上他们默认保存的那个文件格式相当于office低级版的xls,如果做这个账本模板的人只是直接的把后缀改了,没有通过另存为的方式,会不会就导致了这种莫名其妙的问题呢?之所以我会那么自信选择降级保存是因为工作表里没什么高端的东西,低端的Excel也能完美应付。

WPS吹了那么多年,至今我都觉得无法接受那个东西。当我还是个高中生的时候,我的同学就有人在用WPS。那个时候,我家的电脑是win95,好像对应的office版本也是95。我读高中的时候,上电脑课学校用的那个office是2000的,这就意味着某些功能我没办法在家里那台电脑上练习。好像我家那台电脑的office无论如何调不出文本框功能,所以当某个电脑作业要用文本框设计一份海报的时候,我就只能把所有素材都交给同学,然后把整个版面该如何放置告诉她,让她在她的电脑上帮我完成。那个东西回到我的电脑可以打开,但却没办法进行修改。我觉得office95的界面挺漂亮,比office2000的漂亮。office2000跟office2003相比,我感觉2003又更进一步。我觉得office2003是整个office系列低版本的一个顶级之作,非常完美,很流畅,基本不会出现任何问题。之所以得出这个评价,是因为office2003后一个版本office2007简直是灾难性的,office2010好那么一点点,但还是有bug。office2013在数据透视表方面简直让人无语到了极点,到office2016的时候,基本上数据透视表方面算是好了,但是在新加入的power query和power pivot方面,office2016又是一个bug乱飞的存在。

那个莫名其妙的账本工作簿,我通过每个都降级再升级的方式成功减肥。不是每个人都是我这种有点痴迷属性的 office狂热分子,所以当大家用那个东西的时候,估计会半天想不明白为什么自己的文件会那么大?默认只能用WPS的某些单位,美其名曰为了安全,实际上是主动降低自己的工作效率。当然,这有个好处,当某件事做不好的时候,就可以赖在软件的头上,是软件不好,不是我能力有问题。

2024-08
20

其实大家都可以不累的

By xrspook @ 8:46:44 归类于: 烂日记

以前我从来没有觉得检查这东西有多么令人厌恶,那只会让我紧张。现在随着检查频率越来越高,范围越来越广,我开始厌恶这个东西了。在没有检查之前做好自己的事情也就完了,别人要你做什么你就做什么,但是当被检查的次数越来越多以后,发现情况远没有那么简单。因为对方要求给出的数据不按常规的套路出牌。平时我们各自完成ABCD四项任务,某些检查需要我们提供的数据是A和B联合,再加C的部分,然后是在D的条件之下。你还不能把ABCD全盘托出给他们,你必须按照他的条件把ABCD融合在一起,这个东西就很让人绝望。为什么要提出这样的要求呢?因为他们检查的角度和我们工作的角度不一样。他们从一个点发散开来,相关的东西全部都得要,而我们的工作实际上是至上而下一级一级深化,到最后就变成了ABCD四款由1234四个人完成,各自独立。所以这到底是他们的问题还是我们的问题?我感觉,如果有一套系统把这些都联合起来的话,什么问题都没有。我们做我们的,做好我们的事,自动关联就已经结成了。他们检查,想从什么方面钻取是他们的自由。现在的实际情况是,没有系统,没有预先的联合。1234这四个人之间从来没有什么交集。光是交出最后的那份数据,从谁开始然后到谁,由谁去加工,这些关系已经让人觉得足够迷糊,就更不用说有些部分可能是互相关联的,就一条桥而已,搭上了就解决了,但关键是谁也不愿意搭这条桥,谁都觉得那不应该由我去做,应该由别人去做。

工作是这样,检查是那样,退一步会观察这件事。实际上很多东西早就应该摸出对应关系,然后通过引用而不是通过重复工作的方式自己干自己的。基层的烦恼在于,上面总是要我们提供数据,但实际上那些数据翻来覆去,已经提供了无数遍,上面的这个部门要这样的,那个部门要那样的,实际上原始数据都是一个东西,上面也做了一些系统的玩意,也的确要求我们把一些数据之类的东西都通过人工的方式转化上去,但问题是他们中的有些人根本没想过我们上传的明细数据和他们所要的那些汇总数据的关系,所以每当上上面要求某些汇总数据的时候,还是要基层的人按照上上面的要求重新提供。我不知道为什么上面的人就不能从基层的角度考虑一下这件事情到底该怎么做。上上面有什么要求,上面的人就得让基层的人提供数据,其实这个工作也很累。如果基层的人反馈不及时,更加会让中间的人像热锅上的蚂蚁一样急得要死,一点办法都没有。如果一开始就想清楚关系,直接抓取数据,基层的人只管生产正确的数据,中间的人想好要用什么方式汇总来应对上面人的各种奇怪要求。要做到这样,中间的那些人对上面和下面都得非常熟悉。好像到此为止,从来没有一个人敢站出来,承担这个责任,所以现在的状况就是上面下达指令的时候层层逼迫,出现问题的时候层层推卸责任。

的确有方式让大家都舒服,但得先有人多做一些。

© 2004 - 2024 我的天 | Theme by xrspook | Power by WordPress