L
LarryPritchard
I have a project that I am tracking with over 50 individual sub-projects. I
have some VBA code that extracts from a Time Reporting SQL database and then
posts any hours from that week to the correct sub-project.
Here is the function that posts the updates to the actual hours:
'===============================================
'= Sub Step1_UpdateActualWork(strErrors)
'= Description: This sub will apply the programmer submitted hours
'===============================================
Sub Step1_UpdateActualWork(ByRef strErrors)
Dim strFunctionSub
Dim objConn
Dim objRS
Dim tskTask
Dim strTaskISRNbr
Dim strSQL
Dim strStatus
Dim strEndDate
Dim strStartDate
Dim lngTaskUID
Dim strResourceName
Dim lngResourceUID
Dim strTaskID
Dim strResourceID
Dim lngAssignmentUID
Dim strWorkEntryDate
Dim strWork
On Error GoTo ErrorHandler
strFunctionSub = "Step1_UpdateActualWork"
'Create local objects
Set objConn = CreateObject("ADODB.Connection")
Set objRS = CreateObject("ADODB.RecordSet")
'Open the connection object
objConn.Open g_strConnectInfo
'Loop thru all the Tasks so we can calculate the total hours worked.
For Each tskTask In ActiveProject.Tasks
'We only want to calculate on the tasks that
'have this Text10 Value (ISR Nbr)
strTaskISRNbr = tskTask.Text10
If strTaskISRNbr <> "" Then
'We don't want to update the project if the Flag1 (Complete)
'is set to Yes.
If tskTask.Flag1 = False Then
'Get the project info
strSQL = "SELECT PTR.Project_No, PTR.Project_Name,
PTR.Entry_Date, PTR.Close_Dt, PTR.Project_Status, P.Change_ID, Sum(P.Hours)
AS SumOfHours, P.Entry_Date As TimeEntryDate " & _
"FROM dbo.Project_Time P INNER JOIN dbo.PTR_Master PTR ON
P.Project_No = PTR.Project_No " & _
"WHERE PTR.Project_No = '" & strTaskISRNbr & "' And
P.Change_ID Is Not Null And P.Entry_Date > '" & g_strSearchBeginDate & "' And
P.Entry_Date <= '" & g_strSearchEndDate & "' And P.Hours > 0 " & _
"GROUP BY PTR.Project_No, PTR.Project_Name, PTR.Entry_Date,
PTR.Close_Dt, PTR.Project_Status, P.Change_ID, P.Entry_Date " & _
"ORDER BY PTR.Project_No, P.Entry_Date;"
'Make the SQL call
Call objRS.Open(strSQL, objConn)
If Not objRS.EOF Then
'First use the TaskUID for lookups
lngTaskUID = tskTask.UniqueID
strTaskID = CLng(tskTask.ID)
'Status will be OPEN or COMPLETED or CANCELLED
strStatus = objRS("Project_Status")
'Set the Begin/End Dates
strStartDate = CStr(objRS("Entry_Date"))
If UCase(strStatus) = "OPEN" Then
'Set the End Date = NA
strEndDate = "NA"
Else
strEndDate = CStr(objRS("Close_Dt"))
End If
'Loop thru multiple resources that could of worked
'on this Task
Do While Not objRS.EOF
'What resource are we looking for?
strResourceName = UCase(objRS("Change_ID"))
'Get the TaskUID or 0 if it doesn't exist
lngResourceUID = GetResourceUID(strResourceName)
If lngResourceUID = 0 Then
'Add the Resource
lngResourceUID =
ActiveProject.Resources.Add(strResourceName)
End If
'''''
'We have the Resource UID now, so we can update the
assignments
'''''
strResourceID =
CLng(ActiveProject.Resources.UniqueID(lngResourceUID).ID)
'Check to see if we need to add this Assignment
lngAssignmentUID = GetAssignmentUID(strTaskID,
strResourceID)
If lngAssignmentUID = 0 Then
'Add the Assignment
lngAssignmentUID =
tskTask.Assignments.Add(strTaskID, strResourceID, "1")
End If
'Update the hour assigments
strWorkEntryDate = objRS("TimeEntryDate")
'Work is stored in seconds so multiply by 60
strWork = objRS("SumOfHours") * 60
tskTask.Assignments.UniqueID(lngAssignmentUID).TimeScaleData(strWorkEntryDate,
strWorkEntryDate, pjAssignmentTimescaledActualWork, pjTimescaleWeeks,
1).Item(1).Value = strWork
'Get the next record if it exists
objRS.MoveNext
Loop
'''''''''''''''''''''''''''''''''''''
'Update the Task level Info, we want to do this last so
'the time reporting is not skewed
'''''''''''''''''''''''''''''''''''''
'Update the Actual Start Date
tskTask.ActualStart = strStartDate
'Update the Actual End Date
tskTask.ActualFinish = strEndDate
Else
'Since this returned and EOF condition, make a call into
'the PTR system by its self to see if the project was
'Closed or cancelled with no time assigned.
'Close the RS
objRS.Close
'Build the PTR_Master call
strSQL = "SELECT Project_Status, Close_Dt, Entry_Date "
& _
"FROM PTR_Master " & _
"WHERE Project_No = '" & strTaskISRNbr & "';"
'Make the SQL call
Call objRS.Open(strSQL, objConn)
If Not objRS.EOF Then
strStatus = objRS("Project_Status")
If strStatus <> "OPEN" Then
'Just complete it. We don't need to know if
this was
'a COMPLETED or CANCELLED Project at this time.
'tskTask.PercentComplete = "100%"
'Update the Actual Start Date
't.Date3 = CStr(objRS("Entry_Date"))
tskTask.ActualStart = CStr(objRS("Entry_Date"))
'Update the Actual End Date
't.Date1 = CStr(objRS("Close_Dt"))
tskTask.ActualFinish = CStr(objRS("Close_Dt"))
End If
End If
End If
'Close the RS
objRS.Close
End If
End If
Next
GoTo NormalExit
ErrorHandler:
strErrors = strErrors & strFunctionSub & "::Unexpected Error Occurred:"
& vbCrLf & vbCrLf
strErrors = strErrors & "Error: " & Err.Number & "-" & Err.Description
Resume NormalExit
NormalExit:
Set objRS = Nothing
Set objConn = Nothing
End Sub
This is the line that I am having trouble with:
tskTask.Assignments.UniqueID(lngAssignmentUID).TimeScaleData(strWorkEntryDate,
strWorkEntryDate, pjAssignmentTimescaledActualWork, pjTimescaleWeeks,
1).Item(1).Value = strWork
Now this code works fine, execpt for the fact that instead of just posting
the number of hours/minutes for that week, it will sometimes add hours in
surrounding weeks. So instead of posting 30 hours / 180 mintues into the
week of 3/17/2006, it will post 180 minutes in the week of 3/17/2006 AND 240
hours in the week of 3/24/2006 AND 240 hours in the week of 3/31/2006.
I have not been able to find any Best Practices of using this method
(TimeScaleData). Any help or pointers would be greatly appreciated.
have some VBA code that extracts from a Time Reporting SQL database and then
posts any hours from that week to the correct sub-project.
Here is the function that posts the updates to the actual hours:
'===============================================
'= Sub Step1_UpdateActualWork(strErrors)
'= Description: This sub will apply the programmer submitted hours
'===============================================
Sub Step1_UpdateActualWork(ByRef strErrors)
Dim strFunctionSub
Dim objConn
Dim objRS
Dim tskTask
Dim strTaskISRNbr
Dim strSQL
Dim strStatus
Dim strEndDate
Dim strStartDate
Dim lngTaskUID
Dim strResourceName
Dim lngResourceUID
Dim strTaskID
Dim strResourceID
Dim lngAssignmentUID
Dim strWorkEntryDate
Dim strWork
On Error GoTo ErrorHandler
strFunctionSub = "Step1_UpdateActualWork"
'Create local objects
Set objConn = CreateObject("ADODB.Connection")
Set objRS = CreateObject("ADODB.RecordSet")
'Open the connection object
objConn.Open g_strConnectInfo
'Loop thru all the Tasks so we can calculate the total hours worked.
For Each tskTask In ActiveProject.Tasks
'We only want to calculate on the tasks that
'have this Text10 Value (ISR Nbr)
strTaskISRNbr = tskTask.Text10
If strTaskISRNbr <> "" Then
'We don't want to update the project if the Flag1 (Complete)
'is set to Yes.
If tskTask.Flag1 = False Then
'Get the project info
strSQL = "SELECT PTR.Project_No, PTR.Project_Name,
PTR.Entry_Date, PTR.Close_Dt, PTR.Project_Status, P.Change_ID, Sum(P.Hours)
AS SumOfHours, P.Entry_Date As TimeEntryDate " & _
"FROM dbo.Project_Time P INNER JOIN dbo.PTR_Master PTR ON
P.Project_No = PTR.Project_No " & _
"WHERE PTR.Project_No = '" & strTaskISRNbr & "' And
P.Change_ID Is Not Null And P.Entry_Date > '" & g_strSearchBeginDate & "' And
P.Entry_Date <= '" & g_strSearchEndDate & "' And P.Hours > 0 " & _
"GROUP BY PTR.Project_No, PTR.Project_Name, PTR.Entry_Date,
PTR.Close_Dt, PTR.Project_Status, P.Change_ID, P.Entry_Date " & _
"ORDER BY PTR.Project_No, P.Entry_Date;"
'Make the SQL call
Call objRS.Open(strSQL, objConn)
If Not objRS.EOF Then
'First use the TaskUID for lookups
lngTaskUID = tskTask.UniqueID
strTaskID = CLng(tskTask.ID)
'Status will be OPEN or COMPLETED or CANCELLED
strStatus = objRS("Project_Status")
'Set the Begin/End Dates
strStartDate = CStr(objRS("Entry_Date"))
If UCase(strStatus) = "OPEN" Then
'Set the End Date = NA
strEndDate = "NA"
Else
strEndDate = CStr(objRS("Close_Dt"))
End If
'Loop thru multiple resources that could of worked
'on this Task
Do While Not objRS.EOF
'What resource are we looking for?
strResourceName = UCase(objRS("Change_ID"))
'Get the TaskUID or 0 if it doesn't exist
lngResourceUID = GetResourceUID(strResourceName)
If lngResourceUID = 0 Then
'Add the Resource
lngResourceUID =
ActiveProject.Resources.Add(strResourceName)
End If
'''''
'We have the Resource UID now, so we can update the
assignments
'''''
strResourceID =
CLng(ActiveProject.Resources.UniqueID(lngResourceUID).ID)
'Check to see if we need to add this Assignment
lngAssignmentUID = GetAssignmentUID(strTaskID,
strResourceID)
If lngAssignmentUID = 0 Then
'Add the Assignment
lngAssignmentUID =
tskTask.Assignments.Add(strTaskID, strResourceID, "1")
End If
'Update the hour assigments
strWorkEntryDate = objRS("TimeEntryDate")
'Work is stored in seconds so multiply by 60
strWork = objRS("SumOfHours") * 60
tskTask.Assignments.UniqueID(lngAssignmentUID).TimeScaleData(strWorkEntryDate,
strWorkEntryDate, pjAssignmentTimescaledActualWork, pjTimescaleWeeks,
1).Item(1).Value = strWork
'Get the next record if it exists
objRS.MoveNext
Loop
'''''''''''''''''''''''''''''''''''''
'Update the Task level Info, we want to do this last so
'the time reporting is not skewed
'''''''''''''''''''''''''''''''''''''
'Update the Actual Start Date
tskTask.ActualStart = strStartDate
'Update the Actual End Date
tskTask.ActualFinish = strEndDate
Else
'Since this returned and EOF condition, make a call into
'the PTR system by its self to see if the project was
'Closed or cancelled with no time assigned.
'Close the RS
objRS.Close
'Build the PTR_Master call
strSQL = "SELECT Project_Status, Close_Dt, Entry_Date "
& _
"FROM PTR_Master " & _
"WHERE Project_No = '" & strTaskISRNbr & "';"
'Make the SQL call
Call objRS.Open(strSQL, objConn)
If Not objRS.EOF Then
strStatus = objRS("Project_Status")
If strStatus <> "OPEN" Then
'Just complete it. We don't need to know if
this was
'a COMPLETED or CANCELLED Project at this time.
'tskTask.PercentComplete = "100%"
'Update the Actual Start Date
't.Date3 = CStr(objRS("Entry_Date"))
tskTask.ActualStart = CStr(objRS("Entry_Date"))
'Update the Actual End Date
't.Date1 = CStr(objRS("Close_Dt"))
tskTask.ActualFinish = CStr(objRS("Close_Dt"))
End If
End If
End If
'Close the RS
objRS.Close
End If
End If
Next
GoTo NormalExit
ErrorHandler:
strErrors = strErrors & strFunctionSub & "::Unexpected Error Occurred:"
& vbCrLf & vbCrLf
strErrors = strErrors & "Error: " & Err.Number & "-" & Err.Description
Resume NormalExit
NormalExit:
Set objRS = Nothing
Set objConn = Nothing
End Sub
This is the line that I am having trouble with:
tskTask.Assignments.UniqueID(lngAssignmentUID).TimeScaleData(strWorkEntryDate,
strWorkEntryDate, pjAssignmentTimescaledActualWork, pjTimescaleWeeks,
1).Item(1).Value = strWork
Now this code works fine, execpt for the fact that instead of just posting
the number of hours/minutes for that week, it will sometimes add hours in
surrounding weeks. So instead of posting 30 hours / 180 mintues into the
week of 3/17/2006, it will post 180 minutes in the week of 3/17/2006 AND 240
hours in the week of 3/24/2006 AND 240 hours in the week of 3/31/2006.
I have not been able to find any Best Practices of using this method
(TimeScaleData). Any help or pointers would be greatly appreciated.