设计者思维丨权限轴

应用背景

数据的本质是为了业务服务,从而达到更高效的工作方式,实现数据对业务的赋能和推动作用。
因此在构建报表时,需要开发者有设计思维,能够考虑多种应用场景,帮助业务解决实际应用中的问题。
例如,在实际业务场景中,管理层用户习惯向下管理的方式,那么在查看报表时,能否也保留这种方式呢?

规则描述

  • 组织架构分为多级,1级、2级、3级,数字越小,级别越高

  • 上级用户有权限查看下属子部门数据

  • 各级用户在查看报表时,默认展开下级部门,例如1级部门用户,则展示下属所有2级部门,以此类推

  • 当用户分管多个平级部门时,则展示自身所在层级,不进行展开

案例数据


图1和图2两张事实表分别存储Actual和Budget数据。

  • 预算和实际存在挂在父级部门不下放的情况,因此事实表存在1级2级3级部门混合在一列的情况

  • 除了预算和实际存在此情况外,有时候项目也会存在这种情况

图3是维度表,存储部门数据。

  • 因为存在预算和实际不下放的情况,所以需要将本部门下落到子级,保证该部门的数据完整

  • 除了保证数据完整,还要保证数据可进行钻取,父级部门既可以看到下属子级部门的数据,也可以看到挂靠在本部门的数据

图4是维度表,存储Actual和Budget的类别数据。

级别 字段1 字段2 字段3
1 一级 一级 一级
1 一级 二级 二级
1 一级 二级 三级
2 一级 一级 一级
2 二级 二级 二级
2 二级 三级 三级
3 一级 一级 一级
3 二级 二级 二级
3 三级 三级 三级

图5是多维的维度表,本身是部门维度数据的变体。

  • 多维表结构图,是多维表的设计理念

  • 级别分为3级,代表着部门的层级结构

  • 从权限管理的角度来说,子级部门不可以看到归属上级部门的数据

  • 每个级别中,都有不属于该级别的数据,例如:2级部门中,存在1级部门,这个是为了保证测试时,每个级别的数据都是完整的,减少测试的工作量

图6是配置表,存储用户的权限信息。

图7是表模型,多维表和配置表不需要建立模型关系。

构建度量值

01.Actual = 
SUM ( 'Fact_Act'[实际] )
02.Budget =
SUM ( 'Fact_Bud'[预算] )
03.AnalysisActual =
VAR Analysis=
    VALUES ('Dim_Analysis'[L3])
VAR Result=
    CALCULATE ([01.Actual], FILTER ('Dim_Dept','Dim_Dept'[部门2] IN Analysis))
RETURN
    Result
04.AnalysisBudget =
VAR Analysis=
    VALUES ('Dim_Analysis'[L3])
VAR Result=
    CALCULATE ([02.Budget], FILTER ('Dim_Dept','Dim_Dept'[部门2] IN Analysis))
RETURN
    Result
05.AnalysisRate = 
DIVIDE ( [03.AnalysisActual], [04.AnalysisBudget] )

可视化结果

添加轴权限

06.DisplayLevel =
VAR Access =
    CALCULATE (
        MIN ( 'Config_Access'[ID_DepartmentLevel] ),
        'Config_Access'[LB_AdAccount] = USERNAME ()
    ) + 0
VAR AccessCount =
    COUNTROWS (
        CALCULATETABLE (
            VALUES ( 'Config_Access'[LB_Accessible] ),
            'Config_Access'[LB_AdAccount] = USERNAME (),
            'Config_Access'[ID_DepartmentLevel] = Access
        )
    )
VAR AccessLevel =
    IF ( AccessCount > 1 && Access <> 0, Access - 1, Access )
VAR Result =
    IF (
        AccessLevel <> 3,
        VALUE ( MIN ( 'Dim_Analysis'[LB_LEVEL] ) ) - AccessLevel,
        VALUE ( MIN ( 'Dim_Analysis'[LB_LEVEL] ) ) - 2
    )
RETURN
    Result

DAX解析

  • 变量Access是为了获取当前用户的最大权限,数字越小权限越大

  • 如果用户有访问此报表的权限,但是权限表中没有对应的权限数据,则该用户为Admin权限,Access度量值需要进行补0操作

  • 变量AccessCount是为了获取当前用户的权限行数,因为存在一个用户管理多个部门的情况

  • 变量AccessLevel是为了输出参数,实际场景中,如果用户管理多个部门,全部展开下属部门数据会变的特别多,因此不需要展开,仅需要展示同级即可

  • 变量Result是判断用户默认的查看层级,如果用户非3级部门,那么管理多个部门看本级,管理一个部门看子级,3级部门则看本级

结果

从结果上看,权限控制展示的维度是正确的,但是展示的数据不正确,A的达成率应该是16.67%,C的达成率应该是2.33%。

产生原因

  • 筛选器会将X轴的所有字段与列图例里面的字段组合,重新构建上下文

  • 筛选器构建上下文的过程中,度量值03参与了此过程,导致一部分值被排除在外了

  • 类别维度表与部门维度表之间没有直接关系,二者在一起有类似笛卡尔积的效果,也对结果有影响

解决方案

度量值内部权限判断,不依赖于筛选器判断

07.DisplayRate =
VAR Access=
    CALCULATE (
        MIN ('Config_Access'[ID_DepartmentLevel]),
'Config_Access'[LB_AdAccount]= USERNAME ()
)+0
VAR AccessCount=
    COUNTROWS (
        CALCULATETABLE (
            VALUES ('Config_Access'[LB_Accessible]),
'Config_Access'[LB_AdAccount]= USERNAME (),
'Config_Access'[ID_DepartmentLevel]=Access
)
)
VAR AccessLevel=
    IF (AccessCount>1&&Access<>0,Access-1,Access)
VAR Result=
    IF (
AccessLevel<>3,
        VALUE ( MIN ('Dim_Analysis'[LB_LEVEL]))-AccessLevel,
        VALUE ( MIN ('Dim_Analysis'[LB_LEVEL]))-2
)
RETURN
    IF (Result=1,[05.AnalysisRate], BLANK () )

结果如下:

度量值内部屏蔽多余上下文干扰

08.AnalysisRateExcept =
CALCULATE (
    DIVIDE ( [03.AnalysisActual], [04.AnalysisBudget] ),
    ALLEXCEPT ( 'Dim_Analysis', 'Dim_Analysis'[L1] ),
    ALL ( 'Dim_Type'[类别] )
)

结果如下:

计算组封装,屏蔽干扰因素

VAR Access =
    CALCULATE (
        MIN ('Config_Access'[ID_DepartmentLevel]),
'Config_Access'[LB_AdAccount]= USERNAME ()
)+0
VAR AccessCount=
    COUNTROWS (
        CALCULATETABLE (
            VALUES ('Config_Access'[LB_Accessible]),
'Config_Access'[LB_AdAccount]= USERNAME (),
'Config_Access'[ID_DepartmentLevel]=Access
)
)
VAR AccessLevel=
    IF (AccessCount>1&&Access<>0,Access-1,Access)
VAR Result=
    IF (
AccessLevel<>3,
        VALUE ( MIN ('Dim_Analysis'[LB_LEVEL]))-AccessLevel,
        VALUE ( MIN ('Dim_Analysis'[LB_LEVEL]))-2
)
RETURN
    IF (Result=1, SELECTEDMEASURE (), BLANK () )

结果如下:

补充

  • 若部门连接类别,类别连接事实表,则不会存在此问题

  • 上述问题的诱因,也存在笛卡尔积的原因,导致内部计值流发生了变化

特别鸣谢夕枫大佬



最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,393评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,790评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,391评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,703评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,613评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,003评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,507评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,158评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,300评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,256评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,274评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,984评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,569评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,662评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,899评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,268评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,840评论 2 339

推荐阅读更多精彩内容