2024-09
14

升级VBA抓取方案

By xrspook @ 19:26:21 归类于: 烂日记

无论是SQL方案还是数据透视表方案,我都是用4个类似的脚本,一款做出来了以后,调整部分的内容,生成其它三款,所以一开始的时候抓取数据我有4个宏,其实里面的内容大多相同。汇总数据,我也有4个宏,SQL有4个,数据透视表也有4个。因为SQL跟数据透视表作用是相同的,所以它们分别搭配4个抓取数据的宏各自组成两个文件。就实现功能来说,这两个文件从形成的那一刻起,已经可以起作用,但是我能不能更进一步呢?

数据抓取用的是最基本的VBA,就只是把数据区域选了一下,然后去掉表头,最后搭配我想要的表头输出。我没有在那个地方就进行筛选,因为之前已经说过,VBA自带的AutoFilter功能不太好用。一开始我没想过要用数据透视表,如果到了SQL,一句where可以把正向的反向的或的且的,想怎么加就怎么加,只是一句话的事情而已。既然在一开始数据抓取单元格层面那么难做筛选,那么我到SQL里做筛选就可以了。后来,因为我又做了数据透视表方案,数据透视表方案可以对字段进行筛选,但关键是如果我抓取了那个数据里面不含有我要排除的内容,又或者我抓取的数据全部字段都要被排除掉,无论是哪一款,都会出错,所以如果用同样的抓取方式,到了数据透视表的那个宏里面,我就需要进行复杂的循环和判断。嵌套一层又一层的公式,再加一层又一层的判断。虽然也能实现我想要的东西,但那样做很麻烦。在做出数据透视表方案的那天晚上,我就在想,在一开始的抓取的宏里面,我能不能直接把筛选这个步骤给做了呢?

要在数组里面进行数据筛选,想想都知道肯定可以实现,但是我想到需要嵌套那些数字就觉得很烦,所以我就翻出了多年以前我用来合并某些数据表的宏。在那里我发现自己用的是把全部数据都粘贴到一起,然后做一个行的删除。当时做的行删除很简单,只要匹配一个字段就行了,我现在的行删除,需要匹配的字段可能会有很多,所以我就把那些需要删除的字段都先放在一个数组里面,然后再利用之前那一天从网上抄回来的那招Application.match方案。在一句if里面就能实现查找某个元素在不在某个数组里,如果在的话就把行删掉。之前写的那个宏的确就这么简单,因为需要删掉的那个部分隔好多行才会出现一次。现在我需要处理的那些数据,说不准我需要删掉的那些行是隔一些才出现,还是下一个就又得删掉,所以在删掉之后,我又赶紧做了一个减法操作,让程序重新测试那一行到底需不需要删除。

在一开始数据抓取阶段,我就把数据范围确定了,把需要例外的数据全部删除,所以后面的SQL跟数据透视表我就可以轻松地直接进行操作,尤其是数据透视表,操作变得简单明了。

因为一开始我不是大神,我只能摸着石头过河,逐渐的磨练自己。

2024-09
13

VBA里搞数据透视表

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

因为我知道我要实现的那个功能,SQL可以做,数据透视表也可以做。就写代码的熟练程度来说,SQL我肯定更熟悉,VBA的数据透视表有很多参数,我搞不懂到底是什么,反正要实现那个功能,通常是录制一个宏,然后看着办,有需要的数据保留下来,不需要的数据直接删掉。录制的宏通常都很啰嗦,里面有非常多没有必要存在的东西。在不了解数据透视表在VBA里的参数的前提下,先进行一个录制显然是比较靠谱的步骤。但有些东西靠录制是录制不出来的,比如某些字段我需要进行筛选,我只知道有些东西是不能出现的,但我没办法确定可以出现的是什么,所以那一堆不能出现的东西都是反参数。在录制宏的时候,你只能看到什么就反选什么,但关键是这个数据源跟那个数据源的那些参数是不一样的。不一样我只能设定一堆反参数,只要它们是其中一个,就不能显示,但实际上这样的反参数让VBA的数据透视默认不出现你就得兜一个大圈,套上好几层公式实现。最终,在我调试的时候发现的确那些嵌套的公式能把那些反参数都排除在外,但如果数据源里所有数据都是反参数的一部分,那么就会报错,于是我又得在外面加一层捕捉错误的判断。真的是非常折腾。为什么之前我考虑的是SQL而不是数据透视表,反参数是其中一个点,另外一个点是排序。在SQL里,使用自定义序列排序是非常简单的事情,但是数据透视表的字段该如何排序呢?兜了一大圈我发现也就只能真的在Excel里面增加自定义序列,但如果我想用即弃呢,于是还得出了一招VBA先增加自定义序列,排序完以后再把自定义序列删除掉。这个操作在ExcelHome的教程里有,他们教的是在VBA里面,对单元格或者数组排序,不是针对数据透视表的,但实际上原理一样。

这个增自定义序列和减自定义序列到底是怎么确认呢?原来Excel还会对自定义序列给一个序号,所以在增自定义序列的时候,你就得把这个序号记下来,在减的时候把那个序号写上去。我不知道为什么其他人说数据透视表的自定义序列好像怎么排都不是自己想要的效果,但就我个人的经验来说,只要你在Excel里增加了自定义序列,当你刷新数据,默认对某个已经自定义过的字段进行升序,那就是你定义的那个顺序,不需要在设置里面搞一大通。但实际上我也搞不懂,手动设置里很麻烦的东西到底是什么。为什么数据透视表里面的排序就不能像普通表格排序那样那么的直观。我要以什么字段排序、以什么标准排序是系统默认的还是自定义序列。当然,数据透视表里还得考虑一个问题,就是有可能是套叠了多个汇总条件的,如果你自定义的是最后一层条件,首先限制你的是前面的那些所有条件,所以你想最后的那个自定义序列完全按照你的想法排列,你只能把它放到最前面。数据透视表跟SQL比起来,我感觉运行速度会慢一点,可能因为我里面判断设置的东西比较多,所以需要闪那么一下才能结束,但是SQL虽然我已经有意识地关注结尾这个问题,但测试频繁以后,SQL是会出现一些莫名其妙的事故,当你把所有东西关掉再打开就正常了。相比之下,数据透视表不会这么神经。

用不同的方法实现同样的事情,得出一样的结果,这种感觉很好。在探索这个的过程中,会让我体会到二者的优劣,以后选择的时候,我就可以更有底气地数出1234。

2024-09
12

不完整的错

By xrspook @ 8:09:45 归类于: 烂日记

上一篇说到了数据汇总的问题。这个周一我就是按照上周五设定的那个步骤去做。在做的过程中,几乎没有发现什么问题,但是当我做完所有,一个个表格验证的时候却发现不知道为什么有些表格 SQL抓取的数据不完整,VBA从原始表格筛选、抓取的数据没有问题,但关键是SQL从本地的文件里提取到的那些数据不完成。第一次发现这个问题的时候,我看到的是为什么汇总数不一致。当我把SQL回退到第1步的时候发现第1步获取的数据就已经不完整。明明有50行数据,实际上只能提取到42行,重复多次依然是那个效果,但是偶然当我把文件关掉重开以后又好了。所以这个有时发生,有时不发生,到底是什么情况呢?当我打开VBA文件,一个一个测试的时候,发现前几个还好,后面就会出状况,可能是数据不完整,也可能是弹出一些莫名其妙的错误,但只要你把所有Excel都关掉,再重新打开又没有问题了,但是在测试几个以后,又会出现这样这样那样的状况。用VBA+ADO+SQL整理输出数据我已经实施过很多遍,之前从来没有遇到过这种神奇的状况。最后当我打开VBA脚本,无意之间拉到最后,居然发现cnn没有close,也没有初始化。cnn是个非常牛逼的东西,但是那个玩意也要耗费巨大的资源,在我出现数据状况的时候,我没有观察过我电脑的性能到底如何了,会不会CPU或者内存甚至二者都有点状况了。因为一次又一次的验证数据就意味着我得一次又一次调用cnn,光是打开又不关闭,最后就会出现奇奇怪怪的事情。当我把所有脚本都加上了结尾以后。从头到尾10个表以上的数据,一次性搞完,期间不会出现状况,所以多么神经质的行为才会导致了这种弱智事情呢?以前我倒真的从未试过这样。有过这样的经历以后就让我明白到cnn打开和关闭都必须是一个闭环,在一个宏里就得实现到位。如果某个宏被卡住了,半路停在那里,估计那个cnn是不正常的,当我又再次启动其它,只会让错误不断积累,最终导致崩溃,又或者是得不到我想要的东西。

写程序可以很快,但是调试却非常耗时间。这大概是所有码农都必须面对的事情,但实际上更多的人只顾写,只顾实现,而不考虑全盘,不尽可能地用全面数据测试,最终的结果就是使用的时候出现各种各样的未知情况。我不知道其他人到底是如何调试的,反正我真觉得调试的过程比写脚本更费神,因为要考虑所有的情况,哪怕某些条件可能非常极端,几乎不会碰到,但即便那样,一个健壮的程序应该依然能捕捉到那个错误,然后给出对应的反馈。比如我抓取不到数据了,我就应该弹框告诉人家我抓不到,因为有些操作的抓取数据以后才能进行,所以既然能判断抓不到数据,后面的也就不用继续了。

调试程序是一个很磨人的过程,这个过程重复多了,人自然而然就会向完美靠拢,即便我们一定不能成为完美的那个。

2024-09
11

VBA里奇怪的筛选与粘贴

By xrspook @ 9:05:57 归类于: 烂日记

上周五我尝试纯粹用VBA的方式对某些数据先进行筛选,然后保留在粘贴板,又或者是把那些东西输出。前提是对某些数据进行筛选复制的时候,我首先必须得有个条件。理想很完美,现实很骨感。

VBA本身就自带一个叫做autofilter的函数,那个东西可以对选定的单元格区域进行筛选,你可以正向选择,正向的时候可以多选,可以把需要选择的内容组成一个数组,实现多选。你也可以进行反选,但反选的时候你却不能把反选的条件建立成一个数组进行同样的操作。这些都只是针对一次筛选而言的,如果同一片区域多次叠加筛选,第一次你筛选的是第1列,第二次筛选的是第2列,我感觉如果第三次和第四次你反选的是第2列估计也行,但关键是我需要选择的那个数据是一个作死的不规范有两行甚至三行的标题栏,但是autofilter这个函数默认输出的东西就含有标题栏。本来我的数据范围是不规范的,如果我一开始就把前面三个标题栏给去掉。那么在我进行autofilter的时候,就会从纯粹的数据开始,显然那就不是我想要的东西了。因为哪怕最终筛选的数据是空,也会默认带入那个标题栏。所以你就搞不懂为什么步骤都对,但结果就不对。

autofilter之后要进行一个特殊粘贴,那个东西是只对可见的数据复制。就普通人的思维而言,我复制了可见的数据,那么理论上我就可以算出它有多少行,如果是0我就直接不输出了,如果大于0,那么我就可以输出,但实际上特殊粘贴又不可以用一般的技术判定到底筛选的结果是不是0。虽然也能判断有没有,但需要绕一个圈去实现这种功能,所以VBA为什么有那么神奇的思路呢?筛选可以进行,但是你不能对反向的数据批量进行处理,你也不能把特殊筛选结果直接保存为某个东西。当你觉得你大概可以把可见的部分保存到一个新的区域,然后你就可以去头去尾之类,但实际上当你再去查看那个新区域的时候发现原来是保存了个寂寞而已,那种神经性质跟那个可见区域是一样的。我不知道以前的人到底是怎么忍耐VBA这些奇怪脾性的,因为在接触这个之前我就已经接触过pandas。pandas的数据分为两个,一个是标题,另外一个是数据。输出的时候你可以都输出,你也只可以只输出其中的一部分。在使用pandas的时候,我没有解决过一些我的实际问题,我都是按照书本上的例子进行操作的,所以到底在我使用的过程中会不会也遇到一些像VBA这么神经,明明觉得可以,但实际上又不可能直接实现的事情不知道。

周五的下午,折腾了一番以后,我的目标数据最终可以复制到粘贴板,但是在VBA那个脚本结束之前,我就也得把那粘贴出来,否则当那个结束以后,剪贴板的内容就没有了。为什么会这样呢?不是说当我把数据复制到了剪贴板,而我又把Excel关掉,软件会问我要不要清空剪贴板的数据吗?但显然现在Excel都没关闭,我只是关闭了那个脚本,但我剪贴板却什么也没有了。

周五在回家的路上,我又努力地想了想这个问题。最后决定,我没有必要这么折腾自己获取剪贴板数据。反正全体数据不多,我直接对那个整体数据进行加工处理就行。加工处理的方法是首先从我的目标数据那里通过VBA获取我要的部分,然后输出到指定的位置,接着通过ADO+SQL进行数据处理。准确的来说,就是一个分组聚合、添加汇总以及排序。当然其实最后这个ADO+SQL的操作我也可以换成数据透视表,但如果那样的话,最后的排序我要让那完美的按照我想要的方式,我就只能先在Excel添加一个自定义的序列。无论是SQL还是数据透视表,分类汇总和排序都一定会比在VBA里用数组方便非常多。

思考一个问题的时候,有时可能我们有点过于钻牛角尖了,退一步,可能会有一个更清晰的思路。

2024-09
10

发现规律,抽象步骤

By xrspook @ 8:53:01 归类于: 烂日记

星期天的下午,初中的同学群又开始了数学题答问答。这一次又不知道是什么题目,反正照出来的那个相片右下角页码那里写的是有理数。有理数无理数具体是什么东西,实际上我已经不太记得了,但这就只是一个定义,稍微翻看一下书本,就会回忆起来。我不知道有理数跟那道题有什么关系。对一个路人来说,我觉得那道题就是一个考察发现规律的,发现那堆数字正负值的规律、发现那堆数字排列组合的规律。相对于高中时代的题目来说,我感觉那道可能是小学或者初中的题目,规律还是比较好找的。

当我第一眼看到那道题目的时候,我就彻底没想过要理,直接继续看我的电视,把那忽略掉,因为我知道即便我不回答,其他人也会回答。我不是唯一的一个答案。看上去那是一本习题册或者一个试卷册,无论是哪一款,肯定有标准答案,问题只是我的那个同学不知道那个答案到底是怎么来的。其实我也不知道他为什么要知道那个答案是怎么来的,毕竟要做这个题目的人不是他,而是他的孩子。所以孩子不知道怎么做那道题,为什么操心了半天的人却是家长呢?当我那个同学还是个孩子的时候,他不会做的题目他的家长绝对不会为他操心。不会做就不做,不会做就回去问老师问同学。现在这个该怎么做的这个责任仿佛都落到了家长的身上,又或许,是因为我的同学觉得他还是个小孩的时候,他的父母没尽过这种义务,他觉得不好,所以现在他成了孩子的家长,他觉得自己有责任去弄清楚,然后教小孩。

他觉得这是他的义务,但我就只是个同学而已,我没有义务解答题目。有兴趣的时候可能看一眼,没兴趣的时候就像这样直接忽略。周日下午吃过晚饭,回单位的路上,我又打开了那个群,仔细看了一下题目以及同学的回答。看过那道题目以后,我就得出了最上面的那个看法。我不知道那道题跟有理数到底有什么关系,但可以肯定的是,那道题的意图就是让做题的人发现规律并利用规律。

发现规律利用规律这种东西,在往后的人生之中实在太普遍了。抽象到哲学的层面,几乎每一件事都是这么个情况。数学这种东西,理论上是最容易用逻辑解决的,尤其是对大学以下的数学而言。以前没发现,后来我才意识到,以前那些有标准答案的题目逻辑性都非常强。只是当年的我要应付的事情太多,没办法逐个击破,没有领会其中的逻辑,于是也就只能死记硬背了。

那道题给我的感觉就是,对懂的人来说,找出规律以后,代入数字就能出结果,但是对那些知道规律,但又不知道如何把规律抽象成公式的人来说,那就等于是只能把那些东西都罗列出来,但关键是如果数量级很大,全部罗列是不可能的任务。对懂行的人来说,无论是自己列公式,还是写个程序跑一下,前提都是你发现了其中的规律,而且你把那个规律抽象成某些公式,于是最后题目就变成代入数字求和。如果硬是把所有东西都罗列一遍,那就只是写个程序,让程序按照你要的那个样子跑一遍,但这个跑一遍对懂的人来说是毫无意义的。因为不需要跑,不需要用最后的结果数字验证就能得出预判的那个结果就是最终答案。

编程是什么呢?编程就是发现规律,然后把那些规律抽象成某些步骤。

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