门店数是企业经营最基础的指标,在一定程度上代表着市场占有率,也是核算单店营业额(店效)的基础。
在讲解门店数的计算逻辑前,首先聊下一家门店,从开店到撤店所经历的几个重要时点。一家门店装修完成,就可以择日开张营业,营业第一天就是开店日期。也有些店在正式开张前,会试营业一段时间,然后选择吉日,做正式的开业庆典。这样,试营业第一天就作为开店日期,开业庆典的日期则记为开业庆典日期。在正常经营了几年后,门店的装修及道具需要升级改造,或是由于经营业绩原因,需要扩大或缩小营业面积,门店进入重装阶段,这样会有重装开始日期及重装结束日期。又经过一段时间,门店周边客流较差,或是房租到期续签租金过高,老板决定关店。做了几场特卖活动,甩了一部分库存后,门店正式关店。门店不产生销售的日期,就作为撤店日期。门店在系统中的状态,就根据这几个阶段,分为装修中、营业中、重装中、撤店。计算门店数时,就要根据以上这些字段确定。
店铺数
一张典型的店铺表的结构如下:
用 PowerBI DAX 计算如下:
代码语言:javascript复制门店数 =
VAR MaxDate =
MAX ( 'Model-Dimdates'[Date] )
RETURN
CALCULATE (
DISTINCTCOUNT ( 'Model-Dimstore'[商店代码] ),
'Model-Dimstore'[开业时间] <= MaxDate,
OR ( 'Model-Dimstore'[撤店日期] = BLANK (), 'Model-Dimstore'[撤店日期] > MaxDate )
)
[门店数]
度量值通过用当前时期和门店的开业时间及撤店日期比较,确定一家门店在当前期间内是否为有效门店。当门店的开业时间小于等于当前期间的最大值,并且处于经营状态(撤店日期为空)或者已撤店但撤店日期大于当前期间的最大值(即当前期间还未撤),那么该店在当前期间为有效经营门店。
年初门店数
对于年度初始门店数,用 PowerBI DAX 计算如下:
代码语言:javascript复制门店数 年初始 =
IF (
STARTOFYEAR ( 'Model-Dimdates'[Date] ) IN VALUES ( 'Model-Dimdates'[Date] ),
CALCULATE ( [门店数], PREVIOUSDAY ( STARTOFYEAR ( 'Model-Dimdates'[Date] ) ) )
)
利用 [门店数]
求得本年初始门店数,第 4 行使用 PREVIOUSDAY ( STARTOFYEAR ( 'Model-Dimdates'[Date] ) )
首先找到年初日期,再通过 PREVIOUSDAY
前移一日找到上年末日期,从而求得上年末门店数,即为本年初始门店数。第 2 行的 IF 条件限制该度量值只在年初的期间内显示,其它时期不显示。
新增与撤店
对于其他指标,用 PowerBI DAX 计算如下:
代码语言:javascript复制门店数 本期新增 =
CALCULATE (
DISTINCTCOUNT ( 'Model-Dimstore'[商店代码] ),
'Model-Dimstore'[开业时间] IN VALUES ( 'Model-Dimdates'[Date] )
)
门店数 本期撤店 =
CALCULATE (
DISTINCTCOUNT ( 'Model-Dimstore'[商店代码] ),
'Model-Dimstore'[撤店日期] IN VALUES ( 'Model-Dimdates'[Date] )
)
门店数 本期净增 =
[门店数 本期新增] - [门店数 本期撤店]
[门店数 本期新增]
和 [门店数 本期撤店]
比较好理解,[开业时间]
或是 [撤店日期]
处于本期期间内,则记为本期新增或本期撤店。开关店明细-按月份,示例如下:
开关店明细-按部门,示例如下:
避免错误
这里有一点需要注意,在计算 [门店数 年初始]
时,使用的是上年末日期,PREVIOUSDAY ( STARTOFYEAR ( 'Model-Dimdates'[Date] ) )
,而不是直接使用本年初日期 STARTOFYEAR ( 'Model-Dimdates'[Date] )
。主要是因为如果门店开业日期是1月1日,则使用本年初日期 STARTOFYEAR ( 'Model-Dimdates'[Date] )
会把该店也算入初始门店中,而再计算新增门店时,这个店又重复计算,这样就会导致年初始门店数、净增门店数和期末店数无法对平。
错误的算法,如下:
代码语言:javascript复制门店数 年初始 Wrong =
IF (
STARTOFYEAR ( 'Model-Dimdates'[Date] ) IN VALUES ( 'Model-Dimdates'[Date] ),
CALCULATE ( [门店数], STARTOFYEAR ( 'Model-Dimdates'[Date] ) )
)
如果使用了错误算法,则得到:
可以看出,由于门店 a021 开业时间是 2019/1/1,[门店数 年初始 Wrong]
将该店也记入初始门店数量,而在[门店数 本期净增]
中,该店又重复计数,导致 2019年1月中,年初 145 加上净增 4 大于 1 月末的 148 家。
剔除装修
以上度量值计算了当前上下文中事实存在的门店数,这其中包含了营业中和装修中两种状态。如果只统计公司当前现存店铺数,以上表达式没有问题,但是如果统计门店数进而计算期间内的店均营业额,则要剔除掉装修中的门店,毕竟这部分门店在当期的部分期间或是整个期间并未营业。
对于重装中店铺数的计算,用 PowerBI DAX 实现,如下:
代码语言:javascript复制门店数 重装中 =
VAR MinDate =
MIN ( 'Model-Dimdates'[Date] )
VAR CurDate =
VALUES ( 'Model-Dimdates'[Date] )
RETURN
CALCULATE (
DISTINCTCOUNT ( 'Model-Dimstore'[商店代码] ),
FILTER (
'Model-Dimstore',
'Model-Dimstore'[装修开始日期] IN CurDate
|| 'Model-Dimstore'[装修结束日期] IN CurDate
|| (
'Model-Dimstore'[装修开始日期] <> BLANK ()
&& 'Model-Dimstore'[装修开始日期] < MinDate
&& 'Model-Dimstore'[装修结束日期] = BLANK ()
)
)
)
门店数 营业中 = [门店数] - [门店数 重装中]
[门店数 重装中]
通过筛选 Model-Dimstore 中,装修开始日期处于所选期间或是装修结束日期处于所选期间,或是装修开始日期小于所选期间,但在该期间内正装修中的门店,找到所选期间内处于重装中的门店数量。最后用总门店数减去重装中门店数得到营业门店数。
示意如下:
标记法
以上是通过开业日期、撤店日期、装修开始及结束日期来确定门店数的方法。如果只是计算最新的门店数量,可以直接筛选 Model-Dimstore 中的店铺状态列即可。
代码语言:javascript复制门店数 最新 =
CALCULATE (
DISTINCTCOUNT ( 'Model-Dimstore'[商店代码] ),
'Model-Dimstore'[店铺状态] IN { "营业中", "重装中" }
)
门店数 营业中 最新 =
CALCULATE (
DISTINCTCOUNT ( 'Model-Dimstore'[商店代码] ),
'Model-Dimstore'[店铺状态] = "营业中"
)
总结
门店数的计算是企业经营分析中最基础的指标,它的计算依赖于门店维表中的开关店时间和装修开始、结束时间这 4 个时点来确定。所以及时维护好门店维表是计算该指标的关键。
这涉及到以系统化的思维设计审批流程以及信息维护人员的执行力及责任心。结合可比店、不可比店角度进一步对门店数进行分析,效果更加。