ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
123
返回列表 发新帖
楼主: shwangfeng

[求助] [PowerBI]ALLEXCEPT在扩展表中表现错误

[复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-5-24 13:13 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 shwangfeng 于 2019-5-24 16:14 编辑
张文洲 发表于 2019-5-24 08:46
更正一下第3步表述,上下文A并不会参与Intersect运算,因为上下文A不会影响维度表的计算。

特别感谢版主与@张文洲,以及回复我的各位大佬给我的启发,以下是我根据各位的建议做的初步结论:

Allexcept跟All一样有两种用法——作为Removefilter和(在需要的时候)返回一张表。
第一种作为Removefilter,它清除"除了排除参数之外的"所有在(第一参数的)扩展表中的列的筛选器,也就是它字面上的用法——只保留特定列的筛选器而清除其他的。
第二种返回一张表,它清除/忽视一切(第一参数的)扩展表中的筛选器——即如果某列没有被排除,那么它的筛选器被清除;如果某列被排除,那么它的筛选器被忽略(不接受),最终都是不起任何作用。
对于返回表的情况,它返回的是一种特殊的表,这个表只含扩展表中没有被排除的列,但这个不完整的表依然(尽量)保留扩展表的属性,例如依然可以实现从事实表到维度表的筛选——只要别把整个维度/事实表都排除掉就好。
以下是我的测试方法,建议配合DAX Studio使用:

写法一
接受外部筛选时,结果集只有39行,因为结果表不能有重名列,直接用Data不行,索性用selectcolumns挨个重命名了……
  1. EVALUATE
  2. GENERATE (
  3.     VALUES ( Data[Name] ),
  4.     CALCULATETABLE (
  5.         SELECTCOLUMNS (
  6.             Data,
  7.             "Data[newName]", Data[Name],
  8.             "Data[newType]", data[Type],
  9.             "Data[newDatetime]", Data[Datetime],
  10.             "Data[newamount]", Data[amount]
  11.         )
  12.     )
  13. )
复制代码


写法二
此结果集有10个Name*39行记录=390行,可见Allexcept没有接受Name列筛选,即它在排除某参数的同时忽略(或者说拒绝?)了该参数上的筛选器,同时清除了其他列的筛选器。
此结果集有四列,结构与原Data相同,即Allexcept返回的结果表中只有三列,确实少了一列。
  1. EVALUATE
  2. GENERATE (
  3.     VALUES ( Data[Name] ),
  4.     CALCULATETABLE ( ALLEXCEPT ( Data, Data[Name] ) )
  5. )
复制代码


简化上面一种写法,虽然没有使用Calculatetable,但Generate对第二参数的要求使得Allexcept不得不返回了一张表(也就是官方说的when required,只要有需要就会返回表),结果与上面完全相同。
  1. EVALUATE
  2. GENERATE ( VALUES ( Data[Name] ), ALLEXCEPT ( Data, Data[Name] ) )
复制代码


写法二的参考一
由于有排除参数,Allexcept返回的结果表已经不是完整的表了,那么这个不完整表是否依然具有扩展表的属性呢?为此我只留了一个amount列,其他通通排除。
如果有,那么此处结果应当是38行,因为原Data表39行中有38个不重复日期。
结果确实是38行。
  1. EVALUATE
  2. CALCULATETABLE ( 'Date', CALCULATETABLE ( ALLEXCEPT ( Data, Data[Name],Data[Datetime],Data[Type] ) ) )
复制代码
这里我又尝试追加排除一列'Date[Date]',也就是最后的扩展表只剩Data[amount]与Date[YearMonth]两列,此时的计算结果有334行,因为在Data中当前有效的amount是39个(等于原Data行数),他们对应11个不同的[YearMonth],把这11个值作为有效值,拿去筛选Date表,得到的就是334行。这个例子再一次印证了返回表具有扩展表的属性(“尽量”保留)。

写法二的参考二
以下可以任意排除列(当然至少保留Data四列中的一列以及Date两列中的一列),筛选任意列(只要属于Data扩展表,无论是否被排除,也无论筛选条件多么奇怪),可以看到结果都是不变的——说明Allexcept无视扩展表中的一切筛选器。
  1. EVALUATE
  2. CALCULATETABLE (
  3.     'Date',
  4.     CALCULATETABLE (
  5.         ALLEXCEPT ( Data, Data[Name] ),
  6.         Data[Name] = "Tom",
  7.         'Date'[YearMonth] = 1
  8.     )
  9. )
复制代码


到此为止,再回头去看原题,应该可以说是水到渠成,无需多言的了——至于最好的解法,版主已经提供了。

最后附上测试文件与DAX Studio文件的打包:
Allexcept.rar (64.3 KB, 下载次数: 12)

欢迎各位指正!
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-14 14:37 , Processed in 0.035913 second(s), 9 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表