通过深入研究 Chris Webb 和 Mosha 的帖子以及与 MSDN 论坛上的一些人合作,我在下面找到了解决方案。最终,我与业务合作,我们不需要询问底层行来辨别它们是否处于活动状态,因为添加根功能消除了这种需求,只要它们从 DimMiscellaneous 中过滤就可以了。但是为了帮助遇到类似问题的人,下面是完整的 MDX。
//Only evaluate if they are active
CREATE HIDDEN UtilizedFTESummator;
[Measures].[UtilizedFTESummator] = Iif([Measures].[Is Active For Utilization Value] > 0,[Measures].[Period FTE],NULL);
NON_EMPTY_BEHAVIOR([Measures].[UtilizedFTESummator]) = [Measures].[Is Active For Utilization Value];
//only include this measure if the underlying employee has values in their underlying data for active in utilization
CREATE MEMBER CURRENTCUBE.[Measures].[FTE Active Utilization]
AS
SUM
(
EXISTING [Historical Personnel].[Employee Id].[Employee Id],
[Measures].[UtilizedFTESummator]
),VISIBLE=0;
//Show weighted FTE by workdays
CREATE MEMBER CURRENTCUBE.[Measures].[FTE MTD Active Utilization]
AS SUM
(
DESCENDANTS([Historical Personnel].[Employee Id].CURRENTMEMBER,[Historical Personnel].[Employee Id].[Employee Id]),
(
DIVIDE
(
SUM
(
DESCENDANTS([Period].[Fiscal Period].CURRENTMEMBER,[Period].[Fiscal Period].[Fiscal Period]),
[Measures].[FTE Active Utilization]*[Measures].[Work Days In Month]
)
,SUM(ROOT([Historical Personnel].[employee id].currentmember),[Measures].[Work Days In Month])
,0
)
)
);
//Use Weighted FTE for calculating the weighted value for each person (all periods aggregated)
//Forecast Billable End Of Year has default aggregation of last child
CREATE MEMBER CURRENTCUBE.[Measures].[Annualized CBH Projected]
AS DIVIDE
(
SUM
(
DESCENDANTS([Historical Personnel].[Employee Id].CURRENTMEMBER,[Historical Personnel].[Employee Id].[Employee Id]),
[Measures].[Billable Client Hours Current] *
(
DIVIDE
(
[Measures].[Forecast Billable End Of Year]
,
[Measures].[Forecast Billable FTE]
,0
)
)
*[Measures].[FTE MTD Active Utilization]
)
,[Measures].[FTE MTD Active Utilization]
,0
);
用户对 Is Active For Utilization 标志进行过滤的简化答案如下:
//Weight FTE by employee calculating FTE * workdays for each period and then dividing by the sum of days irrespective of filters on historical personnel or miscellaneous
CREATE MEMBER CURRENTCUBE.[Measures].[FTE MTD]
AS SUM
(
DESCENDANTS([Historical Personnel].[Employee Id].CURRENTMEMBER,[Historical Personnel].[Employee Id].[Employee Id]),
(
DIVIDE
(
SUM
(
DESCENDANTS([Period].[Fiscal Period].CURRENTMEMBER,[Period].[Fiscal Period].[Fiscal Period]),[Measures].[Period FTE]*[Measures].[Work Days In Month]
)
,
SUM((ROOT([Historical Personnel].[employee id].currentmember),ROOT([Miscellaneous]),[Measures].[Work Days In Month]))
,0
)
)
);
//Weight by FTE with default agg for Forecast EOY being last child.
CREATE MEMBER CURRENTCUBE.[Measures].[Annualized CBH Projected]
AS DIVIDE
(
SUM
(
DESCENDANTS([Historical Personnel].[Employee Id].CURRENTMEMBER,[Historical Personnel].[Employee Id].[Employee Id]),
[Measures].[Billable Client Hours Current] *
(
DIVIDE
(
[Measures].[Forecast Billable End Of Year]
,
[Measures].[Forecast Billable FTE]
,0
)
)
*[Measures].[FTE MTD]
)
,[Measures].[FTE MTD]
,0
);