matteoluigi Posted October 6, 2020 Share Posted October 6, 2020 Hi, sorry for bothering again 😉 but, you have been really of help!!! thanks a lot!  i want to assign data to record fields of more objects. Is this possible?  Or am I right when I say, that: - I can assign only one single object to a handle - I can only assign an object to a handle by its (in the Vectorworks-file) unique name?  I`d prefer selecting more objects by database attributes and assign the data simultaneously to more than one object...  Somehow I think, that I want to much, now. 😔 Do I?  Thanks for you great help, anyway! Quote Link to comment
JBenghiat Posted October 6, 2020 Share Posted October 6, 2020 A handle is basically a block of memory where the data describing an object is stored. A handle VARIABLE stores the address of that memory. In other languages, we’d call that a pointer.  You can set a handle variable to refer to any object you want, and thus use it for SetRField. GetObject returns a handle value based on the object name. You can also iterate through a series of handles with the ForEachObject... routines or with the commands in the Document List Handling section. Quote Link to comment
Pat Stanford Posted October 6, 2020 Share Posted October 6, 2020 Josh is correct that you are going to need to use some kind of loop and assign the data to a single object at a time. The question is what is the easiest way to get the objects you want. Â Since you said you want to use "database attributes" I think you mean Criteria. If that is the case, then the ForEachObject procedure is your friend. Â Simplified psuedocode below: Procedure Demo; Procedure CalledProc(H1:Handle); Begin SetRField(H1, YourRecord, YourField); End Begin ForEachObject(CalledProc, YourCriteriaGoHere); End; Run(Demo) Create a sub procedure in your main procedure that takes a single handle. (CalledProc) Use ForEachObject to repeatedly call the sub procedure once for each object returned by the criteria (passing the handle as the object for CalledProc to process. Â HTH 1 Quote Link to comment
Sam Jones Posted October 6, 2020 Share Posted October 6, 2020 SetRField(H1, YourRecord, YourField);  Should be  SetRField(H1, YourRecord, YourField, YourValue); 1 Quote Link to comment
Pat Stanford Posted October 7, 2020 Share Posted October 7, 2020 @Sam Jones I did say it was pseudo code didn'tI.  ;-)  Thanks for the catch.   1 Quote Link to comment
matteoluigi Posted October 7, 2020 Author Share Posted October 7, 2020 15 hours ago, Pat Stanford said: Since you said you want to use "database attributes" I think you mean Criteria oh, excuse me, I have been translating directly from german. I want to select objects by record fields and not by their names and assign new data to other record fields.  Let's say, "get me all geometry(=rectangles, polygons,...)" who match "(('Apartment',Housing'=HNr) &('Apartment',Apartmentnumber'=ANr)) and assign the values for total-nr of rooms and total area to a record field in every room-geometry of this apartment...  Somehow it seems to me, that it isn't possible to assign an object to a handle which is chosen by a record field and not by its name... (and now I try to limit myself to assigning single objects to that handle 😉 ) sorry for bothering  Quote Link to comment
JBenghiat Posted October 7, 2020 Share Posted October 7, 2020 This may be a language barrier— but don’t you don’t assign objects to handles. Every object has a handle already, you just need different routines to find the value of that handle, and if desired, assign the handle to a variable.  Pat’s example with Sam’s correction, will do exactly what you want. Use the script editor to help build your criteria, which can include object type, record presence, and field value.  If I’m understanding your needs correctly, you would run ForEachObject twice with two different handler routines. The first would sum the areas into global variables. (You can use Count() to get the count). The next would store those values in the record field. 1 Quote Link to comment
matteoluigi Posted October 7, 2020 Author Share Posted October 7, 2020 Did I understand right, that I have to pack two procedures in one script?  like that:  Quote PROCEDURE DB;  VAR  Variables: *****  PROCEDURE CalledProc(HNDL:Handle); Begin SetRField(HNDL,'Wohnung','Whg-Typ’,’myvalue’); End;  BEGIN FOR HNR:=1 TO 6 DO BEGIN FOR WHGNR:=10 TO 15 DO BEGIN ZANZAHL := COUNT((('Wohnung'.'Haus-Nr'=HNR) & ('Wohnung'.'Whg-Nr'=AptNr)) ; ForEachObject(CalledProc, (('Wohnung'.'Haus-Nr'=HNR) & ('Wohnung'.'Whg-Nr'=WHGNR)); END; END; END; RUN(DB);  Quote Link to comment
JBenghiat Posted October 7, 2020 Share Posted October 7, 2020 Essentially, yes. If you wanted the same script to also calculate the area, you would add another sub-procedure and a ForEachObject after Count() that gets the area of the passed handle and adds it to a global variable.  A couple notes: SetRField will only accept field values as strings. Criteria can be finicky with variables, particularly as they need to be surrounded in single quotes. Using Concat to build the criteria string can be more reliable. In this example, I'm using a constant as the single quote character. You can also escape a single quote by typing it two times: '', which is more compact but potentially more confusing.  PROCEDURE DB; const kQC = Chr(39); VAR gZANZAHL :LONGINT; HNR :INTEGER; WHGNR :INTEGER; critSTRING :DYNARRAY[] OF CHAR; PROCEDURE CalledProc(HNDL:Handle); Begin SetRField(HNDL,'Wohnung','Whg-Typ', Concat(gZANZAHL)); End; BEGIN FOR HNR:=1 TO 6 DO BEGIN FOR WHGNR:=10 TO 15 DO BEGIN critSTRING := Concat('((', kQC,'Wohnung', kQC,'.', kQC,'Haus-Nr', kQC,'=', kQC, HNR, kQC,') & (', kQC,'Wohnung', kQC,'.', kQC,'Whg-Nr', kQC,'=', kQC, WHGNR, kQC,'))'); gZANZAHL := COUNT(critSTRING) ; ForEachObject(CalledProc, critSTRING; END; END; END; RUN(DB); critSTRING := Concat('((''Wohnung''.''Haus-Nr''=''', HNR, ''') & (''Wohnung''.''Whg-Nr''=''', WHGNR, '''))');  1 Quote Link to comment
matteoluigi Posted October 7, 2020 Author Share Posted October 7, 2020 26 minutes ago, JBenghiat said: SetRField will only accept field values as strings. Yes, I‘ve already solved that problem with three variables for one issue, the first is REAL or INTEGER, the second one is a STRING and the third one a ...CHAR variable, num2str converts my REAL or INTEGER into a STRING... works fine thanks a lot I will check out the rest tomorrow 🤗 Quote Link to comment
matteoluigi Posted October 8, 2020 Author Share Posted October 8, 2020 @JBenghiat packing single quotes into a string can be a lot of fun, i guess 😉 thank you Quote Link to comment
matteoluigi Posted October 8, 2020 Author Share Posted October 8, 2020 15 hours ago, JBenghiat said: SetRField(HNDL,'Wohnung','Whg-Typ', Concat(gZANZAHL)); here you have been using Concat instead of Num2Str, why not, seems much easier... Quote Link to comment
JBenghiat Posted October 8, 2020 Share Posted October 8, 2020 9 hours ago, matteoluigi said: here you have been using Concat instead of Num2Str, why not, seems much easier... Concat provides a fairly fast and universal conversion. In this case the value is an integer, so I'm not worried about decimal places, units, etc. And I didn't have to recall whether the value or the precision goes first the way I do with Num2Str. 2 Quote Link to comment
matteoluigi Posted October 20, 2020 Author Share Posted October 20, 2020 (edited) @JBenghiat @Pat Stanford I finally made it 😄 (with a week off vacation inbetween 😉 )   It works. I hope there is nothing strange in that script. I decided not to use the critstring. I didn't get it working, now without critstring the script works fine.  Thanks a lot for your help!  Quote PROCEDURE DB; VAR HNR:         INTEGER;   {House-Number} WHGNR:         INTEGER;   {Apartment-Number} ZNR:         INTEGER; ZANZAHL:      REAL;      {Number of Rooms from the actually looped apartment} WKANZAHL:      REAL;      {Number of half-rooms from the actually looped apartment} WHGSCL:         REAL;      {Type of apartment (= one-room two-room,...} WHGFL:         REAL;      {Apartment aera} WHGSCLSTR:      STRING;      {String of Type of apartment (= one-room two-room,...} WHGFLSTR:      STRING;      {String of Apartment aera} PROCEDURE CalledProc(HNDL:Handle); Begin    {SetRField(HNDL,'Wohnung','Whg-Typ', Concat('TEST'));}    {AlrtDialog(Concat('Handle: ',(Concat(HNDL))));}    SetRField(HNDL,'Wohnung','Whg-Typ', Concat(WHGSCLSTR,'-Zi-Whg'));    SetRField(HNDL,'Wohnung','Whg-Flaeche', Concat(WHGFLSTR,' m2')); End; BEGIN FOR HNR:=1 TO 6 DO BEGIN FOR WHGNR:=10 TO 50 DO BEGIN ZANZAHL := COUNT((('Wohnung'.'Haus-Nr'=HNR) & ('Wohnung'.'Whg-Nr'=WHGNR)) & (('Wohnung'.'Zimmertyp'='Zimmer') | ('Wohnung'.'Zimmertyp'='Arbeitszimmer') | ('Wohnung'.'Zimmertyp'='Wohnen')));    {Zählt, wieviele Zimmer in der Wohnung mit der Wohnungsnummer NR sind.} WKANZAHL := COUNT(('Wohnung'.'Haus-Nr'=HNR) & ('Wohnung'.'Whg-Nr'=WHGNR) & ('Wohnung'.'Zimmertyp'='Wohnküche')); WHGSCL:= ZANZAHL+WKANZAHL/2; WHGFL:=AREA(('Wohnung'.'Haus-Nr'=HNR) & ('Wohnung'.'Whg-Nr'=WHGNR)); WHGSCLSTR := Num2Str(1, WHGSCL);  {i needed to set the rounding for half rooms,...} WHGFLSTR := Num2Str(2, WHGFL); {i needed to set the rounding for the apartment-area} {AlrtDialog(Concat('Haus: ',HNR, ' ; Wohnung: ',WHGNR, ' ; ZI-NR: ',WHGSCL,';',WHGSCLSTR, ' ; Fläche: ',WHGFLSTR, ' m2: '));}          ForEachObject(CalledProc, (('Wohnung'.'Haus-Nr'=HNR) & ('Wohnung'.'Whg-Nr'=WHGNR))); END; END; END; RUN(DB);  Edited October 20, 2020 by matteoluigi 1 Quote Link to comment
Recommended Posts
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.