Explode gives error on Dynamic block with Visibility states

Explode gives error on Dynamic block with Visibility states

GilesPhillips
Collaborator Collaborator
1,830 Views
11 Replies
Message 1 of 12

Explode gives error on Dynamic block with Visibility states

GilesPhillips
Collaborator
Collaborator

Hi All,

I have a routine that explodes blocks (for fabrication) using the object.explode method, and it fails on a particular block which happens to be a dynamic block with visibility parameters.

 

Public Sub exptest()
Dim ent As AcadEntity
Dim exp

For Each ent In ThisDrawing.ModelSpace
exp = ent.Explode

Next

End Sub

It fails with the error "Invalid Key" and the number -2145386465

 

Can anyone suggest why this is happening, and how I can work around it?

 

(File with offending block is attached.)

 

many thanks ..

 

G

ACad, MEP, Revit, 3DS Max
0 Likes
1,831 Views
11 Replies
Replies (11)
Message 2 of 12

norman.yuan
Mentor
Mentor

Can this blockreference be exploded manually? Does the drawing's ModelSpace ONLY contains AcadBlockReferences, nothing else?

 

You probably simplified your code while posting, but the code is to all Explode() against each entity in the ModelSpace. If the modelSpace contains AcadEntity that does not support Explode() (i.e. cannot be exploded), your code would raise exception. Did you step the code in debugging to confirm the error occurs when it is the dynamic block to be explode?

 

I downloaded your drawing, exploded the block manually and with code (see bellow), all worked as expected.

Option Explicit

Public Sub TestExplode()

 Dim ents As Variant
 Dim ent As AcadEntity
 Dim blk As AcadBlockReference
 Dim count As Integer
 
 For Each ent In ThisDrawing.ModelSpace
    If TypeOf ent Is AcadBlockReference Then
        Set blk = ent
        blk.Explode
        count = count + 1
    End If
 Next
 MsgBox "Exploded entity count: " & count
 
End Sub

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 3 of 12

GilesPhillips
Collaborator
Collaborator

Hi Norman,

 

You're correct, the code is a simplification, however it still demonstrated the issue. In the routine I'm running there are conditionals that will only explode the correct block, as you rightly surmise, otherwise I'd be exploding everything.

 

I've stepped through the code, and other valid blocks which don't have visibility states (yet are still dynamic) explode as expected.

 

Also the block definition has the 'explodable' property set.

 

With your code example below, is there a way to collect the exploded objects for further manipulation? Maybe its the act of putting the objects into an array that causes the error?

ACad, MEP, Revit, 3DS Max
0 Likes
Message 4 of 12

GilesPhillips
Collaborator
Collaborator
I've just quickly copied your code into my IDE and tried running it, and I'm still getting the invalid key error.

I'm running Acad2019 - for what it's worth.
ACad, MEP, Revit, 3DS Max
0 Likes
Message 5 of 12

Ed__Jobe
Mentor
Mentor

In your code, you dim ents but don't specify a type. It should be Variant. The variant type can accept an array, which is the return value of the Explode method. In Norman's code, he dim'ed ents as Variant but didn't use it. Just set ents like this:

Set ents = blk.Explode()

 

PS, I'm not sure if you know this, but the Explode method does not get rid of the original. It returns the blocks subentities in the same place, i.e. a copy.

Ed


Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
How to post your code.

EESignature

Message 6 of 12

GilesPhillips
Collaborator
Collaborator

Even when I dim ents as a variant I still get the error:

Dim ents
Dim ents as Variant
dim ents() as Variant

all generate the same error in the same way.

 

Strangely, if I were to change the visibility state, then try the code, then the block reference explodes without errors.

 

When I examine the block reference via a watch, I can see the name property starts off as the same as the effectivename but after I've changed the visibility state, it then becomes an anonymous block *U2

I feel this may have a bearing on why it crashes - perhaps it can't cope with a dynamic block which has it's name and effectivename properties the same?

 

edit: PS - aware of the not deleting the original bit - I've got code elsewhere in my main project that handles this bit 🙂

ACad, MEP, Revit, 3DS Max
0 Likes
Message 7 of 12

Ed__Jobe
Mentor
Mentor

I can't duplicate your error. I opened the dwg you supplied, copied the block 3 times and set the visibility state for each one and ran your code from post 1. No errors. Anonymous blocks are standard for dynamic blocks. That's why the EffectiveName property was introduced. It retains the original block name while an anonymous block is used to represent the altered entities.

Ed


Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
How to post your code.

EESignature

0 Likes
Message 8 of 12

GilesPhillips
Collaborator
Collaborator

That's this issue - or not.

 

it copes fine with dynamic blocks when they are defined as anonymous blocks - but when (for whatever reason) the name property is not anonymous - it fails.

 

To humour me, try opening the dwg, and running the script without manipulating the block at all - maybe put a breakpoint in and inspect the block references properties. 

 

The image attached is what I see.  -Note the Name property is the same as the EffectiveName - and then it crashes.

 

ACad, MEP, Revit, 3DS Max
0 Likes
Message 9 of 12

Ed__Jobe
Mentor
Mentor

That does replicate the error. It returns an err number you can trap for, -2145386465. Create your sub with a structured error handler and test for that error number. If it pops up, go to the block definition and get its contents. If you don't know how to do that post a reply. You can also test:

If blk.Name = blk.EffectiveName Then ...

 

Depending on the rest of your code, you may be able to use SendCommand "Explode " if they are equal.

Ed


Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
How to post your code.

EESignature

Message 10 of 12

GilesPhillips
Collaborator
Collaborator

Ed - I had written a workaround, similar to what you suggest, with a bit of code that changes the visibility state to another state - then back again - which then changes the name property of the block to an anonymous value, which allows exploding.

 

It's rare that this scenario actually occurs - which made it all the more puzzling when it actually did.


Code fragment here:

                If ExpBlkRef.IsDynamicBlock Then
                    If ExpBlkRef.EffectiveName <> ExpBlkRef.Name Then
                        Exploded = ExpBlkRef.Explode
                    Else
                        'need to tickle the visibility parameter to make the block name anonymous
                        'get dynamic properties
                        DynProps = ExpBlkRef.GetDynamicBlockProperties
                        Dim Q As Integer
                        Dim DProp As AcadDynamicBlockReferenceProperty
                        Dim ExgVal As Variant
                        For Q = 0 To UBound(DynProps)
                            'loop through dynamic properties
                            Set DProp = DynProps(Q)
                            If UBound(DProp.AllowedValues) > 0 Then
                            'until we find one with multiple allowed values - this is probably a visibility state
                                ExgVal = DProp.Value
                                'remember existing value
                                For P = 0 To UBound(DProp.AllowedValues)
                                'loop through allowed values
                                    If DProp.Value = DProp.AllowedValues(P) Then
                                        'once we've found an allowed value that the same as the existing value
                                        Report = Report & "Block: " & Ent.EffectiveName & " required state flipping prior to exploding." & vbCrLf
                                        If P < UBound(DProp.AllowedValues) Then
                                            DProp.Value = DProp.AllowedValues(P + 1)
                                            'set the actual value to a different one
                                        Else
                                            DProp.Value = DProp.AllowedValues(P - 1)
                                        End If
                                        'then set it back again
                                        DProp.Value = ExgVal
                                        Exit For
                                        'block name should now be anonymous
                                    End If
                                Next P
                            End If 'ubound(dprop.allowedvalues)
                        Next Q
                        Exploded = ExpBlkRef.Explode
                    End If 'effectivename<>name
                Else
                    Exploded = Ent.Explode
                End If 'is dynamic

 

ACad, MEP, Revit, 3DS Max
Message 11 of 12

Ed__Jobe
Mentor
Mentor

This is the default behavior of dynamic blocks. When you first insert it, it can use the default visibility state version that is stored in the block definition. Once you change visibility states, it creates another version of the block as an anonymous version. I tested this by creating a new dynamic block. I ran the method from the first post and the EffectiveName is the same as the Name and the method exploded it just fine. So you can't test for equal names. It must be something wrong with the block definition for the default visibility state. Try redefining the block to see if it fixes the block.

Ed


Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
How to post your code.

EESignature

Message 12 of 12

Ed__Jobe
Mentor
Mentor

I deleted the two constant/invisible attributes and I don't get the error any more. I also, tried it by making them visible and it works. Having them invisible AND constant is conflicting. You don't even know they are there.

Ed


Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
How to post your code.

EESignature

0 Likes