I will try to take a look at this in a bit, but I wanted to commend you on an excellent question! This is one of the best-asked, most complete, and concise posts I've ever seen on this forum. Kudos!
To be honest my post still was not complete: I forgot to mention that I've also created an SR for that and it lead into an SPR (1067857: API: how to check if block instance is nested). The SR is still open and I hoped to find some other ideas here because I know there a lot of very intelligent and helpful people posting here.
So I played with this a little bit...
A solution to your problem may run a little deeper. Sorry, I'm on 2017 so I couldn't use your file, but what I found was that nested block instances only exist once, no matter how many instances of the parent exist.
What I mean is, that if you insert Block A, then nest it inside Block B, you can make as many as you want of Block B and there is still only one instance of Block A. Of course, you can still make more independent instances of A, but only one instance of A will exist for all nested ones.
So the question is... How are you looking to use this information? Do you want the user to select something? Or iterate through things?
If you want to get the coordinates of every Block A, including ones that don't really "exist" because they're part of Block B, I think you may have to:
Inside your current Instances loop:
Get coordinates of TheInstance
Get all block definitions from SketchManager
For each TheDefinition
Get definition sketch
Get all block instances inside that sketch
Check if any block instance IS TheInstance
Get all SubInstance of TheDefinition
For each SubInstance
Modify SubInstance coordinates with TheInstance coords
I guess the above will have to be sort of iterative because Block B could be nested inside Block C, and so on to any number of levels.
Here, give this a look. Sorry, it's pretty bodgy. I re-used a couple of variables you were done with 'cuz I'm lazy.
This doesn't do everything in the pseudocode loop, but it does do what you requested in your original post....
It's sorta like reachin' one arm shoulder deep into a noodlin' hole, grabbin' holt to a tail, then reachin' the other arm in the next hole, grabbin' some whiskers, and then figgerin' out if ya got holt to the same dang mud cat.
' ' Precondition: ' (1) Drawing is open that contains at least ' one block definition with at least one ' block instance. ' (2) The block definition is selected in the ' FeatureManager design tree. ' ' Postconditions: None ' '---------------------------------------------------- Option Explicit Dim swApp As SldWorks.SldWorks Dim swModel As SldWorks.ModelDoc2 Dim swSelMgr As SldWorks.SelectionMgr Dim swFeat As SldWorks.Feature Dim swBlockDef As Variant 'SldWorks.SketchBlockDefinition Dim swBlockInst As SldWorks.SketchBlockInstance Dim nbrBlockInst As Integer Dim vBlockInst As Variant Dim BInstPT As MathPoint Dim BVInstPT As Variant Dim BloxDef As Variant Dim Blox As Variant Dim bloxInst As SldWorks.SketchBlockInstance Dim i As Long Dim itr As Integer Sub main() Set swApp = Application.SldWorks Set swModel = swApp.ActiveDoc Set swSelMgr = swModel.SelectionManager Set swFeat = swSelMgr.GetSelectedObject6(1, 0) Set swBlockDef = swFeat.GetSpecificFeature2 BloxDef = swModel.SketchManager.GetSketchBlockDefinitions Dim lastSketch As Sketch Debug.Print "Feature type: " & swFeat.GetTypeName nbrBlockInst = swBlockDef.GetInstanceCount Debug.Print "Number of instances of selected block: " & nbrBlockInst Debug.Print "Number of selections: ", swSelMgr.GetSelectedObjectCount2(-1) If nbrBlockInst > 0 Then vBlockInst = swBlockDef.GetInstances For itr = 0 To (nbrBlockInst - 1) Set swBlockInst = vBlockInst(itr) Set BInstPT = swBlockInst.InstancePosition BVInstPT = BInstPT.ArrayData Debug.Print "Name of block instances: " & swBlockInst.Name For Each swBlockDef In BloxDef If swBlockDef.GetSketch.GetSketchBlockInstanceCount > 0 Then Blox = swBlockDef.GetSketch.GetSketchBlockInstances For i = 0 To UBound(Blox) Set bloxInst = Blox(i) If bloxInst Is swBlockInst Then Set swFeat = swBlockDef Debug.Print "This is an embedded instance inside block definition " & swFeat.Name End If Next i End If Next swBlockDef Debug.Print Math.Round(BVInstPT(0) * 1000, 1) & " / " & Math.Round(BVInstPT(1) * 1000, 1) Next itr End If End Sub
really cool, that's what I needed.
What I want to do is to give the user a list of blocks / block instances in the active drawing document including some information of these blocks (position, scale factor, angle, ...).
You've made a very interesting observation "...that nested block instances only exist once, no matter how many instances of the parent exist...".
In that case I think I'll probably use your solution to just check whether an instance belongs to a nested block and then to exclude that from my list.
Thank you very much for your help.
blocks_nested_2017.zip 449.1 KB