Change a parameter value in memo
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎2018-10-19
04:35 PM
- last edited on
‎2022-10-05
01:36 PM
by
Daniel Kassai
I'm still quite new to this but i'm making progress

I need your help to change the value of a parameter in an element's memo.
i want this to work on an external library's object, that is selected in Archicad.
I'm able to get the selected items, iterate on them, list the parameters in the memo of each object but don't know how to change them.
I guess i have to use ACAPI_​Element_​Change ??
GSErrCode ACAPI_Element_Change ( API_Element* element, const API_Element* mask, const API_ElementMemo* memo, UInt64 memoMask, bool withdel );so that's what i'm doing:
ACAPI_ELEMENT_MASK_CLEAR() ACAPI_ELEMENT_MASK_SET(mask, API_ObjectType, ???); //don't know what to put here changeErr = ACAPI_Element_Change(&element, objectmask; changeErr = ACAPI_Element_Change(&element, ??, &memo, ??, false); //don't know what masks to puthelp

Solved! Go to Solution.
- Labels:
-
Add-On (C++)
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎2018-10-20 11:38 AM
API_Element mask; ACAPI_ELEMENT_MASK_SETFULL(mask); ACAPI_Element_Change(elemData, &mask, elemMemo, APIMemoMask_AddPars, true)The easiest way to change parameter values is
Central Innovation
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎2018-10-20 11:38 AM
API_Element mask; ACAPI_ELEMENT_MASK_SETFULL(mask); ACAPI_Element_Change(elemData, &mask, elemMemo, APIMemoMask_AddPars, true)The easiest way to change parameter values is
Central Innovation
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎2018-10-22 10:21 AM
I'll look into it tomorrow at work and keep you posted

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎2018-10-24 03:04 PM
void ManageSelection(void) { API_Element element, mask; API_ElementMemo memo; GSErrCode err, changeErr; API_SelectionInfo selectionInfo; API_Neig **selNeigs; int ii, nSel, j, nbParams; API_AddParType param; // Get selected elements (which are all objects from a custom library) err = ACAPI_Selection_Get(&selectionInfo, &selNeigs, false); if (err == NoError){ if (selectionInfo.typeID != API_SelEmpty){ nSel = BMGetHandleSize((GSHandle)selNeigs) / sizeof(API_Neig); API_ParamOwnerType paramOwner; API_ChangeParamType chgParam; API_GetParamsType getParams; for (ii = 0; ii < nSel && err == NoError; ii++) { //iterating on the selection BNZeroMemory(&element, sizeof(element)); //insert guid in header element.header.guid = (*selNeigs[ii]).guid; //get the element if (ACAPI_Element_Get(&element) == NoError) DBPrintf("\n\n GET_ELEMENT OK\n\n"); else DBPrintf("\n\n GET_ELEMENT NOK\n\n"); if (element.header.hasMemo) { BNZeroMemory(&memo, sizeof(memo)); err = ACAPI_Element_GetMemo(element.header.guid, &memo, APIMemoMask_AddPars); if (err == NoError) DBPrintf("\n\n GETMEMO OK\n\n"); else ErrorBeep("ACAPI_Element_GetMemo", err); } //change value of attribute N_panneau of each item in selection // start by filling the param owner BNZeroMemory(¶mOwner, sizeof(API_ParamOwnerType)); paramOwner.libInd = 0; //this should be 0 because it's not a library part, it's a placed element paramOwner.typeID = API_ObjectID; // object element paramOwner.guid = (*selNeigs[ii]).guid; // placed element guid BNZeroMemory(&getParams, sizeof(API_GetParamsType)); // Open a Library Part parameter list to edit err = ACAPI_Goodies(APIAny_OpenParametersID, ¶mOwner, nullptr); if (err == NoError) { DBPrintf("\n\n APIAny_OpenParametersID OK"); BNZeroMemory(&chgParam, sizeof(API_ChangeParamType)); // Returns the actual (edited) values of a Library Part parameter list opened to edit. err = ACAPI_Goodies(APIAny_GetActParametersID, &getParams, nullptr); if (err == NoError) { DBPrintf("\n\n APIAny_GetActParametersID OK"); CHCopyC("N_panneau", chgParam.name); //N_panneau is the parameter's name chgParam.realValue = 13.0; //setting the value to 13 instead of 11 // Changes a value in an opened Library Part parameter list err = ACAPI_Goodies(APIAny_ChangeAParameterID, &chgParam, nullptr); if (err == NoError) { DBPrintf("\n\nAPIAny_ChangeAParameterID OK"); err = ACAPI_Goodies(APIAny_GetActParametersID, &getParams, nullptr); } else DBPrintf("\n\n APIAny_ChangeAParameterID NOK\n\n"); } else DBPrintf("\n\n APIAny_GetActParametersID NOK"); err = ACAPI_Goodies(APIAny_CloseParametersID, nullptr, nullptr); if (err == NoError) { DBPrintf("\n\n APIAny_CloseParametersID OK"); element.header.typeID = API_ObjectID; ACAPI_ELEMENT_MASK_CLEAR(mask); ACAPI_ELEMENT_MASK_SETFULL(mask); memo.params = getParams.params; err = ACAPI_Element_Change(&element, &mask, &memo, APIMemoMask_AddPars, true); //the error is here, the error check prints ACAPI_Element_Change NOK if (err == NoError) DBPrintf("\n\n ACAPI_Element_Change OK"); else DBPrintf("\n\n ACAPI_Element_Change NOK %d", err); } else DBPrintf("\n\n APIAny_CloseParametersID NOK"); } else DBPrintf("\n\n APIAny_OpenParametersID NOK\n\n"); } BMKillHandle((GSHandle *)&selNeigs); } else { DBPrintf("\n\n SELECTION_EMPTY \n\n"); } } }basically i'm selecting elements in archicad then running this function
the output i'm getting is:
GET_ELEMENT OK
GETMEMO OK
APIAny_OpenParametersID OK
APIAny_GetActParametersID OK
APIAny_ChangeAParameterID OK
APIAny_CloseParametersID OK
ACAPI_Element_Change NOK ,APIERR_NEEDSUNDOSCOPE
this is the attribute i want to change: (it's called "Numero de panneau" here but the actual name is "N_panneau") First of all am I doing this right ?
and does this really need an undo scope ?
because I haven't seen it used in the example for APIAny_OpenParametersID here: link
and if so what would it look like ?
because this:
GSErrCode err = ACAPI_CallUndoableCommand ("Create text", [&] () -> GSErrCode { return ACAPI_Element_Create (&element, &memo); }); if (err != NoError) ErrorBeep ("ACAPI_Element_Create (text)", err); ACAPI_DisposeElemMemoHdls (&memo);is beyond my comprehension

Thank you for your precious help

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎2018-10-24 03:13 PM
Central Innovation
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎2018-10-24 03:28 PM
THANK YOU !

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎2018-10-24 03:44 PM
wacim wrote:Yes, at first sight it looks correct.
First of all am I doing this right ?
wacim wrote:Yes, as Ralph said, all operations which do some kind of element database modification can be executed only from an UndoableCommand.
and does this really need an undo scope ?
wacim wrote:That example calls ACAPI_Element_ChangeDefaults function and you call ACAPI_Element_Change. That's the main difference which explains why you need an undo scope.
because I haven't seen it used in the example for APIAny_OpenParametersID here: link
wacim wrote:Don't be shocked, it's just a little lambda expression (available since C++11)
and if so what would it look like ?
because this is beyond my comprehension
Thank you for your precious help![]()

You just have to change one line: Instead of calling your ManageSelection function directly, call it this way:
ACAPI_CallUndoableCommand ("Manage Selection", [&] () -> GSErrCode { ManageSelection (); return NoError; });
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎2018-10-24 04:08 PM
as for the " lambda expression" now i know how it's called so i can google it and see how it works...
what i did is i searched in all examples folder for use cases of "ACAPI_CallUndoableCommand" and tried to do something similar, which worked but now i'll actually be able to understand
