Jump to content

NextObj or NextSObj that works across layers?

Recommended Posts

I've always used h:=NextSObj or h:=NextObj in loops to run a script across a series of items.  While updating my scripts, I'm trying to get them to work across layers if layers are set to Show/Snap/Modify.  Selection works across the layers, reporting the number of selected items world across layers, but NextObj and NextSObj do not.  Is there another procedure I should be using?

Share this post

Link to post

The Next and Previous commands work with a concept called Lists.  You get a handle to an object in a list and then the Next will give you the handle to the next object in that specific list. Depending on exactly how you get the original handle the list will contain different objects.


FInLayer get a handle to the first object in the specified layer. NextObj on this list will get you the next object in the layer (Next is defined primarily by the order in which they were drawn, but Send Forward/Backward/Front/Back will change the stacking order and list order). NextSObj will get you the next selected object in the layer.


FinGroup get you a handle to the first object in a group (I think this also works in symbols), so the list is all of the objects that are in the group.


FIn3D gets a handle to the first 3D object in a specified object. The list is all of the 3D items that make up that object.


FinSymDef - The list is all of the objects that are part of the symbol.


FObject - The list is all of the objects that are in the same layer as the very first object in the drawing. I learned about this limitation the hard way. It seems as if this should let you iterate through the entire drawing, but you can't as soon as you try to step past the last object in the layer you will get a Nil handle and not be able to go any further.


FSActLayer - The list is all of the objects in the selected layer that come after the selected object. NextSObj will get you just the selected objects. NextObj will get you all of the objects.


FSObject - The list is all of the object after the selected object that are in the same layer as the selected object. See FObject


FSymDef - The list is all of the symbol definitions in the drawing.


There is no easy way to use NextObj to step through objects on different layers.


The work around is to use the ForEachObject command and an appropriate criteria to process the objects.


Ask if you need more information.



  • Like 1

Share this post

Link to post
10 minutes ago, Pat Stanford said:

The work around is to use the ForEachObject command and an appropriate criteria to process the objects.




Was wondering about ForEachObject, but since the function reference guide states that it's essentially the same as writing a NextSObj loop, I thought it might not work.  But I guess I will go test more of that.

Share this post

Link to post

I tend to use ForEachObjectInLayer() more than ForEachObject(). Some people like to think using <criteria> to sort the whole document, while I like to think of lists describing smaller sections of the document. Essentially you should be able to do either to get the same result, but with ForEachObject() you will be looking at everything drawn on all layers if you don't filter anything out. 


Since you got your problem working, you can ignore this for now, but you might want to give ForEachObjectInLayer() a try next time. ForEachObjectInList() is also quite useful if you have a targeted list you want to traverse, like the Symbol Definition List, and you already have a handle to an object in that list. One caveat, the ForEach... commands use a built in equivalent of NextObj(), and not PrevObj(). Lists will always be traversed this way.



Share this post

Link to post

One important point to remember when working with lists is that adding objects or deleting objects can be problematic.


If you start at the top of the list and delete the object, then NextObj will not find anything because the handle to the "first" object no longer exists. For deleting objects you are normally better off starting at the bottom and using PrevObj (or PrevSObj). Get a handle to the PrevObj before you do the delete.


If you are adding objects, you need to be careful that you don't create an infinite loop. Consider the following pseudo code.


Get first object

While Handle <> Nil

Create new object at bottom of list

Get next object

End While


You will never get to the bottom of the list because every loop through you add another object to the bottom of the list.


Just some lessons I learned the hard way.


Share this post

Link to post

This is all great info.  I've been using it over the past week to update a bunch of scripts.  Now, if they'd just fix the workplace limits after years of annoyance!

Share this post

Link to post



I used the information to write and test code. The searched layers were written in a text file. I noticed that not all layers were searched. Am I doing something wrong?


Procedure Test;


Var ...


PROCEDURE SelectThem(oLayer :HANDLE);

    hLayer := GetParent(oLayer);
    WHILE hLayer <> NIL DO BEGIN   
        tempLayerName := GetLName(hLayer);    
        hLayer := NextLayer( hLayer );
        WriteLn(concat('LayerName: ',tempLayerName));       




    ForEachObject(SelectThem, ALL)



Share this post

Link to post

ForEachObject handles objects in the drawing, not layers. The criteria you have specified should give you one entry in the text file for each object in the drawing. If you have layers without any objects then you will not have entries for those layers.


If you just want to make a list of the Layers in a drawing, just use FLayer and NextLayer.

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