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;
}
Creating the "Project" (actually just a folder in this case - "words get in the way" again) with aaApi_CreateProject() doesn't do more than just create the folder. If you want the new folder to use an environment, you have to add it with a second API call such as aaApi_ModifyProject2().
You can call one API function, aaApi_CreateProject2(), to do most of the things you want, but you have to first allocate and populate a buffer (AADMSPROJITEM). Typically you select the parent folder and then inspect its properties to determine what to use for the child folder you want to create, such as the environment, storage area, etc. and then you can set the corresponding properties (and flags) in the AADMSPROJITEM structure that you allocated.
As I mention in the SDK training, some things that you think are just one function call, actually involve multiple calls, and others that you would expect to be multiple API functions, sometimes have a single function, you just have to do all the work setting up all the parameters that it expects to be passed to it.
And lWorkspaceProfileId is for, well workspaces!
HTHs
Thank you, but i still have a problem.
aaApi_CreateProject2 responds:"error creating a new folder, Name required as parameter for this function"
' 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 ' 211555732 DonneesProject.lptstrName = strptrNomProject ' 209048980 DonneesProject.lStorageId = lStorageId ' 1 DonneesProject.lTypeId = AADMS_PROJECT_TYPE_NORMAL DonneesProject.lWorkflowId = 0 DonneesProject.lWorkspaceProfileId = 0 DonneesProject.projFlagMask = 0 DonneesProject.projFlags = 0 Drapeaux = AADMSPROJF_ENVID Or AADMSPROJF_PARENTID Or AADMSPROJF_PROJECTID _ Or AADMSPROJF_DESC Or AADMSPROJF_NAME _ Or AADMSPROJF_STORAGEID Or AADMSPROJF_TYPEID DonneesProject.ulFlags = Drapeaux ptrDonneesProject = VarPtr(DonneesProject) HeriterControleAcces = 0 ' 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
What name does it need, it has the name of the directory?
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.
I'm still at the same point.
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.