Compartir a través de


del método Project.QueueUpdateProject

Actualiza las entidades en un proyecto desprotegido. También se agrega, modifica o elimina los valores de campo personalizado.

Espacio de nombres:  WebSvcProject
Ensamblado:  ProjectServerServices (en ProjectServerServices.dll)

Sintaxis

'Declaración
<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 _
)
'Uso
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
)

Parámetros

  • jobUid
    Tipo: System.Guid

    El GUID de la tarea de la cola.

  • sessionUid
    Tipo: System.Guid

    El GUID de la sesión en la que se envía el trabajo en cola.

  • validateOnly
    Tipo: System.Boolean

    Si true, solo valida los datos de entrada y no lleve a cabo la acción.

Comentarios

QueueUpdateProject no crear o eliminar entidades de proyecto; modifica las entidades existentes, como tareas, asignaciones y recursos del proyecto. QueueUpdateProject puede también agregar, modificar, o eliminar los valores de campo personalizado en un proyecto, pero no se puede crear o eliminar un campo personalizado propio (use CreateCustomFields o DeleteCustomFields). QueueUpdateProject es un método asincrónico que envía un mensaje para el servicio de cola de Project Server.

Los métodos de clase Project , como QueueUpdateProject, no se pueden crear, editar o eliminar recursos de costo. Si el ProjectDataSet en el parámetro dataset incluye un recurso de costo, el método devuelve el error ProjectCannotEditCostResource 1050. Puede usar el método CreateResources para crear los recursos de costo, pero los métodos de la clase Resource no pueden editarlos. Para obtener más información, vea What the PSI does and does not do.

Nota

Al crear o actualizar un proyecto, puede procesar la PSI hasta 1000 filas de datos al mismo tiempo. Si el número total de filas de datos nuevos o actualizados de todas las tablas de ProjectDataSet superior a 1000, la PSI devuelve el error ProjectExceededItemsLimit .

Al crear un ProjectDataSet.TaskRow, debe especificar TASK_DUR_FMT. En caso contrario, su uso posterior del proyecto en Project Professional puede producir un comportamiento impredecible, incluida la posible pérdida de datos.

Los cambios realizados en las propiedades de recurso de empresa en ProjectDataSet.ProjectResourceRow se perderá la próxima vez que Project Professional actualiza los datos de Project Server.

Cuando se modifica una tarea en un ProjectDataSet, no establezca la propiedad TASK_WBS . La propiedad TASK_WBS es de sólo lectura, aunque lo haya marcado como lectura y escritura en la PSI. Si agrega una tarea con la propiedad TASK_WBS establecida en un valor especificado, Project Professional omite el valor establecido de la PSI y asigna un valor según la posición de esquema de tarea cuando se abre el proyecto. Para ver el resultado en Project Professional, compruebe el valor de código EDT en la ficha Avanzadas del cuadro de diálogo Información de la tarea.

QueueUpdateProject no se puede cambiar una tarea de una referencia null (Nothing en Visual Basic) a una tarea real. Por ejemplo, si la creación de tareas mediante el uso de Project Professional y deje una o varias líneas en blanco entre algunas de las tareas, las líneas en blanco son tareas de una referencia null (Nothing en Visual Basic) .

Cambio de la propiedad TASK_IS_ACTIVE

El motor de programación de Project Server puede mostrar Inicio incoherente o finalizar veces cuando utilice el método QueueUpdateProject para cambiar el estado activo de una tarea, si hay varios cambios en el objeto ProjectDataSet para el parámetro dataset . Si la propiedad TASK_IS_ACTIVE es el único cambio en el parámetro dataset , puede actualizar el proyecto.

Para obtener más información, vea la programación de proyectos en la sección servidor en Programación de Project Server.

Cambio de la propiedad TASK_OUTLINE_LEVEL

Si intenta cambiar el TASK_OUTLINE_LEVEL, puede obtener un error de ProjectSchedulingEngineException desde el servicio de cola de Project Server. El contenido del error incluye exception="Microsoft.Office.Project.Scheduling.SchedulingCycleException: Cycle detected … . El motor de programación de Project Server no administra la ediciones de masivas donde cambiar la TASK_OUTLINE_LEVEL o cambiar una tarea con un vínculo de comienzo a fin (CF) a una tarea de resumen. Una solución alternativa es comprobar la cola de Project Server y controlar el valor específico en la tabla QueueStatusDataSet.Status . En el siguiente ejemplo se modifica el método WaitForQueueJobCompletion en la aplicación ProjTool (consulte Using the ProjTool Test Application). La modificación utiliza ReadJobStatus en el servicio web de QueueSystem y muestra un mensaje adecuado.

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);
        }
    . . .
}

Eliminación de los valores de campo personalizado

Use QueueUpdateProject en lugar de QueueDeleteFromProject para eliminar los valores de campos personalizados de un proyecto. El método correcto para eliminar un valor de campo personalizado es obtener un ProjectDataSet, establezca la propiedad RowState de un campo personalizado DataRow en Deletedy, a continuación, use la modificación ProjectDataSet para actualizar el proyecto. Para establecer un DataRow en Deleted, llame al método de Delete en el objeto row en lugar de establecer el valor en una referencia null (Nothing en Visual Basic).

Para usar el siguiente código de ejemplo en una aplicación de prueba, crear un campo personalizado de tarea de tipo texty, a continuación, cree un proyecto con una tarea. Asignar un valor del campo personalizado en las propiedades de la tarea y, a continuación, busque los valores GUID del proyecto y el campo personalizado de tarea. Si está trabajando en una instalación de prueba de Project Server, puede usar ProjTool para encontrar fácilmente el PROJ_UID de un proyecto. Seleccione el proyecto en ProjTool, haga clic en Detalles de proyecto de lectura y, a continuación, haga clic en la ficha TaskCustomFields para encontrar el CUSTOM_FIELD_UID. Para obtener más información sobre ProjTool, consulte 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);
}

Permisos de Project Server

Permiso

Descripción

SaveProject

Permite al usuario guardar el proyecto especificado. Permiso de categoría.

SaveProjectTemplate

Permite a un usuario crear y guardar un proyecto como una plantilla de proyecto de empresa.

Ejemplos

En el ejemplo siguiente se crea un proyecto de ejemplo, comprobaciones, modifica un nombre de tarea, guarda la actualización y, a continuación, se comprueba el proyecto de nuevo.

Para obtener información crítica acerca de cómo ejecutar este ejemplo de código, vea Prerequisites for Reference Code Samples.

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;
      }
   }
}

Vea también

Referencia

clase Project

Miembros Project

Espacio de nombres WebSvcProject

Otros recursos

Using the ProjTool Test Application