Jump to content
twk

Getting Objects from Worksheet Database

Recommended Posts

Greetings all,

I have a worksheet that shows all windows/doors in the drawing. 

I was trying to grab handles to these objects from the worksheet database, but could not find any sdk functions to call it.

 

So I added an extra column that calls the GlobalID from the IFCDoor/IFCWindow, and noticed that these are as expected all unique ids.

 

My question is, does this ID, remain throughout the life of the drawing document? as opposed to handles? Could I then use these ID's to uniquely identify these in a script database somehow?

 

Cheers,

Tui

 

 

 

Share this post


Link to post

I have no idea if the IFC fields are unique or not, but depending on what you are doing I don't know that I would trust them as it is possible for something else to modify them.

 

If you need a unique identifier, VectorScript (so I am sure the SDK does also) has a UUID function. Store this in one of the user fields, or create a custom hidden record and store it there.

 

Alternatively, if you don't need to have it unique for life, but just for now, you could create a very small Worksheet Script that would return the Handle to the object as a LongInt (or String) you could then grab the data from that cell and convert back to a handle. Every time the worksheet runs the handle column would be updated.

Share this post


Link to post

A few, possibly separate questions. 
 

Are you specifically trying to access the objects that a user has selected for a worksheet database? If you’re just looking to access the underlying data, you can do this directly, without dealing with the worksheet. 
 

If you’re trying to access the report criteria, try retrieving column 0 of the database row. 
 

You mention the SDK — do you mean the actual SDK, or the Python API?
 

A few versions ago, Vectorworks started adding a UUID to every object. This doesn’t seem to be on the developer wiki, but GetObjectByUuid() and GetObjectUuid() are valid calls. As this ID is core level, it will be a lot more robust than a plug-in code managed ID. 

  • Like 2

Share this post


Link to post
14 hours ago, Pat Stanford said:

... return the Handle to the object as a LongInt (or String) you could then grab the data from that cell and convert back to a handle.

 

I wish this were possible. To the best of my knowledge you can only look at a handle value, but you cannot cast the value back to a handle. On a similar track, since the VW App went to 64 bit, I've seen some handle values (not all) that exceed the Longint range. There is no 64-bit integer type in VS that would accommodate really large integers.

 

@Pat Stanford if I'm wrong and you do know of a way to convert values back to a handle, would you mind sharing. I could use this.

 

Thanks,

Raymond

Share this post


Link to post

@MullinRJ No Raymond, I think you are correct. I don't know if I am mistaken or if the last time I played with this is so long ago that things have changed.

 

I am currently playing with a possible Python solution that would grab the handle as Text, Convert it to a Python integer, and then store that back to a Handle variable.  But my Python is so weak as to be really painful. I think @twk is much more of a Python expert, so perhaps he can take my outline below and make it work.

 

😞

 

Procedure Test;

Var    H1,H2:    Handle;
    S1,S2:    String;
    L1: LongInt;
    
Begin
    H1:=FSActLayer;
    S1:=Concat(H1);

{    DselectAll;
    AlrtDialog(Concat(S1));
}    PythonBeginContext;
    PythonExecute('S1 = vs.GetVSVar("S1")');
    {PythonExecute('L2 = int(S1)');
    PythonExecute('vs.SetVSVar("H2", "L2")');}
    PythonEndContext;
    
    L1:=Str2Num(Copy(S1,1,10))*10;
    AlrtDialog(Concat(S1,' - ',L1,' - ',H2));
End;

Run(Test);

Procedure Test;

Var	H1,H2:	Handle;
	S1,S2:	String;
	L1: LongInt;
	
Begin
	H1:=FSActLayer;
	S1:=Concat(H1);

{	DselectAll;
	AlrtDialog(Concat(S1));
}	PythonBeginContext;
	PythonExecute('S1 = vs.GetVSVar("S1")');
	{PythonExecute('L2 = int(S1)');
	PythonExecute('vs.SetVSVar("H2", "L2")');}
	PythonEndContext;
	
	L1:=Str2Num(Copy(S1,1,10))*10;
	AlrtDialog(Concat(S1,' - ',L1,' - ',H2));
End;

Run(Test);

 

 

  • Like 1

Share this post


Link to post
3 hours ago, JBenghiat said:

A few versions ago, Vectorworks started adding a UUID to every object. This doesn’t seem to be on the developer wiki, but GetObjectByUuid() and GetObjectUuid() are valid calls. As this ID is core level, it will be a lot more robust than a plug-in code managed ID. 

 

This will actually do it. Thanks a million guys. How do you find these @JBenghiat!

On that note, would you know if there is a function call for this for worksheets? I've resorted to creating a script to pull that info into the worksheet, and can then cylce through the worksheet to grab the UUID and the object on the drawing.

 

Would be perfect if I could skip the script part, as everytime the worksheet resets it asks me to execute the script.

 

In any case, thanks again.

 

 

Share this post


Link to post

@twk ,

   The Always Execute Scripts button will reset when VW re-launches, so you are not giving up your ability to block script execution forever. That was my biggest concern when I first ran into this dialog. Was afraid to press the button. I don't know if this is documented, I found it out by trial and error and I was very pleased to see the function resets at the end of a VW session. I feared it would open the door for scripts to execute forever. On a tangential note: it would be extremely helpful for this dialog to have a Help window to explain the scope of each button's functionality. 

 

HTH,

Raymond

Share this post


Link to post

@twk I use Debug List View from the Debug menu quite a bit.

 

vs.EnableDebugMenu()

This reveals the data attached to every object, which includes the UUID. I believe the UUID was necessitated by project sharing. The Debug menu also provides a viewer for the VS reference that comes in the SDK. It is autogenerated, so fairly definitive.

 

I'm unclear whether you are using the worksheet to process data or whether the worksheet is the end goal. If the former and you're creating the script for your own use, you can just use ForEachObject() with the criteria you are using for the worksheet report, and GetRField() to retrieve any data without dealing with the worksheet. 

 

If you're starting with a worksheet, as I guessed, using vs.GetWSCellFormulaN() on column 0 will return "=DATABASE({criteria})," which then lets you extract the criteria and pass it to ForEachObject(), eliminating the need to use the worksheet to step through objects.

 

@Pat Stanford and @MullinRJ, I would caution against any routines that try to store a handle. The handle is really just a pointer to a memory block — as objects get removed and added, the same handle can point to different objects or be null. If you know you're not creating any objects (including containers), you may be ok, but it's dangerous.

  • Like 1

Share this post


Link to post

Thanks, Josh. @JBenghiat

   Advice heeded. I've wanted to do this in the past only for investigative purposes, but never for anything practical. On one occasion (only one) I stored the string values of handles so I could sort them and do a binary search of the Symbol Library. It worked perfectly. Thanks for the warning.

 

Raymond

Share this post


Link to post
28 minutes ago, JBenghiat said:

I'm unclear whether you are using the worksheet to process data or whether the worksheet is the end goal. If the former and you're creating the script for your own use, you can just use ForEachObject() with the criteria you are using for the worksheet report, and GetRField() to retrieve any data without dealing with the worksheet. 

 

The aim is to have the worksheet as a sort of staging area for the filtering and sorting of windows/doors. -- (I'm creating an automatic window/door elevation tool for schematic scheduling)

 

Once the filtering was set I found there was no way for me to sift through the displayed subrow data and grab the object handles to create the elevation on the drawing. Now I can!

 

I did use the ForEachObject() on the db criteria, however any sorting that happened on the worksheet was difficult to replicate through my script. I'd rather have the sorting/grouping all done on the worksheet, and then have the graphical display just pull from the UUID on the worksheet.

 

Edited by twk

Share this post


Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


 

7150 Riverwood Drive, Columbia, Maryland 21046, USA   |   Contact Us:   410-290-5114

 

© 2018 Vectorworks, Inc. All Rights Reserved. Vectorworks, Inc. is part of the Nemetschek Group.

×
×
  • Create New...