问题
I have multiple resources (learners, Facilitators and Rooms) allocated to Tasks (training sessions) and I want to identify which are double-booked and then adding them into a text column.
I am using the TimeScale method and I am currently trying to calculate a double-booking by assuming that any resource that has more time than the length of the session allocated to them over a given start and end date for that session must be double-booked.
However I cannot work out how to determine the total amount of time they have been assigned. The pjTimeScale attribute does not seem to be returning what i need. Using pjTimescaleHours is the closest to the actual value that should be returned.
What am I missing? or is there a better approach?
Sub Overallocations()
'T.Text19 is the Overallocation column
'Identify the overallocations and the source ID
Dim T As Task
Dim R As Resource
Dim tsvs As TimeScaleValues
Dim asn As Assignment
For Each T In ActiveProject.Tasks
T.Text19 = ""
Next T
'Start the allocation of Rooms process
For Each T In ActiveProject.Tasks
i = 0
Application.StatusBar = "Checking Session No." & T.ID
'Checks to see if the task is a valid Module session and if it has been
confirmed. Skips if not a session or if its a confirmed session
If Left(T.Name, 1) <> "M" Then
GoTo SkipT
End If
For Each R In T.Resources
Set tsvs = R.TimeScaleData(T.Start, T.Finish, pjResourceTimescaledWork,
pjTimescaleHours)
Duration = (T.Finish - T.Start) * 60 * 24
If tsvs(1).Value > Duration + 1 Then 'THIS IS WHAT IS NOT WORKING
If T.Text19 = "" Then
T.Text19 = R.Name
Else
T.Text19 = T.Text19 & ", " & R.Name
End If
End If
Next R
SkipT:
Next T 'Next Task
MsgBox "The identification of overallocation has been completed.",
vbInformation, "Resource Overallocation Complete"
End Sub
回答1:
I have multiple resources (learners, Facilitators and Rooms) allocated to Tasks (training sessions) and I want to identify which are double-booked...
In other words, need to identify learners, facilitators, and rooms that are assigned to overlapping training sessions.
While this can be done using the TimeScaleData
method, a far easier approach is to look for overlapping sessions. There are four scenarios where training sessions overlap:
- Class B starts before Class A and finishes while Class A is still running.
- Class B starts while Class A is running and finishes after Class A.
- Class B starts and finishes while Class A is running.
- Class B starts before Class A and finishes after Class A.
All four scenarios can be identified with a common expression: Class B starts before Class A ends and Class B ends after Class A starts
; see diagram below.
Here is your code adapted for this method:
Sub IdentifyOverlappingAssignments()
Dim T As Task
Dim R As Resource
For Each T In ActiveProject.Tasks
Application.StatusBar = "Checking Session No." & T.ID
T.Text19 = vbNullString
'Checks to see if the task is a valid Module session and if it has been confirmed.
If Left(T.Name, 1) = "M" Then
For Each R In T.Resources
' check to see if this resource is assigned to another task
' at all during the duration of this task
Dim asn As Assignment
For Each asn In R.Assignments
If asn.Task.UniqueID <> T.UniqueID Then
' do the tasks overlap?
If asn.Task.Finish > T.Start And asn.Task.Start < T.Finish Then
If T.Text19 = "" Then
T.Text19 = R.Name & " (" & asn.Task.ID & ")"
Else
T.Text19 = T.Text19 & ", " & R.Name & " (" & asn.Task.ID & ")"
End If
End If
End If
Next asn
Next R
End If
Next T
MsgBox "The identification of overallocation has been completed." _
, vbInformation, "Resource Overallocation Complete"
End Sub
Note: using TimeScaleData is problematic in this case for various reasons including: 1) resources could be assigned at 50% usage and would not be identified as double-booked because the would not be overallocated, 2) if classes started on the half hour (e.g. 10:30 AM - 12:00 PM), you would need to get the timescale values down to the minute because using pjTimescaleHours will return the full hour (e.g. the timescale values will start at 10:00 AM), and that's an easy bug to introduce to your code.
回答2:
Two things, one pointer about the code and one question.
If you are for...nexting through the tasks collection remember to put an If..Then just inside it like this one to catch blank rows. PMs LOVE blank rows and they will error out your code. I also do it for resources because sometimes they will put blank rows there too.
Can I ask why you are doing this instead of using the built in 'Overallocated' functionality in Project? If a resource is assigned more than 1 hour of work in any given hour then that resource will automatically get flagged as such as will any task to which they are assigned. This is cool code but SHOULD be unnecessary unless Im missing something.
Code:
Sub Foo()
Dim T As Task
Dim R As Resource
For Each T In ActiveProject.Tasks
If Not (T Is Nothing) Then
'Task stuff
For Each R In T.Resources
If Not (R Is Nothing) Then
Resource Stuff
End If
Next R
End If
Next T
End Sub
来源:https://stackoverflow.com/questions/55156271/identifying-specific-resources-that-are-overallocated-in-ms-project-using-timesc