Project Utilities PDS Extender

This content is no longer actively maintained. It is provided as is, for anyone who may still be using these technologies, with no warranties or claims of accuracy with regard to the most recent product version or service release.

Summary

This article describes how to use the Project Utilities Project Data Service (PDS) Extender sample application for Microsoft® Project Server.

Introduction

In addition to describing how to use the Project Utilities PDS Extender sample application, this article also describes the steps for installation, and its important features, including the ability to parse a request and retrieve data from the Microsoft Project Server database. For a general explanation of how PDS Extenders work, see the Writing a Project Data Service Extender article in the Microsoft Project 2002 Software Development Kit (SDK).

The Project Utilities PDS Extender

The Project Utilities PDS Extender allows you to create enterprise resources and projects, and add enterprise resources to an enterprise project team in the Microsoft Project Server database without using Microsoft Project Professional.

The extender implements three custom methods: ResourcesAdd, ProjectResourcesAdd, and ProjectCreate (see below for more information about these methods). Because these methods are implemented within a PDS Extender, it appears to the client as if the PDS itself supports this functionality. This makes it possible for the client to reuse existing code to format requests to the PDS and parse returned responses for data.

In order to use the Project Utilities PDS Extender, you need to install the DLL to your Microsoft Project Server computer, register the extender, and add the stored procedure to the Microsoft Project Server database.

Installing and Registering the Extender

ProjectUtilities.vbp is a Microsoft Visual Basic® project containing code that implements the Project Utilities PDS Extender. Building the ProjectUtilities.vbp project creates a COM DLL named ProjectUtilities.dll. After building ProjectUtilities.dll, you need to register the extender as a COM component, and then register the extender with Microsoft Project Server.

To register the extender as a COM component, open a command prompt window, browse to the directory containing ProjectUtilities.dll, and type the following command:

  REGSVR32 ProjectUtilities.dll

This command registers the component with a ProgID value of ProjectUtilities.CMain.

To register the extender with Microsoft Project Server, open the registry (click Start, click Run, type regedit, and click OK), then locate the following registry key:

  [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\10.0\MS Project\ _
      WebClient Server\ProjectServer]

Create the following string-value key:

  "PDSExtension1"=" ProjectUtilities.CMain"
Adding the ProjectUtilites SQL Stored Procedure to the Microsoft Project Server Database

The PDS Extender also requires a group of SQL stored procedures that must be added to the Microsoft Project Server database. The user must run the SQL script ProjUtil.sql against the Project Server database with OSQL from a command prompt, for example:

  OSQL �S ServerName �d ProjectServer �E �I ProjUtil.sql

This command uses Microsoft Windows NT® authentication to run the SQL script against the SQL Server computer named "ServerName" and the database named "ProjectServer". For information about other OSQL command-line options, type OSQL -?.

Parsing the Request

The PDS can call a PDS Extender when the extender implements a public function named XMLRequest, which has the following signature in Visual Basic:

  Public Function XMLRequest( _
      ByVal sXML As String, _
      ByVal sUser As String, _
      ByVal sConnect As String, _
      ByVal lDBType As Long, _
      ByRef nHandled As Integer) _
      As String

The primary parameter is sXML, which contains the XML request string. For the ResourcesAdd method, this request takes the following form:

  <Request>
     <ResourcesAdd>
        <Resources>
           <Resource>
              <ResourceName></ResourceName>
           </Resource>
        </Resources>
     </ResourcesAdd>
  </Request>

For the ProjectResourcesAdd method, this request takes the following form:

  <Request>
     <ProjectResourcesAdd>
        <ProjectID></ProjectID>
        <Resources>
           <Resource>
              <ResourceUID></ResourceUID>
              <ResourceUID></ResourceUID>
           </Resource>
        </Resources>
     </ProjectResourcesAdd>
  </Request>

For the ProjectCreate method, this request takes the following form:

  <Request>
     <ProjectCreate>
        <Project>
           <ProjectName>CreatedProject</ProjectName>
           <Version>Published</Version>
           <StartDate>2002-09-23</StartDate>
           <Milestones>
              <Milestone>
                 <TaskName>Project Milestone</TaskName>
                 <StartDate>2002-10-31</StartDate>
              </Milestone>
           </Milestones>
        </Project>
     </ProjectCreate>
  </Request>

The XMLRequest function uses the Microsoft XML Parser (MSXML) to check if the XML request is valid:

      If Len(sXML) = 0 Then
          sXMLReply = "<Error>Request string is empty</Error>"
          m_lStatus = STATUS_INVALID_REQUEST
          GoTo PrepareReply
      End If
  
      Set oXMLDocument = New Msxml2.DOMDocument
      oXMLDocument.loadXML sXML
      If oXMLDocument.parseError.errorCode <> 0 Then
          sXMLReply = "<Error>XML Parse error</Error>"
          m_lStatus = STATUS_INVALID_REQUEST
          GoTo PrepareReply
      End If 

If the XML request is valid, the XMLRequest function looks for the <Request> node for each of the methods. Otherwise, it returns a user-defined Status code indicating an invalid request.

      Select Case sNodeName
          Case "Request"
              Dim oNode As Msxml2.IXMLDOMNode
              Dim oChildNode As Msxml2.IXMLDOMNode
              For Each oNode In oXMLRoot.childNodes
                  sNodeName = oNode.nodeName
                  result = oNode.hasChildNodes()
  
                  Select Case sNodeName
                      Case "ResourcesAdd"
                          sXMLReply = ResourcesAdd(oNode)
                          nHandled = REQUEST_HANDLED
                      Case "ProjectCreate"
                          sXMLReply = ProjectCreate(oNode)
                          nHandled = REQUEST_HANDLED
                      Case "ProjectResourcesAdd"
                          sXMLReply = ProjectResourcesAdd(oNode)
                          nHandled = REQUEST_HANDLED
  
                      Case Else
                          m_lStatus = STATUS_UNKNOWN_REQUEST
                  End Select
  
              Next oNode
          Case Else
              m_lStatus = STATUS_UNKNOWN_REQUEST
      End Select

If the XMLRequest function does not recognize the request, the returned Status code indicates the error. Additionally, the XMLRequest function sets the nHandled parameter to 0, which notifies the PDS that another extender may be able to handle the request.

Parsing the ResourcesAdd Method Call

If the XMLRequest function determines that the request is a call to the ResourcesAdd method, it calls the ResourcesAdd helper function to further parse the request and retrieve the requested data. The ResourcesAdd function has the following signature:

  Function ResourcesAdd( _
      ByVal oNode As MSXML2.IXMLDOMNode) _
      As String

The ResourcesAdd function receives the XML node whose parent is the <ResourcesAdd> tag. The function then looks for the ResourceName value by examining the child nodes:

       result = oNode.hasChildNodes()

If the ResourcesAdd function fails to find the ResourceName value, RESOURCE_NAME_NOT_FOUND is returned. Otherwise, the ResourcesAdd function continues parsing the request and calls the AddNewResource function, which processes the actual request for adding a resource to the enterprise resource pool.

Adding New Enterprise Resources

You add enterprise resources to the Microsoft Project Server database by using the AddNewResource function. This function has the following signature:

  Function AddNewResource( _
      ResName As String) _
      As Integer

The AddNewResource function first checks whether the resource name is too long for the RES_NAME field in the MSP_WEB_RESOURCES table and, if so, stops parsing and returns RESOURCE_NAME_TOO_LONG:

      If Len(ResName) > 255 Then
          m_lStatus = RESOURCE_NAME_TOO_LONG
          Exit Function
      End If

If the resource's name fits in the field, the AddNewResource function verifies the connection to the Microsoft Project Server database, and then queries the database to determine whether the resource's name is unique in the enterprise resource pool:

      sSQL = "SELECT * FROM MSP_RESOURCES WHERE RES_NAME = '" & ResName & "'"

If the resource's name is not a unique name, the AddNewResource function stops parsing and returns RESOURCE_NAME_NOT_UNIQUE. Otherwise, it queries the Microsoft Project Server database to determine whether the resource's name is a unique name in the Microsoft Project Server database:

      sSQL = "SELECT * FROM MSP_WEB_RESOURCES WHERE RES_NAME = '" & ResName & "'"

If the resource's name is not a unique name in the Microsoft Project Server database, the AddNewResource function stops parsing and returns RESOURCE_WEB_NAME_NOT_UNIQUE. Otherwise, the AddNewResource function opens the enterprise resource pool:

      sSQL = "SELECT * FROM MSP_PROJECTS WHERE PROJ_TYPE = 3"

If the enterprise resource pool is not found, the AddNewResource function stops parsing and returns RESOURCE_GLOBAL_NOT_FOUND. Otherwise, the AddNewResouce function verifies whether the enterprise resource pool is checked out to the current user. If it is not, the AddNewResource function stops parsing and returns RESOURCE_GLOBAL_NOT_CHECKED_OUT.

If the enterprise resource pool is checked out to the current user, the AddNewResource function executes the following SQL queries against the MSP_RESOURCES and MSP_CALENDARS tables in the Microsoft Project Server database:

      sSQL = "SELECT MAX(RES_UID) AS MAX_UID FROM MSP_RESOURCES WHERE PROJ_ID = " & lResGlobalID
       ...
      sSQL = "SELECT MAX(RES_ID) AS MAX_ID FROM MSP_RESOURCES WHERE PROJ_ID = " & lResGlobalID
       ...
      sSQL = "SELECT MAX(CAL_UID) AS MAX_ID FROM MSP_CALENDARS WHERE PROJ_ID = " & lResGlobalID

These queries gather the next available unique IDs for the resource. The AddNewResource function then adds the resource to the enterprise resource pool:

      cmd.CommandText = "INSERT INTO MSP_RESOURCES (PROJ_ID,RES_UID,RES_EUID,RES_ID,RES_CAL_UID,RES_NAME,RES_TYPE,RES_RTYPE,EXT_EDIT_REF_DATA) VALUES(?,?,?,?,?,?,?,?,?)"
      cmd.ActiveConnection = m_oConnection
      cmd.CommandType = adCmdText
      With cmd.Parameters
         ...
      End With

Finally, the AddNewResources function adds a valid entry in the MSP_CALENDARS table for the newly created resource:

          cmd.CommandText = "INSERT INTO MSP_CALENDARS (PROJ_ID,CAL_UID,RES_UID,CAL_BASE_UID,CAL_IS_BASE_CAL) VALUES(?,?,?,?,?)"
      cmd.ActiveConnection = m_oConnection
      cmd.CommandType = adCmdText
      With cmd.Parameters
         ...
      End With

Parsing the ProjectResourcesAdd Method Call

If the XMLRequest function determines that the request is a call to the ProjectResourcesAdd method, it calls the ProjectResourcesAdd helper function to further parse the request and retrieve the requested data.

The ProjectResourcesAdd function has the following signature:

  Function ProjectResourcesAdd( _
      ByVal oNode As MSXML2.IXMLDOMNode) _
      As String

The ProjectResourcesAdd function receives the XML node whose parent is the <ProjectResourcesAdd> tag. The ProjectResourcesAdd function then looks for the ProjectID value and its associated ResourceID values by examining the child nodes:

      result = oNode.hasChildNodes()
      fil.WriteLine ("ProjectResourcesAdd has child nodes = " & result)
      If (result = True) Then
          Set oNode2 = oNode.selectSingleNode("ProjectID")
          sProjID = oNode2.Text
          fil.WriteLine ("Found ProjectID = " & sProjID)
          Set oNode2 = oNode.selectSingleNode("Resources")

If the ProjectResourcesAdd function does not find the <Resources> container for a particular project, RESOURCES_TAG_NOT_FOUND is returned. Otherwise, the ProjectResourcesAdd function continues parsing the request to determine the actual resource unique IDs for each resource associated with the project. If the <Resource> container is not found, RESOURCE_TAG_NOT_FOUND is returned and the ProjectResourcesAdd function stops parsing the request.

If the function fails to find one or more ResourceUID values, RESOURCE_ADD_FAILED is returned. Otherwise, the ProjectResourcesAdd function continues parsing the request and calls the AddEnterpriseResourceToProject function, which processes the actual request for adding a resource to a project in the Microsoft Project Server database.

Adding Resources to Projects

You use the AddEnterpriseResourceToProject function to associate enterprise resources with enterprise projects in the Microsoft Project Server database. This function has the following signature:

Function AddEnterpriseResourceToProject( _

       PROJ_ID As String, _
       RES_UID As String) _
       As Integer

The AddEnterpriseResourceToProject function first verifies the connection to the enterprise global resource pool, then executes the following query:

  sSQL = "SELECT * FROM MSP_PROJECTS WHERE PROJ_ID = " & PROJ_ID

If the AddEnterpriseResourceToProject function is unable to connect to the requested enterprise project, PROJECT_NOT_FOUND is returned and the AddEnterpriseResourceToProject function stops parsing the request. Otherwise, the AddEnterpriseResourceToProject function verifies that the requested enterprise project is checked out to the current user. If it is not, the AddEnterpriseResourceToProject function stops parsing and returns PROJECT_NOT_CHECKED_OUT. If the requested enterprise project is checked out to the current user, the AddEnterpriseResourceToProject function executes the following SQL queries against the MSP_PROJECTS and MSP_RESOURCES tables in the Microsoft Project Server database:

      sSQL = "SELECT R.RES_NAME FROM MSP_RESOURCES R, MSP_PROJECTS P WHERE R.RES_EUID=" & RES_UID & "AND P.PROJ_TYPE=3"
       ...
      sSQL = "SELECT MAX(RES_UID) AS MAX_UID FROM MSP_RESOURCES WHERE PROJ_ID = " & PROJ_ID
       ...
      sSQL = "SELECT MAX(RES_ID) AS MAX_ID FROM MSP_RESOURCES WHERE PROJ_ID = " & PROJ_ID
       ...
      sSQL = "SELECT MAX(CAL_UID) AS MAX_ID FROM MSP_CALENDARS WHERE PROJ_ID = " & PROJ_ID

The preceding queries gather the next available resource and calendar IDs in the requested enterprise project. The AddEnterpriseResourceToProject function then adds the resource to the project:

      cmd.CommandText = "INSERT INTO MSP_RESOURCES (PROJ_ID,RES_UID,RES_EUID,RES_ID,RES_CAL_UID,RES_NAME,RES_TYPE,RES_RTYPE,EXT_EDIT_REF_DATA) VALUES(?,?,?,?,?,?,?,?,?)"
      cmd.ActiveConnection = m_oConnection
      cmd.CommandType = adCmdText
      With cmd.Parameters
         ...
      End With

Finally, the AddEnterpriseResourceToProject function adds a valid entry in the MSP_CALENDARS table:

      cmd.CommandText = "INSERT INTO MSP_CALENDARS (PROJ_ID,CAL_UID,RES_UID,CAL_BASE_UID,CAL_IS_BASE_CAL) VALUES(?,?,?,?,?)"
      cmd.ActiveConnection = m_oConnection
      cmd.CommandType = adCmdText
      With cmd.Parameters
        ...
      End With

Parsing the ProjectCreate Method Call

If the XMLRequest function determines that the request is a call to the ProjectCreate method, it calls the ProjectCreate helper function to further parse the request and retrieve the requested data. The ProjectCreate function has the following signature:

  Function ProjectCreate( _
      ByVal oNode As MSXML2.IXMLDOMNode) _
      As String

The ProjectCreate function receives the XML node whose parent is the <ProjectCreate> tag. The ProjectCreate function then creates a new project by calling the CreateNewProject function, and returns the new project's ID:

  sXMLReply = sXMLReply & "<ProjectID>" & iProjectAdd & "</ProjectID>"
Creating a New Enterprise Project

The CreateNewProject function adds a new enterprise project to the Microsoft Project Server database. This function has the following signature:

  Function CreateNewProject( _
      ByVal oNode As MSXML2.IXMLDOMNode) _
      As Long

The CreateNewProject function walks through the XML contained in the sXML parameter in the XMLRequest function to determine the project name, version, and start date. If the name of the project exceeds the limit defined for the PROJ_NAME field in the MSP_PROJECTS table, PROJECT_NAME_TOO_LONG is returned and the CreateNewProject function stops parsing the request; if the project's version name is too long, VERSION_NAME_TOO_LONG is returned and the CreateNewProject function stops parsing the request. If both the project's name and version name are valid lengths, the CreateNewProject function appends the version name to the project name, separated by a period ("."); for example, "ProjectName.Published."

  PROJ_NAME = SHORT_PROJ_NAME & "." & PROJ_VERSION

Next, the CreateNewProject function verifies that the project name is unique in the MSP_PROJECTS table in the Microsoft Project Server database by executing the following SQL query:

  sSQL = "SELECT * FROM MSP_PROJECTS WHERE PROJ_NAME = '" & PROJ_NAME & "'"

If the project name is not a unique name in the Microsoft Project Server database, PROJECT_NAME_NOT_UNIQUE is returned, and the CreateNewProject function stops parsing the request. Otherwise, the CreateNewProject function verifies whether the version name is valid, and is the default, by executing the following SQL query against the MSP_VERSIONS table in the Microsoft Project Server database:

  sSQL = "SELECT * FROM MSP_VERSIONS WHERE VERS_VERSION = '" & PROJ_VERSION & "'"

If the version name is not a valid name in the Microsoft Project Server database, VERSION_NAME_NOT_FOUND is returned, and the CreateNewProject function stops parsing the request. If the version name is not the default, the CreateNewProject function checks to see if a valid default version name exists in the MSP_VERSIONS table:

  sSQL = "SELECT * FROM MSP_VERSIONS WHERE VERS_DEFAULT = 1"

If the valid default version is not found, the CreateNewProject function executes the following SQL query against the MSP_PROJECTS table to determine whether the default version exists:

  sSQL = "SELECT * FROM MSP_PROJECTS WHERE PROJ_PROJECT = '" & PROJ_PROJECT & "' AND PROJ_VERSION = '" & sDefaultVersion & "'"

If the default version does not exist anywhere in the Microsoft Project Server database, PROJECT_DEFAULT_VERSION_NOT_FOUND is returned, and the CreateNewProject function stops parsing the request. If the default version is found, the CreateNewProject function executes the following SQL query:

  sSQL = "SELECT WPROJ_ID FROM MSP_WEB_PROJECTS WHERE WLOCAL_PATH = '" & PROJ_PROJECT & "." & sDefaultVersion & "'"

The CreateNewProject function then gets the next available project ID from the MSP_PROJECTS table:

  sSQL = "SELECT MAX(PROJ_ID) AS MAX_ID FROM MSP_PROJECTS"

The CreateNewProject function reserves that ID by inserting a valid row in the MSP_PROJECTS table:

  cmd.CommandText = "INSERT INTO MSP_PROJECTS (PROJ_ID,PROJ_NAME,PROJ_PROP_TITLE,PROJ_PROJECT,PROJ_VERSION,PROJ_INFO_START_DATE,PROJ_CREATION_DATE,PROJ_EXT_EDITED) VALUES(?,?,?,?,?,?,?,?)"
      cmd.ActiveConnection = m_oConnection
      cmd.CommandType = adCmdText
      With cmd.Parameters
         ...
      End With

Next, the CreateNewProject function inserts a record into the MSP_WEB_PROJECTS table to register the project in the Microsoft Project Server database so that the project is available in Microsoft Project Web Access:

     sSQL = "SELECT * FROM MSP_WEB_PROJECTS WHERE PROJ_ID = " & PROJ_ID
         ...
      With RS
          ![PROJ_ID] = PROJ_ID
          ![PROJ_NAME] = SHORT_PROJ_NAME
          ![WLOCAL_PATH] = PROJ_PROJECT & "." & PROJ_VERSION
          ![PROJ_TIMESTAMP] = sDateUID
          ![WDSN_ID] = -1
          ![WPROJ_TYPE] = 2
          .Update
          If iDefaultVersion = 1 Then WPROJ_ID = ![WPROJ_ID]
          ![WPROJ_DEFAULT_WPROJ_ID] = WPROJ_ID
          .Update
      End With

Finally, the CreateNewProject function inserts a record into the MSP_WEB_ASSIGNMENTS table so that the project is available in the Project Center of Microsoft Project Web Access. If the project has <Milestones> associated with it, the CreateNewProject function calls the CreateMilestones function. If milestone data is invalid or incomplete, PROJECT_MILESTONE_ERROR is returned and the CreateNewProject function stops parsing the request.

Adding Milestones to New Projects

When you add a new project that has milestones to the Microsoft Project Server database with the CreateNewProject function, you use the CreateMilestones function. This function has the following signature:

  Function CreateMilestones(
       ByVal oNode As Msxml2.IXMLDOMNode, _
      PROJ_ID As Long, _
       Flag As Integer) 
      As Long

The CreateMilestones function first determines whether the project is checked out to the current user. If it is, the CreateMilestones function sets the PROJ_EXT_EDITED flag in the MSP_PROJECTS table to 1, which allows external editing of that project in the Microsoft Project Server database. The CreateMilestones function then executes the following SQL queries against the MSP_TASKS table, linking the new milestones and tasks in the Microsoft Project Server database:

      sSQL = "SELECT MAX(TASK_UID) AS MAX_UID FROM MSP_TASKS WHERE PROJ_ID = " & PROJ_ID
       ...
      sSQL = "SELECT MAX(TASK_ID) AS MAX_ID FROM MSP_TASKS WHERE PROJ_ID = " & PROJ_ID

Next, the CreateMilestones function loops through and adds the task name and start date for each milestone and executes the SQL query that adds these milestones to the Microsoft Project Server database:

      Set CurNode = oNode.selectSingleNode("Milestones")
             ...
          Set CurNode = ChildNode.selectSingleNode("TaskName")
             ...
  
          Set CurNode = ChildNode.selectSingleNode("StartDate")
             ...
  
          cmd.CommandText = "INSERT INTO MSP_TASKS (PROJ_ID,TASK_UID,TASK_ID,TASK_NAME,TASK_START_DATE,TASK_DUR,TASK_IS_MILESTONE,TASK_CONSTRAINT_TYPE,EXT_EDIT_REF_DATA) VALUES(?,?,?,?,?,?,?,?,?)"
          cmd.CommandType = adCmdText
          With cmd.Parameters
             ...
          End With

Reference

ProjectCreate

This method creates new enterprise projects in the Microsoft Project Server database. Though this method does not require any milestones (tasks), you can associate one or more milestones with the project when it is created. The ProjectCreate method creates a valid enterprise project directly in the Microsoft Project Server database with the project's name, version, and start date specified. Milestones are automatically created for the project, if they have been specified.

Syntax
  <Request>
     <ProjectCreate>
        <Project>
           <ProjectName>CreatedProject</ProjectName>
           <Version>Published</Version>
           <StartDate>2002-09-23</StartDate>
           <Milestones>
              <Milestone>
                 <TaskName>Project Milestone</TaskName>
                 <StartDate>2002-10-31</StartDate>
              </Milestone>
           </Milestones>
        </Project>
     </ProjectCreate>
  </Request>
Parameters

ProjectName

Name of the project. Project names must not contain more than 200 characters and may not contain any of the following characters: . (period) \ " / : ; ? � < > *

Version

Version of the project; for example, "Published."

StartDate

Start date of the project.

Milestones

Optional. A milestone consists of a <TaskName> (the name of the task) and a <StartDate> (the start date for the task). One or more milestones may be associated with a new project.

Return Value

If the method succeeds, the user gets a successful HRESULT and STATUS, along with the ProjID of the newly created project.

  <Reply>
     <HRESULT>0</HRESULT>
     <STATUS>0</STATUS>
     <ProjectCreate>
        <ProjectID>70</ProjectID>
     </ProjectCreate>
  </Reply>
ResourcesAdd

This method adds resources to the Enterprise Resource Pool stored in the Microsoft Project Server database. ResourcesAdd first determines whether the Enterprise Resource Pool is checked out to the current user. The method then checks if the resource name is unique in both the Enterprise Resource Pool and the Microsoft Project Server database. If this resource does not match an existing resource, this method creates a new resource in the Enterprise Resource Pool directly in the Microsoft Project Server database.

Syntax
  <Request>
     <ResourcesAdd>
        <Resources>
           <Resource>
              <ResourceName></ResourceName>
           </Resource>
        </Resources>
     </ResourcesAdd>
  </Request>
Parameters

ResourceName

The name of the resource.

Return Value

If the method succeeds, the user gets a successful HRESULT and STATUS along with the resource name of the created resource.

  <Reply>
     <HRESULT>0</HRESULT>
     <STATUS>0</STATUS>
     <ResourcesAdd>
        <Resource>SDK Developer</Resource>
     </ResourcesAdd>
  </Reply>
ProjectResourcesAdd
Description

This method adds enterprise resources to the requested enterprise project team. ProjectResourcesAdd requires the user to pass in a <ProjectID> and at least one <ResourceUID>. ProjectResourcesAdd first determines whether the requested project is checked out to the current user. Then the method adds each enterprise resource to the project team directly in the Microsoft Project Server database.

Syntax
  <Request>
     <ProjectResourcesAdd>
        <ProjectID></ProjectID>
        <Resources>
           <ResourceUID></ResourceUID>
           <ResourceUID></ResourceUID>
        </Resources>
     </ProjectResourcesAdd>
  </Request>
Parameters

ProjectID

The ID for the project.

ResourceUID

The unique ID for the resource.

Return Value

If the method succeeds, the user gets a successful HRESULT and STATUS along with the <ResourceUID> for each added resource.

  <Reply>
     <HRESULT>0</HRESULT>
     <STATUS>0</STATUS>
     <ProjectResourcesAdd>
        <ResourceUID></ResourceUID>
     </ProjectResourcesAdd>
  </Reply>
Status Codes

Status codes are included in the <STATUS> tag of a PDS call's reply, for example, <STATUS>0</STATUS>. The Project Utilities PDS Extender supplies the following status codes.

Status code
Error

0

STATUS_OK

10001

STATUS_UNKNOWN_REQUEST

10002

STATUS_INVALID_REQUEST

10003

RESOURCES_TAG_NOT_FOUND

10004

RESOURCE_TAG_NOT_FOUND

10005

RESOURCE_NAME_TAG_NOT_FOUND

10006

RESOURCES_ADD_TAG_NOT_FOUND

10007

RESOURCE_NAME_NOT_FOUND

10008

RESOURCE_ADD_FAILED

10009

RESOURCE_NAME_TOO_LONG

10010

RESOURCE_NAME_NOT_UNIQUE

10011

RESOURCE_WEB_NAME_NOT_UNIQUE

10012

RESOURCE_GLOBAL_NOT_FOUND

10013

RESOURCE_GLOBAL_NOT_CHECKED_OUT

10014

PROJECT_INFO_NOT_FOUND

10015

PROJECT_NAME_TOO_LONG

10016

VERSION_NAME_TOO_LONG

10017

VERSION_NAME_NOT_VALID

10018

PROJECT_DEFAULT_VERSION_NOT_FOUND

10019

PROJECT_MILESTONE_ERROR

10020

PROJECT_NOT_FOUND

10021

PROJECT_NOT_CHECKED_OUT

10022

PROJECT_NAME_NOT_UNIQUE

10023

PROJECT_NAME_INVALID

10024

RESOURCE_NAME_INVALID

10025

RESOURCE_UID_INVALID

10100

INSERT_MIN_RECORDS_ERROR