2019-05-13 09:52 AM - last edited on 2022-10-05 01:28 PM by Daniel Kassai
static void Do_SelectWallsFromExcel(void) { DBPrintf("Selecting walls based on Excel document...\n"); GS::Array<API_Guid> apiguids; ACAPI_Goodies(APIAny_GetSelectedElementID, &apiguids); GS::Array<API_Guid> selection; libxl::Book* book = xlCreateXMLBook(); if (DBERROR(book == nullptr)) return; IO::Location location; IO::fileSystem.GetSpecialLocation(IO::FileSystem::UserDocuments, &location); location.AppendToLocal(IO::Name("export.xlsx")); GS::UniString filepath; location.ToPath(&filepath); bool loaded = book->load(UNISTR_TO_LIBXLSTR(filepath)); if (DBERROR(!loaded)) return; libxl::Sheet* sheet = book->getSheet(0); if (DBERROR(sheet == nullptr)) return; for (int i = 0; i < sheet->lastRow(); ++i) { GS::Guid xlGsGuid; const auto* cellContentPtr = sheet->readStr(i, 0); if (cellContentPtr == nullptr) continue; GSErrCode err = xlGsGuid.ConvertFromString(cellContentPtr); if (err != NoError) continue; API_Guid xlApiGuid = GSGuid2APIGuid(xlGsGuid); if (!apiguids.Contains(xlApiGuid)) continue; selection.Push(xlApiGuid); } book->release(); USize selCount = selection.GetSize(); API_Neig** selNeig = (API_Neig**)(BMAllocateHandle(selCount * sizeof(API_Neig), ALLOCATE_CLEAR, 0)); for (UIndex i = 0; i < selCount; ++i) { (*selNeig).neigID = APINeig_Wall; (*selNeig).guid = selection; } GSErrCode err = ACAPI_Element_Select(selNeig, selCount, true); if (DBERROR(err != NoError)) DBPrintf("Selection of %d wall(s) failed.\n", selCount); else DBPrintf("%d walls successfully selected\n", selCount); BMKillHandle(reinterpret_cast<GSHandle*> (&selNeig)); }
Solved! Go to Solution.
2019-05-14 09:56 PM
GS::Array<API_Guid> apiguids; // Original line from Database_Control example Add-On: ACAPI_Element_GetElemList (API_WallID, &apiguids); // Changed line by SajW: ACAPI_Goodies (APIAny_GetSelectedElementID, &apiguids);If you revert this change, then it should work Make sure that the Excel table contains the GUIDs of the exisiting placed walls.
SajW wrote:Easy peasy
Is it possible to select elements in archiCAD by GUID/s from the clipboard? GUIDs will be copied to the clipboard with line breaks.
static GSErrCode SelectWallsFromClipboard (const GS::UniString& clipboardString) { GS::Array<GS::UniString> guidStrings; clipboardString.Split ("\n", GS::UniString::SkipEmptyParts, &guidStrings); const USize count = guidStrings.GetSize (); API_Neig** neigs = (API_Neig**) (BMAllocateHandle (count * sizeof (API_Neig), ALLOCATE_CLEAR, 0)); for (UIndex i = 0; i < count; ++i) { (*neigs).guid = APIGuidFromString (guidStrings.ToCStr ().Get ()); } GSErrCode err = ACAPI_Element_Select (neigs, count, true); BMKillHandle (reinterpret_cast<GSHandle*> (&neigs)); return err; }
2019-05-14 09:56 PM
GS::Array<API_Guid> apiguids; // Original line from Database_Control example Add-On: ACAPI_Element_GetElemList (API_WallID, &apiguids); // Changed line by SajW: ACAPI_Goodies (APIAny_GetSelectedElementID, &apiguids);If you revert this change, then it should work Make sure that the Excel table contains the GUIDs of the exisiting placed walls.
SajW wrote:Easy peasy
Is it possible to select elements in archiCAD by GUID/s from the clipboard? GUIDs will be copied to the clipboard with line breaks.
static GSErrCode SelectWallsFromClipboard (const GS::UniString& clipboardString) { GS::Array<GS::UniString> guidStrings; clipboardString.Split ("\n", GS::UniString::SkipEmptyParts, &guidStrings); const USize count = guidStrings.GetSize (); API_Neig** neigs = (API_Neig**) (BMAllocateHandle (count * sizeof (API_Neig), ALLOCATE_CLEAR, 0)); for (UIndex i = 0; i < count; ++i) { (*neigs).guid = APIGuidFromString (guidStrings.ToCStr ().Get ()); } GSErrCode err = ACAPI_Element_Select (neigs, count, true); BMKillHandle (reinterpret_cast<GSHandle*> (&neigs)); return err; }
2019-05-21 04:55 AM
static GSErrCode SelectWallsFromClipboard (const GS::UniString& clipboardString) { GS::Array<GS::UniString> guidStrings; clipboardString.Split ("\n", GS::UniString::SkipEmptyParts, &guidStrings); const USize count = guidStrings.GetSize (); API_Neig** neigs = (API_Neig**) (BMAllocateHandle (count * sizeof (API_Neig), ALLOCATE_CLEAR, 0)); for (UIndex i = 0; i < count; ++i) { (*neigs).guid = APIGuidFromString (guidStrings.ToCStr ().Get ()); } GSErrCode err = ACAPI_Element_Select (neigs, count, true); BMKillHandle (reinterpret_cast<GSHandle*> (&neigs)); return err; }Thanks for this code, but I am having trouble calling this function.. How do I call it?
2019-05-21 08:43 AM
SajW wrote:
Thanks for this code, but I am having trouble calling this function.. How do I call it?
// Get string from clipboard GS::UniString clipboardString; Clipboard::GetInstance ().GetUniString (Clipboard::uniTextTypeId, clipboardString); // Call the function by passing the string from clipboard SelectWallsFromClipboard (clipboardString);Update:
2019-05-24 05:29 AM
2019-05-24 09:14 AM
void Do_SelectWallsFromExcel(void) { GS::UniString clipboardString; Clipboard::GetInstance().GetUniString(Clipboard::textTypeId, clipboardString); // Call the function by passing the string from clipboard SelectWallsFromClipboard(clipboardString); }I tried to call it inside the Database_control example Do_SelectWallsFromExcel, but I cannot get it working
2019-05-24 09:50 AM
SajW wrote:Are you sure the clipboard contains GUIDs of existing elements separated by a '\n' character?
I have tried to call the function but does not work.
2019-05-24 11:31 AM
2019-06-10 11:48 AM
Tibor wrote:Value of guidStrings array is something like this.
Are you sure the clipboard contains GUIDs of existing elements separated by a '\n' character?
When you debug the code, what is the content of the guidString array inside the SelectWallsFromClipboard functions?
2019-09-19 11:36 AM