次の方法で共有


機能の進捗統合サンプルレポート

Azure DevOps サービス |Azure DevOps Server |Azure DevOps Server 2022

この記事では、積み上げ横棒グラフ レポートを作成し、完成した子ユーザー ストーリーに基づいて機能の進行状況を表示する方法について説明します。 レポートには、特定のアクティブなフィーチャーセットのストーリーポイントのロールアップによる達成率が表示されます。 ロールアップ列を追加することで、バックログから同様の進行状況横棒グラフを表示できます。 方法については、「表示ロールアップの進行状況または合計」を参照してください。

Power BIを使用してロールアップ レポートを作成すると、データセット内の入れ子になったデータに関連する問題が発生する可能性があります。 具体的には、ネストされたデータを持つ列を含むテーブルをピボットしようとすると、エラーメッセージが表示されることがあります。 詳細については、ネストされたデータの処理に関するセクションを参照してください。

前提条件

カテゴリ 要求事項
アクセス レベル - プロジェクトメンバー
- 少なくともベーシックアクセス。
アクセス許可 既定では、プロジェクト メンバーには Analytics にクエリを実行してビューを作成する権限があります。 サービスと機能の有効化と一般的なデータ追跡アクティビティに関するその他の前提条件の詳細については、「 Analytics にアクセスするためのアクセス許可と前提条件を参照してください。

この記事では、OData クエリを使用したサンプル レポートの概要を読み、Power BIに関する基本的な理解があることを前提としています。

サンプル クエリ

機能の進行状況は、 WorkItems エンティティに対してクエリを実行して、現在の進行状況を取得します。

フィルター処理またはレポートに使用できるプロパティを見つけるには、Azure Boardsの Metadata リファレンスを参照してください。 クエリをフィルター処理したり、プロパティを返したりするには、Propertyで定義されている任意のEntityType値、またはNavigationPropertyBinding Pathに一覧表示されている任意のEntitySet値を使用します。 各 EntitySet は、各プロパティのデータ型を文書化する EntityTypeにマップされます。

エリア パスに基づいて機能の進行状況を確認する

次のPower BIクエリをコピーして、Get Data>Blank Query ウィンドウに直接貼り付けます。 詳細については、「 OData クエリを使用したサンプル レポートの概要を参照してください。

let
   Source = OData.Feed ("https://analytics.dev.azure.com/{organization}/{project}/_odata/v3.0-preview/WorkItems?"
        &"$filter=WorkItemType eq 'Feature' "
            &"and State ne 'Removed' "
            &"and startswith(Area/AreaPath,'{areapath}') "
            &"and Descendants/any()"
            &"&$select=WorkItemId,Title,Area,Iteration,AssignedTo,WorkItemType,State,AreaSK"
            &"&$expand=Descendants( "
            &"$apply=filter(WorkItemType eq 'User Story') " 
                &"/groupby((StateCategory), "
                &"aggregate(StoryPoints with sum as TotalStoryPoints)) "
            &")  "
    ,null, [Implementation="2.0",OmitValues = ODataOmitValues.Nulls,ODataVersion = 4]) 
in
    Source

置換文字列とクエリの内訳

次の文字列を実際の値に置き換えます。 置換に波括弧 {} を含めないでください。 たとえば、組織名が "Fabrikam" の場合は、{organization}ではなく、Fabrikam{Fabrikam}に置き換えます。

  • {organization} - 組織名
  • {project} - プロジェクト間クエリの場合は、チーム プロジェクト名を指定するか、 /{project} 全体を省略します
  • {areapath} - 領域パス。 形式の例: Project/Level1/Level2

クエリの内訳

次の表では、クエリの各部分について説明します。

クエリ部分

説明


$filter=WorkItemType eq 'Feature'

戻り値の特徴。

and State ne 'Removed'

削除済みとしてマークされた機能を省略します。

and startswith(Area/AreaPath,'{areapath}')

特定のエリア パスの下にある作業項目を返します。 を に Area/AreaPath eq '{areapath}' 置き換えると、特定のエリア パスにある項目が返されます。
チーム名でフィルター処理するには、filter ステートメント Teams/any(x:x/TeamName eq '{teamname}')を使用します。

and Descendants/any()

少なくとも 1 つまたはいずれかの子孫を持つ作業項目を除外します。 少なくとも 1 つの子作業項目を持つすべての機能が含まれます。 子孫を含むすべての作業項目を取得するには、たとえ子孫が存在しなくても、Descendants/any() フィルターを使わずにクエリを実行します。 子ユーザー ストーリーがないフィーチャーを省略するには、 any(d:d/WorkItemType eq 'User Story')に置き換えます。

すべての作業項目 子孫ありとなしの場合:

$filter=endswith(Area/AreaPath,'suffix')
&$select=WorkItemId,Title,WorkItemType,State,Area, Descendants
&$expand=Descendants($select=WorkItemId)

少なくとも 1 つの子孫を持つすべての作業項目について:

$filter=endswith(Area/AreaPath, 'suffix')and Descendants/any()
&$select=WorkItemId,Title,WorkItemType,State,Area, Descendants
&$expand=Descendants($select=WorkItemId)

&$select=WorkItemId, Title, WorkItemType, State

返すプロパティを選びます。

&$expand=Descendants(

expand Descendants 句の開始

$apply=filter(WorkItemType eq 'User Story')

子孫をフィルター処理します。 ユーザー ストーリーのみを含めます (タスクとバグを省略します)。

/groupby((StateCategory),

StateCategory でロールアップをグループ化します。 状態カテゴリの詳細については、「ワークフローの 状態と状態カテゴリ をバックログとボードで使用する方法」を参照してください。

aggregate(StoryPoints with sum as TotalStoryPoints))

ストーリー ポイントの合計。

)

Descendants() クローズします。

チームの機能の進行状況を確認する

次のクエリは、前に使用したクエリと同じですが、エリア パスではなくチーム名でフィルター処理されます。

次のPower BIクエリをコピーして、Get Data>Blank Query ウィンドウに直接貼り付けます。 詳細については、「 OData クエリを使用したサンプル レポートの概要を参照してください。

let
   Source = OData.Feed ("https://analytics.dev.azure.com/{organization}/{project}/_odata/v3.0-preview/WorkItems?"
        &"$filter=WorkItemType eq 'Feature' "
            &"and State ne 'Cut' "
            &"and (Teams/any(x:x/TeamName eq '{teamname}') or Teams/any(x:x/TeamName eq '{teamname}') or Teams/any(x:x/TeamName eq '{teamname}')) "
            &"and Descendants/any() "
        &"&$select=WorkItemId,Title,WorkItemType,State,AreaSK "
        &"&$expand=Descendants( "
            &"$apply=filter(WorkItemType eq 'User Story') "
                &"/groupby((StateCategory), "
                &"aggregate(StoryPoints with sum as TotalStoryPoints)) "
            &")  "
    ,null, [Implementation="2.0",OmitValues = ODataOmitValues.Nulls,ODataVersion = 4]) 
in
    Source

Power Query エディターでデータを変換する

このクエリでは、レポートの作成に使用する前に展開する必要がある複数の列が返されます。 OData $expand ステートメントを使用してプルするすべてのエンティティは、複数のフィールドを含むレコードを返します。 レコードを展開し、エンティティをそのフィールドにフラット化します。

機能の進行状況レポートでは、次の変換を実行します。

  • Descendants列を 2 つの列 (Descendants.StateCategoryDescendants.TotalStoryPoints) に展開します。
  • Descendants.StateCategory変換を適用して、個々の状態カテゴリを分離します。
  • ピボットされたすべての列の null 値を置換します。
  • 完了率を表すカスタム列を追加します。 ピボットされた State 列に null 列がある場合、カスタム列にはエラーが表示されます。

その方法については、Transform Analytics データを参照して、Power BI レポートを生成します。

ネストされたデータの処理

ピボット操作を実行する前に、データセットに入れ子になったデータを含む列が含まれていないことを確認します。 次の手順に従います。

  1. ネストされた列を特定する: データセットで、1 つのセル内にリスト、レコード、またはテーブルが含まれている可能性のある列がないか確認します。
  2. 入れ子になったデータの拡張または削除: Power Queryの Expand 機能を使用して、入れ子になった列を削除するか、別の列に展開してフラット化します。
  3. ピボット操作を実行する: 入れ子になったデータに対処した後、エラーが発生することなくピボット操作を続行できます。

この例では、User StoryState 値には、ProposedIn Progress、および Completed が含まれます。

クエリを閉じて変更を適用する

すべてのデータ変換が完了したら、[ホーム] メニューから [閉じて適用] を選択します。 このアクションによりクエリが保存され、Power BIの Report タブに戻ります。

Power Query エディター閉じて適用オプションのスクリーンショット.

積み上げ棒グラフ レポートを作成する

  1. Power BIで、Visualizations の下にある Stacked 横棒グラフ を選択します。

    Power BIの視覚化オプションとフィールド選択肢のスクリーンショット(Feature Progressの積み上げ横棒グラフレポート)。

  2. TitleY軸に追加します。

  3. PercentComplete X軸に追加し、右クリックして合計を選択します。

レポートの例が表示されます。

サンプル機能の進行状況の積み上げ横棒グラフ レポートのスクリーンショット。