通过VB.NET/VSTO修改资源使用视图时间分段遇COM异常求助
Hey there, let's tackle this COM error you're hitting when trying to modify resource hours time phasing in the Resource Usage view with VB.NET/VSTO. I’ve dealt with similar headaches in Project’s object model before, so here’s what you need to check and fix:
1. Double-Check You’re Targeting the Right Time-Phased Field
Project’s object model is picky about the exact field you want to modify. For resource work hours, you must use the pjResourceWork constant (not task work or other unrelated fields). Using the wrong field ID is one of the most common causes of this error.
Example of the correct field reference:
Dim targetField As PjField = PjField.pjResourceWork
2. Validate Your Time Segment Dates
Time-phased data is tied directly to the resource’s assignment dates, and Project won’t accept invalid date ranges. Make sure:
- The segment start date is on or after the assignment’s start date
- The segment end date is on or before the assignment’s end date
- You’re not trying to edit a date range that falls outside the project’s overall timeline
Here’s a quick snippet to set a valid date range for an assignment:
Dim proj As Project = Globals.ThisAddIn.Application.ActiveProject Dim resource As Resource = proj.Resources("YourResourceName") Dim assignment As Assignment = resource.Assignments(1) ' Use 1-based indexing for Project collections ' Define a valid 3-day segment within the assignment's timeline Dim segmentStart As Date = assignment.Start.AddDays(1) Dim segmentEnd As Date = segmentStart.AddDays(2)
3. Use the TimeScaleData Method to Modify Values Directly
You can’t edit the Resource Usage view’s grid directly—you need to interact with the Assignment.TimeScaleData method to access and modify time-phased values. This method returns a TimeScaleValues collection that you can update and commit.
Full working VB.NET/VSTO example:
Try Dim app As MSProject.Application = Globals.ThisAddIn.Application Dim proj As Project = app.ActiveProject Dim targetResource As Resource = proj.Resources("John Doe") ' Replace with your resource name Dim targetAssignment As Assignment = targetResource.Assignments(1) ' Adjust to your target assignment ' Fetch time-phased work data for the assignment's full duration (daily intervals) Dim tsValues As TimeScaleValues = targetAssignment.TimeScaleData( StartDate:=targetAssignment.Start, EndDate:=targetAssignment.End, Type:=PjAssignmentTimescaledData.pjAssignmentTimescaledWork, TimeScaleUnit:=PjTimescaleUnit.pjTimescaleDays, Count:=1 ) ' Modify the work value for the first day (set to 8 hours) If tsValues.Count > 0 Then tsValues(1).Value = 8 ' Project accepts hours here (it converts to minutes internally) tsValues(1).Commit() ' Save the change to the project End If ' Refresh the Resource Usage view to see your updates app.ViewApply("Resource Usage") Catch ex As System.Runtime.InteropServices.COMException MessageBox.Show($"COM Error: {ex.Message}. Double-check field IDs, date ranges, and assignment references.") Catch ex As Exception MessageBox.Show($"Unexpected error: {ex.Message}") End Try
4. Rule Out Locked/Read-Only Data
If your project is stored on Project Server/Online, make sure it’s checked out and editable. Also, verify:
- The resource assignment isn’t locked by another user
- You have permissions to modify resource work data
- The project isn’t marked as read-only in your file system
5. Watch for Off-by-One Indexing Errors
Project uses 1-based indexing for all collections (like Assignments(1) instead of the .NET-standard Assignments(0)). Using 0-based indexing here will immediately throw an invalid argument error—double-check all your collection references.
内容的提问来源于stack exchange,提问作者Marcos Sulevis

