手贱惹的祸
VBA可以对普通的Excel文件用SQL查询,虽然我已经用的是超级表,理论上单元格的数据格式是一致的,但实际上这不是一个标准化的数据库,我没有办法在一开始的时候就对每个数据进行声明,所以在数据处理过程中就会出现这样那样说不准为什么的事情。
星期一的下午我跟往常一样做了些普通操作,最后当我用VBA生成一个汇总数据的时候发现弹出一个“标准表达式中数据类型不匹配”的警告。看到这个东西,我的第一反应是肯定是获取的数据里面有一些不规范的东西,比如说某一列通常是数字的,但是却出现了文字,但实际上我翻查了全部源数据都没有发现这个玩意。没办法之下,我只能做一个脚手架,一个一个的去排除,最后发现问题出在where里。where里有一个“性质<>某某某”的限定条件,问题就出现在那个地方,只要把这一句删掉,VBA是可以正常运行的,至于结果对不对不知道,反正能运行,然后我又回到了这一条的上一条结果,发现where里面的那个条件是没有问题的,所以这到底是什么问题呢?
然后我又想起,在进行普通操作的时候,我好像在某列数值的单元格里发现了一个汉字,说不准为什么那里会有一个汉字,但一个汉字足以影响那个单元格的类型。为什么我深有这种体会,因为如果某一列全部都是数字那么 VBA+ADO+SQL通常都会默认那是一个数值,但只要那一列里面有一个文字,所有东西都会被识别为文本。对数字进行聚合是理所当然没有问题的,但如果对文本进行这种操作,我不敢想象会出现什么东西。当然了,把文本作为分组条件,一点问题都不会有。
我感觉自己的VBA程序是健壮的,因为我已经用了他一年多了,之前从来没有出现过这种问题。有段时间经常会出现这样那样说不准什么问题的问题,但是过了一段时间之后,那些问题又自动消失了,所以我更相信那是有段时间windows更新导致某些框架不稳定导致了那段时间的意外。除非我对源数据做了更改,又或者是出现了某些意外,否则不会报这样的错误。
接着我又记起周一下午某个基本操作的时候,我好像发现在那个超级表的下面有一个“她”字。那个东西在不连续的单元格里,不是超级表的一部分,但关键是如果我用SQL获取数据,那肯定也会被纳入其中。看到那个莫名其妙的“她”字以后我已经把那删掉了,所以我看到的那个原始数据表格没有问题,但只是看上去没有问题。
折腾了好长时间未果,之后,我不得不重新翻出前一天晚上的源数据。然后手动把周一更新过的东西全部都贴回去。再去用VBA汇总,一切正常。在贴回去之前我首先用VBA测试了一下汇总没有问题,然后我才开始贴,贴了之后也没有问题。如果这个东西没有问题,也就是周一之前这个表格是没有问题的,但不知道周一进行了什么操作,导致了问题的出现。倒退以后重新贴数据没有问题,的确这个汇总也算保住了,但是我却一直放心不下,找不出问题的原因下一次依然会手忙脚乱。
吃过晚饭后我重新翻出有有问题的那个源数据。我的猜测是,因为数值列里面出现了一个文本,虽然我已经把文本删掉了,但是那个文本已经影响了那列单元格的类型,最终导致VBA弹出错误提示,虽然那个错误提示并不是出现在VBA调试发现的那一列。我的做法是在不修改VBA的前提下,把有问题源数据超级表下面的所有行全部删除,然后保存,再次运行vba,源数据通过了,可以正常运行。通过这样的操作,就能排除错误,非常有可能意味着我上面的猜测是对的。然后,我故意在数据列超级表外的单元格写一个字,然后保存,VBA汇总挂了。我把那个字删除,保存,VBA依然挂。但是当我把写过字的那一行删除,VBA汇总好了。这再一次验证了我的猜想。
这种事情该如何避免呢?首先不要手误,不要乱填。手误乱填这种事过去那么多年都从来没有发生过,为什么就发生了呢?到底是我的问题,还是另外一个人的问题?如果要避免这个事情,最好我在SQL引用源数据的时候就直接就限定为超级表范围,而不要把超级表所在的所有列都含进去。无论是哪一点,都是可以实现的。限定超级表的范围不太难,但关键是人手贱的这个行为,这一次出现在某个不知道为什么的单元格,下一次如果覆盖掉超级表的一个老数据呢?要避免这种人的失误非常难,但是人为什么会犯这种弱智到极点的失误呢?而且是犯了还毫不知情。
但总算这一次,我找出了可能的原因。