场景
今天分享物流运费常见场景的计算方法。计费规则,根据长、宽、高、周长、重量5个维度不同范围,有多档价格,如下所示。假设有包裹A,长40,宽38,高20,重2.35。要确定A的运费,需分别考虑5个维度同时满足的情况。
包裹类型 | 长 | 宽 | 高 | 周长 | 重量 | 运费 |
---|---|---|---|---|---|---|
小信封 | 20 | 15 | 1 | 70 | 0.08 | ¥1.59 |
标准信封 | 33 | 23 | 2.5 | 112 | 0.06 | ¥1.66 |
标准信封 | 33 | 23 | 2.5 | 112 | 0.21 | ¥1.87 |
标准信封 | 33 | 23 | 2.5 | 112 | 0.46 | ¥2.01 |
大信封 | 33 | 23 | 4 | 112 | 0.96 | ¥2.45 |
超大号信封 | 33 | 23 | 6 | 112 | 0.96 | ¥2.58 |
小包裹 | 35 | 25 | 12 | 120 | 0.15 | ¥2.49 |
小包裹 | 35 | 25 | 12 | 120 | 0.4 | ¥2.71 |
小包裹 | 35 | 25 | 12 | 120 | 0.9 | ¥2.76 |
小包裹 | 35 | 25 | 12 | 120 | 1.4 | ¥3.08 |
小包裹 | 35 | 25 | 12 | 120 | 1.9 | ¥3.25 |
小包裹 | 35 | 25 | 12 | 120 | 3.9 | ¥5.25 |
一维情况
首先考虑最简单的情况,比如只有长一个条件。要判断40落在哪个价格区间,可以用match函数,如下所示(本文公式里的中文,表示规则表中对应维度所在的列,如【长】表示规则表中长度所在列):
代码语言:javascript复制=MATCH(40,长,1) 1
这个公式会求出,在长那一列中,满足大于40的最小行序数。在本例文件中,是13,也即在价格表中的第13行。那么对应的运费也在第13行,套个index公式,即可取得。
代码语言:javascript复制= index(运费,
MATCH(40,长,1) 1,
0)
注:
index用法:index(区域,行序数,列序数),取得某区域内第几行第几列的值。
多维情况
多维情况是多个一维情况的叠加,并取同时满足条件的行序数。理想情况下,同时满足条件,即取最大的行序数。比如长、宽、高、周长、重量分别对应13、12、14、15、16行,则取16行对应的运费。公式可以这么写:
代码语言:javascript复制=INDEX(运费,
MAX(
MATCH(40,长,1) 1,
MATCH(38,宽,1) 1,
MATCH(20,高,1) 1,
MATCH((40 38)*2,周长,1) 1,
MATCH(2.35,重量,1) 1
),
0)
这个公式可能会存在一个问题,即match当第三个参数为1时,要求查找列必须是从小到大按顺序排列。而规则表中,重量列,并不是严格按照从小到大排列。因此,这种方法下取得的满足重量的最小行序数,并不一定能同时满足其他几个维度的条件。
该运费规则表也无法实现5个维度同时从小到大排序。那么只能另辟蹊径,不能分别取值再取最大值。解决方法,可以参考之前文章 【动态数组系列】filter 中提到的,用【*】来串联获取同时满足多条件的结果。公式可改为:
代码语言:javascript复制=INDEX(运费,
MATCH(1,
(40<=长)*
(38<=宽)*
(20<=高)*
((40 38)*2<=周长)*
(2.35<=重量),
0),
0)
上式中,我们只用了1个match。第二个参数,通过【*】连接判断同时满足5个条件的情况。即对规则表进行逐行判断,是否同时满足条件,是则返回1,否则返回0。然后用match取查找最早出现的1所在的行序数。