普通视图

就是要用not exists

2026年1月24日 08:30

我知道有一个大表,我也有这个大表其中了一些数据的小表,我需要筛选出除了小表以外的数据,思路非常清晰,但实际上要用Excel里面的SQL实现却好像异常困难。在一些高级数据库里,有特殊的函数实现这个功能,有些用的是except,有些用的是minus,但是Excel里没有。如果可以用except或者是minus,这将意味着可以对大小表全列对比,但是如果用其他方法,只能选取其中一些。刚好我要操作的表有一列刚好是多个列信息的集合,所以用那一列作为标识刚好,但如果我根本没有那一列呢?难道我还得先造一列出来,然后再进行操作吗?无论是用not exists或者not in的方式去进行这种筛选,都只能选取其中的某一列操作。如果是用not in的方式,还得要注意,如果那个小表是空的时候,会导致筛选失效。如果用not exists的方式,则不需要考虑小表是空的情况。

一开始想实现这种功能,我想到的不是这两个,而是用count。先去计算那些有重复项的行,然后针对不同计数结果分别处理。就思路来说很清晰,但就实现来说,很啰嗦。但虽然啰嗦,还是能得出我想要的结果。第一天我用这种计数的方式得到了我想要的结果,但我依然觉得应该有一些更直接一点的方法,于是第2天我就想用not in或者not exists的方式去实现。

not in的方式总算是做到了,但是效率不高,感觉耗时是用计数方式的两倍。in和exists相比,我感觉exists的效率更高,但关键是实际上我使用的是not in和not exist,所以估计还是挺麻烦。虽然就语句来说,不过是多了一个not而已。exists的实现耗费了我不少时间,理论上我的写法没有任何问题,但关键是就会报错。折腾了一个下午都无果。晚上洗澡的时候,我突然想到可能是引用数据简写那里出了状况。在使用not exists子查询的时候。我依然是用经典的a和b简写,但实际上在这个子查询引用的数据里面就曾经出现过a和b。如果某一句查询里面的简写a和b是同一个层次的,没什么问题,但关键是子查询这种操作有递归的感觉,主查询跟子查询不是一个层次。VBA弹出来的报错窗口说某个简写可能指向多个数据。后来我觉得大概是因为之前我就已经有用过a这种简写,层层嵌套之下,exists的子查询不知道我指的到底是哪一层的a。洗完澡以后,我赶紧找文件测试,把主查询的a改为了之前从来没用过的c。果然,not exists子查询通过了!多次测试对比发现not in跟not exists的性能确有区别,not exists会快一点点,但是跟计数相比,好像计数依然是三者之中最快的。从好理解的角度而言,not exists最为复杂,最好理解的我觉得是计数,但是就语句使用的长短而言,not exists和not in最简单的。最后我采用的是not exists的方案,但是not in跟之前计数的方案我都只是把它们注释掉了,没有删除。

如果Excel里面的SQL能与时俱进,我能用一些那些高端的函数,我根本不需要这么大费周折。别人有现成的模块,连个线就能用,但我什么都没有,所以哪怕是一个螺丝,我都得从零开始手搓。

结束2025

2026年1月9日 08:16

明明今年2月份中旬才过年,不知道为什么好像所有事情都在开年的第一周就要做完了。幸好去年年末那几天不忙,所以最后一天我居然只加班了两个小时就把以前可能1月1日得做一整天的事情都做完了。倒不是因为那两个小时我创造出了人生加速度,而是因为绝大多数的事情实际上在那天我已经全部解决掉了。接下来的事情平时可能得一个月甚至几个月之内才要求全部到位,但不知道为什么2026年就这么特殊,突然一下子之间仿佛要求都得结束。如果是以前,必定会让我手忙脚乱,但事情就是这么巧合。2025的结尾没那么忙乱,所以我可以把之前可以拖很长时间才结束的都逐步结束。不把那些都干完,我总觉得欠2025年的债还没还清。2026年工作日的第一周星期四下午,基本上我就把那些都结束掉了,余下来的只是静静等待各种检查的到来。除了检查以外,还会开各种各样乱七八糟的会议。那些叫什么扩大会议的,基本上我都翘掉了,余下那些必须全体参加的,哪怕我在那里打瞌睡,我也要在场,但实际上我又真的没办法控制住自己真的瞌睡。虽然我知道某些部分实际上我是睡着的,但是有些东西我还是会竖起耳朵去听,哪怕左耳进右耳出,只是过了一遍而已,但我还是有认真听。

据说2026年的第二周,绩效考核的就要过来做2025年最后一次清算。一直以来大家都把那个当作是最后的大考,但这些年以来我已经有点麻木了。虽然也会紧张,但我知道紧张也没用,该做的都已经做了。我不可能一直都没有问题。因为我做的那些事情基本没人会帮我复合,只能靠我自己一遍又一遍的审核。自审也好,其他人审也好,肯定会有漏洞。问题只是这个漏洞是不是刚好碰上被暴露出来。但暴露出来也未尝是坏事,因为知道漏洞的存在,找出了漏洞的原因之后,就再也没有那个错误的烦恼了。

2025年国粮局的直报系统在6月的时候升级为了新版本。虽然看上去导出来的表格差不多,但实际上肯定有区别。没开始整理那些之前,我就知道一定会撞板。果然不出我所料,但让我有点意外的是,其实1-5月的也有撞板,于是我不得不对自己那个VBA的程序一步一步检查。对别人来说,其实没有VBA批处理也可以,但我觉得用统一的方法处理数据会更客观,不容易出错,而且这些东西是不允许出错的。最后整理发现其实新表和旧表虽然有区别,有一些很明显的改动,我只需要修改一下就完了,而另外一些则属于后来的那些表格数据跟之前我设计那套脚本的时候相比已经发生了变动。在不知道错误在哪里的时候可能很茫然,但是当所有东西都理清真相大白之后,我觉得这个VBA写的时候的确很费劲,但思路是清晰的,注释也很到位,维护起来不算太麻烦,最重要的是,原来我2021年就把它开发出来了。用了5年,基本没出什么大问题。即便国粮局的报表系统发生了变动,我的程序依然可以支持兼容,所以实际上我写的那个VBA也挺强壮。12月最后一个月报不出来,全年的数据就没办法汇总,虽然我也有点急,但也没用。我知道我一定会碰钉,但那既然我选择了这么一条整理思路,我只能勇敢地撞上去。

感觉时间过得越来越快。不知道怎么就熬过了一年。

ADO+SQL突发报错

2025年12月16日 08:19

周日晚上感觉一切都好,没有遇到什么特殊的情况。周一早上打开wifi连接网络,打开微信以后发现同事给了我一个信息说前一天晚上VBA的查询失败了,无法获取数据。看到那条信息,我的第一反应是会不会重命名有问题。那里有个截图,但我没有仔细看。VBA的弹窗都那个模样,而且大概差不多都是那些内容。虽然有说是什么方面的问题,但通常你往那个方向想的话,可能根本找不出原因,所以我就没有看。出现这么个状况,最大可能是浪潮升级系统以后又改过某个导出数据的表,导致那个表里面的某些字段名改变了,那个字段又是我使用的,于是就会查询失败。为什么我觉得是浪潮的原因呢?因为20点多的时候还是很正常的,我的同事是23点多的时候查询。她查询的时候,单位的作业已经结束了半个小时以上,如果浪潮要抓紧时间升级,估计会在作业结束以后马上进行。综上所述,如果查询失败,我的第一感觉是浪潮整出来的幺蛾子,但我不确定这真的是浪潮的幺蛾子还是我同事文件名不对导致出状况,唯一能做的就是上班以后我自己试验一下。

文件导出后,的确发现查询失败了,错误代码是80004005,对应的描述是“这种对象类型不支持该操作”。在我印象之中,没有遇到过这种描述的错误,但是搜索800044005这个代码,很多各种各样的原因都会是这个号,所以这到底是什么毛病呢?在我记忆之中,如果是浪潮改了那个表,导致我查询失败,应该不是这个描述,但是我没有太多的时间去研究到底是什么,我得先把我手头上的东西都搞完。

搞完那些日常必须做的东西以后,我开始研究这个查询失败。按照常理,浪潮bug的概率最大,所以我首先把之前从浪潮导出的表格和现在从浪潮表出的导出的表格的字段核对了一遍。发现字段是完全一致的,整个表格的构造也是一样的,所以这基本排除是浪潮的问题,为了证明的确不是浪潮的问题,我把以前导出的数据喂给查询文件,发现和新导出数据弹出的错误一样。这样就说明了肯定不是浪潮的问题,但不是浪潮的问题,那是什么问题呢?在进行新旧表格对比后,我又回到查询代码那里,先是逐个删除我觉得可疑的,结果发现还是那样,最后就直接原表输出,居然原表输出也出了状况。到这一步的时候,我基本确定是微软的问题。因为前几个月我们才经历过如果进行ADO+SQL查询的时候引用了当前查询文件所在的表格,就会让查询时间大幅增加。如果查询的时候,源文件所在的文件打开了,也会让查询时间大幅增加。到底是什么样的更新才会出现这种问题呢?我们不知道,但肯定的是一定是微软升级导致的问题,因为有些人有问题,有些人没有。用批量版的那些没有,用零售版的出现了问题,那些用零售版的一直没有更新的也没有问题。最终几乎可以追溯到到底是具体哪一个版本的更新引发了这个问题。

如果是SQL语句导致的状况,当我什么都不设置原表输出理论上应该没有问题,但实际上问题依旧。

研究到了这个程度,我知道这不是我一个人能解决的。我大概知道这是不是我们这些用户能解决的。那到底是什么问题突然触发了这个事故,得问那些负责windows系统更新的人。

用这三货做数据查询

2025年11月22日 08:02

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

一开始只是想实现某个功能,后来发现原来实现同样东西,我用不同方法都可以做到。哪个方法更直观简便一些?我感觉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年11月21日 08:57

周三下午开会,周四要切换系统,到周五下午快下班的时候,我想到经常查这个数据的人还有会计。就去问了一下,他们需要哪些数据,然后我就可以在导出的表那里为他们挑选有必要的字段,没有必要的就直接不理会了。因为之前已经做了两个格式化,在做第三个的时候,我只是在之前的那个基础上修改而已,所以非常简单,从询问需求到最终出来大概只花了15分钟,同事非常惊讶。要知道前两个版本出来花了好几个小时,尤其是第一个版本,所以最后这一个只是细微的些许的变动当然显得很简单。那些需要用已有的字段做判断,得出新数据的新字段,该怎么个判断法之前我也已经考虑得很透彻了。

我觉得对导出数据用SQL做筛选或者分组合并是最恰当的,因为那个大表里的字段很多,如果用经典VBA的方法,要保留某些,要剔除某些很费劲,但是如果用SQL去考虑这个东西就很简单,我根本不需要考虑原来有多少个字段,我只需要知道我需要留下什么字段就好了。字段的排序是可以随意捣乱的,字段名也可以重命名为我想要的那个。我不知道浪潮脑子里想的是什么,字段名里面有括号有斜杠,反正就是不少不太恰当的字符。要在SQL里面引用这些字段名就得用`。这个东西之前我还真不知道,但我肯定有某些方法可以把某些特殊字符认定为某个名字而不是特殊字符的特殊含义。SQL筛选很简单,就像是点菜一样。最关键的是我得知道你要做什么菜,然后我才能为你考虑我得为你准备什么食材,那些食材应该怎么预加工。在做第三个格式化的时候,基本上所有事情都已经得心应手。

当我把这个东西交给我的同事,让她试用的时候,又发现一个新的问题了。我没有给他们配置宏大按钮,所以要运行那个宏还是用office经典的那个快捷键Alt+F8。在标准的键盘里直接按这两个就可以了,但是在某些品牌的键盘,布局是不可能光按一个键就调出F1到F12的。比如联想的台式机标配的键盘或者笔记本电脑就不行。他们默认的是那个键所对应的是多媒体。我同事的那个键盘是罗技的Wave Keys,也就是人体工程学键盘。她那个键盘默认的也是多媒体,所以当我要她按Alt+F8时候,F8根本出不来,在那种情况下,最直接的办法是按三个键,Alt+Fn+F8。联想的键盘有可能无法把F1到F12锁定为这些键原来的功能,但我确定罗技肯定可以。当我要给我的同事干这种事情的时候,她跟我说多媒体键盘那里的截图很好用。

以前的windows系统自带的截图要不全屏,要不窗口。大概好像从win10开始。win+Shift+S能调出任意选取框的截图,默认会保存到粘贴板。这个也是在我遇到了那个键盘的快捷键之后才去搜索出来的。一直以来我用的都是QQ或者微信的截图。QQ的截图是Ctrl+Alt+A,微信的截图是Alt+A。当我有截图需求的时候,这两个东西肯定有一个挂着,这两个东西除了截图以外,你还可以对图片进行各种加工,比如框选比如模糊。我的同事虽然的电脑也挂着微信,但是她用的却是罗技键盘上面的截图快捷键,也就是调用系统的截图。既然她喜欢用那个快捷键,我也没办法让她把F1到F12的功能还原出来。

在office里,Alt+F8就能马上调出宏的运行窗口,如果只有一个宏直接按回车就完了,但关键是如果遇到某些人的键盘F8不能直接出来,这显得很郁闷。我明明可以告诉她office里面找到开发工具,然后点击宏也能出那个快捷键的窗口,但我选择不告诉。因为如果她知道能用鼠标点的方式,她就不会使用快捷键。这也就是为什么明明很多事情可以很简单,他们需要点击很多次鼠标、滚动很多次滑轮才能做到的原因。

程序该考虑的我会考虑到位,但使用方法,我真的不想再为他们费心了。

实战

2025年11月20日 08:32

对系统的导出数据进行了两种形式的格式化以后,接下来我要把其中一种格式化的VBA交给同事,告诉她该怎么用。在我印象之中,每天他们报送数据的时候用的电脑装的是office软件。我这里说的报送,意思是要得出某个文字转化版本的那些人。单位是很奇怪的存在。联想电脑附带的软件是office家庭学生版的正版,另外一些系统不知道为什么一开始的时候就被格式化了,被某些人装了windows系统之后装过各种奇奇怪怪的软件,最终可能定下来的是一个不知道什么版本的wps。也不知道从哪一年开始单位就有批量买的wps,但因为我是office软件的超级粉丝,wps根本无法满足我的要求。因为wps没办法做Power三剑客。Power Pivot还好一点,我用得比较少,但是如果要对一些数据进行文本合并,SQL没那么容易,需要用字典搭配字符拼接才能实现。在那种情况下,我首选通过Power Query合并。当然用Python也能做到,但是如果某个人的电脑里面装的是office,又在2019以后,PQ内置功能,但如果要别人运行Python,还需要安装,还需要配置环境。

我没想到的是那个同事居然先拿回办公室试一下,她办公室电脑用的是wps。wps我猜她安装的版本是32位,因为我的VBA查询用了ADO+SQL,这两个东西意味着不是所有的wps都可以直接执行。即便单位买的那个wps的版本能运行宏,但是宏里面又用了SQL,这个估计就很悬,最终能不能用,可能也可以但估计得折腾一番。幸好她没有挣扎,直接拿着那个VBA文件就直冲工作地点。她第一次在办公室截图回来告诉说wps无法运行宏的时候我就下去找人,结果没找到,原来她已经直接去工作地点了。过了一阵她又跟我说运行不了,反馈出来的那个信息就是VBA脚本没有找到恰当的源文件。

我第一个反应是她导出的文件会不会文件名有一些空格没有留意到,于是我马上赶往那个地方,结果发现她的确导出了文件,但是她发现导出文件的名字跟我之前跟她说的不一样,所以她重命名了。重命名没有任何的意义,因为导出的文件名不一样,基本可以确定她导出的位置不对。当我问她是在哪里导出的时候,她自己估计也马上发现了问题所在,果然就是因为她导出的文件导出错了。

工作地点的那台电脑一次就通过VBA考验。旁边的那台电脑是一台新的联想,预装office2021家庭学生版,但是那台电脑打开VBA之后就会有一条红色的提示。正常情况下,理论上那应该是一个黄色的提醒,按确定或者允许之类就可以了,但红色的提示好像根本没办法按掉。只要按那条红色的东西,就会弹出一个网页,告诉你一些细节。一开始我没有留意,我不管那条红色直接去选项那里设置允许宏,但即便这样,这个文件也依然运行不了。我就不得不去仔细看红色那条提示对应的那个网页。发现是因为因为出于某些安全原因,系统锁定了这个带宏的文件,需要在文件那里按右键点击属性,然后再点击某个解除按钮,之后才能运行那个文件的宏,打开文件才会出现黄色的提示。所以到底是什么安全设置让那个电脑带宏的文件出现那条红色的提示呢?起码在之前我接触过的所有office里未曾遇到过。

对用宏文件的人来说,宏可能有风险,但是对我来说,宏是我自己写的,我不可能不放心。

❌