Jump to content

Record format for a symbol within a symbol


Recommended Posts

Hello all...

I'm pretty sure I'm chasing after a lost cause here. I tried doing a search of past topis and didn't find a definitive answer, but here we go...

Is there a way to have a record format attached to a symbol control values for a symbol within that symbol.

For instace, I have a bunch of lighting instruments that each have a little thing denoting circuit and dimmer number in two different shapes for easy reading.

Every now and then, I'd like to make those shapes or the numbers look a little different. This requires going into each and every lighting symbol and changing the look. What I'd like to have is another symbol which is just the circuit/dimmer symbol as part of the lighting symbol.

This is great, except for the fact that updating a record format on the lighting symbol won't do anything to the circuit symbol as desired.

Am I making any sense here? Any help would be appreciated!!

[smile] Sam

Link to comment
  • Vectorworks, Inc Employee

Each symbol instance can have a unique record attached. But as your symbol instances are themselves within a symbol definition, I'm pretty sure that they can't be altered on an instance-by-instance basis of the parent symbol. From your description of the problem, it would seem that you suspect this already...?

Link to comment

I think we have a symbol with a record attached containing a symbol. You'd like to in some way change the interior symbol with changes made to the containing symbols record.

Is this correct? What is the nature of the changes you want to make to the interior symbol, and what are the values entered in the record? Could this be text linked to the record field?

Or are you looking for some way to replace an interior symbol with a different symbol?

Charles

Link to comment
  • 8 years later...

I think CCroft you are on point. This is also a struggle of mine ... see my post

I think it would be a useful thing to have, being able to micro manage a symbol through embedded symbols. If somebody can some up with a script for this, it would be great, sadly it's above my head as well for the moment.

Edited by sle7en7
Link to comment

I came up with this script which compiles fine but doesn't do what I want it to do... which is changing the record field string of the "ChildSymbol" to the "ParentSymbol". I know I'm doing something wrong...

PROCEDURE Impose_Record_Field;	
VAR ChildSymbol: HANDLE;
ParentSymbol: HANDLE;
ParentSymbolName: STRING;
MyRField: STRING;
BEGIN	MyRField:=GetRField(ParentSymbol,'WINDOW INFORMATION','WINDOW TYPE');
	SetRField(ChildSymbol,'WINDOW INFORMATION','WINDOW TYPE',MyRField); 
END;
RUN(Impose_Record_Field);

Edited by sle7en7
Link to comment

You never assign values to the handles for ChildSymbol and ParentSymbol, so there is no way for the script to know what objects you are trying to get and set information from.

Adding something like:

ChildSymbol:=FSActLayer;

ParentSymbol:=GetParent(ChildSymbol);

Should do it, but only if you can select the ChildSymbol before you run the script. If not, you will need to use some other method to get a handle to the ChildSymbol.

Link to comment

I hear you all. Thanks for all the responses first of all.

-Pat, I'll give it a try with that addition and let you know how it goes. Although, I guess that

some other method
should be when I select the ParentSymbol.

I mean in order to get a handle on the ChildSymbol do we need to go into every ParentSymbol (meaning; go into symbol edit mode for ParentSymbol and change the record field for the ChildSymbol and get out and do the next one) ? Is this the way to go about OR I'm fine by selecting one ParentSymbol and running the script...

So maybe this will work... which gets a handle on the child symbol by sharing the same record with the parent... or tries to...

PROCEDURE Impose_Record_Field;	
VAR; 
       ChildSymbol: HANDLE;
ParentSymbol: HANDLE;
ParentSymbolName: STRING;
MyRField: STRING;
BEGIN;
       SelectObj((INSYMBOL & INVIEWPORT & (L='DesignLayer') & (R IN ['WINDOW INFORMATION'])));
       ParentSymbol:=FSActLayer;
       ChildSymbol:=GetObject(IF(S IN [ParentSymbol] (R IN ['WINDOW INFORMATION']);
       MyRField:=GetRField(ParentSymbol,'WINDOW INFORMATION','WINDOW TYPE');
       SetRField(ChildSymbol,'WINDOW INFORMATION','WINDOW TYPE',MyRField);	 
END;
RUN(Impose_Record_Field);

Don't think this will work but, I guess you guys got the idea what I'm trying to do, also I'm starting understand it is much more of a needy process than I thought it would be so I think splitting the 2 symbols and grouping them seems to be the option for me to follow.

-Hippo

I left a response over at the post thread

Thanks a lot for the help though.

Link to comment

You could select the ParentSymbol instance in the drawing and get a handle to that. Then use that info to get a handle to the symbol definition then use FInSymbol to get a handle to the first object in the symbol definition. Step through the list until you find an object of Type Symbol.

As long as the ParentSymbol only contains a single ChildSymbol this should be a relatively easy way to get handles to both objects.

If you are interested in working on this, let me know and I can probably get you a better outline of how to do the steps necessary to find the ChildSymbol.

Link to comment

I am interested of course but the issue which I came to realization is (a bit late I must admit) the fact that I can't set 2 same ParentSymbols different Record fields and expect them to show up inside the ChildSymbol... But nevertheless it would be a useful script in future, so I'm in. The other issue we have is, I do have other symbols in the ParentSymbol but they don't have the record in debate attached to it.

But you are saying something along the lines of...

PROCEDURE Impose_Record_Field;	
VAR; 
       ChildSymbol: HANDLE;
ParentSymbol: HANDLE;
ParentSymbolName: STRING;
MyRField: STRING;
BEGIN;
       SelectObj((INSYMBOL & INVIEWPORT & (L='DesignLayer') & (R IN ['WINDOW INFORMATION'])));
       ParentSymbol:=FSActLayer;
       ChildSymbol:=IF 
FInSymbol((ActSymbolDef(GetSDName(ParentSymbol))):
R IN ['WINDOW INFORMATION']
ELSE: 
END;
       MyRField:=GetRField(ParentSymbol,'WINDOW INFORMATION','WINDOW TYPE');
       SetRField(ChildSymbol,'WINDOW INFORMATION','WINDOW TYPE',MyRField);	 
END;
RUN(Impose_Record_Field);

I'm guessing. Although that was far as I could get which I'm sure there is something wrong again, didn't give it a go yet.

I just realized you guys had this developer.vectorworks site you guys had where I was just wasting time in vectorlabs, the former seems way more helpful for scripting.

Anyhow Pat, let me know what you think about 2 ParentSymbols having different Record values and trying to reflect these into the same ChildSymbols. It's a tricky thing, but I would like to accomplish this even if we apply it as the same Record Field value to all the ParentSymbols.

Link to comment

Here is an outline of how to do the handle traverse.

I created a file with a record format named MyRecord with two fields, MyNumber and MyName. If you Attache Text To Record on the child symbol and attached the record to the parent, it will show up inside the parent when you run the script. Change the data on the parent and rerun the script and you will see the update happen.

Procedure Test;

Var	ParentHandle:Handle;
ChildHandle:Handle;
SymDefHandle:Handle;
H1:Handle;
SymName:String;

Begin
ParentHandle:=FSActLayer;
SymDefHandle:=(GetObject(GetSymName(ParentHandle)));

ChildHandle:=FInSymDef(SymDefHandle);

While GetType(ChildHandle) <> 15 do
	Begin
		ChildHandle := NextObj(ChildHandle);
	End;

SetRField(ChildHandle, 'MyFormat', 'MyName', GetRField(ParentHandle, 'MyFormat', 'MyName'));
SetRField(ChildHandle, 'MyFormat', 'MyNumber', GetRField(ParentHandle, 'MyFormat', 'MyNumber'));

Message(Date(2,2),'  ', GetType(ChildHandle), '  ', ChildHandle);
End;

Run(Test);

Link to comment

Ok Pat, I basically turned it into this but the one issue I'm having is the >In< special keyword which I get "reserved for future use" error. I mean, If I can rephrase the part which eliminates objects that do not contain 'MyRecord' then we can get some results. Do you think you can help me with this?

Also, we assign the H1 handle but never use it, is that for just in case we need it?

Really appreciate the help, thanks a lot.


{THIS CODE DOES NOT WORK. DO NOT USE IT.} 

Procedure Test;

Var	ParentSymbol:Handle;
ChildSymbol:Handle;
SymDefHandle:Handle;
H1:Handle;
SymName:String;

Begin
ParentSymbol:=FSActLayer;
SymDefHandle:=(GetObject(GetSymName(ParentSymbol)));

ChildSymbol:=FInSymDef(SymDefHandle);

While (GetTypeN(ChildSymbol) <> 15) And (NOT(ChildSymbol In ['MyRecord'])) Do {eliminates objects which are not symbols and do not have 'MyRecord' attached}	 
	Begin
		ChildSymbol := NextObj(ChildSymbol);
	End;

SetRField(ChildSymbol, 'MyRecord', 'MyName', GetRField(ParentSymbol, 'MyRecord', 'MyName'));
SetRField(ChildSymbol, 'MyRecord', 'MyNumber', GetRField(ParentSymbol, 'MyRecord', 'MyNumber'));

Message(Date(2,2),'  ', GetTypeN(ChildSymbol), '  ', GetSymName(ChildSymbol));
End;

Run(Test);

Link to comment

I don't think you can use IN the way you want to use it.

Take a look at this one. I have left my debugging messages and wait statements in so you can see how it runs.

I made a Function that will check and see if a record of a given name is attached to an object. This should probably be built-in, but is not as far as I know.

It is probably possible to get rid of the EndFlag and do the check in a single While statement, but my head exploded trying to figure it out and I took the cheaters way. Actually this is probably much cleaner to read later when you need to go back to this in six months.

I read a quote somewhere one time that by definition it is harder to debug a program than to write it. Therefore if you write a program as cleverly as you can, by definition, you are not clever enough to debug it.

Procedure Test;

Var	ParentSymbol:Handle;
ChildSymbol:Handle;
SymDefHandle:Handle;
NumberOfRecords:Integer;
SymName:String;
EndFlag:Boolean;


{********* Function to test if a record is attached to an object by the Record Name ************}
Function IsRecordAttached(ObjectHand : Handle; RecName : String) : Boolean;
var	ThisRecName:String;
	NumberOfRecords:Integer;
	ThisRecordNumber:Integer;

Begin
Message(Date(2,2),' Beginning of IsRecordAttached');
Wait(20);
	IsRecordAttached:=False;
	NumberOfRecords:=NumRecords(ObjectHand);
Message(Date(2,2),'  NumberofRecords  ',NumberOfRecords);
Wait(20);
	For ThisRecordNumber := 1 to NumberOfRecords Do
		Begin
			ThisRecName:=GetName(GetRecord(ObjectHand,ThisRecordNumber));
			If ThisRecName = RecName then IsRecordAttached:=True;
Message(Date(2,2),' ThisRecName ',ThisRecName);
Wait(20);
		End;
End;

{********* Begingin of the main program *************}
Begin
ParentSymbol:=FSActLayer;
SymDefHandle:=(GetObject(GetSymName(ParentSymbol)));

ChildSymbol:=FInSymDef(SymDefHandle);

EndFlag:=False;

While ((EndFlag = False) and (ChildSymbol <> Nil)) Do
	Begin
Message(Date(2,2),'  ',GetType(ChildSymbol));
Wait(20);
		If ( (GetType(ChildSymbol)=15) AND (IsRecordAttached(ChildSymbol,'MyRecord')) ) Then
			Begin
				EndFlag:=True;
			End
		Else
			Begin
				ChildSymbol:=NextObj(ChildSymbol);
			End;
	End;

SetRField(ChildSymbol, 'MyRecord', 'MyName', GetRField(ParentSymbol, 'MyRecord', 'MyName'));
SetRField(ChildSymbol, 'MyRecord', 'MyNumber', GetRField(ParentSymbol, 'MyRecord', 'MyNumber'));

Message(Date(2,2),'  ', GetTypeN(ChildSymbol), '  ', GetSymName(ChildSymbol));
End;

Run(Test);

Link to comment

Nice and true saying

by definition it is harder to debug a program than to write it.

I would rather demolish a building than doing a retrofit but the world doesn't work like that I guess. Thanks so much again Pat, I don't know how I can express my appreciation but hope you understand. I have stuff to take care of, so it will be a while until I fiddle with this. I'll get back to you.

Edited by sle7en7
Link to comment

This part is unsafe:

SetRField(ChildSymbol, 'MyRecord', 'MyName', GetRField(ParentSymbol, 'MyRecord', 'MyName'));

As you don't check if the handle is valid.

Also, remember that when you do change these fields, ALL symbols in the drawing will have the same change. You can't have unique values in subparts of a symbol.

Link to comment

YES! That script works to change the ChildSymbol's fields. The only thing I have to take care of is if I can make 2 ParentSymbols' have different values for a field and the ChildSymbol's will reflect those accordingly. Right now, when you run the code on a ParentSymbol and change the ChildSymbol's record field, then it alters the other ParentSymbols' ChildSymbol record value as well. It's tricky, and you do expect that to happen. I mean, you don't need to run the code at all, if you change any ChildSymbol's record field it is also changed in other ParentSymbol's as well. It doesn't act unique to its' ParentSymbol. Which is again, expected. Anyhow, at least we have this script at our hands for future use, I'm calling it a HURRAH! for us (mostly you PAT) and going back to manual labor.

Link to comment

If the ChildSymbol handle is Nil, you might get a run time warning, and the data would not be written to the Child Symbol because there is no handle to it.

If the Parent Symbol is Nil, you would probably write bad data to the Child Symbol because the GetRField would fail when getting the Parent data. You might also get a run time warning.

In this particular case, I don't think you have a problem. Since we are using ParentSymbol to get the ChildSymbol, You can't get a valid handle to the ChildSymbol unless the ParentSymbol is defined.

There is always more error checking that can be done. ;-)

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