Zeiterfassung mit Team Foundation Server (ohne Microsoft Project)

Donnerstag, 13. Juni 2013

Wenn man in Team Foundation Server (TFS) schon Zeitaufwände wie etwa Completed und Remaining Work erfasst und es ein Benutzermanagement gibt, kann man die Daten dann nicht auch gleich als Ersatz für die Zeiterfassung nutzen?

In diesem Teil der Blog-Reihe zu Zeiterfassung mit TFS zeigen wir Ihnen wie weit man mit TFS-Boardmitteln tatsächlich kommt...

Was wir benötigen...

Zunächst einmal gibt es organisatorische Herausforderungen. Wenn man die Zeiterfassung durch TFS ablösen und kein weiteres System verwenden möchte, dann müssten auch:

  1. alle anderen Mitarbeiter (Nicht-Entwickler/Tester) über TFS Zeiten erfassen und
  2. alle Aufgaben, also auch die außerhalb des aktuellen Projektes sowie für Meetings usw. im TFS erfasst werden - und dazu pro Beteiligtem je Aufgabe je ein Task Work Item.

Das ist sicher nicht erwünscht. Doch schon die Auswertung der "Entwickler- und Testeraufwände” könnte interessant genug sein. Dazu reicht es aber nicht, am Ende des Projektes eine Gesamtsumme aus allen Tasks zu ermitteln. Die Aufwände sollen z.B. monatsweise oder gar tagesgenau pro Mitarbeiter ausgewertet werden können, um Sie z.B. mit dem Zeiterfassungssystem abzugleichen oder weitere Details über die angefallenen Tätigkeiten zu geben.

Was der TFS-Cube bietet...

Team Foundation Server bietet Out-Of-The-Box in den Process Templates MSF for CMMI und Agile im Task Work Item die Felder Completed Work und Remaining Work an. Hier ein Beispiel aus dem Template MSF for CMMI 6:

Beispiel-Task aus dem Process Template MSF for CMMI Process Improvement 6
Abbildung: Beispiel-Task aus dem Process Template MSF for CMMI Process Improvement 6

Diese werden so verwendet, als dass in Completed Work stets die Summe aller angefallenen Aufwände und in Remaining Work die Summe der wahrscheinlich verbleibenden Aufwände eingetragen ist. Dafür muss der Benutzer sorgen. Original Estimate kann verwendet werden, um die initial geschätzte Zeit festzuhalten.

Ein Beispiel: Entwickler Dave trägt in einem neuen Task der ihm zugewiesen ist initial seine Schätzung in Original Estimate und den gleichen Wert in Remaining Work ein. Im weiteren Verlauf verwendet er nur noch die Felder Completed und Remaining Work:

AktionOriginal EstimateRemaining WorkCompleted Work
Initiale Schätzung2020
Erste Aufwände20155
Korrektur der Schätzung nach weiterer Arbeit20148
Abschluss der Aufgabe2024
Tabelle: Beispiel der Änderungen an den Aufwandsfeldern im Task Work Item

Man stellt fest, dass sowohl der Bearbeiter als auch der Auswertende ständig rechnen müssen, um zu ermitteln, wer wann wie viel gearbeitet hat. Zudem zeigt der Task ja immer nur die aktuellen Werte.

Der Verlauf ist in der Historie unter allen anderen Änderungen "vergraben”:

Historie des Beispiel-Task
Abbildung: Historie des Beispiel-Task

TFS bietet mit dem Reporting (über ein Warehouse) die Möglichkeit für historische Auswertungen und die Betrachtung des Verlaufs von Werten. Wenn man über den TFS Cube geht (siehe auch Reporting mit dem TFS Teil 1/3 - Berichte mit Excel) erhält man auch recht einfach über eine Pivot-Tabelle die folgende Auswertung für die Aufwandsfelder nach Work Item Id (hier 4)

Reporting der Aufwandsfelder für Task #4 am 11.03.2013
Abbildung: Reporting der Aufwandsfelder für Task #4 am 11.03.2013

Diese ließen sich auch mit dem Assigned-To-User verknüpfen, so dass man die Zuordnung der Tasks zu den Benutzern in der Tabelle auflisten kann.

Wenn man nun aber auch Änderungen an diesem Tag und von unterschiedlichen Benutzern darstellen möchte und deshalb die Work Item Revision mit einblendet, erhält man lediglich Nullwerte wo eigentlich nach der obigen Tabelle andere Werte stehen müssten:

Reporting mit Revisionsnummern des Task #4 am 11.03.2013
Abbildung: Reporting mit Revisionsnummern des Task #4 am 11.03.2013

Der Grund für die Nullwerte ist technisch begründet: Das Analysis-Reporting löst die Änderungen im Cube nicht auf Revisionen auf, bzw. werden Measures (aggregierbare Werte im Cube wie z.B. Completed Work) für Zwischenrevisionen pro Tag auf 0 gesetzt. Nur die letzte Änderung an einem Tag enthält tatsächlich einen Wert für ein Measure. Das liegt daran, dass die Gesamtsumme pro Work Item stimmen muss. Für eine Id muss die Summe von Completed Work pro Tag passen. Wenn nun aber pro ein anderer Wert steht, würde die Gesamtsumme in Completed Work der Summe aller Revisionen entsprechen und das wäre falsch. Daher sieht man im Cube für die Revisionen immer Nullwerte.

Wie es mit dem relationalen Warehouse besser geht...

Neben dem Cube, der für langfristige historische Auswertungen optimiert ist, gibt es ein relationales Warehouse. Im Gegensatz zum Cube lässt sich das in Excel nicht direkt in einer Pivot-Tabelle öffnen, sondern bedarf ein paar mehr Handgriffen.

Um das relationale Warehouse zu verwenden, benutzt man in Excel ebenfalls den Verbinden-Dialog:

Verbinden mit dem relationalen Warehouse
Abbildung: Verbinden mit dem relationalen Warehouse

Als Server gibt man das TFS Data-Tier an und wählt dann die Datenbank "Tfs_Warehouse" und darin die Tabelle "WorkItemHistoryView". Dies erzeugt im Spreadsheet von Excel eine Tabelle, die zunächst alle Felder der View enthält. Jedoch sollte man die hinterlegte Query noch anpassen:

Ändern der hinterlegten Abfrage
Abbildung: Ändern der hinterlegten Abfrage
Die zu hinterlegende Abfrage lautet:
SELECT
[System_Id] As [Id],[System_Rev] As [Rev]
,[System_ChangedBy] As [Changed By],[System_ChangedDate] As [Changed Date]
,[Microsoft_VSTS_Scheduling_OriginalEstimate] AS [Original Estimate] ,[Microsoft_VSTS_Scheduling_RemainingWork] AS [Remaining Work]
,[Microsoft_VSTS_Scheduling_CompletedWork] AS [Completed Work]
,[System_Title] As [Title],[System_AssignedTo] As [Assigned To]
,[ProjectNodeName] AS [Team Project]
,[AreaName],[AreaPath],[IterationName],[IterationPath]
FROM
[Tfs_Warehouse].[dbo].[WorkItemHistoryView]
WHERE
/** Filter team project **/
[ProjectNodeName] LIKE ‘XXX’
/** Filter correction entries **/
AND [RevisionCount] IS NOT NULL
/** Filter empty entries **/
AND ([Microsoft_VSTS_Scheduling_OriginalEstimate] IS NOT NULL
OR [Microsoft_VSTS_Scheduling_RemainingWork] IS NOT NULL
OR [Microsoft_VSTS_Scheduling_CompletedWork] IS NOT NULL)

Die Tabelle enthält jedoch immer noch die stetig wachsenden bzw. sinkenden Summen von Completed bzw. Remaining Work und nicht die am jeweiligen Tag von einem Benutzer eingetragene Zeit. Um dies zu erreichen wird eine berechnete Spalte mit folgender Formel zur Tabelle hinzugefügt:

=[@[Completed Work]]-IF(AND(ISNUMBER(INDIRECT("J" & ROW([@Title])-1));INDIRECT("E" &
ROW([@Title])-1)=[@Id]);INDIRECT("J" & ROW([@Title])-1);0)
Ergebnistabelle in Excel
Abbildung: Die Ergebnistabelle in Excel

Die Spalte "Completed Diff" enthält dann die Differenz zum vorherigen Eintrag also zur letzten Work Item-Änderung.
Einziges Manko: Die eingetragenen Zeiten werden immer auf den Tag "gebucht” an dem die Eintragung ins Work Item erfolgte. Ein Benutzer kann also nicht nachträglich für letzte Woche Zeiten eintragen. Diesen Punkt gehen wir im nächsten Blog-Post an in dem wir uns mit Erweiterungen beschäftigen.

Sollten Sie bereits zu diesen TFS-Grundfunktionen Fragen haben, sprechen Sie uns an: sven.hubert@aitgmbh.de

Verwandte Artikel

Benötigen Sie Unterstützung bei der Software-Entwicklung und Architektur von .NET basierten Lösungen oder bei Einführung und Anpassung von Visual Studio / Microsoft Test Manager / Team Foundation Server? Wir stehen Ihnen unter info@aitgmbh.de gerne zur Verfügung.

Microsoft Virtual Academy.