Jump to content
Thomas K.

Collecting and writing data / Connectcad

Recommended Posts

Hi all,

 

is it possible to do the following via marionette/script:

 

- device generated via connectcad sits on design layer: media room

- the device name is: projector

- the script collects all devices with the same name (for example:projector)  and adds the design layer name to the device name, then it numbers all these devices

- result: projector-media room-01

 

is this possible or out of reach?

 

i am a newbie to all aspects of scripting and marionette but willing to learn...

Share this post


Link to post
Posted (edited)

With a little help it was possible to get the following to work:

 

get design layer name as prefix/suffix via script.

 

is there a way to insert this data between the name and the given number of the device:

(name)-(number)

must have: (name)-(design layer)-(number)

 

What i am looking for is one more criteria to manage the insert. therefor i think the criteria that handles the device name needs to be expanded to find out where the letters end and the number begin. (or where the (-) is located)

 

Thank you for your help!

Edited by Thomas K.

Share this post


Link to post

This is certainly possible with a script but might be out of reach with Marionette (I find it far faster to script something like this as it's faster for me to type everything out compared to the thousands of clicks a similar Marionette script would require).

 

I don't have ConnectCAD, so I don't know what the needed Records and Record Fields are, but what you're describing is easily achievable using a ForEachObject call to find objects with a matching record field (device name), on a target layer, then using GetRField to pull that information, Concat to put it into a single string, the using SetRField and ResetObject to reapply that string to the Device Name field.

 

I'm a little busy this week, but if you get me the record and field information for ConnectCAD devices, I can draft up a script for you.  It would even be feasible to make a GUI with a drop-down for device type and layer to help with selection.

Share this post


Link to post

@Jesse Cogswell here you go:

the script so far. usually the device name is like: projector-01.

in an ideal world it transfers to: projector-RoomA-01 cause it was drawn on design layer "RoomA".

It will be important that the script only functions on active devices or it will be possible to choose before running the script.

 

devName := GetRField( h, 'Device', 'Name' );

SetRField( h, 'Device', 'Name', Concat( devName, '/', currLayerName ));

devTag := GetRField( h, 'Device', 'Tag' );

SetRField( h, 'Device', 'Tag', Concat( devTag, '/', currLayerName ));

ResetObject( h );

 

 

currLayerName := GetLName(ActLayer);

criterion := Concat( '(((SEL=TRUE) & (R IN [''Device'']) & (L=''', currLayerName, ''')))' );

ForEachObject( callback, criterion );

RedrawAll;

Share this post


Link to post

Sorry for the delay, it's been a very busy week, but I have today and tomorrow off so I can take a look at this.  Based on your first post, it appeared that you wanted to have the script both append the container layer as well as an object index number, but in your last post, it looks like the device name already has an index number and you would be instead just add the design layer.  Either of these options are easily done, I just need to know which you are going for.

 

Next, I need to know how you plan to use the script as there are a couple of different options:

  • Does this command want to apply to ALL of the devices of a certain type in the drawing?  It would be relatively simple to write a script that generates a dialog box with a pop-up menu populated with all Device Names found in the drawing, allowing you to select one and click "OK" and have every one of those objects with the selected Device Name to have their Device Name updated with their layer and an index (unique to the layer or to the drawing as a whole).
  • I can also make it so that you can select a Device Name and a Layer, so that the command only runs on one device and one layer at a time.
  • Or I can make it only work on selected objects, regardless of Device Name or layer.  The perk of this is that it will work without a dialog box, simplifying the code quite a bit.

Final question, what is the Device Tag?  Is it different information than the Device Name (assuming so, since it's a different field).

 

 

Share this post


Link to post

Okay, done bashing in a script for you.  This script performs the following actions:

  1. Prompt the user to enter a starting value for the device index.  This allows you to add devices later and maintain the current index count.  If you always want to start the count at 1, then comment out line 96 (the line with the IntDialog function).  Also, if you want to change the prompt question to German, just edit the sIndexInput variable in the LoadPluginStrings procedure.
  2. Polls current layer using GetLName(ActLayer)
  3. Strips existing suffix from selected objects using the SubString function and "-" as a delimiter.  If you want a different delimiter, change the sDelimit variable in the LoadPluginStrings procedure.  So if you have something like "projector-media room-01", this will reset to just "projector".  This allows the script to be run on objects if they move to a different layer or change Device Names, or if they are copied and pasted from a device which already has a suffix.
  4. Builds an array of strings selected Device Names.  This allows multiple Device Names in the selection to be counted separately.
  5. Uses a FOR loop with the Device Name array to go through one Device Name at a time using ForEachObject to add the suffix to the device name and tag.  The current format is Device Name-Layer Name-Index (as in "projector-media room-01").  The script will add in a leading 0 to indexes below 10 (so an index of 9 will be changed to 09).

A COUPLE IMPORTANT CAVEATS:

  • The Device Name and Tag cannot contain a "-" (or whatever delimiter you choose) as the data will be stripped off.  So you can't have a device name be something like "mixing-console" as this will be shortened to "mixing" with the script.
  • The index will be determined by creation order.  VW always goes through order of creation when using ForEachObject, so the first Device with a Name of "projector" will be given an index of 1, with the next created Device getting an index of 2, etc.  So if you're wondering why the counting seems off in terms of where Devices are in relation to each other, that's why.
  • I do not have ConnectCAD, so I was only able to test it on a couple of dummy objects that I attached the Device record to.  It all worked properly in the testing, but let me know if there are any oddities that appear.

Code is pasted below.  Let me know if you need any help with it or if you want any help adding it to your permanent workspace.

 

PROCEDURE DeviceLayerSuffix;

{*	Polls selected Device objects on the active layer and appends the layer name and an index to the Name and Tag fields
	Developed by: Jesse Cogswell
	Date: 4/26/2021
	VW Version: 2021
	Revisions:
*}

VAR

	{Plug-in Strings}
	sIndexInput,sDelimit,sDevice,sName,sTag:STRING;
	
	{Other variables}
	currLayer,currDevice:STRING;
	devNames:DYNARRAY[] OF STRING;
	devCount,devIndex,devIndexOffset,i:INTEGER;
	blah:STRING;

PROCEDURE LoadPluginStrings;

{Loads plug-in strings into variables}

	BEGIN
		sIndexInput:='Enter Starting Index Number:';
		sDelimit:='-';
		sDevice:='Device';
		sName:='Name';
		sTag:='Tag';
	END;
	
PROCEDURE PollSelectedDeviceNames(h:HANDLE);

{Polls selected Devices and builds array of Device Names and strips current suffix}

	LABEL 99;

	VAR
	
		fullName,name:STRING;
		j:INTEGER;

	BEGIN
		fullName:=GetRField(h,sDevice,sName);
		name:=SubString(fullName,sDelimit,1);
		
		SetRField(h,sDevice,sName,name);
		ResetObject(h);
		
		IF(devCount=0) THEN
			BEGIN
				devCount:=1;
				ALLOCATE devNames[1..devCount];
				devNames[devCount]:=name;
			END
		ELSE
			BEGIN
				FOR j:=1 TO devCount DO
					BEGIN
						IF(devNames[j]=name) THEN GOTO 99;
					END;
				devCount:=devCount+1;
				ALLOCATE devNames[1..devCount];
				devNames[devCount]:=name;
			END;
		
		99: {End}
	END;
	
PROCEDURE UpdateDeviceName(h:HANDLE);

{Appends layer and index to given Device object's Name and Tag fields}

	VAR
	
		name,fullTag,tag,strIndex:STRING;

	BEGIN
		name:=GetRField(h,sDevice,sName);
		fullTag:=GetRField(h,sDevice,sTag);
		tag:=SubString(fullTag,sDelimit,1);
		
		IF(devIndex<10) THEN strIndex:=Concat('0',Num2Str(0,devIndex)) ELSE strIndex:=Num2Str(0,devIndex);
		
		SetRField(h,sDevice,sName,Concat(name,sDelimit,currLayer,sDelimit,strIndex));
		SetRField(h,sDevice,sTag,Concat(tag,sDelimit,currLayer,sDelimit,strIndex));
		ResetObject(h);
		
		devIndex:=devIndex+1;
	END;

BEGIN
	LoadPluginStrings;
	devIndexOffset:=1;
	devIndexOffset:=IntDialog(sIndexInput,'1');
	
	currLayer:=GetLName(ActLayer);
	devCount:=0;
	ForEachObject(PollSelectedDeviceNames,(SEL=TRUE) & (R IN [sDevice]) & (L=currLayer));
	
	FOR i:=1 TO devCount DO 
		BEGIN
			devIndex:=devIndexOffset;
			currDevice:=devNames[i];
			ForEachObject(UpdateDeviceName,(SEL=TRUE) & (R IN [sDevice]) & (L=currLayer) & (sDevice.sName=currDevice));
		END;
END;

Run(DeviceLayerSuffix);

 

  • Like 1

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