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
7

xlookup+超级表实现动态引用

By xrspook @ 11:38:23 归类于: 烂日记

谈Excel,索引肯定是离不开的话题。从经典的lookup到用得很多的vlookup,到index+match,再到vlookup的升级版xlookup,所有的这些都是为了让搜索更方便。xlookup相对vlookup来说的确已经进步了不少,但无论是这些搜索的函数也好,其它按条件汇总的函数也好,总是有一些支持选择列,有一些不支持。之所以有支持和不支持之分,其中一个很重要的原因是支持选择列对写公式的那个人来说很方便,但关键是选择列可能严重影响搜索的性能。感觉上明明很简单的东西却要加载很长一段时间才能出结果,那个加载时间,甚至让你觉得是不可接受的慢,所以在使用这些索引函数的时候,绝大多数的教程都会提醒你数据源得用绝对引用。引用一个确切的范围,即便你把那个范围搞得很宽也行,但是引用一些空白行,又会导致一些意想不到的事情发生,尤其是对某些经典函数来说就会出错。当然,出现这种问题可能是因为我道行不够,如果是高手操作,什么问题都不是问题。

为什么搜索出来的结果可以动态显示,可以显示多行,但是被搜索的内容必须得用绝对引用呢?为什么教程里除了整列选择就没有一些动态确定索引范围的方式呢?隐隐之中我觉得新出现的公式应该可以做到,因为新出的那些高级函数出来的结果都是很动态的。虽然实际上近几年我已经很少关注学习那些新出的东西了,但是我还是有那么一点印象的。

在超级表里面使用公式,引用的单元格不再是经典的单元格名字,而是超级表的列名,前提是你用的那种公式不涉及跨行,如果跨行了,我好像没发现超级表能有什么超级功能,但是如果用超级表的偏移定位函数,的确能实现到达上下行。

xlookup是个比较新的函数,所以它能不能把索引的范围定为超级表的某一列呢?我发现的确是可以这么干的。如果有两个超级表,我要用超级表A作为索引,超级表B的某些数据作为查询条件。那么我在写xlookup公式的时候,我就可以完全用超级表的快捷引用方式。暂时我只尝试过一些比较简单的数据,出来的效果非常好,比我整列引用速度快很多。虽然xlookup是支持整列引用的,但那样的话很慢,而之所以很慢,我估计一个很重要的因素是xlookup只在高级的Excel里面使用,而高级的Excel文件又比低级的Excel文件行数多很多。其实我一直搞不懂为什么同样是Excel的公式,有些函数可以整列引用,有些却不行。有些虽然可以整列引用,但实际上效率不高。用同样的公式,一个引用的是超级表,一个引用的是整列,同样是xlookup,出来的结果就很有差别。如果你在超级表B更新了数据要索引超级表A的内容。引用整列的那个在你把数据粘贴到超级表B的时候,就已经会把你卡得痛不欲生。也正是因为有这种痛不欲生,所以以前当我要引用很多数据的时候,我选择的是用Power Query做一个后台匹配。因为如果用前台做这种整列的索引,整个文件哪怕不是互相影响的那些表,也会变得奇慢无比。在这里我巧妙的地方是利用了超级表的动态性。以前,如果要动态应用可能会增减数据表格内容的时候,好像需要套用offset。

当我要指定某片数据区域的时候,Excel其实是能感知其连片区域范围的,但只是在用公式索引的时候没有给用户一个直截了当的方案而已。

2024-04
24

为啥要这么折腾呢

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

要做一个报销指引的时候,我首先想到的是做一个Word,然后再做一个目录,那么不管你前面有多少个分类,对这个Word和那些目录都是不受影响的,所以实际上就是把需要的东西全部都分在一页一页里面,然后就可以了,目录这种事,是由Word才能完成的,然后可以选择到底得显示到什么分类。目录这个东西,你可以把它当做是一个页码的指引,你也可以把它当做是一个超链接。无论哪一条,你都可以直接找到你要找的那个东西,如果你操作足够熟练,甚至不需要查、不需要肉眼找,只需要调出查询框,然后直接到达。报销项目页面包括了要完成这个报销需要准备的所有资料,有些表格是需要填写的,有些资料是需要预先准备的,比如各种合同、发票之类的东西。需要填写的表格我感觉应该有空表和范表,都带有超链接。这些表格不需要在Word里体现,只需要把空表和范表都放在Word同级或者下级的文件夹,通过超链接就可以直接到达。我感觉Office的超链接应该可以做到引用相对地址,万一真的做不到相对地址,用还可以把那些需要填写的空表和范表做一个排序,给一个序号,在Word里面把这些表格的序号给填上去,同样一目了然,非常快速就能找到你要的表格。这样的操作,谁都可以做。增加修改很方便,因为索引是系统自动完成的。这个也可以保存为PDF,以防有些人手贱,修改了某些东西。保存为PDF之后,超链接依然是可用的,至于那个PDF会不会自动根据Word生成一个一样的PDF目录,我不太清楚,万一真的不行,也可以跟根据Word的目录手动生成一个PDF的目录,可能一开始的时候不太习惯,习惯了以后PDF的目录也会很快完成。总的来说,我觉得Word的这套方案非常实在,无论大家喜欢用电子版,还是喜欢把Word的全套东西打印出来、用纸质查阅都很方便。

我不负责这个项目。一开始被委派了给予这个项目技术支持的人用的是Excel。因为她太熟悉Excel的超链接以及数据有效性操作,所以做了一套级联下拉的东西出来。这其实也没有什么问题,但关键是报销项目的具体附件她以二维展开的方式加在各级分类那里。一直以来我都觉得人肉实现二维操作是非常繁琐的,尤其是当你的附件超过你的显示器的程度,你会找得很麻烦。无论是分类作为列,还是附件作为列。最终的结果都要你在茫茫的东西里找你要找的东西,首先通过一个级联下拉搜索得出某个报销项目,然后同时会出现完成这个报销项目需要准备的附件。接下来她把这些附件全部都设定了超链接,这些超链接对应的表格全部都在这个Excel里面。我已经不记得我到底说了多少个全部。这个东西的维护,一般人不是说上手就能上手,这里里面可能有几十个空标或者范表。报销的人还得懂得在一系列的表格里把自己要的那个复制出来,这个操作可能超越了绝大多数人的能力范围。他们会复制一个文件夹,也会复制一个文件,但要在Excel里把其中一个工作表复制出来,而且还不能改变里面的格式,这个操作能难倒来报销80%的人。我没试过,设定了有数据有效性的Excel转化为网页或者PDF之后会有什么效果,转化为PDF,估计就没有然后了,转换为网页还能进行数据有效性级联下拉操作吗?我觉得这条路不太靠谱,但是直接跟她那么说,又好像打击了她的积极性。

最后我只能悄咪咪地自己努力学习jQuery+Json,努力憋一个网页的大招出来。

2023-09
21

找事干

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

整个科室的人都出去培训了,除了我,所以一整天下来很安静,几乎没有人过来打搅我。只有一个过来找出去培训的那些人,神奇的是昨天单位微信群上也很安静,没有经常闪动。为什么会如此平静呢?

摸鱼这种事情有别人在跟没别人在对我来说没有区别,当我要摸鱼的时候,谁也阻止不了我。虽然有时摸鱼的时候不得不东躲西藏。可当我要认真的时候,同样也是没人能阻止我,不管那是上班还是下班,是白天还是半夜,只要我想干下去,哪怕那跟加班费没有半点关系,我也不会停下来,因为那是我想要干的事。

四周很安静,没有任何的干扰,也没有什么特殊的任务突然降临,所以我该做些什么呢?在做完平时应该做的那些事以后,我应该做些什么呢?摸鱼什么的摸多了也会觉得无聊,所以还是要找一些正经事干一下。有事可干的时候,你就只管去干,干就完了,但是当你无事可干又得找些事干的时候,的确挺烦恼。我觉得这个烦恼对我来说已经存在了好长一段时间。究其原因是有些时候你根本打不起去干某事。一方面你没什么事干,另一方面是有些事你或许可以干,但是你不想去干。这两个因素凑起来就变成了一个死循环,人就是在这个死循环里。慢慢地耗费着生命。

前天下午,我突然想到要以另外一个数据模板写一个VBA的汇总脚本。汇总脚本之前我已经写过,而且已经用了一个入户周期,2.1万吨的玉米入库绝大多数都是通过那个东西生成的,一直都没有问题,所以根据我的数据模板生成那个东西是完全没有毛病的,但如果我换了一个数据模板呢?我自己的数据模板没有毛病,其中一个很重要的原因是里面一些关键参数的设定我是以我的模板的某些数据量身定做的,但如果我换了一个模板我就得把某些数据转换过来。比如把两列的数据有条件地合并为一列,这是可以预知的,另外一些不可预知的我只能尽可能的把我想到的都做出来。当我遇到这个问题的时候。我感觉明明很简单的东西,为什么就要搞出那么多的花样呢?为什么这个不应该随心所欲的东西,实际上就这般随心所欲呢?大家都是说根据某个国标去做的列表,但实际上用起来的时候五花八门。我自己用的那个转换脚本是完全根据我的那些乱七八糟理出来的,但我不知道别人的乱七八糟到底乱成一个什么模样。这是一个无底洞,我自己的处理方式是嵌套很多层replace,但显然对小白来说,这样的操作非常不友好。所以在新的汇总脚本里,我采取的方式是建立一个索引,把集合五花八门的索引得先建立好了,然后我再以左外的方式匹配某些关键词,把所有的内容给关联上去。因为是开放的,可以很容易进行编辑,而且不需要他们懂得任何公式嵌套技术。这是我能想到的一个很大的坑,但我觉得还有一些更大的坑隐藏在阴暗处,比如别人生成汇总的那个数据模板不是我理解的那一款,他们需要在那个模板上手动编辑才能出结果。这就意味着索引的方式得发生变换了。还有一个就是万一在另外一个参数的地方,他们那个基础数据表还得进行某些修改才是他们汇总表的那个格式,那么那个地方也需要进行加工。综上所述,我觉得其实这些坑可以完全不存在,但问题就是设计软件的人和使用软件的人思路不一致,使用软件的人没有考虑到以后会被要求进行这样的操作,所以一开始默认套用了某些增加参数的方式。最终结果是他们得绕一大个圈、人肉查找好几个表才最终汇总出一个结果。这样就会导致汇总出错的概率提高,同时也会让人没有必要地忙乎一大轮,而且是天天都得这么忙。

如果把这些事情都理清了,根本不是问题,但可以肯定的是,不是所有人都愿意在这个理清上面花时间、把这一整套人肉的操作变成自动化。因为从根本上说大部分的他们只是为了仅仅完成任务,而从来没想过要把那做得更好、做到极致。

2023-07
29

最后的小计也出来了

By xrspook @ 10:03:24 归类于: 烂日记

又花了大半个下午的时间,我把python跨表查询版最后的那个小计功能也开发出来了。其实前一天晚上我已经找到了类似的案例,只要按研究透的那个东西,接着往我自己那里套就可以了。我大概明白里面用到的公式到底是干什么用的,但是把它们套起来了以后,我发现用在我的那里无论如何都不对,所以我就在案例里不断套脚手架,不断地做注视去掉东西。最终发现让我失败的原因是我的那个dataframe是没有索引的,这就让我后面折腾了好长一段时间。

要在dataframe里加小计,首先需要对进行小计的项目进行分组处理。前一天我已经了解过,这样分组出来结果就只是那些聚合的数据。这些聚合的数据如果你不需要带入特殊的分组词,那么你跟原数据合并,然后根据你的分组项目名排序,小计就会合体到原来的dataframe里。如果你要加入小计这样的词语,你就得虚拟新增一列以非分组项目为名称的列名,内容就是小计之类的词。这样的分组结果我不知道为什么那个案例最后要设定以分组项目为索引,因为我在折腾那个案例的时候发现做不做这一步出来的结果没区别。

最最关键,让我折腾半天的根本原因是我要加小计的那个dataframe在从Excel读取数据的时候就已经设定了不添加索引。我发现当我去掉了案例的默认索引以后,和我的脚本出现了同样的问题。所以解决方案是先给我的datafame添加一个默认索引,然后再进行上面说到的分组操作,接着把有默认索引的dataframe跟分组结果结合在一起。同时对分组项目排序。分组后的结果有没有默认索引都无所谓,因为合并时都得重置索引。我没有试过如果这个dataframe也自带了默认索引,最后能不能成功合并。纯粹为了探索,我应该了解这个,但因为我运气好,在研究之前就已经得到了我想要的结果,所以我就没有继续下去,接下来我会继续拿那个案例把玩一下。

为什么会在Excel的单元格数据传入pandas的时候就把默认索引禁止掉呢?其实不禁止也完全没有问题。因为在最后把加工过的东西输出的时候,我可以控制不输出。之所以会有这样的习惯,写出这样的控制,是因为我看的第一本用python批处理Excel的书里面是这么写的。在看那本书的时候,我觉得那本书写得一般般,因为他给出了一个例子,然后大概告诉你要实现什么功能,接着就是展示脚本。我觉得起码你得在介绍那个例子的时候,除了源数据本身,也得展示一下你最终的效果是什么。他们还偶尔说不清具体需求是什么,唯有去研究他们的代码,你才知道原来具体他们要干那个。

在一个明细数据表里加入小计这东西是完全可以实现的,但是从数据处理的角度考虑,为什么我要把明细跟汇总合并在一起呢?如果用我的Excel思维去考虑这个问题,我觉得明细表就是,明细表汇总表用透视表表达出来就好了。因为数据透视表是很灵活的,可以用任意的汇总维度去观察同一个源数据。python可以轻松处理Excel的数据,但是到了Excel以后,展示的方式的控制好像python的插件就有点难以直接控制,而要控制这个最好的方法就是通过api,用VBA控制,因为vba是原生office的自带工具。

我发现python批处理Excel脚本的运行速度跟电脑的CPU有很大关系,跟内存大小关系不大。用我办公室的电脑运行,但需不到6秒,用我宿舍的电脑运行大概需要7秒,用我家里的电脑运行大概需要7.5秒。这是在正常的情况下,如果我的电脑正在执行多任务,这些时间就会说不准了。之所以我说这跟电脑的CPU性能有关,因为运行脚本的时候我盯着任务管理器。发现有段时间Excel的CPU会飙升最大40%,虽然维持的时间很短。不同性能的电脑同样CPU,封顶都会飙到40,这就意味着CPU的核数越多,单核的性能越好,那么这个脚本的运行速度就会越快。6系的i5运行6秒,2系的i3运行8秒,是有差距,但经历过Power Pivot得12秒起,python很爽了。

我觉得这个python脚本还有继续改进的空间,继续努力。

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