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
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
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