Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019
工作項目花費在特定工作流程狀態或一系列狀態的時間,是瞭解效率的重要層面。 循環時間和前置時間 分析小工具提供一些狀態停留時間的量度指標。 不過,這些小工具可能沒有您想要的詳細數據層級。
本文提供使用數據分析表示式 (DAX) 來評估工作專案在狀態組合中花費的時間的配方。 具體而言,您將瞭解如何將下列量值和計算結果列新增至Power BI報表,並使用這些數據行來產生各種趨勢圖表。 除了列出的第一個字段以外,所有欄位都是計算結果列。
計數 | 描述 |
---|---|
工作項目計數 (量值) | 根據工作項目的最後一天紀錄計算不同工作的數量 |
狀態排序順序 | 加入數據行,以根據 狀態類別 順序排序工作流程狀態 |
上一個日期 | 加入一個資料行,根據Date資料欄計算上一個日期。 |
日期相差天數 | 加入一個數據行,以計算 Date 和 Date Previous 數據行之間的天數 |
在州內的最後一天 | 加入一個欄,判斷 Date 值是否是專案處於狀態的最後一天 |
表示時間以天為單位 | 加入一個欄位,用於計算工作專案在每個狀態中花費的天數。 |
上一個狀態 | 加入數據行,以識別數據表中每個數據列的上一個狀態 |
狀態已變更 | 加入數據行,決定工作專案從某個狀態轉換到另一個 狀態 的日期 |
狀態流 | 當工作專案從某個狀態轉換到另一 個狀態 時,加入說明狀態流程的數據行 |
狀態變更計數 | 加入數據行,以計算工作專案從某個狀態轉換成另一個 狀態 的次數 |
狀態變更計數 - 第一個完成 | 加入一個數據行,決定工作專案第一次轉換成已完成狀態的次數。 換句話說,當它從任何其他狀態移至 [已完成] 狀態時。 |
狀態變更計數 - 最後提議 | 新增一個欄位,以判斷在轉換至較新的狀態後,工作項目是否曾經處於建議狀態。 |
狀態重新啟動時間以天為單位 | 加入一個數據行,這個數據行會計算工作項目花費在重新啟動狀態中的天數 |
狀態重新工作天數 | 加入一個欄位,以計算工作專案在已完成以外狀態所花費的天數。 |
重要
- 根據本文中所示範例新增計算欄位或量值時,請將檢視名稱替換為分析檢視或資料表的名稱。 例如,將檢視名稱取代為作用中的 Bug。
- 分析不支援日內修訂。 這些範例在參考分析檢視時使用 每日 間隔時,精確度最高。
- 計算會忽略所有日內或期間內(每周/每月)修訂。 這可能會導致特定情境下產生非預期的結果,例如當工作專案「進行中」的時間少於一天時,並未顯示其「進行中」狀態。
- 盡可能使用Power BI 預設匯總,而不是建置量值。
- 某些計算包含 +0 ,以確保每個數據列包含數值,而不是BLANK。
- 您可能需要根據專案所使用的工作流程狀態來修改一些匯出數據行定義。 例如,如果您的專案使用 新增、作用中 和 已關閉 以替換 建議、進行中 和 已完成。
- 本文中提到的 Date 欄位不是 Azure DevOps 的原生欄位,而是在 PowerBI 中建立的衍生欄位,用來支援 狀態時間報表。 您可以使用現有的日期相關數據行來建置此數據行,例如「已變更日期」或「狀態變更日期」。
必要條件
類別 | 要求 |
---|---|
存取層級 |
-
專案成員。 - 至少擁有 基本 存取權限。 |
許可 | 根據預設,項目成員具有查詢分析及建立檢視的許可權。 如需有關服務與功能啟用和一般數據追蹤活動之其他必要條件的詳細資訊,請參閱 存取分析的許可權和必要條件。 |
注意
若要執行本文所述的所有狀態持續時間量測,請確保在您的 Analytics 檢視、Power Query 或 OData 查詢中包含以下欄位:除了預設欄位 區域路徑、指派給、反覆專案路徑、狀態、標題、工作專案 ID 和 工作項目類型 外,還需包括 建立日期 和 狀態類別。
此外,請考慮根據 每日 數據粒度使用分析視圖。 本文中的範例是基於根據自定義分析檢視在 Power BI 中建立作用中 Bug 報表時所定義的 Active Bugs 分析檢視,但選擇了 60 天的歷程記錄和每日數據粒度除外。 同時決定您是否要檢閱已完成或已關閉的工作項目。
新增工作項目計數指標
為了簡化快速產生報表,我們設計了分析檢視來處理Power BI中的預設匯總。 為了說明預設匯總與量值之間的差異,我們從簡單的工作專案計數量值開始。
將分析檢視載入 Power BI Desktop。 如需詳細資訊,請參閱 使用Power BI資料連接器連線、連線到分析檢視。
選取資料表,然後從 功能區的 [數據表工具 ] 索引卷標[ 計算 ] 區段,選擇 [ 新增量值]。
以下列程式代碼取代預設文字,然後選取
複選標記。
Work Items Count=CALCULATE(COUNTROWS ('View Name'),LASTDATE ('View Name'[Date]))
工作項目計數度量會使用
CALCULATE
、COUNTROWS
和LASTDATE
這些 DAX 函式,詳細說明在本文的後面部分提供。注意
請記得將檢視名稱替換為 Analytics 檢視的數據表名稱。 例如,在這裡,我們將檢視名稱替換為作用中 Bug。
量值與運算欄位有何不同
度量值總是評估整個資料表,而計算欄位則特定於單一資料列。 如需詳細資訊,請參閱 DAX 中的匯出數據行和量值。
比較 工作項目計數 量度與根據 工作項目標識碼 的預設計數聚合。 下圖是藉由將卡片視覺效果和工作專案計數量值新增至第一張卡片,並將工作專案標識符屬性新增至第二張卡片來建立。
若要使用預設彙總取得正確的計數,您可以套用篩選器「Is Current」等於「True」。 這個將篩選套用至預設匯總的模式,是本文中提供的許多範例的基礎。
新增狀態排序順序
根據預設,Power BI 會在視覺效果中依字母順序顯示狀態。 當您想要依狀態將時間可視化時,如果進行中之後出現建議,可能會讓人感到困惑。 下列步驟可協助解決此問題。
確認 [狀態類別 ] 欄位已包含在 [分析] 檢視中。 此欄位包含在所有預設共享檢視中。
選取資料表,然後從 功能區的 [數據表工具 ] 索引卷標[ 計算] 區段,選擇 [ 新增數據行]。
以下列程式代碼取代預設文字,然後選取
複選標記。
State Sort Order = SWITCH ( 'View Name'[State Category], "Proposed", 1, "InProgress", 2, "Resolved", 3, 4 )
請參閱下列範例:
注意
如果您需要比 [狀態類別] 提供的更細微度,您可能需要修改定義。 不論任何狀態自定義為何,狀態類別目錄都會在所有工作項目類型之間提供正確的排序。
開啟 [數據] 檢視,然後選取 [狀態] 資料行。
從 [ 數據行工具] 索引標籤中,選擇 [依數據行 排序],然後選取 [ 狀態排序順序 ] 字段。
新增前一個日期
計算狀態時間的下一個步驟需要將數據集中每個數據行映射到前一個間隔中(日、周、月)。 使用一個計算欄位進行簡單的計算。 一般而言,您會定義此數據行,如下所示。
Date Previous =
PREVIOUSDAY ( 'View Name'[Date] )
不過,此方法有兩個主要問題:
- 它僅適用於每日時段。
- 它無法處理資料中的缺失。 例如,如果工作專案在專案之間移動。
若要解決這些問題,計算結果列應該藉由掃描 [日期 ] 字段來尋找前一天。
若要新增 Date Previous 計算結果列,請從 [資料表工具] 索引卷標選擇 [新增數據行],然後將預設文字取代為下列程式代碼,然後選取複選標記。
Date Previous =
CALCULATE (
MAX ( 'View Name'[Date] ),
ALLEXCEPT ( 'View Name', 'View Name'[Work Item Id] ),
'View Name'[Date] < EARLIER ( 'View Name'[Date] )
)
先前日期的計算結果列會使用三個 DAX 函數,MAX
、ALLEXCEPT
和 EARLIER
,這些內容將在本文稍後部分更詳細地描述。 因為數據行是計算的,所以它會針對數據表中的每個數據列執行,而且每次執行時,它都有該特定數據列的內容。
提示
從 日期 和 上一個日期 欄位的內容選單中,選擇 日期(而不是 日期階層)以便查看單一日期。
新增以天數計算的日期差異
Date Previous 會計算每個數據列上一個日期與目前日期之間的差異。 使用 Date Diff in Days,我們會計算每個期間之間的天數。 對於每日快照中的大部分資料列,此值等於 1。 不過,對於數據集中有間距的許多工作專案,此值大於 1。
重要
您必須將 Date Previous 計算欄新增到數據表中。
請務必考慮數據集的第一天,也就是 Date Previous 為空白的那一天。 在此範例中,我們會為該數據列提供標準值為 1,以保持計算一致。
從 [ 模型] 索引標籤標中,選擇 [ 新增數據行 ],然後將默認文字取代為下列程式代碼,然後選取 複選標記。
Date Diff in Days =
IF (
ISBLANK ( 'View Name'[Date Previous] ),
1,
DATEDIFF (
'View Name'[Date Previous],
'View Name'[Date],
DAY
)
)
此計算結果列會使用 ISBLANK
和 DATEDIFF
DAX 函式,如本文稍後所述。
新增為狀態中的最後一天
在下一個步驟中,我們會計算指定的數據列是否代表特定工作專案處於狀態的最後一天。 它支援 Power BI 中的預設匯總功能,我們將在下一節中新增 以天為單位的狀態時間 資料行。
從 [ 模型] 索引標籤標中,選擇 [ 新增數據行 ],然後將默認文字取代為下列程式代碼,然後選取 複選標記。
Is Last Day in State =
ISBLANK (CALCULATE (
COUNTROWS ( 'View Name' ),
ALLEXCEPT ( 'View Name', 'View Name'[Work Item Id] ),
'View Name'[Date] > EARLIER ( 'View Name'[Date] ),
'View Name'[State] = EARLIER ( 'View Name'[State] )
))
在天數中新增狀態時間
工作專案在特定狀態所花費的時間現在可以透過將每個工作專案的日期差異(以天計)相加來計算。 此計算包含花費在特定狀態的所有時間,即使它多次切換狀態也一樣。 您可以使用日期將每個行評估為趨勢,或者使用狀態為最後一天來評估最新資訊。
重要
您必須將 [日期差異(以天計)] 和 [是否為狀態的最後一天] 計算列加入至表格。
從 [ 模型] 索引標籤標中,選擇 [ 新增數據行 ],然後將默認文字取代為下列程式代碼,然後選取 複選標記。
State Time in Days =
CALCULATE (
SUM ( 'View Name'[Date Diff in Days] ),
ALLEXCEPT ( 'View Name', 'View Name'[Work Item Id] ),
'View Name'[Date] <= EARLIER ( 'View Name'[Date] ),
'View Name'[State] = EARLIER ( 'View Name'[State] )
) + 0
根據狀態時間(以天為單位)建立堆疊柱形趨勢圖
用於展示 天中的狀態時間 欄位,會建立下列堆疊柱形圖。 第一張圖表顯示一段時間中每個狀態的工作項目計數。
第二張圖表說明使用中工作項目處於特定狀態的平均天數趨勢。
新增狀態所花時間(以天為單位)- 最新 (是否為狀態中的最後一天)
在評估數據表中每個工作項目的時間狀態,或依區域路徑等欄位進行篩選時,請勿在匯總中使用 狀態時間(天)欄。 匯總會針對工作項目在某狀態的每一天使用該值。 例如,如果工作專案在星期一處於進行中,並在週四移至已完成,那麼在狀態中的時間是三天,但狀態時間(天數)欄的總和為六天,1+2+3
這是不正確的。
若要解決此問題,請使用 [天數 中的狀態時間],並套用篩選 條件為 [狀態 的最後一天] 等於 'True'。 它會排除趨勢所需的所有歷程記錄數據,並改為專注於每個狀態的最新值。
增加以天數計算的狀態時間 - 進行中
在先前的範例中,[狀態時間(以天計)] 只有在指定的工作專案處於該特定狀態時才會計算。 如果您的目標是讓給定工作專案的在狀態時間不斷計入平均值,您必須變更計算方式。 例如,如果我們想要追蹤「進行中」狀態,我們會新增計算結果列[狀態時間(天數)- 進行中]。
從 [ 模型] 索引標籤標中,選擇 [ 新增數據行 ],然後將默認文字取代為下列程式代碼,然後選取 複選標記。
State Time in Days - In Progress =
CALCULATE (
SUM ( 'View Name'[Date Diff in Days] ),
ALLEXCEPT ( 'View Name', 'View Name'[Work Item Id] ),
'View Name'[Date] <= EARLIER('View Name'[Date]),
'View Name'[State] = "In Progress"
) + 0
注意
您可能需要根據專案所使用的工作流程狀態來修改定義。 例如,本文範例中使用的專案會使用「進行中」工作流程狀態,不過 Agile、Scrum 和 CMMI 程式通常會使用「作用中」或「認可」狀態來代表進行中的工作。 如需概觀,請參閱 工作流程狀態和狀態類別。
下圖顯示兩種不同的影響:左圖顯示考慮每個現有工作專案所有狀態時段的情況,而右圖則顯示僅考慮特定一天中處於特定狀態的工作專案的情況。
多個狀態的天數時間趨勢
您也可以使用「連續」模式,分析多個狀態的效能。 不過,此方法只適用於趨勢圖。
從 [ 模型] 索引標籤標中,選擇 [ 新增數據行 ],然後將默認文字取代為下列程式代碼,然後選取 複選標記。
State Time in Days - Working States =
CALCULATE (
SUM ( 'View Name'[Date Diff in Days] ),
ALLEXCEPT ( 'View Name', 'View Name'[Work Item Id] ),
'View Name'[Date] <= EARLIER('View Name'[Date]),
'View Name'[State] IN { "Committed", "In Progress" }
) + 0
注意
您可能需要根據專案所使用的工作流程狀態來修改定義。 例如,如果您的專案使用 『Active』 取代 『Committed』 或 'Proposed'。
左側圖表會顯示合併平均值,而右側則顯示每個個別狀態。
取得多個狀態的狀態時間- 多個狀態的最新狀態
您在建立趨勢時會使用狀態時間(以天計)- 最新計算欄位。 使用狀態篩選時,狀態時間(以天為單位) 欄和 是否為狀態的最後一天 欄提供了一個簡單方法,可以獲得任何工作項目或工作項目群組在一組狀態中所花費的總時間。
新增前一個狀態
Date Previous 計算結果列也可以用來查閱過去的值,例如每個工作專案的先前狀態。
重要
必須先將 Date Previous 計算的欄位新增到資料表中。
從 [ 模型] 索引標籤標中,選擇 [ 新增數據行 ],然後將默認文字取代為下列程式代碼,然後選取 複選標記。
State Previous =
LOOKUPVALUE (
'View Name'[State],
'View Name'[Work Item Id], 'View Name'[Work Item Id],
'View Name'[Date], 'View Name'[Date Previous]
)
此計算結果列會使用LOOKUPVALUE
本文稍後所述的 。
第一個 LOOKUPVALUE
參數 'View Name'[State]
會指定傳回 [State] 的值。
下一個參數 'View Name'[Work Item Id], 'View Name'[Work Item Id]
指定只考慮具有相符工作項目ID且與目前資料列相符的資料列。
而且,最後一個參數 'View Name'[Date], 'View Name'[Date Previous]
指定傳回資料列的 [Date] 必須符合當前資料列的 [上一個日期]。 在快照中,只有一個數據列可以符合此準則。
新增狀態已變更
使用 上一狀態 欄,我們可以標記發生狀態轉換的每個工作項目的數據行。 階段變更 計算欄有兩個特別需要考慮的事項:
- *State Previous 的空白的值,我們已設定為 工作專案的建立日期。
- 建立工作項目被視為狀態轉換
重要
您必須將名為State Previous的計算資料行新增至資料表。
從 [ 模型] 索引標籤標中,選擇 [ 新增數據行 ],然後將默認文字取代為下列程式代碼,然後選取 複選標記。
State Changed =
IF (
ISBLANK ( 'View Name'[State Previous] ),
'View Name'[Created Date].[Date] = 'View Name'[Date],
'View Name'[State Previous] <> 'View Name'[State]
)
計算結果列是布爾值,可識別數據列是否為狀態轉換。 藉由使用 Not Equal To
運算符,您可以正確攔截先前狀態不符合目前狀態的數據列,這表示比較會如預期般傳回 True。
新增狀態流程
使用 狀態之前 和 狀態變更 的計算欄位,您可以建立欄位來展示給定工作項目的狀態流程。 就本文之目的而言,建立此欄位是選擇性的。
重要
您必須將 [狀態上一頁] 和 [狀態變更] 計算欄位新增到表格。
從 [ 模型] 索引標籤標中,選擇 [ 新增數據行 ],然後將默認文字取代為下列程式代碼,然後選取 複選標記。
State Flow =
IF([State Changed], [State Previous], [State]) & " => " & [State]
新增狀態變更計數
當我們進入更複雜的量值時,我們需要有狀態變更總數的表示法,以比較指定工作專案的數據列。 我們會藉由新增 狀態變更計數 計算結果列來取得表示法。
重要
需要您已經將 狀態變更 計算結果列新增至資料表。
從 [ 模型] 索引標籤標中,選擇 [ 新增數據行 ],然後將默認文字取代為下列程式代碼,然後選取 複選標記。
State Change Count =
CALCULATE (
COUNTROWS ( 'View Name' ),
ALLEXCEPT ( 'View Name', 'View Name'[Work Item Id] ),
'View Name'[Date] <= EARLIER ( 'View Name'[Date] ),
'View Name'[State Changed]
) + 0
新增狀態變更計數 - 最後建議的時間和狀態重新啟動時間以天為單位
狀態重新啟動時間(以天為單位) 是相當複雜的計算。 第一個步驟是尋找工作專案處於建議狀態的最後一次。 新增狀態變更次數 - 最後提議計算列。
注意
您可能需要根據專案所使用的工作流程狀態來修改下列定義。 例如,如果您的專案使用 'New' 取代 'Proposed'。
從 [ 模型] 索引標籤標中,選擇 [ 新增] 數據行 ,然後將預設文字取代為下列程式代碼,然後選取 複選標記。
State Change Count - Last Proposed =
CALCULATE (
MAX ( 'View Name'[State Change Count] ),
ALLEXCEPT ( 'View Name', 'View Name'[Work Item Id] ),
'View Name'[Date] <= EARLIER ( 'View Name'[Date] ),
'View Name'[State] = "Proposed"
)
然後,再回顧更早的過去,看看在提議的狀態之前是否存在一些活躍狀態。 最後,總結工作專案在上次建議之前處於作用中狀態的所有天數。
從 [ 模型] 索引標籤標中,選擇 [ 新增數據行 ],然後將默認文字取代為下列程式代碼,然後選取 複選標記。
State Restart Time in Days =
CALCULATE (
SUM ( 'View Name'[Date Diff in Days] ),
ALLEXCEPT ( 'View Name', 'View Name'[Work Item Id] ),
'View Name'[Date] <= EARLIER ( 'View Name'[Date] ),
'View Name'[State Change Count] < EARLIER('View Name'[State Change Count - Last Proposed] ),
'View Name'[State] <"Proposed"
) + 0
由於每個數據列都會更新狀態重新啟動時間,因此您可以建立趨勢來評估特定短期衝刺的重新作業,或使用Is Current檢查個別工作專案的重新作業。
新增狀態重新工作時間(以天為單位)
與 「狀態重啟時間(天數)」 類似,「狀態返工時間(天數)」 會尋找工作項目首次處於 [已完成] 狀態類別的時間。 從那時起,每天停留在 [已完成] 以外的狀態的工作項目,都將被計算為返工。
建立 [狀態變更計數 - 第一個已完成] 欄。 此數據行會追蹤工作專案從任何其他狀態轉換為已完成狀態的次數。
State Change Count - First Completed = VAR CompletedState = "Completed" RETURN CALCULATE( COUNTROWS('YourTable'), FILTER( 'YourTable', 'YourTable'[State] = CompletedState && 'YourTable'[State Change Date] = MIN('YourTable'[State Change Date]) ) )
從 [ 模型] 索引標籤標中,選擇 [ 新增數據行 ],然後將默認文字取代為下列程式代碼,然後選取
複選標記。
State Rework Time in Days = IF ( ISBLANK ( 'View Name'[State Change Count - First Completed] ), 0, CALCULATE ( SUM ( 'View Name'[Date Diff in Days] ), ALLEXCEPT ( 'View Name', 'View Name'[Work Item Id] ), 'View Name'[Date] <= EARLIER ( 'View Name'[Date] ), 'View Name'[State Change Count] <= EARLIER ( 'View Name'[State Change Count - First Completed] ), 'View Name'[State] IN {"Completed", "Closed", "Cut" } = FALSE() ) + 0 )
注意
您可能需要根據專案所使用的工作流程狀態來修改先前的定義。 例如,如果您的專案使用 Done 替代 Closed,等等。
DAX 函式
本節提供用於建立本文中新增之導出數據行和量值之 DAX 函式的其他資訊。 另 請參閱 DAX 時間智慧函式。
函式 | 描述 |
---|---|
ALLEXCEPT |
移除資料表中所有的上下文篩選,但套用至指定欄位的篩選條件除外。 基本上, ALLEXCEPT ('View Name'', 'View Name'[Work Item Id]) 將數據表中的數據列縮減為只共用與目前數據列相同的工作專案標識碼的數據列。 |
CALCULATE |
此函式是幾乎所有範例的基礎。 基本結構是表達式,後面接著套用至表達式的一系列篩選。 |
COUNTROWS |
此函式 COUNTROWS ( 'View Name' ) 只會計算套用篩選之後所保留的數據列數目。 |
DATEDIFF |
傳回兩個日期之間跨越的間隔界數。
DATEDIFF 從之前的日期減去日期,以判斷兩者之間的天數。 |
EARLIER |
傳回指定資料行在所提到資料行的外部評估過程中的目前值。 例如,'View Name'[Date] < EARLIER ( 'View Name'[Date] ) 會進一步縮小數據集,只保留發生在目前數據列所參考日期(使用EARLIER 函式計算)之前的數據列。
EARLIER 不會參考先前的日期;它特別定義匯出資料行的數據列內容。 |
ISBLANK |
檢查某值是否為空白,並傳回 TRUE 或 FALSE。
ISBLANK 評估目前的數據列,以判斷 Date Previous 是否有值。 如果條件不符,If 語句會將Date Diff in Days設定為 1。 |
LASTDATE |
例如,我們會將 LASTDATE 篩選套用至表達式, LASTDATE ( 'View Name'[Date] ) 以尋找數據表中所有數據列的最新日期,並排除未共用相同日期的數據列。 使用分析檢視所產生的快照集數據表,此篩選會有效地挑選所選期間的最後一天。 |
LOOKUPVALUE |
針對符合search_columnName和search_value指定之所有準則的數據列,傳回 result_columnName 中的值。 |
MAX |
傳回一個資料行中或兩個純量運算式之間的最大數值。 我們會套用 MAX ( 'View Name'[Date] ) ,以判斷套用所有篩選之後的最新日期。 |