矩阵乘积函数mmult进阶应用4:累加求和
小伙伴们好,不知道mmult有没有让你感觉很晕,反正我是有点晕了。咱们接着昨天的问题继续深入,准备好了吗?
1.计算甲原料在哪个仓库的库存量先达到30,并确定是在哪一天达到此库存量。(增加了原料)
在昨天最后一个题目的基础上增加了原料的条件,现在的要求是计算甲原料在A仓库的库存量先达到30,还是在B仓库的库存量先达到30,并确定在哪一天达到此库存量。结果如右侧所示,甲原料在A仓库的库存量先达到30,并且对应的日期是5月24。
![](http://n4.ikafan.com/assetsj/blank.gif)
想要解决这个问题,先要计算出甲原料分别在A,B两个仓库中每天的库存量,然后从这些库存量中找出最先达到30的,就可以计算出它所对应的仓库和日期。了解了这些,我就给出公式,再慢慢解释。
日期的公式为=TEXT(MIN(IF(MMULT(N(ROW(1:10)>=COLUMN(A:J)),(B4:B13="甲")*(C4:C13={"A","B"})*(D4:D13-E4:E13))>=30,A4:A13)),"m月d日"),不用按三键。
还是先来看mmult的部分,它的第1参数N(ROW(1:10)>=COLUMN(A:J))返回的结果是正方形区域,第2参数(B4:B13="甲")*(C4:C13={"A","B"})*(D4:D13-E4:E13)的意思是甲原料分别在A,B两个仓库中每天的净入库量。大家要理解3部分相乘的意思,不明白的话,可以分步拆开来看它们的结果。也可以按(B4:B13&C4:C13={"甲A","甲B"})*(D4:D13-E4:E13)这样的方式来理解,也就是把原料和仓库合并成一个条件,我认为这样会好理解一点。mmult2个参数返回的结果如下图array1和array2所示。最好是参考文件,这样看不好理解。
![](http://n4.ikafan.com/assetsj/blank.gif)
接下来就是用mmult对第2参数进行累加求和,这样的话就得到了甲原料分别在A,B两个仓库中每天的库存量,返回的结果如上图最右侧的mmult部分。然后从这些库存中找出最先达到30的,也就是大于等于30的。我们找到的结果就是上图中标记红色的31。然后根据31的位置找到对应的仓库和日期。
所以就用if判断mmult返回的结果是否大于等于30,成立的话返回对应的日期,否则就返回false。if的第3参数省略不写,那么不成立的就返回false。也就是IF(MMULT(N(ROW(1:10)>=COLUMN(A:J)),(B4:B13="甲")*(C4:C13={"A","B"})*(D4:D13-E4:E13))>=30,A4:A13)这部分。然后用min取出最小值就是对应的日期,最后用text设置一下日期格式,就完成了。
所在仓库的公式为=MID("AB",--RIGHT(MIN(IF(MMULT(N(ROW(1:10)>=COLUMN(A:J)),(B4:B13="甲")*(C4:C13={"A","B"})*(D4:D13-E4:E13))>=30,A4:A13/1%+{1,2}))),1),不用按三键。
mmult的部分是不变的,因为我们还是从标红的31的位置找仓库。从if开始有所变化,如果mmult返回的结果大于等于30,返回日期乘以100再加上{1,2},这就是一种加权的处理方式,将日期和仓库的列号合并起来。{1,2}可以看作仓库{"A","B"}的列号,if返回的结果形成一个二维数组。
然后用min取出最小值4397501,前面的5位数43975代表日期,后面的2位数01代表仓库的列号。现在我们需要的是后两位。所以用right取出最后一位,因为仓库现在只有2个,所以right取1位就可以了。或mod除以100取余数也可以得到列号。
列号得到后,用mid从"AB"中取出对应的仓库,比如列号得到1,就用mid从第1个位置取1位得到A;列号得到2,就从第2个位置取1位得到B。
你也可以用if把成立的返回对应的行号,然后用min取出最小的行号,最后用index返回对应列的内容。
如果用offset的多维引用来完成,日期的公式为=TEXT(MIN(IF(SUMIFS(OFFSET(D4,,,ROW(1:10)),OFFSET(B4,,,ROW(1:10)),"甲",OFFSET(C4,,,ROW(1:10)),{"A","B"})-SUMIFS(OFFSET(E4,,,ROW(1:10)),OFFSET(B4,,,ROW(1:10)),"甲",OFFSET(C4,,,ROW(1:10)),{"A","B"})>=30,A4:A13)),"m月d日"),按三键完成。
所在仓库的公式为=MID("AB",MOD(MIN(IF(SUMIFS(OFFSET(D4,,,ROW(1:10)),OFFSET(B4,,,ROW(1:10)),"甲",OFFSET(C4,,,ROW(1:10)),{"A","B"})-SUMIFS(OFFSET(E4,,,ROW(1:10)),OFFSET(B4,,,ROW(1:10)),"甲",OFFSET(C4,,,ROW(1:10)),{"A","B"})>=30,A4:A13/1%+{1,2})),100),1),按三键完成。
这就是mmult和offset累加的差别,条件越多,offset越繁琐,公式越长。
2.计算以下4种情况中,哪种原料在哪个仓库的库存量先达到30,并确定是在哪一天达到此库存量。(条件再一次增加)
现在条件又增加了,不只算甲原料在A,B仓库的库存量,而且还要算乙原料在A,B仓库的库存量,也就是下图的4种情况。求库存量最先达到30的是哪种情况,并且找到对应的日期。这个题目如果只用offset的多维引用,我认为就完成不了了,除非加辅助列。而mmult依然能完成。
![](http://n4.ikafan.com/assetsj/blank.gif)
选中G19:I19,输入公式=TEXT(OFFSET(A18:C18,MIN(IF(MMULT(N(ROW(1:10)>=COLUMN(A:J)),(B4:B13&C4:C13={"甲A","甲B","乙A","乙B"})*(D4:D13-E4:E13))>=30,ROW(19:28)-18)),),"m月d日"),区域数组三键结束。
mmult的第1参数N(ROW(1:10)>=COLUMN(A:J))保持不变,第2参数(B4:B13&C4:C13={"甲A","甲B","乙A","乙B"})*(D4:D13-E4:E13)的意思是分别返回"甲A","甲B","乙A","乙B"这4种情况每天的净入库量,这里将原料和仓库合并成一个条件。mmult2个参数返回的结果如下图array1和array2所示。
![](http://n4.ikafan.com/assetsj/blank.gif)
接下来对mmult第2参数的4列数据累加求和,得到了对应的库存数,返回的结果如上图右侧mmult的部分。然后从库存中找出最先达到30的,如红色33所示。根据33的位置找到对应的原料仓库和日期。和之前的处理方式基本是一样的,就不详细说明了。
由于这里4种情况包含了所有的可能性,所以也可以用整列来完成,选中横向的3个单元格,输入公式=TEXT(OFFSET(A18:C18,MIN(IF(MMULT(N(ROW(1:10)>=COLUMN(A:J)),(B19:B28&C19:C28=TRANSPOSE(B19:B28&C19:C28))*(D19:D28-E19:E28))>=30,ROW(19:28)))-18,),"m月d日"),按三键结束。
主要是B19:B28&C19:C28=TRANSPOSE(B19:B28&C19:C28)这一部分。
文件链接:
https://pan.baidu.com/s/1Y-obW60USo88PQ6Ov1FCYA
提取码:bmgl