Jump to content

Adding new attribute to each block in this drawing


Recommended Posts

Posted

Hi all,

 

How can I search thisdrawing for blocks wich don't have an attribute named "Handle_ID". If they don't, then add a tribute in the block.

 

I got this:

 
Sub test2()
Dim attributeObj As AcadAttribute
Dim BlockObj As AcadBlockReference
Dim BlockObj2 As AcadBlock

   For Each Elem In ThisDrawing.ModelSpace
       With Elem
           If StrComp(.EntityName, "AcDbBlockReference", 1) = 0 Then
               If ((Elem.HasAttributes) And (Left(Elem.EffectiveName, 3) = "G_B") Or (Left(Elem.EffectiveName, 3) = "G_E") Or _
               (Left(Elem.EffectiveName, 3) = "G_I") Or (Left(Elem.EffectiveName, 3) = "G_L")) Then
               Handle = Elem.Handle
               Dim InsertionPnt(0 To 2) As Double
               InsertionPnt(0) = 0#: InsertionPnt(1) = 0#: InsertionPnt(2) = 0#

               Set BlockObj = Elem
               Set BlockObj2 = BlockObj [color=red]<-FIRST ERROR)[/color]
               Set attributeObj = BlockObj2.AddAttribute(1, acAttributeModeInvisible, "HANDLE_ID", InsertionPnt, "HANDLE_ID", Handle) [color=red]<-SECOND ERROR)[/color]

               ThisDrawing.SendCommand "_ATTSYNC" & vbCr & "NAME" & vbCr & Elem.EffectiveName & vbCr

               End If
           End If
       End With
   Next Elem
End Sub

 

Can you guys help me? :)

Posted

Because of the AcadBlockReference and AcadBlock are two different objects

You can get AcadBlock from Block collection like this:

Set BlockObj2  = ThisDrawing.Blocks(BlockObj.Name)

or

Set BlockObj2  = ThisDrawing.Blocks(BlockObj.EffectiveName)

for dynamic block

HTH

 

~'J'~

Posted
Because of the AcadBlockReference and AcadBlock are two different objects

You can get AcadBlock from Block collection like this:

Set BlockObj2  = ThisDrawing.Blocks(BlockObj.Name)

or

Set BlockObj2  = ThisDrawing.Blocks(BlockObj.EffectiveName)

for dynamic block

HTH

 

~'J'~

 

Thanks for your response. But can you put it in a working procedure wich also checks if the Handle_ID is present? And if not, it's added to the block? :oops:

Posted
Thanks for your response. But can you put it in a working procedure wich also checks if the Handle_ID is present? And if not, it's added to the block? :oops:

 

You need to check on existing attribute name (TagString)

instead of check on Handle

Just iterate trough attributes - see Gettributes in the help file

There are a lot of code examples on this forum too :)

From other hande you can use Selection with filter instead

of looping trough all drawing objects

Sorry I haven't enough time to write complete solution for you now

 

~'J'~

Posted
Thanks for your response. But can you put it in a working procedure wich also checks if the Handle_ID is present? And if not, it's added to the block? :oops:

Ok, I have a few minutes so I've tryed to write it quick and dirty

Just I can't test it without dynamic blocks though

Hope this will get you some idea

 

Option Explicit

Sub test2()
   Dim attributeObj As AcadAttribute
   Dim BlockObj As AcadBlockReference
   Dim BlockObj2 As AcadBlock
   Dim elem As AcadEntity
   Dim Handle As String
   Dim blockName As String
   Dim collNames As New Collection
   Dim i As Integer
   Dim j As Integer

   'collect just unique block names into collection
   For Each elem In ThisDrawing.ModelSpace
       If (TypeOf elem Is AcadBlockReference) Then
           Set BlockObj = elem
           With BlockObj
               If ((.HasAttributes) And (Left(.EffectiveName, 3) = "G_B") Or (Left(.EffectiveName, 3) = "G_E") Or _
                   (Left(.EffectiveName, 3) = "G_I") Or (Left(.EffectiveName, 3) = "G_L")) Then
                   On Error Resume Next    ' to bypass error on duplicate name
                   collNames.Add .EffectiveName, .EffectiveName
               End If
           End With
       End If
   Next elem

   Dim InsertionPnt(0 To 2) As Double
   InsertionPnt(0) = 0#: InsertionPnt(1) = 0#: InsertionPnt(2) = 0#

   ' iterate trough collection
   For i = 1 To collNames.Count
       blockName = collNames.Item(i)

       Set BlockObj2 = ThisDrawing.Blocks(blockName)

       Set attributeObj = BlockObj2.AddAttribute(1, acAttributeModeInvisible, "New prompt", InsertionPnt, "NEW_TAG", "0")
       With ThisDrawing
           .SetVariable "CMDECHO", 0
           .SendCommand "_ATTSYNC _N " & blockName & vbCr
           .SetVariable "CMDECHO", 1
           .Regen acAllViewports
       End With
   Next i
   ThisDrawing.Regen acAllViewports
   Dim ftype(1) As Integer
   ftype(0) = 0: ftype(1) = 2
   Dim fdata(1) As Variant
   fdata(0) = "INSERT"
   ' iterate trough collection again
   For i = 1 To collNames.Count
       blockName = collNames.Item(i)
       fdata(1) = "`*," & blockName
       Dim oSset As AcadSelectionSet
       
       With ThisDrawing.SelectionSets
           While .Count > 0
               .Item(0).Delete
           Wend
           Set oSset = .Add("$Blocks$")
       End With
       
       oSset.Select acSelectionSetAll, , , ftype, fdata
      
       For Each elem In oSset

           Set BlockObj = elem
           Handle = elem.Handle
           Dim atts() As AcadAttributeReference
           Dim att As AcadAttributeReference
           
           With BlockObj
               atts = .GetAttributes()
               For j = 0 To UBound(atts)
                   Set att = atts(j)
                   If att.TagString = "NEW_TAG" Then
                       att.TextString = CStr(Handle)
                       '//Exit For
                   End If
               Next j
               Exit For
           End With
           
       Next elem
       
       '//oSset.Delete
       
   Next i

   MsgBox "Get to work!"

End Sub

 

~'J'~

Posted

Thnx! I also tried something and it works also... I guess i'm not so bad at it at all :wink:

 

Sub test2()
Dim attributeObj As AcadAttribute
Dim BlockObj As AcadBlock
Dim InsertionPnt(0 To 2) As Double
InsertionPnt(0) = 0#: InsertionPnt(1) = 0#: InsertionPnt(2) = 0#
For Each Elem In ThisDrawing.ModelSpace
       With Elem
           If StrComp(.EntityName, "AcDbBlockReference", 1) = 0 Then
               If ((Elem.HasAttributes) And (Left(Elem.EffectiveName, 3) = "G_B") Or (Left(Elem.EffectiveName, 3) = "G_E") Or _
               (Left(Elem.EffectiveName, 3) = "G_I") Or (Left(Elem.EffectiveName, 3) = "G_L")) Then
                   Handle = Elem.Handle
                   Found = False
REDO_ACTION:
                   Attributen = Elem.GetAttributes
                   For Count = LBound(Attributen) To UBound(Attributen) 'Read attributes from block
                           If Attributen(Count).TagString = "HANDLE_ID" Then
                               If Attributen(Count).TextString = "" Then
                                   Attributen(Count).TextString = Handle
                               End If
                           Found = True
                           Exit For
                       End If
                   Next Count

                   If Found = False Then
                       Set BlockObj = ThisDrawing.Blocks(Elem.EffectiveName)
                       Set attributeObj = BlockObj.AddAttribute(1, acAttributeModeInvisible, "HANDLE_ID", InsertionPnt, "HANDLE_ID", "")
                       attributeObj.Layer = "Attrib-Hidden"
                       ThisDrawing.SendCommand "_ATTSYNC" & vbCr & "NAME" & vbCr & Elem.EffectiveName & vbCr
                       ThisDrawing.Regen (acActiveViewport) 'NODIG??
                       GoTo REDO_ACTION
                   End If

               End If
           End If
       End With
   Next Elem
End Sub

 

Except it look a lot simple then yours :P

Posted

Grenco,

 

This thread appears to relate directly to the thread “Whats Up with the Handle?”

 

The issues discussed in these threads, as well as the one RK McSwain posted, will be important to anyone attempting to coordinate an AutoCAD drawing to an outside database.

 

I will say the process posted above is a clever way to resolve a non persistent handle issue, but it is discouraging to accept that such an issue actually exists. The customization docs have always stated that Handles are unique, and remain constant, within a document.

 

I don’t doubt your statement about a coordination break between drawing and database; what would provide some comfort, however, is if there was some common element with the drawings in which this break occurred.

 

Is there anything different between where this did and did not occur?

Posted

That http://discussion1.autodesk.com/forums/thread.jspa?threadID=729961 link, despite the rather antagonistic undertone (or should I say overtone) is pretty informative, and lists a couple of possible causes for Handle change.

 

WBLOCKing is certainly a likely candidate, and could be addressed without too much difficulty.

 

Also:

 

RECOVERing may be another possible cause, though I’d be a bit annoyed if that did actually change the Handles.

 

If the re-Handle-ing isn’t document wide, i.e., only a subset of the drawing is changing, then Cut and Paste, or even Lisp/VBA/etc., procedures may need examination.

Posted

The only thing I know is that all handles in a drawing are changed but I can't reproduce it. It doesn't happend often. Only with some of my colleagues. Probably when they are doing something unusual.

 

I'm busy reconstructing the VBA-routine because it's slow with dynamic blocks and some features aren't working properly. We also thought it was the cause of empty databases. Except, it happend to me too!

 

If you look at the attached image you can see how my database is filled. I ONLY ADD a record to it when there is a new item (new handle) in my drawing.

 

The records with Note_2 = !!DELETED!! are the items with a handle (unique Object_ID in Database) wich isn't found in the drawing. So if I delete an item, the database sets the Note_2 to !!DELETED!!. You can see that for the first record (Object_ID=1A83B) the Type and Group are "P" and "355". This is the original item with his original Handle.

 

Some how the handle is changed to 1C431. I haven't copied, cut, paste, wblock or what so ever. It's a unchanged block in the same drawing. When my database is updated, the changed handle is for my database seen as new, so it adds it to itself. You can find "P" and "355" back in this record because these are added according the attributes of that particular block. This item is only once in my drawing offcourse.

 

As you can see, this happend for every item and its added again to the database. The other information (descrip, supplier type_dim etc) is added in the database so this data isn't added to the new record.

 

Before I was rebuilding the routine we didn't know the cause of the problem because the records where instantly removed from the database. Now I know the problem (changed handle), so I want to make a back up of each item its handle by adding it to his own attributes and in the database. Now I can check if there is a changed handle. If there is, the original record is replaced by the new handle.

 

If I build it correct, no more empty databases, but there is one thing left... Why/when were my handles changed?? :?

Capture.jpg

Posted

You have put me on alert. I’ve designed a game plan based on an immutable HANDLE but will now watch it closely.

 

Quite frankly, I’m hoping to keep it as such based on a few of the issues raised by Tony Tanzillo in the Autodesk.Discussion link. Most predominantly, the ability to copy objects without duplicating IDs. An important issue if additional work is performed subsequent to initial database construction.

 

I did think of one thing you could check with the Handle-Attribute methodology. Does the mere act of adding an additional attribute to a Block/BlockReference change an entity’s handle? That may be likely with the Block; probably not so much with the references.

Posted
You have put me on alert. I’ve designed a game plan based on an immutable HANDLE but will now watch it closely.

 

Quite frankly, I’m hoping to keep it as such based on a few of the issues raised by Tony Tanzillo in the Autodesk.Discussion link. Most predominantly, the ability to copy objects without duplicating IDs. An important issue if additional work is performed subsequent to initial database construction.

 

I did think of one thing you could check with the Handle-Attribute methodology. Does the mere act of adding an additional attribute to a Block/BlockReference change an entity’s handle? That may be likely with the Block; probably not so much with the references.

 

If I correctly understand what you're saying. :oops:

 

The AddAttribute action is added after I discoverd that my handle was changed. Even tough, when I use addattribute, the handle of the block stays the same.

 

Just to be sure: i'm not interested in the handle of the attribute. I'm interested in the block his handle wich contains several attributes. :)

Posted

Actually, that part of the post wasn’t so much a possible cause of the Handle change as something to investigate as you go forward.

 

I’m not exactly sure what constitutes a “new” object in AutoCAD. For instance, a circle could be created and acquire a handle. It can be moved, perhaps even scaled, yet the handle would remain constant. If a section of the circle were trimmed, however, that circle may constitute a new entity (ARC), thus acquiring a new Handle.

 

A Block object may consider itself “changed” as soon as an element is added or subtracted, thus acquiring a new Handle.

 

It sounds like you are only interested in Block References, though, so what happens at the Block level may not matter.

 

I guess the bottom line is if I plan to employ a Handle based coordination system I should have a comprehensive understanding of what AutoCAD does with the handles behind the scenes.

 

It may be beneficial to set up some persistent, Event Monitor that I can use for a trial period - to see how and when handles are modified. I suspect it will be a bit of a pain to work with, but could be quite informative.

Posted

Well, after setting up a down and dirty routine, I can say that a circle trimmed to an arc does not cause an immediate Handle change. Apparently handles are an "Object" based property and, regardless of what else changed, an arc is still an object. :)

Posted

What do you think of my solution?

 

Adding Block his handle to a seperate attribute in the same block, so I can compare the Block.Handle with the Attribute wich has the original Handle value. If these values aren't equal, I change the record in my database and change it in the new handle. I also change the original Handle value in the attribute to the new handle. This way I can keep the unique handle in my database up to date with the handle in my drawing.

Posted
What do you think of my solution?

 

Adding Block his handle to a seperate attribute in the same block, so I can compare the Block.Handle with the Attribute wich has the original Handle value. If these values aren't equal, I change the record in my database and change it in the new handle. I also change the original Handle value in the attribute to the new handle. This way I can keep the unique handle in my database up to date with the handle in my drawing.

 

That process seems sensible enough, though I suppose it would depend on exactly how and why handles change.

 

If in the course of a day’s work tagged elements are copied, along with the drawing suffering a handle “update”, then none of the elements would have matching handle/attribute. There may be problems determining which element was the original and maintaining a coordinated outside database.

 

If the handle change could be determined to only happen at drawing-open, then coordinating the outside database should probably be relegated to that time.

Posted

My plan was when there are object added to a drawing (acaddocument_objectadded(ByVal object As Object)) to fill in the attribute with the new object's handle value. This way when I copy/paste (or other commands), the attribute with handle gets refreshed by his own value and not the older (when pasting) value.

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
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
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.

×
×
  • Create New...