Jump to content
Developer Wiki and Function Reference Links ×

SetRField -> in more than one object


Recommended Posts

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!

Link to comment

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. 

Link to comment

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

  • Like 1
Link to comment
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

 

Link to comment

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. 

  • Like 1
Link to comment

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

 

Link to comment

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, '''))');

 

  • Like 1
Link to comment
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 🤗

Link to comment
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.

  • Like 2
Link to comment
  • 2 weeks later...

@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 by matteoluigi
  • Like 1
Link to comment

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.

×
×
  • Create New...