Jump to content

Importing Symbol Folder Ressources (Callback Function Problem)

Recommended Posts



I'm trying to import a list of symbol folders with all contained symbols from a source file and this works fine using 'vs.BuildResourceListN2' and 'vs.ImportResToCurFileN'.
I'm having trouble figuring out how the required callback function for 'vs.ImportResToCurFileN' is supposed to work though.


The first time I run the script in Work_file_B it successfully imports the list of symbol folders from Source_file_A. 
When I run the script again Vectorworks prompts me to rename the folder.
I would like it to be replaced though (and all the contents as well).

The documentation for 'vs.ImportResToCurFileN' says that you need a return value of '1' from the callback function to handle this.
However, this does not seem to work. Maybe I'm misunderstanding what the callback procedure does?

I want to be able to make changes to symbols in a central file A. When I run the script in work files B,C,D,..... (that have the same symbol folders) I want to import and replace that set list 
of symbol folders and their content from file A to file B. This way I would be able to update all changes to symbols in the source file to all work files that run the script.


Would be great if someone could shed some light on the workings of the callback function.
i.e. Why does it have an input parameter but is not called with one?


Here is what my code looks like:

def callback(resName): # callback for 'vs.ImportResToCurFileN'-used in case of conflict (imported res already in cur file)
    ImportResCallback = 1 # '0' = Do not import ; 1' = replace ; '2' = rename
    return ImportResCallback

sourcePath = r"C:\Users\Username\My\Path\Source_File_A.vwx"
symFoldList = ["Symbols - Geometry", "Symbols - Text"]

importSymFoldListID, importSymFoldNumItems = vs.BuildResourceListN2(92, sourcePath, False)
importSymFoldDict = {}
for i in range(importSymFoldNumItems):
	importSymFoldName = vs.GetNameFromResourceList(importSymFoldListID, i + 1)
	importSymFoldDict[importSymFoldName] = i + 1

for foldername in symFoldList:
	vs.ImportResToCurFileN(importSymFoldListID, importSymFoldDict[foldername], callback)

vs.AlrtDialog(str(importSymFoldListID) + "\n" + str(importSymFoldNumItems) + "\n" + str(importSymFoldDict))


Source_File_A.vwx Work_File_B.vwx

Share this post

Link to post
Posted (edited)

Here are a few things I have figured out so far:


The callback in the form shown in the original post does seem to work but seems to behave differently depending on the type of resource that is being imported.


1. When vs.BuildResourceListN2 is used with object type selector 92 (symbol folder) the replacement in case of conflict works for the symbol definitions contained in the symbol folders but not for the symbol folders themselves.
This means if the imported symbol folder is already a resource in file B when I run the script again, Vectorworks prompts me to rename the imported symbol folder

(instead of replacing it at as the callback function says).

However, if I have made a change to any of the contained symbol definitions in file A that symbol definition will be re-imported and will replace the symbol definition

with the same name in file B. (In file B it will be placed in the manually renamed folder though).


2. When I use vs.BuildResourceListN2 with object type selector 16 (symbol definition) the replacement of symbol definition resources works as intended but

the imported symbol definitions will always be placed in the topmost resource directory of file B, which means the structure of the the resources
I have created in my file A by using symbol folders is lost. 

I have unsuccessfully spent some time trying to figure out a workaround by determining from the resource list from file A what symbol folder each symbol definition is in.

I could not figure it out though. The resource list gives only a list ID and the index of each contained item. Generating a handle from that with vs.GetResourceFromList

only works for resources in the current document. Without the handle I don't know how to determine the parent container (symbol folder).

3. Interestingly, when I use vs.BuildResourceListN2 with object type selector 51 (script palette) everything works exactly the way I would like it to.

I can run the script and import a script palette with all included scripts. Already existing scripts in file B are automatically replaced. This way i can make 

updates to scripts in file A, then run the script-update-script in file B and the existing, older version of the scripts in file B are automatically replaced with

the updated versions from file A. This also means, that if I add a new script to the script palette in file A, the script-update-script in file B will import that new script
without knowing of it by hardcoded stringname because it simply imports the whole palette with all its contents.
(I would really love for this to work with symbol folders and their contained symbol definitions.)


That the same callback function behaves this way for the 3 different types of objects is something I can't explain.


Here is my slightly updated (more generalized) version of the script. It is prepared to work with the 3 different object types (uncomment/comment):

def callback(resName): # callback for 'vs.ImportResToCurFileN'-used in case of conflict (imported res already in cur file)
	ImportResCallback = 1 # '0' = Do not import ; 1' = replace ; '2' = rename
	return ImportResCallback

sourcePath = r"C:\Users\Username\My\Path\Source_File_A.vwx"
#objType = 92 #symbol folder
#importInclList = ["Symbols - Geometry", "Symbols - Text"]
#objType = 16 #symbol definition
#importInclList = ["Symbol-1-Circle", "Symbol-2-Rectangle", "Symbol-3-Triangle", "Symbol-4-Circle-Text", "Symbol-5-Rectangle-Text", "Symbol-6-Triangle-Text"]
#objType = 49 #document script
#importInclList = ["Script-1", "Script-2", "Script-3"]
objType = 51 #script palette
importInclList = ["Scripts"]

importListID, importListNumItems = vs.BuildResourceListN2(objType, sourcePath, False)
importDict = {}
for i in range(importListNumItems):
	importSymFoldName = vs.GetNameFromResourceList(importListID, i + 1)
	importDict[importSymFoldName] = i + 1

for entry in importInclList:
	vs.ImportResToCurFileN(importListID, importDict[entry], callback)

vs.AlrtDialog(str(importListID) + "\n" + str(importListNumItems) + "\n" + str(importDict))

BTW,  don't mind the vs.AlrtDialog. I just like it better to view my outputs than vs.Message in most cases.

Edited by hybridobject

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.

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