aaApi_CreateProject is not working

Hello,

I cannot figure out what is wrong with the following code. Do anyone has idea?

This always returns False.

bool createProj(int projectID, LPCTSTR name, LPCTSTR description)
{

LONG projectID2 = 0L;
LONG lngWorkSpaceID = aaApi_GetWorkspaceProfileId(projectID, 0);
LONG userID = aaApi_GetCurrentUserId();
LONG lStorageId = aaApi_GetStorageId(0);

BOOL resultCreate = aaApi_CreateProject(

&projectID2,
projectID,
lStorageId,
userID,
AADMS_PROJECT_TYPE_NORMAL,
0,
lngWorkSpaceID,
0,
name,description);

return resultCreate;

}

Parents
  • Did you check to see what is on the ProjectWise error stack? Use aaApi_GetLastErrorId(), etc. to determine why the call failed.

    Also, you aren't showing in this call that you actually filled the static buffers you are using for aaApi_GetWorkspaceProfileId() or aaApi_GetStorageId() which will return a value which may or may not be what you think unless you first filled the buffers based on your needs. See the topic "ProjectWise Data Buffers" under "ProjectWise Developer's Guide" under "Modules" in the SDK help for more about using static and dynamic buffers in ProjectWise.
  • Dan, Thanks for advise. I added aaApi_GetLastErrorId() and got error id 58002. Can you advise where is the error id table? Thank you!
  • I would have to see your actual code to determine what the problem is, but I suspect that either you have not included the bit mask AADMSPROJF_NAME in the ulFlags property of the AADMSPROJITEM structure, or your project name is invalid.  It isn't clear to me what programming language you are using.

    Perhaps an example would help?  Here's a snippet of C++ code that I have used before:

            AADMSPROJITEM   PrjInfo;
    
            PrjInfo.ulFlags = AADMSPROJF_PROJECTID|AADMSPROJF_ENVID|AADMSPROJF_PARENTID|AADMSPROJF_STORAGEID|AADMSPROJF_MANAGERID|AADMSPROJF_TYPEID|AADMSPROJF_WORKFLOW|AADMSPROJF_NAME|AADMSPROJF_DESC|AADMSPROJF_MGRTYPE|AADMSPROJF_WSPACEPROFID;
            PrjInfo.lProjectId = 0L;
            PrjInfo.lEnvironmentId = ENVNO_NON_ENG;
            PrjInfo.lParentId = glPrjId;
            PrjInfo.lStorageId = glPrjStorageId;
            PrjInfo.lManagerId = glPrjManagerId;
            PrjInfo.lTypeId = glPrjTypeId;
            PrjInfo.lWorkflowId = glPrjWorkflowId;
            PrjInfo.lptstrName = CSTR_NON_ENG;
            PrjInfo.lptstrDesc = CSTR_NON_ENG;
            PrjInfo.lManagerType = glPrjManagerType;
            PrjInfo.lWorkspaceProfileId = glPrjWorkspaceProfileId;
    
            if( !aaApi_CreateProject2( &PrjInfo, -1 ) )
            {
                glNonEngPrjId = 0L;
                strErrMsg.Format
                    (
                    _T("Could not create the subfolder \"%s\" for PrjNo:%ld:%s\n"), 
                    CSTR_NON_ENG, 
                    glPrjId, 
                    gstrPrjName
                    );
                strErrMsg.Format( _T("[%ld] %s %s\n"), aaApi_GetLastErrorId(), aaApi_GetLastErrorMessage(), aaApi_GetLastErrorDetail() );
            }
            else
            {
                glNonEngPrjId = PrjInfo.lProjectId;
                bFoundNonEng = TRUE;
            }
    

  • No, there is no shortage of flags

    I am using Visual Basic in Excel. Apart from the syntax, it is basically not very different from C ++

    #define

    Type AADMSPROJITEM ' la structure est utilisée pour représenter les données de l'élément de projet.
        guidVault As Long ' Spécifie le GUID du projet.
        lComponentClassId As Long ' Spécifie l'ID de classe de l'instance ODS contenant les propriétés
                                  ' de projet riches.
        lComponentInstanceId As Long ' Spécifie l'ID d'instance de l'instance ODS contenant les propriétés de
                                     ' projet riches.
        lEnvironmentId As Long ' Spécifie l'environnement auquel appartient le projet.
        lManagerId As Long ' Spécifie l'ID du chef de projet.
        lManagerType As Long ' Spécifie le type de chef de projet.
                             ' Voir Types de projets et de gestionnaires de documents pour les valeurs
                             ' prédéfinies.
        lParentId As Long ' Spécifie l'identifiant du projet parent.
        lProjectId As Long ' Spécifie l'ID du projet.
        lptstrDesc As Long ' Pointeur vers une chaîne terminée par un caractère nul spécifiant
                           ' la description du projet.
        lptstrName As Long ' Pointeur vers une chaîne terminée par un caractère nul spécifiant le nom du projet.
        lStorageId As Long ' Spécifie le stockage par défaut du projet.
        lTypeId As Long ' Spécifie le type de projet.
                        ' Voir Types de projets pour plus d'informations.
        lWorkflowId As Long ' Spécifie l'identificateur de workflow attribué au projet.
        lWorkspaceProfileId As Long ' Spécifie le type de profil d'espace de travail de projet.
        projFlagMask As Long ' Spécifie les bits valides dans les projFlags membres.
        projFlags As Long ' Spécifie les indicateurs de projet (flags) à définir ou à réinitialiser.
        ulFlags As Long ' Ce membre est le masque de bits spécifiant lequel des membres de la structure
                        ' contient des informations valides.
                        ' Reportez-vous à AADMSPROJF_* pour une liste détaillée des valeurs possibles.
    End Type
    

    the apostrope is worth //

    flags

    ' Définitions des indicateurs (flags) AADMSPROJITEM
    'Public Const AADMSPROJF_ALL As Long = &HFFFF ' S'il est défini, tous les membres contiennent des
                                                 ' informations valides.
    'Public Const AADMSPROJF_GUID As Long = &H1000 ' S'il est défini, le membre guidVault contient des
                                                  ' informations valides.
    'Public Const AADMSPROJF_COMPONENT_CLASSID As Long = &H2000 ' S'il est défini, le membre lComponentClassId
                                                               ' contient des informations valides.
    'Public Const AADMSPROJF_COMPONENT_INSTANCEID As Long = &H8000 ' S'il est défini, le membre
                                                                  ' lComponentInstanceId contient des
                                                                  ' informations valides.
    Public Const AADMSPROJF_ENVID As Long = &H2 ' S'il est défini, le membre lEnvironmentId contient des
                                                ' informations valides.
    'Public Const AADMSPROJF_MANAGERID As Long = &H10 ' S'il est défini, le membre lManagerId contient des
                                                     ' informations valides.
    'Public Const AADMSPROJF_MGRTYPE As Long = &H400 ' S'il est défini, le membre lManagerType contient des
                                                    ' informations valides.
    Public Const AADMSPROJF_PARENTID As Long = &H4 ' S'il est défini, le membre lParentId contient des
                                                   ' informations valides.
    Public Const AADMSPROJF_PROJECTID As Long = &H1 ' S'il est défini, le membre lProjectId contient des
                                                    ' informations valides.
    Public Const AADMSPROJF_DESC As Long = &H100 ' S'il est défini, le membre lptstrDesc contient des
                                                 ' informations valides.
    Public Const AADMSPROJF_NAME As Long = &H80 ' S'il est défini, le membre lptstrName contient des
                                                ' informations valides.
    Public Const AADMSPROJF_STORAGEID As Long = &H8 ' S'il est défini, le membre lStorageId contient des
                                                    ' informations valides.
    Public Const AADMSPROJF_TYPEID As Long = &H20 ' S'il est défini, le membre lTypeId contient des
                                                  ' informations valides.
    Public Const AADMSPROJF_WORKFLOW As Long = &H40 ' S'il est défini, le membre lWorkflowId contient des
                                                    ' informations valides.
    'Public Const AADMSPROJF_WSPACEPROFID As Long = &H800 ' S'il est défini, le membre lWorkspaceProfileId
                                                         ' contient des informations valides.
    'Public Const AADMSPROJF_PROJFLAGS As Long = &H4000 ' S'ils sont définis, les membres projFlagMask et
                                                       ' projFlags contiennent des informations valides.
    ' ulFlags est forcément valide, obligatoire

    &H means 0x

    the function

    Public Function CreerProject(ParentProjectID As Long, EnvironnementID As Long, WorkFlowID As Long, _
                    Niveau As Integer, NomProject As String, DescriptionProject As String) As Long
    ' Crée un nouveau projet dans PW. Appelé par l'objet Project.
    
    Dim strptrNomProject As Long
    Dim strptrDescriptionProject As Long
    Dim SousProjectID As Long
    Dim UserId As Long
    Dim StorageIndex As Long
    Dim lStorageId As Long
    Dim SousNiveau As Integer
    Dim ValeurZero As Long
    Dim lOK As Long
    Dim EstRacine As Boolean
    Dim AvecDocuments As Boolean
    Dim AvecProprietes As Boolean
    'Dim Nombre As Long
    
    Dim DonneesProject As AADMSPROJITEM
    Dim ptrDonneesProject As Long
    Dim HeriterControleAcces As Long
    Dim Drapeaux As Long
        
        ' Récupération des infos
        ValeurZero = 0
        If Trim(NomProject) = "" Then
            strptrNomProject = 0
            MsgBox "Il faut un nom au répertoire"
            Stop
        Else
            strptrNomProject = StrPtr(NomProject) ' Sous_Repertoire_1
        End If
    
        If Trim(DescriptionProject) = "" Then
            strptrDescriptionProject = 0
        Else
            strptrDescriptionProject = StrPtr(DescriptionProject)
        End If
        SousProjectID = 0
        UserId = aaApi_GetCurrentUserId()
        StorageIndex = aaApi_SelectStoragesForProject(ParentProjectID)
        Select Case StorageIndex
        Case Is = -1
            lOK = aaApi_ShowLastErrorMessageBox ' renvoie un strptr sur le message de l'erreur
            Stop
        Case Is = 0
            MsgBox "Eléments de stockage introuvables"
            Stop
        End Select
        lStorageId = aaApi_GetStorageId(ValeurZero) ' On prends le premier (base 0)
        If lStorageId = 0 Then
            MsgBox "Stokage introuvable"
            Stop
        End If
    
        ' On rempli la structure descriptive
        DonneesProject.guidVault = 0
        DonneesProject.lComponentClassId = 0
        DonneesProject.lComponentInstanceId = 0
        DonneesProject.lEnvironmentId = EnvironnementID ' 102
        DonneesProject.lManagerId = 0
        DonneesProject.lManagerType = 0
        DonneesProject.lParentId = ParentProjectID ' 107
        DonneesProject.lProjectId = 0 ' ce qu'on cherche
        DonneesProject.lptstrDesc = strptrDescriptionProject
        DonneesProject.lptstrName = strptrNomProject ' 209048980
        DonneesProject.lStorageId = lStorageId ' 1
        DonneesProject.lTypeId = AADMS_PROJECT_TYPE_NORMAL ' 0
        DonneesProject.lWorkflowId = WorkFlowID ' 1
        DonneesProject.lWorkspaceProfileId = 0
        DonneesProject.projFlagMask = 0
        DonneesProject.projFlags = 0
    
        Drapeaux = AADMSPROJF_ENVID ' 2
        Drapeaux = Drapeaux Or AADMSPROJF_PARENTID ' 4
        Drapeaux = Drapeaux Or AADMSPROJF_PROJECTID ' 1
        If strptrDescriptionProject <> 0 Then Drapeaux = Drapeaux Or AADMSPROJF_DESC ' 256
        Drapeaux = Drapeaux Or AADMSPROJF_NAME ' 128
        Drapeaux = Drapeaux Or AADMSPROJF_STORAGEID ' 8
        Drapeaux = Drapeaux Or AADMSPROJF_TYPEID ' 32
        Drapeaux = Drapeaux Or AADMSPROJF_WORKFLOW ' 64
        DonneesProject.ulFlags = Drapeaux ' 239
        
        ptrDonneesProject = VarPtr(DonneesProject)
        HeriterControleAcces = 0 ' ça veut dire oui
    
        ' Création du répertoire
        ' Note : PW ne rafraichit pas l'affichage
        lOK = aaApi_CreateProject2(ptrDonneesProject, HeriterControleAcces)
        If lOK = 0 Then
            lOK = aaApi_ShowLastErrorMessageBox ' renvoie un strptr sur le message de l'erreur
            CreerProject = 0
            Stop
        Else
            CreerProject = DonneesProject.lProjectId ' La valeur de retour
    
            ' Mettre le project dans la collection
            EstRacine = False ' Forcément
            AvecDocuments = False
            AvecProprietes = False
            lngCountLevel = Niveau + 1
            CreeObjetProjet SousProjectID, EstRacine, AvecDocuments, AvecProprietes
        
        End If
    
    End Function

    Thank you Dan for your help. without you we would be wrong.!

  • ah, I forgot: the project to create does not exist, obviously.

  • Didier,

    My apologies, I lost track of this conversation.

    I really can't help you with VB for Excel as I haven't ever really used it.  FWIW, I wouldn't say that " Apart from the syntax, it is basically not very different from C ++", as I suspect that there's more differences than you might expect. For one, "strings" are always an "issue" in that a string in C++ can be the C style "string" (a pointer to a memory location to start, and "ends" when a memory offset is zero), or an Object such as MFC CString.  VB, I believe uses a "BSTR", which is likely to be more like MFC's CString, but I'm not an expert on the details.

    I noticed in your declarations that you have defined some enums as LONG.  That may work, but typically, these are unsigned integers.  Here's what can be used in C# to correspond to the C++ #Defines for AADMSPROJF_*:

    I don't know what your application needs to do, but you may want to consider using PowerShell (PWPS_DAB) to create or update your Excel file.  And if the goal is to create new Projects (folders or Work Areas?) in a datasource, then take a look at the Cmdlets that will create folders or "rich projects" (work areas) from a spreadsheet.  Perhaps it may be an easier approach to implement for your needs.

Reply
  • Didier,

    My apologies, I lost track of this conversation.

    I really can't help you with VB for Excel as I haven't ever really used it.  FWIW, I wouldn't say that " Apart from the syntax, it is basically not very different from C ++", as I suspect that there's more differences than you might expect. For one, "strings" are always an "issue" in that a string in C++ can be the C style "string" (a pointer to a memory location to start, and "ends" when a memory offset is zero), or an Object such as MFC CString.  VB, I believe uses a "BSTR", which is likely to be more like MFC's CString, but I'm not an expert on the details.

    I noticed in your declarations that you have defined some enums as LONG.  That may work, but typically, these are unsigned integers.  Here's what can be used in C# to correspond to the C++ #Defines for AADMSPROJF_*:

    I don't know what your application needs to do, but you may want to consider using PowerShell (PWPS_DAB) to create or update your Excel file.  And if the goal is to create new Projects (folders or Work Areas?) in a datasource, then take a look at the Cmdlets that will create folders or "rich projects" (work areas) from a spreadsheet.  Perhaps it may be an easier approach to implement for your needs.

Children
No Data