2023-08
27

连续日期累计求和

By xrspook @ 11:32:10 归类于: 烂日记

昨天说到库存查询,最后的展示方式是透视表,透视这个东西只要前面做对了,就可以实现,那就只是最后一个步骤而已,但是如何得到透视需要的所有东西呢?在做这个库存查询之前,如果我需要得到某数据在连续日期中的汇总,我会先把那些数据按日期分组,然后选定日期表里面其中一段连续日期,接着用左外的方式连接日期表和数据。但问题是在库存查询中,我最后的结果是透视的,这就意味着被透视的那些字段在没有被透视之前,是各自对应一段一样的日期表,如果最后透视出来的字段有5个,就意味着我有5段一样的日期表,我该怎么表达这个东西呢?

在解决这个多段一模一样的连续日期之前,我首先攻克的是累计数。在SQL里面实现累计数有好几种方式,但问题是不是每一个都适合在Excel的VBA里实现,比如窗口函数over在Excel里面就是不支持的,虽然窗口函数的效率是最高的。对同一个表进行子查询可以实现累计,但问题是这样生成的累计无法用在下一步的透视里使用,接着我在另外一个方案里面看到了笛卡尔积的方法,笛卡尔积得出来的结果跟子查询完全一样,但笛卡尔积出来的结果可以用在下一步的透视里,而且同样的数据,笛卡尔积的运行效率比子查询高(可能是我测试的数据少?)。这个累计数的问题,我在Power Pivot里也研究过。我觉得PP的解决方案跟子查询有点类似。在计算累计数的时候,PP的效率很高。在用PP实现累计数之前,我曾经用Power Query实现累计数。我的PQ解决办法是先生成变化数,然后按日期把变化数累加起来。接下来用日期表跟这个数据左外连接,如果不是天天都有变化数,那么这个合并后的累计肯定会有空行,这个时候再用向下填充的方式补全。用这样的方法在PQ里的确是可以计算出每天的库存,但是效率非常低,所以在那以后,当我要做累计库存,我会直接放弃PQ选择PP。现在我已经掌握了在VBA里用SQL的方法实现。在筛选的日期不多,以及最后被透视出来的字段不多的情况下,效率挺高。比如最终我只需要展示一个月的数据。运行时间通常不会超过0.5秒。我个人觉得1秒是一个分水岭,如果1秒以上才出结果的话,我觉得这需要等待,尤其是运行时间超过2秒,我觉得那得优化了。低于0.5秒的运行时间对我来说几乎是无感的,我可以接受这种方案。

在累计数可以实现之后我要继续研究怎么按照条件需求把日期表捆绑上去。折腾了好长一段时间,都是没什么结果,于是我就去吃午饭了,在去吃午饭的路上,我突然想到,要把这个日期表扩充开来,实际上我不就是要做一个按条件笛卡尔积吗?所以我需要进行左外连接左边的部分,在这个情况下就不是一个普通的日期表,而是被透视项和日期表进行笛卡尔积的东西。笛卡尔积这个东西,如果数据很多会是一个噩梦,甚至会让电脑崩溃,所以所有教程都会告诉你,如果你要的不是这种东西,尽量不要做这种操作。但思前想后,我发现我正是需要这种东西。吃过午饭后,我赶紧去测试我的想法,果然,用笛卡尔积的结果再加后续的操作,我就能生成我需要的东西,并最终能以透视的方式展示出来。

我感觉现在当我把一些最基础的东西用熟练了以后,渐渐地我体会到了一些其实你明明知道,但是你却完全没有料到可以这么用的方法。

既然人可以通过某些逻辑得到某些结果,那么我应该可以按照这些逻辑生成一些自动化的方法,在这个时候,我最讨厌例外情况。

2023-08
26

一次一个小愿望

By xrspook @ 10:58:44 归类于: 烂日记

每次都定下一个小目标,然后去实现。结果发现一天多一点的时间居然就能搞定一个问题,这种进度有点出乎我意料,因为之前的那些问题让我挣扎了好长一段时间,起码有两三天,之所以后来进度加快了,大概是因为我明了了我要做什么,但是尽管是这样,还是会遇到很多奇奇怪怪的问题。

这周初我解决的是批量生成月度核对表。我把这个任务分成两个步骤,一个是查询到底要生成多少,接着就是把查询到的结果生成文件,但是那个结果跟文件又不一定是完全对应的,根据不同条件可能10条查询结果最终会生成9个表。因为实际上某些条件是需要合并才能得到我想要的文件。在怎么设定条件,如何进行循环方面,我纠结了好长时间,几乎可以这么说,上个周末我一直在做各种尝试,为的就是最终实现这个目标。

在完成了批量生成月报以后,接下来我要做的是生成某个仓的分仓台账。相对于之前的月度核对表,这个单仓台账相对而言条件是固定的,而且必定只生成一个文件。同样我首先做的也是做一个查询,查询一下这个仓到底有多少条记录是可以生成分仓台账的,我又要生成具体哪一条。有些是无法自动实现的,因为实际情况是某些仓某些筛选条件是不一样的,但实际上应该反映在同一个分仓台账里。这个时候就需要手动合并一下条件。这种例外的事件不确定会在什么时候发生,所以必须给手动留有余地。之所以分步骤,其实一个很重要的原因是其实有时并不是为了生成分仓台账,只是要查询一下这个仓的情况。批量生成月度核对表,我花了好几天的时间,但是生成分仓台账,我只花了一天不到。

接着,我研究的是库存查询。在不同的条件之下进行库存查询,最后的结果是以一个透视表的方式展现出来,根据不同的查询条件透视的项目不一样。虽然我想到透视的项目是不一样的,但实际上在我研究的过程中,我先在单一的条件上做尝试,当单一的条件生成的数据没有问题以后再把它扩充到动态条件。因为有了之前月度核对表的锻炼,所以动态条件该怎么做我是有点底的。

SQL最基本的查询语句基本上我已经比较熟悉,这一次库存查询最后一步需要做一个透视。透视这个东西是我之前没有尝试过的,虽然我是Excel数据透视表的超级粉丝,但是在SQL里面控制这个东西,我还是很不在行的。所以到底什么条件可以控制,可以控制到什么程度我是不知道的。教程通常都只是最简单的那些,用上面的数据你重复100遍都不会出什么幺蛾子,但是在实际情况下你会有更多需求。比如当我要控制被透视列的排序的时候发现好像在Excel的SQL里无法做到。即便我在透视之前那一步已经排好序了,但是透视的时候依然是我行我素。让我比较挣扎的是,在透视之前我已经通过分组合并计算出被透视的列的合计数了,但是透视之后合计混在了那一堆被透视的字段中间。最后我已经想到不计算合计,在SQL里面生成透视以后输出到数组,我在数组里面做合计。就在我几乎要放弃的时候,原来合计可以通过在透视的select里用一个聚合函数实现,这样的话透视之后的表格就是先是条件列,然后是合计,接着是那些被透视的列。虽然合计不是放在我想要的最后面,但起码放在了最前面。

库存查询研究过程中让我纠结的问题是什么,明天继续。

2022-10
11

填充单价

By xrspook @ 9:49:59 归类于: 烂日记

工作出现了些许空余的时光,于是我赶紧继续开始看我的《DAX权威指南》。筛选上下文、行上下文这种东西实在让人非常抓狂。有些时候我是完全理解那种关系到底是什么,但实际上当用起来的时候又好像各处碰钉子。

一步步的学习DAX这没有任何问题,但学着学着自然而然我就会往自己的问题上面靠,于是心就飞走了,然后虽然已经学了100多页,但是感觉我还是找不到思路。我不知道如何在Power Pivot里面把两个日期扩充为一个日期列表。于是我就折腾了一番,这个在Power Query里实现我100%肯定是轻而易举就能做到的。以前我好像做过。支持我使用的方法是修改人家的高级例子,从前只是一步一步按部就班来。以日期扩充之后的表为基础查询模型里的计算库存不是不可以,但是翻来覆去非常耗时间。从前在PQ里计算库存,在情况不那么复杂的情况下弯曲折叠各种填充已经很耗费人力物力,而这种库存的计算实际上在DAX里面是秒杀完成的。这也就是为什么当年我放弃了继续走PQ这条路计算库存以及库存费用。在PP里,计算库存其实我早就已经搞出来了,虽然实际上那个筛选条件我至今都没搞懂。现在的问题是那个阶梯费用表达把我难住了。从简单的几个时间区间生成一堆连续日期单价对PQ来说实在太简单了,但为什么这种事情用DAX去表达却那么的难呢?所以实际上我觉得这个问题跟库存的计算一样,我还没想到那个方法该如何表达,也就是说理论上要做到这个也是很容易的。

如果我的单价用PQ实现,我的库存用PP去实现,最终我只需要很笨地把两边的数复制一下,然后在另外一个地方做一个很弱智的合并,显然这样也能曲线救国,以我现在的知识储备可以这般做到,但显然这不是我想要的效果。这个问题在近期我又开始纠结之前,已经困扰了我一年有多。

虽然不知道最后的那个灵感什么时候才会到来?但我知道那一定会到的。

就在这篇东西口述出来后,那个晚上我什么都没干,没有运动,也没做其它别的,一心就扑在PP里实现单价这个问题上。接近晚上10点,这个问题好像终于有了破解的苗头。用的是LASTNONBLANK函数,网上教程用的是LASTNONBLANKVALUE,但PP里没有这个东西,为什么呢?Power BI里面有但Excel里没有???

LASTNONBLANK ( <列名>, <表达式> ):为表的每行计值表达式,返回结果不为空的最后一个列值。

LASTNONBLANKVALUE ( <列名>, <表达式> ):为表的每行计值表达式,返回结果不为空的最后一个列值所对应的表达式的值。虽然被归为迭代函数,但与 LASTNONBLANK 不同的是,LASTNONBLANKVALUE 的<表达式>参数在筛选上下文中计值,这是由于存在一个隐式的 CALCULATE 将行上下文进行了转换。

https://www.powerbigeek.com/dax-functions-lastnonblank/?f=1
https://www.powerbigeek.com/dax-functions-lastnonblankvalue/?f=1

以我现在的水平我是搞不懂他俩到底什么情况,但Excel里没有我也没办法,把LASTNONBLANKVALUE的东西转化为适用于LASTNONBLANK,这又折腾了好些时间。其实这个东西说白了就是为了向下填充,如果这个地方空白,就用这一列对上一个有数的那个东西向下填充。当然,其实这个东西一开始的意图不是填充,是为了找到最后一条记录,这种东西要准确,通常默认跟时间关联。

虽然道路是曲折的,但我总算在单价这个问题上发现了我觉得应该很简单的实现方式。

2021-04
28

低级错误

By xrspook @ 9:16:37 归类于: 烂日记

非常神奇,单位办公楼的网速理论上限制在500KB/s以内,但是当我用百度网盘的极速下载的时候速度居然能达到900KB/s左右,到底这个数值有没有虚报呢?理论上不可能,但实际上他们真的可以通过某些通道实现这种超越吗?如果网速可以这般超越的话,家里的宽带是不是也能超越呢?但我估计这不行。百度这样的超越顶多是在单位非专业的网管限速条件下实现。一个软件最高下载速度不超过500KB/s,但如果百度在下载进程里伪装成几个软件呢?估计这个速度就能提上去了,而至于极限是多少不知道,反正我在家里试用极速下载的时候能跑满我家的下载速度,也就是超过10MB/s。在单位到晚上高峰期只能保持400KB/s左右的速度,我已经非常满意了,不过神奇的是在百度网盘下载东西,并不是顺序下载的,所以你觉得可以一边下载一边看视频,实际上做不到,因为你可以把视频拉到最后,但非常有可能卡住你的不是最后,而是中间的某一段,这就让人非常抓狂,非把视频全部下载好才能看不可。在等待下载的这段时间里,我顺便语记一下。我有时真的是很佩服自己,因为剩余的下载时间大概只有不到4分钟,我依然可以完成超过500字。如果不是用听写的方式,而是用打字,估计根本没办法实现。起码对我来说,这是不可能的。让我写自己的东西尚且非常难做到,如果让我抄别人的东西,更加是没有存在的可能性。

昨天按照惯例,粮食局的人又来检查我们的食用植物油。昨天我犯了个非常低级的错误,明明前天晚上我已经算好了到前天为止的分品种食用油的库存,但是我只是严格地核对了表,却没有非常上心地记住那个数。其实如果我冷静一点反推的话是可以得出那个数的,因为还剩下100多吨就到7200吨,90%的底线了。但突然被问到散装油的库存的时候,我脑子里一片空白,因为我默认要分品种了,花生油的数量肯定是恒定差不了多少,1800多一点,但豆油这边我却不确定,那个到底是7500,到底是7300,实际上非常明显,应该是7300多,但是脑残就是脑残,突然间脑子短路就会发生这种事。平时他们根本不会问这个问题,过去一年他们已经来了4次,从来没有问过,到检查那天轮换了多少,这个数我一点都不慌,因为每个月末我都会通过微信上报给总公司,所以我只要查到那条聊天记录就万事大吉,昨天我也是这么做到的,其实不看聊天记录,光查账本的话,也依然能得出那个数。显然发生这种事完全是因为我太大意了。如果不是熟到这种程度的检查单位,领导肯定要读一下我们那份自查报告,里面一定会说到当前的库存是多少。至于会不会说到到现在为止轮换了多少很难说。经过昨天这件事以后,我彻底地明白到应对检查这种事不仅仅是要把所有数据都搞得非常准确,而且还得把那些数据烂熟于胸,哪怕不要求精确到小数点,但起码大概的状况我必须得脱口而出。我没有做这样的准备,一定程度是因为过去那么多次检查,说到相关数据的时候,我肯定是早已提供出来,不轮到我这种路人甲去做介绍,但昨天偏偏就是这个包袱丢来丢去以后最后丢到我手上。那个时候我真的感到非常的不好意思,我不应该丢这样的脸,但我敢肯定这样的错误我不会再犯第二次,哪怕是平时去找领导签名的时候,我也会把数目都记住。不仅仅是把某个数记住,也要把某些来龙去脉全部都搞清楚。现在遇到这种事,别人嫌不嫌弃我不知道,反正我是挺嫌弃我自己。事情明明都已经做了,但就缺最后这一步,紧张的时候脑子里一片空白。以前某个领导说我对数字不敏感,的确相对于某些人来说,我不觉得自己敏感,但是我确信有些东西可以弥补回来,比如我花更多的时间去做死记硬背。不做这份检讨,我觉得自己会一直耿耿于怀,甚至睡觉的时候都会辗转,但输出了以后,我觉得自己就会吸取教训、迈过这道坎。

意外不知道什么时候会来,如果能推算出来,肯定就不叫意外了。

2020-10
21

批次问题

By xrspook @ 10:57:55 归类于: 烂日记

我以为我完成了任务,但实际上,我并没有做到。

之所以没有碰钉子,是因为我统计的那些数据,刚好那几个月,只有进没有出,也正是因为这样,我才侥幸的逃过一劫,如果仍然以我之前的批次确定方式,出的时候会出现负数。因为出的时候也是一个日期,而那个日期是之前没有过的。真搞不懂这个合同为什么要这么折腾,但或许这不是合同太折腾,而是我没有想到位。现在我想到的其中一个方法,是到了某个免堆期以后,把那些以日期命名的批次一次性转为一个统一的命名批次,比如无。这样那些一天一天积累入库的东西,到达某个时候就会统一混为一体。出的时候也是从这一个大块里一点一点的减出来。所以批次这种东西只出现在入库的某些部分,出的时候这些一点一点积累起来的东西的时候一律是无。

如果那个屌丝东西入了以后,没到免堆期结束就出了呢?理论上。这种东西是完全不应该计算堆存费,但是出的时候,没有带入入的时候的那个批次。所以入的东西一直挂在这里,出的那些则是从大单位里减去。所以理论上,这样算的话,堆存费就会少了。因为那些特例的东西无论是入还是出,都不影响堆存费,因为那些都不计算堆存费,但如果从大单位里减去,堆存费就少了。我非常想知道,那些算不清谁是谁的散货码头单位到底是如何解决这个问题的。如果能分清楚的东西还好说,比如说货柜,算得清什么时候来的,什么时候走的,但散货呢?一个大堆里,最里面的是最开始进的,最上面的是最后整上去的,但实际上出货的时候,你只能从上面到下面。散货码头界定的批次概念到底是每天进多少就一个批次还是说从的第1天开始,就算做一个批次呢?免堆期之内有进有出,这其中的数量,应该如何去计算呢?大概现在我很烦恼的东西是先进先出的问题。这种东西我现在都想不明白该如何用图表示。之所以想不到如何用图去表示。是因为我想不清楚出的是哪个批次。因为那些东西不是一个整数,如果出的数量少于某个入的批次,还好说,但如果跨越了几个批次呢?那几个批次里面,其中某些只是部分,这个东西又应该如何处理呢?之前我就已经稍微了解过先进先出这种东西。批次这东西,之前我也认为应该进行拆分,但这个拆分要怎么判断呢?考虑这个问题,以我现在的水平来说,显然超纲了,但是这是非常实际的问题,不可能避免。从整体来说好像是没有解决方案,但是如果细分到某个堆场估计能说得清。那些东西到底是什么时候进的,货物来源是哪里,出的时候要分开,应该使用什么规则呢?

我觉得我没搞清楚总分的关系,当分组到最细层次的时候一切都好说,但上面的合并要求不同,于是就会分叉出很多不同的东西。

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