CALCULATE 庖丁解牛系列- 扩展表 (6)
链接、链接回表
Excel与Powerpivot交互的链接表
(部分内容依据简体笔记修改)
链接表并不属于准数据源,但这可能是将数据加载到PowerPivot 的最简单直接的方式。如果你需要一个尚未加载到任何数据库中的表格,则可以简单地创建一个Excel 工作表,并将其链接加载到PowerPivot 表。
由于创建链接表如此容易,我们不仅要展示给你如何创建链接表,还要告诉你如何使用链接表立即更新数据模型,并创建交互式报告需要的维度或度量。
要加载表格到PowerPivot ,只需单击ExceⅠ数据区内任意单元格,然后单击PowerPivot 功能区的“ 添加到数据模型” 按钮(见图) 。表格就立即载入到Power Pivot 数据库中,且模型中的名称与Excel 表格名称相同。一旦该数据加载到数据模型中,就能被看到,如图所示:
此时所有加载进Powerpivot的表之间缺失的一环就是关系,你可通过在关系图视图中拖动关系列来创建表关系,并由此生成一个数据模型。这里从略。你巳看到,将数据从Excel直接置于数据模型内部时,链接表是很便捷的方式。
此时,你可能想知道,使用Excel自动加载到模型中的表格(例如出于创建关系的目的)和使用PowerPivot链接表添加的表格之间有何异同?毕竟它们似乎执行完全相同的操作。但实际上这是不完全正确的。而且这种区别有些微妙,说实话,大部分时间你是不会注意到这种区别的。
以Excel为源文件加载到数据模型的Excel表格,需要通过单击“ 刷新” 来手动刷新。而链接表在打开Power Pivot窗口或刷新数据透视表时就会自动刷新,其交互性更高一点。除了这种微小差异之外,两种方式的行为基本相同,都是将来自Excel 中的数据加载到数据模型的有效手段。
链接回--DAX查询结果表
尽管我们尚未讨论用于创建查询的DAX函数,这里还是要先说明学习DAX作为查询语言的主要原因:你可以选择链接回DAX查询的结果(衔接回表)。
什么是链接回?在详细探讨之前让我们了解两个术语:
(1)链接表。一个链接到Power Pivot模型的Excel表格,也就是说,Excel表格的内容被复制到了PowcrPivot数据模型中,且PowcrPivot数据模型中的该数据会随着原始Excel表格的更新而更新。
(2)逆向链接表(链接回表)。一个使用Excel表作为源的DAX查询。每当Power Pivot数据模型更新时,会对新的数据再次执行查询并刷新Excel表格。
因此,链接表是将数据从Excel移动到PowePr ivot,而将数据从数据模型(PowePrivot)移动到Excel则是链接回表。实际运用中,可能需要采取逆向链接表并基于其创建一个新的链接表。事实上也可以这么做,而且可通过创建一个链接回表格来实现。
链接回表格是一个用于填充为Excel表格的DAX查询,该Excel表随后还可以作为一个链接表,以便其内容再次推送到Power Pivot数据模型内部、或者加载到Powerqurey作进一步的数据加工处理。实际上,你存储于数据模型中的数据是一个DAX查询结果。它可用来定义计算列或计算字段,或两者兼而有之。
此选项将为你带来一种全新的考虑有关DAX的业务解决方案的方式。事实上:
(1)你可从Excel中的数据开始,将其推送到Power Pivot内部并执行一些计算。
(2)然后,建立一个查询来检索Power Pivot模型中的数据,并使用其结果来填充为一个新的Excel表。此时,由于新表格是一个Excel表,你将拥有Excel 语言的全部功能:例如,可以用Excel公式来建立新单元格或新建列,最后将结果返回到PowePrivot。
因此,新表格可输出为数据透视表等,正如它原本就存在于数据模型里一样(可当 作数据模型的一部分)。而且,刷新操作的所有复杂性都由Excel以正确顺序进行处理,能确保正确计算。
链接回表的操作步骤:
第一步:Excel菜单-->数据-->现有连接表格-->选择时期表(任何一个数据量小一点的表,目的只是用于引出一个链接回表)。这一步又分成几个小步骤:
结果生成一个链接回表(即整个时期表),这一步主要是建立起一个从Powerpivot数据模型到Excel的链接回表。
第二步:生成的衔接表,可能并不是我们需要的数据内容。单击表里任意单元格,右键属性-->表格 -->编辑DAX-->下拉选择DAX, 来到链接表代码编写区。
我们输入查询代码,这需要注意:
(1)总是使用Excel表函数 EVALUATE 定义查询表;
(2)使用结果为列表的函数定义表。
例如,我们从数据模型里链接回一个时期表:
EVALUATE
'时期表'
这就是前面第一步里我们选择的链接回表--时期表,现在我们使用计算结果为列表的DAX计算式查询代码:比如, FILTER条件的结果表:
EVALUATE
FILTER('时期表','时期表'[ 年份]=”2018”)
再试想一个作为链接回的例子:比如要看到产品中排名前25位的畅销品。你可以很容易地使用TOPN函数来计算它,以下查询返回表格的前25项:
EVALUATE
SUMMARIZE (TOPN (25,
CALCULATE (SUM (FactinternetSales[SalesAmount]))),
"Sales",
SUM (FactlnternetSales[SalesAmount])
ORDER BY [Sales]
当然,我们还可以在公式的基础上添加其他条件。此查询返回 25 个最畅销产品。由于结果是一个 Excel 表格,你可以使用 Excel 中的其他计算来丰富该表格。
例如,可用Excel 中的 RANK 函数来为每行指定一个排名数字列,然后使用 IF 语句进行简单分组等等,经Excel处理后获得 一个新表格(添加了许多新的衔生列)。
表格中TOP25的公式是:
Position= RANK ([@Sales],
[Sales])Ranking= IF ([@Position] <=5, "TOP 5",
IF ([@Position]<=10, "TOPN", "TOP25"))
此时,如果使用该结果(即Ranking列)并将其作为DirnProduct表的一个属性列来存储,可能是个好主意,因为可使用Ranking属性列作为数据透视表的筛选器。
要达到此目的,依据前面的链接关系,你通过将表格链接到数据模型并建立正确的列表关系来做到这一点。这可以使用关系视图创建,或使用Excel功能区数据选项卡上的“关系”按钮,直接从Excel内部创建关系。在后一种情况下可创建新的关系,如图示:
如果此时回到PowerPivot窗口,会看到Top25Products表巳添加到数据模型里,且同任何其他表一样是可用的,Top25Products表格和所有其他表格之间的最大区别在于:这是一个计算结果表格,而非从任何数据库导入的表格。此时,你可以轻松地创建数据透视表以显示那些排行前五名的产品的订单数和销售数量等,如下图所示:
可以看到,在数据透视表中显示了按销售金额大小排名前五的产品,且销售金额列并不需要在数据透视表中显示出来。由于Ranking-排名列是一个属于数据模型的计算列。事实上无须出现,它并非使用数据透视表的TOPN函数计算得来。
这个例子很简单,但是,你可能己想象到这种做法拥有令人难以置信的扩展性。它将Excel 计算和DAX 建模选项融为一体,这打开了新的、令人兴奋的无限可能性,而且利用这种扩展性的关键是使用DAX 的查询功能。
如果刷新数据源,Excel 从外部连接重新载人表格,并基于DAX 查询对Excel 表进行刷新。然后,如果这些表格是链接回的,将对这些链接到DAX 查询的PowerPivot 表刷新。所有这些操作自动发生而无须执行任何手动操作,即可刷新链接回表格。
链接回表计算ABC分析
作为链接回威力的一个例子,我们要展示一个你可能已解决了的场景,也就是产品ABC类的计算。
在前面已学习到使用DAX度量 或计算列来将ABC 分类属性添加至产品表。该DAX 代码并不复杂,但是在之前的DAX中也并不认为这很容易。
使用链接回功能,现在仅使用Excel 代码,并用一种简单技术即可解决相同场景。你可能还记得,ABC 分析将A 类分配到占70%销售额的产品,将B 类分配到接下来的20%,C 类分配到占销售额的余下10%。
为了计算这些类别,首先需要一个表格来显示每个产品的销售总额,使用类似下面的DAX 查询,很容易地完成:
EVALUATE
SUMMARIZE ( DimProduct,[ProdctKey],
"Total Sales",
SUM (FactinternetSales [SalesAmount])
ORDER BY DESC
使用ORDER BY 的原因在于,这将使得更易于计算累计合计。按照ABC分析的经典三部曲(有很多这方面的介绍,这里不做重复):
下一步是对每个产品计算累计合计,即该产品之前的所有产品的销售总额。
其次,下一步是将累计合计转换成销售总计的百分比。
最后,操作更简单:实用 一个简单的IF 条件将RunningPct 列转换成ABC 类,
=IF ([@RunningPct]<=0.7, "A", IF ([@RunningPct]<=0.9, "B", "C"))
如图:
此时,在Excel 中就有了一个表格,它包含了每个产品所指定的ABC 类。现在,是时候将该表格推送到数据模型中,以便探索链接回的威力。使用ProductKey 列来创建一个从DimProduct到这个新表格之间的关系。
你可以立即使用来自数据透视表中新表的ABC类列。如果你是一个纯粹的数据建模者,可在DimProduct中创建一个新的计算列并使用RELATED 函数来反规范化ABC类列。此时可将仅用作参数过渡的Product_ABC_Class表隐藏。
我们希望这个小例子已向你显示了链接回的威力。但这并不是说你应该总是尝试将Exce l和DAX组合起来。总有一些更赞成使用DAX,而其他更赞成Excel的理由。你所做的选择将取决千你所面临的具体业务场景。
通常,我们认为最好始终用更易于创建的语言来编写公式,这是因为编写和调试的代码量越小越好。在这种特定情况下在Excel中编写累计合计更容易些,而DAX会需要一些复杂的工作来完成。因此,Excel解决方案看起来更容易实现些。
链接回表综合案例
某些业务场景需要(从Powerpivot到Excel,再到Powerpivot)
问题:(这个案例为链接表行为)
(1)如何将Powerpivot或Power BI里设置的多个度量值,将其结果引用到数据模型里作为新的列表(扩展模型),参与计算?
(2)有时候有这种需求:需要将只能放置在透视表数值区的度量值,用来做行、列筛选或切片器?
(3)因为Power BI的强项还是列表关系构建模型,而Excel则具有无法比拟的灵活性、动态性。
比如,你苦苦思索的一个动态性问题,可能在Excel里或许很容易被解决。所以,可以将它们结合起来--强强联手。
这些情况下的两者结合,就需要链接表或链接回表。
下面是步骤说明,你可以拿自己的一个业务案例试试。链接表过程:
第一步: Powerpivot或Power BI里设置好需要的度量值或计算列。
这里,我们需要的主要KPI度量值是下图中的列字段:销售、销量、毛利、日均销售、库存等等(因业务需要构建)。因为接下来由此生成很多业务度量值(衍生度量)都是根据这些条件搭建的。
下面是我们透视出来的一个透视表。如图:
注意:透视结果最后包含你的关系列字段(这里为【条码】列)
第二步:你可以依据这个透视表在后面添加需要的新列,比如库存量为零的,标注为“零库存”,不为零的标记为“有库存”,负的标记为“负库存”,这很容易实现(IF判断一下就好)。这样你就得到一个新的列【库存状况列】(包含需要的列值属性分组内容:零库存和有库存等)。当然,这个步骤也可以放在PQ里新建条件列得出。但是,有时候为什么不在PP里创建?
因为Powerqurey主要是数据处理,关键是透视出的内容是你需要的(数据模型支持的任意维度变化与业务逻辑,而且这些关键度量值是动态变化的)。明白了这点,再看下面这个透视表。我们新建一列:【库存状况列】,如果还有需要的其他属性列,都一并建好。
第三步:将这个新透视表转化为Excel表。这一步的原因是:透视表不能直接加载到Powerqurey、Powerpivot中。
可能的转换方法:
(1)VAR代码(录个宏就好);
(2)GETPIVOTDATA函数构建;
(3)使用函数引用透视表区域值到另一个Excel区域。
第二种其实是透视表的多维数据引用公式,方法是:直接在待引用的Excel单元格写上 “=”,再单击透视比表里你需要引用的某个单元格值,就会生成一个包含GETPIVOTDATA的多维公式,该方法需要将每个引用的单元格内容都设置一遍,好处是设置一次就行,后期数据会随透视表自动更新。
我们采用的是第三种方式:这里使用INDEX函数引用透视表内容:
第四步:将已转换好的Excel表导入Powerqurey或Powerpovit成为一个衔接表。在Powerpivot里的这个表跟其他的数据模型里的表是一样的。如果你只需要【库存状况】这一列,可将该列直接导入数据模型里就行。
当然,也可将此Excel表加载到Powerqurey做进一步的处理,再经Powerqurey处理后加载到Powerpivot成为数据模型的一部分。
注意:不管结果是在Powerqurey里还是Excel里,都要导入到Powerpivot里,才能称为链接表。
最后,可以用这个已导入模型里的表参与数据模型计算或作为输出(如透视表),比如将由此表创建的新[ABC值]列作为透视表的行、列或切片器。