Project.QueueUpdateProject 方法
命名空间: WebSvcProject
程序集: ProjectServerServices(位于 ProjectServerServices.dll 中)
语法
声明
<SoapDocumentMethodAttribute("https://schemas.microsoft.com/office/project/server/webservices/Project/QueueUpdateProject", RequestNamespace := "https://schemas.microsoft.com/office/project/server/webservices/Project/", _
ResponseNamespace := "https://schemas.microsoft.com/office/project/server/webservices/Project/", _
Use := SoapBindingUse.Literal, ParameterStyle := SoapParameterStyle.Wrapped)> _
Public Sub QueueUpdateProject ( _
jobUid As Guid, _
sessionUid As Guid, _
dataset As ProjectDataSet, _
validateOnly As Boolean _
)
用法
Dim instance As Project
Dim jobUid As Guid
Dim sessionUid As Guid
Dim dataset As ProjectDataSet
Dim validateOnly As Boolean
instance.QueueUpdateProject(jobUid, sessionUid, _
dataset, validateOnly)
[SoapDocumentMethodAttribute("https://schemas.microsoft.com/office/project/server/webservices/Project/QueueUpdateProject", RequestNamespace = "https://schemas.microsoft.com/office/project/server/webservices/Project/",
ResponseNamespace = "https://schemas.microsoft.com/office/project/server/webservices/Project/",
Use = SoapBindingUse.Literal, ParameterStyle = SoapParameterStyle.Wrapped)]
public void QueueUpdateProject(
Guid jobUid,
Guid sessionUid,
ProjectDataSet dataset,
bool validateOnly
)
参数
jobUid
类型:System.Guid队列作业的 GUID。
sessionUid
类型:System.Guid队列作业提交的会话的 GUID。
dataset
类型:WebSvcProject.ProjectDataSet包含要更新的项目实体。
validateOnly
类型:System.Boolean如果true,仅验证输入的数据并不会执行该操作。
备注
QueueUpdateProject不会创建或删除项目的实体。修改现有实体如任务、 分配和项目资源。QueueUpdateProject可以还添加、 修改或删除项目中的自定义字段值但不能创建或删除自定义字段本身 (使用CreateCustomFields或DeleteCustomFields)。QueueUpdateProject是将消息发送到项目服务器队列服务的异步方法。
如QueueUpdateProject, Project类方法不能创建、 编辑或删除成本资源。如果ProjectDataSet在dataset参数中包括的成本资源、 该方法将返回 1050年的ProjectCannotEditCostResource错误。您可以使用CreateResources方法来创建成本资源但Resource类方法不能对其进行编辑。更多的信息请参阅PSI 可实现的操作和不可实现的操作。
备注
当您创建或更新项目时,PSI 最多可处理 1000年行数据的一次。如果新的或更新数据的ProjectDataSet的所有表中的总行数超过 1000 个,PSI 将返回ProjectExceededItemsLimit错误。
在创建ProjectDataSet.TaskRow时必须指定TASK_DUR_FMT。否则以后该项目在项目专业人员的使用可能导致不可预知的行为包括可能的数据丢失。
对ProjectDataSet.ProjectResourceRow中的企业资源属性所做的任何更改将会丢失项目专业刷新项目服务器中的数据在下一次。
当您修改ProjectDataSet中的任务时未设置TASK_WBS属性。TASK_WBS属性是只读、 尽管它被标记为读/写在 PSI。如果TASK_WBS属性设置为指定的值添加任务,项目专业人员会忽略从 PSI 设置的值并赋值根据任务大纲位置时打开的项目。若要查看项目专业导致,检查任务信息对话框中的高级选项卡上的WBS 代码值。
QueueUpdateProject不能更改为实际任务的空引用(无 在 Visual Basic 中)任务。如如果使用项目专业人员来创建任务之间的一些任务留出一个或多个空行以及空行将空引用(无 在 Visual Basic 中)任务。
将 TASK_IS_ACTIVE 属性更改
Project Server 计划引擎可以显示不一致的开始或结束的时间使用QueueUpdateProject方法时要更改的任务的活动状态如果dataset参数的ProjectDataSet对象中有多个更改。如果将TASK_IS_ACTIVE属性即在dataset参数中的唯一更改您可以更新项目。
更多的信息请参见项目计划Project Server 可编程性中的服务器部分。
将 TASK_OUTLINE_LEVEL 属性更改
如果想要更改TASK_OUTLINE_LEVEL您可以从项目服务器队列服务来获取ProjectSchedulingEngineException错误。错误内容包括exception="Microsoft.Office.Project.Scheduling.SchedulingCycleException: Cycle detected … 。Project Server 计划编制引擎不处理批量编辑更改TASK_OUTLINE_LEVEL或更改任务的开始-完成 (SF) 链接成一个摘要任务的位置。一种解决方法是检查 Project Server 队列和处理的QueueStatusDataSet.Status表中的特定值。下面的示例修改了 ProjTool 应用程序中的WaitForQueueJobCompletion方法 (请参阅Using the ProjTool Test Application)。修改使用ReadJobStatus在QueueSystem web 服务并显示适当的消息。
SvcQueueSystem.QueueStatusDataSet queueStatusDataSet =
new SvcQueueSystem.QueueStatusDataSet();
. . .
queueStatusDataSet = queueSystem.ReadJobStatus(queueStatusRequestDataSet, false,
SvcQueueSystem.SortColumn.Undefined, SvcQueueSystem.SortOrder.Undefined);
foreach (SvcQueueSystem.QueueStatusDataSet.StatusRow statusRow in queueStatusDataSet.Status)
{
if ((statusRow["ErrorInfo"] != System.DBNull.Value
&& checkStatusRowHasError(statusRow["ErrorInfo"].ToString()) == true)
|| statusRow.JobCompletionState == blockedState
|| statusRow.JobCompletionState == failedState)
{
if (statusRow.ErrorInfo.Contains("SchedulingCycleException"))
{
string schedulingError =
"The Project Server Queue reported an error in the scheduling engine.\n";
scheculingError += "The scheduling engine cannot change the TASK_OUTLINE_LEVEL\n";
schedulingError += "or change a task with a Start-to-Finish (SF) link into a summary task.\n";
schedulingError += "Use Project Professional to make those types of changes.";
MessageBox.Show(schedulingError, "Queue Error",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
else
{
MessageBox.Show(AppendErrorString(statusRow.ErrorInfo), "Queue Error" ,
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
. . .
}
删除自定义字段值
使用而不是QueueDeleteFromProjectQueueUpdateProject从项目中删除自定义字段值。若要删除一个自定义字段值的正确方法是获取ProjectDataSet、 DataRow自定义字段的RowState属性设置为Deleted,然后使用修改后的ProjectDataSet更新项目。若要将DataRow设置为Deleted,调用Delete方法行对象而不是将值设置为空引用(无 在 Visual Basic 中)。
若要在应用程序中测试请下面的代码示例创建类型text的任务自定义字段,然后创建一个任务的项目。将一个值分配给任务属性中的自定义字段和查找的项目和任务自定义字段的 GUID 值。如果您正在从事的项目服务器的测试安装,您可以使用 ProjTool 可以轻松地找到PROJ_UID的项目。在 ProjTool 中选择项目、 单击读取项目详细信息,然后单击TaskCustomFields选项卡来查找CUSTOM_FIELD_UID。有关 ProjTool 的详细信息请参阅Using the ProjTool Test Application。
// Sample project and task custom field GUIDs:
Guid projectId = new Guid("B6064244-101A-4139-A2F8-697620458AAE");
Guid taskCustomFieldId = new Guid("a3549fbc-b49c-42c9-9c56-ba045e438d94");
Guid sessionId = Guid.NewGuid();
Guid jobId = Guid.NewGuid();
WebSvcProject.ProjectDataSet dsProject =
project.ReadProject(projectId, WebSvcProject.DataStoreEnum.WorkingStore);
// Do not use QueueDeleteFromProject to delete a custom field.
// Guid[] taskCustomFields = { taskCustomFieldId };
// project.QueueDeleteFromProject(jobId, sessionId, projectId, taskCustomFields);
bool deleteCF = false;
foreach (WebSvcProject.ProjectDataSet.TaskCustomFieldsRow taskCFRow in dsProject.TaskCustomFields)
{
if ((Guid)taskCFRow[dsProject.TaskCustomFields.CUSTOM_FIELD_UIDColumn] == taskCustomFieldId)
{
// Set the rowstate to be deleted.
taskCFRow.Delete();
deleteCF = true;
break;
}
}
if (deleteCF)
{
project.CheckOutProject(projectId, sessionId, "Test checkout");
bool validateOnly = false;
project.QueueUpdateProject(jobId, sessionId, dsProject, validateOnly);
// Wait approximately four seconds for the queue to finish.
// Or, add a routine that checks the QueueSystem for job completion.
System.Threading.Thread.Sleep(4000);
sessionId = Guid.NewGuid();
jobId = Guid.NewGuid();
bool force = false;
string sessionDescription = "Removed task custom field " + taskCustomFieldId.ToString();
project.QueueCheckInProject(jobId, projectId, force, sessionId, sessionDescription);
// Wait approximately four seconds for queue to finish.
// Or, use a routine that checks the QueueSystem for job completion.
System.Threading.Thread.Sleep(4000);
}
Project Server 权限
权限 |
说明 |
---|---|
允许用户保存指定的项目。类别的权限。 |
|
允许用户创建并保存为企业项目模板的项目。 |
示例
下面的示例创建一个示例项目、 重新检查出、 修改任务名称、 保存更新和再检查项目。
有关运行此代码示例的关键信息,请参阅Project 2013 中基于 ASMX 的代码示例的先决条件。
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Web.Services.Protocols;
using System.Threading;
using PSLibrary = Microsoft.Office.Project.Server.Library;
namespace Microsoft.SDK.Project.Samples.QueueUpdateProject
{
class Program
{
[STAThread]
static void Main()
{
try
{
#region Setup
const string PROJECT_SERVER_URI = "https://ServerName/ProjectServerName/";
const string PROJECT_SERVICE_PATH = "_vti_bin/psi/project.asmx";
const string QUEUESYSTEM_SERVICE_PATH = "_vti_bin/psi/queuesystem.asmx";
const string SESSION_DESC = "Sample utility";
Guid sessionId = Guid.NewGuid();
Guid jobId;
// Set up the web service objects.
SvcProject.Project projectSvc = new SvcProject.Project();
projectSvc.Url = PROJECT_SERVER_URI + PROJECT_SERVICE_PATH;
projectSvc.Credentials = CredentialCache.DefaultCredentials;
SvcQueueSystem.QueueSystem q = new SvcQueueSystem.QueueSystem();
q.Url = PROJECT_SERVER_URI + QUEUESYSTEM_SERVICE_PATH;
q.Credentials = CredentialCache.DefaultCredentials;
// Create the sample project.
Console.WriteLine("Creating sample project");
Guid projectId = CreateSampleProject(projectSvc, q);
// Read the project that you want.
Console.WriteLine("Reading project from database");
SvcProject.ProjectDataSet projectDs = projectSvc.ReadProject(projectId, SvcProject.DataStoreEnum.WorkingStore);
#endregion
#region Change task name and update
// Check out the project.
Console.WriteLine("Checking out project");
projectSvc.CheckOutProject(projectId, sessionId, SESSION_DESC);
// Make changes.
// Note: Task 0 is the summary task, which cannot be changed.
projectDs.Task[1].TASK_NAME += " Changed";
// Save the changes.
Console.WriteLine("Saving changes to the database");
jobId = Guid.NewGuid();
projectSvc.QueueUpdateProject(jobId, sessionId, projectDs, false);
WaitForQueue(q, jobId);
#endregion
#region Check in
// Check in the project.
Console.WriteLine("Checking in the project");
jobId = Guid.NewGuid();
projectSvc.QueueCheckInProject(jobId, projectId, false, sessionId, SESSION_DESC);
WaitForQueue(q, jobId);
#endregion
}
#region Exception Handling and Final
catch (SoapException ex)
{
PSLibrary.PSClientError error = new PSLibrary.PSClientError(ex);
PSLibrary.PSErrorInfo[] errors = error.GetAllErrors();
string errMess = "==============================\r\nError: \r\n";
for (int i = 0; i < errors.Length; i++)
{
errMess += "\n" + ex.Message.ToString() + "\r\n";
errMess += "".PadRight(30, '=') + "\r\nPSCLientError Output:\r\n \r\n";
errMess += errors[i].ErrId.ToString() + "\n";
for (int j = 0; j < errors[i].ErrorAttributes.Length; j++)
{
errMess += "\r\n\t" + errors[i].ErrorAttributeNames()[j] + ": " + errors[i].ErrorAttributes[j];
}
errMess += "\r\n".PadRight(30, '=');
}
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(errMess);
}
catch (WebException ex)
{
string errMess = ex.Message.ToString() +
"\n\nLog on, or check the Project Server Queuing Service";
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Error: " + errMess);
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Error: " + ex.Message);
}
finally
{
Console.ResetColor();
Console.WriteLine("\r\n\r\nPress any key...");
Console.ReadKey();
}
#endregion
}
static private void WaitForQueue(SvcQueueSystem.QueueSystem q, Guid jobId)
{
SvcQueueSystem.JobState jobState;
const int QUEUE_WAIT_TIME = 2; // two seconds
bool jobDone = false;
string xmlError = string.Empty;
int wait = 0;
// Wait for the project to get through the queue.
// Get the estimated wait time in seconds.
wait = q.GetJobWaitTime(jobId);
// Wait for it.
Thread.Sleep(wait * 1000);
// Wait until it is finished.
do
{
// Get the job state.
jobState = q.GetJobCompletionState(jobId, out xmlError);
if (jobState == SvcQueueSystem.JobState.Success)
{
jobDone = true;
}
else
{
if (jobState == SvcQueueSystem.JobState.Unknown
|| jobState == SvcQueueSystem.JobState.Failed
|| jobState == SvcQueueSystem.JobState.FailedNotBlocking
|| jobState == SvcQueueSystem.JobState.CorrelationBlocked
|| jobState == SvcQueueSystem.JobState.Canceled)
{
// If the job failed, error out.
throw (new ApplicationException("Queue request " + jobState + " for Job ID " + jobId + ".\r\n" + xmlError));
}
else
{
Console.WriteLine("Job State: " + jobState + " for Job ID: " + jobId);
Thread.Sleep(QUEUE_WAIT_TIME * 1000);
}
}
}
while (!jobDone);
}
static private Guid CreateSampleProject(SvcProject.Project projectSvc, SvcQueueSystem.QueueSystem q)
{
SvcProject.ProjectDataSet projectDs = new SvcProject.ProjectDataSet();
Guid jobId;
// Create the project.
SvcProject.ProjectDataSet.ProjectRow projectRow = projectDs.Project.NewProjectRow();
projectRow.PROJ_UID = Guid.NewGuid();
projectRow.PROJ_NAME = "Its a wonderful project at " +
DateTime.Now.ToShortDateString().Replace("/", "") + " " +
DateTime.Now.ToShortTimeString().Replace(":", "");
projectRow.PROJ_TYPE = (int)PSLibrary.Project.ProjectType.Project;
projectDs.Project.AddProjectRow(projectRow);
// Add some tasks.
SvcProject.ProjectDataSet.TaskRow taskOne = projectDs.Task.NewTaskRow();
taskOne.PROJ_UID = projectRow.PROJ_UID;
taskOne.TASK_UID = Guid.NewGuid();
// The Task Duration format must be specified.
taskOne.TASK_DUR_FMT = (int)PSLibrary.Task.DurationFormat.Day;
taskOne.TASK_DUR = 4800; // 8 hours in duration units (minute/10)
taskOne.TASK_NAME = "Task One";
taskOne.TASK_START_DATE = System.DateTime.Now.AddDays(1);
projectDs.Task.AddTaskRow(taskOne);
SvcProject.ProjectDataSet.TaskRow taskTwo = projectDs.Task.NewTaskRow();
taskTwo.PROJ_UID = projectRow.PROJ_UID;
taskTwo.TASK_UID = Guid.NewGuid();
// The Task Duration format must be specified.
taskTwo.TASK_DUR_FMT = (int)PSLibrary.Task.DurationFormat.Day;
taskTwo.TASK_DUR = 4800; // 8 hours in duration units (minute/10)
taskTwo.TASK_NAME = "Task Two";
taskTwo.TASK_START_DATE = System.DateTime.Now.AddDays(1);
projectDs.Task.AddTaskRow(taskTwo);
// Save the project to the database.
jobId = Guid.NewGuid();
projectSvc.QueueCreateProject(jobId, projectDs, false);
WaitForQueue(q, jobId);
return projectRow.PROJ_UID;
}
}
}