Author Topic: Redefine Block with VBA..  (Read 17544 times)

0 Members and 1 Guest are viewing this topic.

hardwired

  • Guest
Redefine Block with VBA..
« on: March 19, 2008, 12:04:49 PM »
Hi,

Have a program that creates a block, add a table of attiributes and then inserts it, will all works spot on now (thanks to all who helped me before)...

...but if there is already a block reference of the same type in the drawing i want to redefine it with the new information that the user enters NOT add to it, which what it seems to do...

In the program, when the userform loads, it checks if the block exists and populates the userform with its attribute values, which works fine, and this allows the user to edit the information in the block and not start over each time, but when the user finishes the program and the block is inserted, its an almagamation of the existing and new information..

Any ideas?

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: Redefine Block with VBA..
« Reply #1 on: March 19, 2008, 02:15:05 PM »
If there is already a block reference in the drawing, you can do a few different things ...

a) rename the old block reference
b) programmatically delete all objects in the old definition
c) delete the existing reference(s) and purge the drawing

Of the 3, b sees to be the most desirable
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

Bob Wahr

  • Guest
Re: Redefine Block with VBA..
« Reply #2 on: March 19, 2008, 02:18:07 PM »
don't have the time to test it right now, but try a

for each blkref in thisdwg.mspace
  if blkref.name = "x" then
    blkref.update
  end if
next blkref

Arizona

  • Guest
Re: Redefine Block with VBA..
« Reply #3 on: March 19, 2008, 03:28:31 PM »
Hi,

Have a program that creates a block, add a table of attiributes and then inserts it, will all works spot on now (thanks to all who helped me before)...

...but if there is already a block reference of the same type in the drawing i want to redefine it with the new information that the user enters NOT add to it, which what it seems to do...

In the program, when the userform loads, it checks if the block exists and populates the userform with its attribute values, which works fine, and this allows the user to edit the information in the block and not start over each time, but when the user finishes the program and the block is inserted, its an almagamation of the existing and new information..

Any ideas?

Are the users simply changing attribute information or is the graphic itself changing?
Why redefine the block definition?

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: Redefine Block with VBA..
« Reply #4 on: March 19, 2008, 04:17:40 PM »
try this function before adding your data to the block

Code: [Select]
Function CleanoutBlock(currentBlock As AcadBlock)
    Dim blkItem As AcadEntity
    For Each blkItem In currentBlock
        blkItem.Delete
    Next blkItem
End Function
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

hardwired

  • Guest
Re: Redefine Block with VBA..
« Reply #5 on: March 20, 2008, 05:58:32 AM »
Hi,

I have tried this in my program so far....

(The SSetX is a SelectionSet it creates on UserForm loading, to check for existing blocks..

Code: [Select]
'Redefine current block info if chart exists..
Dim BlK As AcadBlockReference
Dim EntX As AcadEntity

If SSetX.Count > 0 Then
    For Each BlK In SSetX
        If BlK.Name = "Fixings_Chart" Then
            For Each EntX In BlK
                EntX.Delete
            Next EntX
        End If
    Next BlK
End If

......it flags an error says object doesn't support this method, which obviously is refereing to the BlockRef, which if i want to access entities in it, should be a Block not a BlockRef....so where do i go from here?


I also, like Keith's Function:

Code: [Select]
Function CleanoutBlock(currentBlock As AcadBlock)
    Dim blkItem As AcadEntity
    For Each blkItem In currentBlock
        blkItem.Delete
    Next blkItem
End Function

.....but how do i call the function from the code just before i add the new data?

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: Redefine Block with VBA..
« Reply #6 on: March 20, 2008, 08:31:12 AM »
I don't know your exact situation, but your code has some potential issues that perhaps we can resolve.

Using the code you provided, you are evidently selecting all of the blocks in the drawing and then iterating through them all. If you want to edit the block references, you have to edit the block definition. If you edit the block definition, it wil automatically reflect in all of the block references, thereby negating the need to iterate through all of the block references in the drawing. Using the code you provided, if it worked, it would redefine the same block over and over again for each instance the block was inserted in the drawing. This is not necessary and is needless repetition of the same procedure.

Earlier you stated that you have code that puts items into the block, but you didn't have code to remove items from the block. The code I provided removes all items from the block you pass as an argument to the function .. but you have to pass the AcadBlock not the AcadBlockReference.

download the module I posted in the previous thread and import it into your project (right click in the project explorer and click import file) then add this code to your form load event
Code: [Select]
Dim Blk As AcadBlock

If acBlock.BlockExists("Fixings_Chart").Exists = True Then
  Set Blk = ThisDrawing.Blocks.Item("Fixings_Chart")
  CleanoutBlock Blk '<-- call the CleanoutBlock function here
End If
'Add code here to put the new entities in the block
'Blk.Addxxx functions to add the entities as needed

Add this code to your form as a new function

Code: [Select]
Function CleanoutBlock(currentBlock As AcadBlock)
    Dim blkItem As AcadEntity
    For Each blkItem In currentBlock
        blkItem.Delete
    Next blkItem
End Function

You could provide a little more code and we can give you pointers about where you are going wrong.
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

hardwired

  • Guest
Re: Redefine Block with VBA..
« Reply #7 on: March 20, 2008, 09:06:55 AM »
Thanks Keith, for taking the time out for this (and to everyone else for that matter)..

I have done exactly as you said and the new instance it inserts looks exactly how it should, not a mix of the old elements and the new.....the only thing is that all existing block inserts haven't changed and still look as they did before running the program again..



Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: Redefine Block with VBA..
« Reply #8 on: March 20, 2008, 09:11:49 AM »
Thanks Keith, for taking the time out for this (and to everyone else for that matter)..

I have done exactly as you said and the new instance it inserts looks exactly how it should, not a mix of the old elements and the new.....the only thing is that all existing block inserts haven't changed and still look as they did before running the program again..


Then you have something else going on ... have these perhaps been edited and saved as dynamic blocks? if so, they may not be updated properly ... or maybe you should regen all views
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

hardwired

  • Guest
Re: Redefine Block with VBA..
« Reply #9 on: March 20, 2008, 09:41:19 AM »
ah, if i regen then the graphical nature of the block is updated but not the attributes, if the user removes the number of attributes from the list then these still remain in the blocks, so that the table has the correct number of rows, but not the correct number of attributes (some overrun down past the extents of the table)..

I would post my full code but it exceeds the character limit for each post. Maybe, it would help anyway, post the code in sections on different posts..

Bryco

  • Water Moccasin
  • Posts: 1882
Re: Redefine Block with VBA..
« Reply #10 on: March 20, 2008, 10:28:51 AM »
attributes don't update.
It's easier to find each blockref and replace it with  a new one, matching the properties first

hardwired

  • Guest
Re: Redefine Block with VBA..
« Reply #11 on: March 20, 2008, 11:30:00 AM »
But surely, using the function Keith supplied, which deletes all entities in the block, there wouldn't be any attributes that won't update, so the only the new attributes will be present and shown?

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: Redefine Block with VBA..
« Reply #12 on: March 20, 2008, 11:44:50 AM »
Ah .. now I more fully understand the nature of your request ...

To my knowledge, the only method to update the attributes if you change the number of the attributes, is to attsync the block references. You could alternatively insert the blocks with VBA and then grab the attributes and modify them.

In VBA you can only attach attributes to a block, modelspace or paperspace, there is no addattributereference method to add a reference to an attribute in the block.

Presuming you are adding the attributes back to the block with AddAttribute, you must then go through each AcadBlockReference, grab the origin, scale, rotation, layer etc that you want to keep the same, then insert a new block with the same information and then update the attributes as needed.
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

hardwired

  • Guest
Re: Redefine Block with VBA..
« Reply #13 on: March 20, 2008, 12:15:39 PM »
oh right, so even adding:

Code: [Select]
' Checks if table exists and redefines (clearsout) the block of all data..
Function CleanoutBlock(currentBlock As AcadBlock)
    Dim blkItem As AcadEntity
    [color=red]Dim blkAtt As AcadAttribute[/color]
    For Each blkItem In currentBlock
        blkItem.Delete
    Next blkItem
[color=red]    For Each blkAtt In currentBlock
        blkAtt.Delete
    Next blkAtt[/color]
End Function
...to your function won't work?

I tried it, but still nothing. All i want to do is delete the attributes (and all block entities) from the block, so its empty and then put back all the stuff the program does in the block, so if there any blocks the user has inserted anywhere, the blocks will reflect what the user chooses in the program..

Here's a brief lowdown an what the program does: It creates a fixings chart / table from user defined data (the user can also pick a fixing from an inserted block in a drawing and it will enter the block name in the textbox for that chosen fixing. There are 10 possible rows to create, each one selected / deselected by checkbox. When run, it adds two types of attribute for each row to the table / chart, one is the reference number for the item (a constant) (ie: FX1, FX2 etc), the second is the description (a normal) which the user can edit in the text boxes on the userform. When loaded (userform_Initialise), the program searches for any existing insert of the table and populates the userform with that data, so the user can edit / add to / delete from etc.. and when completed, it inserts the block (if new / no existing table was found) or just updates the existing..

Now with my code (and Keith's addition), it works 99% but just won't delete the existing normal attributes (it DOES however delete the constant attributes (the reference ones)..

I thought, as it deletes these constant attributes (all attributes in this program created by Block.AddAttribute by the way) it would also delete the normal ones too, but it doesn't. Is this because of the 'constant' property of the attribute?


Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: Redefine Block with VBA..
« Reply #14 on: March 20, 2008, 01:51:43 PM »
You are not understanding ....

a) When you edit a block with VBA, you only edit the attributes in the block table. It does not affect the block references

b) If you use attsync after using your command, all of the attributes that don't exist in the block, but are attached to the block reference will be removed from the block reference and all attributes in the block, but not in the block reference will be added to the block reference.

c) VBA does not have a mechanism to do this with code, so, you have to create your own.

d) The code I posted earlier does in fact delete the attributes from the block, but not the block reference. There is no method to do that in VBA

You can do one of the following:

1) Execute attsync at the command line after running your program
Quote from: AutoCAD command line
Command: attsync
Enter block name or ? for list <select block>: Fixings_Chart
Command:

2) Delete all occurences of Fixings_Chart in the drawing and replace them with new block references

Code: [Select]
    Dim OldBlkRef As AcadBlockReference
    Dim NewBlkRef As AcadBlockReference
   
    For Each OldBlkRef In ThisDrawing.ModelSpace
        With OldBlkRef
            If UCase(.Name) = "FIXINGS_CHART" Then
                Set NewBlkRef = ThisDrawing.ModelSpace.InsertBlock(.InsertionPoint, .Name, .XScaleFactor, .YScaleFactor, .ZScaleFactor, .Rotation)
                NewBlkRef.layer = .layer
                NewBlkRef.Color = .Color
                NewBlkRef.Linetype = .Linetype
                NewBlkRef.LinetypeScale = .LinetypeScale
                NewBlkRef.Lineweight = .Lineweight
                NewBlkRef.Normal = .Normal
                NewBlkRef.Visible = .Visible
                ' transfer all of the attribute tag values over in this area
                ' if you want to keep the existing values in the attributes
                .Delete
            End If
        End With
    Next OldBlkRef

Now the important thing to remember is that if you utilize the code to replace the existing block references, you will need to manually fill in all of the attributes unless you set the attribute value with a default value in the block.
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie