excel vba update title blocks in drawing with multiple layouts

excel vba update title blocks in drawing with multiple layouts

Anonymous
Not applicable
6,963 Views
32 Replies
Message 1 of 33

excel vba update title blocks in drawing with multiple layouts

Anonymous
Not applicable

Hi I am looking for some help on how to update the title block in drawings with multiple layout tabs. So far my code will only update the title block in the active layout. I was looking into using acSelectionsetall but couldn't figure out how to apply it. 

 


'***********************************************************************

Sub ModifyFrameBlock(DWG As AcadDocument, QUANTITY As String)

Dim blk As AcadBlockReference
Dim attr As Variant
Set blk = FindFrameBlock(DWG)

If Not blk Is Nothing Then

For Each attr In blk.GetAttributes()

If attr.TagString = "RELEASE-NO" Then

attr.TextString = RelNo

DWG.SummaryInfo.SetCustomByKey "Frame No", lbFrameName ' drawing property field

DWG.SummaryInfo.SetCustomByKey "Frame Qty", QUANTITY ' drawing property field
 End If

If attr.TagString = "RELEASE-DATE" Then
attr.TextString = TBReleaseDate
End If

Next
End If

CreatePDF DWG
DWG.AuditInfo FixError ' audit and fix error in drawing
DWG.PurgeAll ' purge drawing

DWG.Close True

End Sub

 

 

'***********************************************************

Function FindFrameBlock(DWG As AcadDocument) As AcadBlockReference
Dim ent As AcadEntity

For Each ent In DWG.PaperSpace
If TypeOf ent Is AcadBlockReference Then
If ent.Name = "blockname" Then

Set FindFrameBlock = ent
Exit Function
End If
End If
Next
Set FindFrameBlock = Nothing
End Function

'***********************************************************

0 Likes
Accepted solutions (2)
6,964 Views
32 Replies
Replies (32)
Message 21 of 33

robert.kulas
Contributor
Contributor

I still have some issue. It means I can change the blocks which were inserted into layouts in opened drawing.

When the drawing is reopen the procedure is not working.

The program cannot find the block... block is not recognized by program...

robertkulas_0-1674507713623.png

 

0 Likes
Message 22 of 33

norman.yuan
Mentor
Mentor

Well, you did not show your code that selects block references into an AcadSelectionSet.

 

If your code is exactly the same as the code showed in previous old replies, then that port of code ONLY select static block reference with given block name. If your target blocks could be dynamic block(s), then that code does not work. So, is your target block dynamic?

 

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 23 of 33

robert.kulas
Contributor
Contributor

Yes, the block is dynamic. If I insert it into drawing without changing dynamic properties I can modify...

 

0 Likes
Message 24 of 33

robert.kulas
Contributor
Contributor

The block includes Visibility States like on the screenshot.

robertkulas_0-1674552765329.pngrobertkulas_1-1674552828854.png

 

One of the solution would be static block (I would have to change many templates) and 3 additional blocks inserted acc. to the drawing status (using insert block VBA command)...

 

 

0 Likes
Message 25 of 33

Ed__Jobe
Mentor
Mentor

When you change the state of a dynamic block, autocad creates an anonymous block of the changed block. To find the anonymous block, your code needs to compare the EffectiveName property. This holds the original name of 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

0 Likes
Message 26 of 33

norman.yuan
Mentor
Mentor

Since your target block is dynamic, you CANNOT use "BlockName" filter in the Selection filter. So, you need to modify your FindBlocksOnAllLayouts2() function to only use the entity name "INSERT" to get ALL block references into the selectionset, then when you loop through the selectionset to update each block reference's attribute, you need to test the block reference's "EttectiveName", something like:

 

Dim blk As AcadBlockReference

For Each blk in blksObj

  If UCase(blk.EffectiveName)="TheTargetBlockName"  and blk.HasAttributes Then

    '' Do your attributereference update here

  End If

Next

 

 

 

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 27 of 33

robert.kulas
Contributor
Contributor

Unfortunately, it does not work. The program cannot find dynamic blocks ...

0 Likes
Message 28 of 33

Ed__Jobe
Mentor
Mentor

Show your code. Maybe you have an error.

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 29 of 33

robert.kulas
Contributor
Contributor

Please find the code:

Private Sub ModifyFrameBlock()
    
    Dim AutoCadApp As Object
    Dim dwg As AcadDocument
    Dim blkName As String
    Dim i, j As Integer
    Dim blk As AcadBlockReference
    Dim blks() As AcadBlockReference  
    Dim attrs As Variant 
    Dim attr As AcadAttributeReference 
    Dim blcksObj As AcadSelectionSet
    
    Dim TITLE_1, TITLE_2, SCALE1, SECTION, SYSTEM As String
    Dim REVISION, SHEET11, REFNUM, PREL, GFA, GFU, ASBUILT, datRev As String
    Dim IndA, IndADate, IndAmod1, IndAmod2, IndAdesign, IndAcheck, IndAcheckApp, IndAapprovedSTX As String
    

    Set AutoCadApp = GetObject(, "AutoCAD.Application")
    Set dwg = AutoCadApp.ActiveDocument

    TITLE_1 = DrawingTable.TextBox1.value
    TITLE_2 = DrawingTable.TextBox2.value
    SCALE1 = DrawingTable.ComboBox2.value
    SECTION = DrawingTable.TextBox6.value
    SYSTEM = DrawingTable.TextBox7.value
    
    datRev = REVISION
    SHEET11 = DrawingTable.TextBox9.value
    REFNUM = DrawingTable.TextBox10.value
    PREL = DrawingTable.TextBox11.value
    GFA = DrawingTable.TextBox12.value
    GFU = DrawingTable.TextBox13.value
    ASBUILT = DrawingTable.TextBox14.value
    
    IndA = REVISION
    DrawingTable.TextBox19 = REVISION
    IndADate = DrawingTable.TextBox16.value
    IndAmod1 = DrawingTable.TextBox17.value
    IndAmod2 = DrawingTable.TextBox18.value
    IndAdesign = DrawingTable.ComboBox3.value
    IndAcheck = DrawingTable.ComboBox4.value
    IndAcheckApp = DrawingTable.ComboBox5.value
    
    'blkName = "DwgTable01"
    'blkName = "CDD_J35_AER_Header_ACDL_Attr"

    Set blcksObj = FindBlocksOnAllLayouts2(dwg, blkName) 

    If blcksObj.Count > 0 Then ' if any block found
        ReDim Preserve blks(0 To blcksObj.Count)
        For Each blk In blcksObj
            If UCase(blk.EffectiveName) = "CDD_J35_AER_Header_ACDL_Attr" And blk.HasAttributes Then
                Set blks(i) = blk
                i = i + 1
            End If
        Next
    
    On Error GoTo ERRORHANDLER
    
        If i = 0 Then
            MsgBox "No blocks """ & blkName & """ with attributes found in current drawing!"
        Else
            ReDim Preserve blks(0 To i - 1)
            For i = 0 To UBound(blks)
                Set blk = blks(i)
                attrs = blk.GetAttributes()
                For j = 0 To UBound(attrs)
                       Set attr = attrs(j)
                    If attr.TagString = "TITLE_1" Then
                        attr.TextString = TITLE_1
                    ElseIf attr.TagString = "TITLE_2" Then
                        attr.TextString = TITLE_2
                   ElseIf attr.TagString = "SCALE" Then
                        attr.TextString = SCALE1
                    ElseIf attr.TagString = "SECTION" Then
                        attr.TextString = SECTION
                    ElseIf attr.TagString = "SYSTEM" Then
                        attr.TextString = SYSTEM
                    ElseIf attr.TagString = "REVISION" Then
                        attr.TextString = REVISION
                    ElseIf attr.TagString = "SHEET" Then
                        attr.TextString = SHEET11
                    ElseIf attr.TagString = "REFERENCE_NUMBER" Then
                        attr.TextString = REFNUM
                    ElseIf attr.TagString = "PRELIMINARY" Then
                        attr.TextString = PREL
                    ElseIf attr.TagString = "GOOD_FOR_APPROVAL" Then
                        attr.TextString = GFA
                    ElseIf attr.TagString = "GOOD_FOR_USE" Then
                        attr.TextString = GFU
                    ElseIf attr.TagString = "AS_BUILT" Then
                        attr.TextString = ASBUILT


'--------------Index_A-------------------------------------------------------
                    ElseIf DrawingTable.TextBox19.value = "A1" Then
                        If attr.TagString = "INDEX_A" Then
                            attr.TextString = IndA
                        ElseIf attr.TagString = "INDEX_A_DATE" Then
                            attr.TextString = IndADate
                        ElseIf attr.TagString = "INDEX_A_MODIFICATION_1" Then
                            attr.TextString = IndAmod1
                        ElseIf attr.TagString = "INDEX_A_MODIFICATION_2" Then
                            attr.TextString = IndAmod2
                         ElseIf attr.TagString = "INDEX_A_DESIGNED" Then
                            attr.TextString = IndAdesign
                        ElseIf attr.TagString = "INDEX_A_CHECKED" Then
                            attr.TextString = IndAcheck
                        ElseIf attr.TagString = "INDEX_A_CHECK_APPROV" Then
                            attr.TextString = IndAcheckApp
                        End If
End If
                Next
            Next
        End If
    Else
        MsgBox "No blocks """ & blkName & """ found in current drawing!"
        Exit Sub
    End If
    
    On Error Resume Next
    
ERRORHANDLER:
        If Err.Description <> "" Then
        Err.Clear
        End If



Function FindBlocksOnAllLayouts2(dwg As AcadDocument, blkName As String) As AcadSelectionSet
    Set FindBlocksOnAllLayouts2 = CreateSelectionSet(dwg, "blcks")
  
    Dim gpCode(0 To 0) As Integer
    Dim dataValue(0 To 0) As Variant
    gpCode(0) = 0:    dataValue(0) = "INSERT"
    'gpCode(1) = 2:    dataValue(1) = blkName
    FindBlocksOnAllLayouts2.Select acSelectionSetAll, , , gpCode, dataValue
End Function



Function CreateSelectionSet(acDoc As AcadDocument, SSset As String) As AcadSelectionSet
    On Error Resume Next
    Set CreateSelectionSet = acDoc.SelectionSets(SSset)
    If Err Then Set CreateSelectionSet = acDoc.SelectionSets.Add(SSset)
    CreateSelectionSet.Clear
End Function
0 Likes
Message 30 of 33

norman.yuan
Mentor
Mentor

Well, this line obviously does not do you any favor:

 

If UCase(blk.EffectiveName) = "CDD_J35_AER_Header_ACDL_Attr" ...

 

UCase()/LCase() is meant to turn the string value to all upper/lower case before comparing it to other string value to avoid "case" issue. So, the code should be:

If UCase(blk.EffectiveName) = "CDD_J35_AER_HEADER_ACDL_ATTR" ...

 

Also, it should have been VERY EASY to find out where the code error is, had you done your diligent, and very basic, debugging run: simply examine the entity counts after the Select() method call and after looping to test the block's EffectiveName.

 

 

 

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 31 of 33

Ed__Jobe
Mentor
Mentor

Just a note on best practice,

Dim TITLE_1, TITLE_2, SCALE1, SECTION, SYSTEM As String

The previous code will create 4 variants and 1 string. Although you can Dim several variables on one line, if you don't specify the data type for each, it will be allocated as a variant, not a String as you might assume from the previous code. You could write it this way.

Dim TITLE_1 As String, TITLE_2 As String, SCALE1 As String, SECTION As String, SYSTEM As String

I just get in the habit of having a single line for each var.

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 32 of 33

robert.kulas
Contributor
Contributor

All your suggestions have been implemented but it doesn't work. I can only use it for static blocks...

the Debugger cannot find issues.

0 Likes
Message 33 of 33

Ed__Jobe
Mentor
Mentor

@robert.kulas wrote:

All your suggestions have been implemented but it doesn't work. I can only use it for static blocks...

the Debugger cannot find issues.


My notes probably wouldn't have any effect in this case. I just wanted you to understand the consequences of what you wrote. You may have wanted a String variable, but you got Variant variables instead. To get it to recognize dynamic blocks, you need to implement Norman's suggestions.

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