how to find all available block reference

how to find all available block reference

a.kouchakzadeh
Advocate Advocate
7,453 Views
8 Replies
Message 1 of 9

how to find all available block reference

a.kouchakzadeh
Advocate
Advocate

Hi

I've got a listbox which I'm willing to list all available blockreferences in it.

I tired to filter them in a selectionset but that doesn't work because first: it lists all blocks in the modelspace, second: it wont list blockreferences which are not inserted in the modelspace.

is there any command to directly list them?

0 Likes
Accepted solutions (1)
7,454 Views
8 Replies
Replies (8)
Message 2 of 9

Anonymous
Not applicable

Still unclear what you are trying to do and what is problem. Do you want to select the block references or

you want to list all available block references.

Below is code which asks user to select the objects and then lists blockreferences with counts in alphabetical order.

This filters xrefs and blocks on locked layers.

You need to create userform with list view.

if you want to select all blocks, use sSet.Select acSelectionSetAll, , , fType, fData

 

 Public Sub blockcount()
    
    
    On Error Resume Next
        
        ''find locked layers
        Dim oLayer As AcadLayer
        Dim strLocked As String
        
        For Each oLayer In ThisDrawing.Layers
            If oLayer.Lock = True Then
                If strLocked = "" Then
                    strLocked = "" & oLayer.Name
                Else
                    strLocked = strLocked & "," & oLayer.Name
                End If
            End If
        Next
    
        ''find xrefs
        Dim oBlock As AcadBlock
        Dim strXref As String
        
        For Each oBlock In ThisDrawing.Blocks
            If oBlock.IsXRef = True Then
                If strXref = "" Then
                    strXref = "" & oBlock.Name
                Else
                    strXref = strXref & "," & oBlock.Name
                End If
            End If
        Next
    
        '' check and delete an existing selection set
        Dim s As Integer
        For s = 0 To ThisDrawing.SelectionSets.Count - 1
            If ThisDrawing.SelectionSets(s).Name = "ssblock" Then
                ThisDrawing.SelectionSets("ssblock").Delete
            End If
        Next
        
        ''make selection set
        Dim sSet As AcadSelectionSet
        Dim fType(9) As Integer
        Dim fData(9) As Variant
    
        'filters
        Set sSet = ThisDrawing.SelectionSets.Add("ssblock")
        fType(0) = 0: fData(0) = "INSERT"
        fType(1) = -4: fData(1) = "<NOT"
        fType(2) = 8: fData(2) = strLocked  'removes locked layers
        fType(3) = -4: fData(3) = "NOT>"
        fType(4) = -4: fData(4) = "<NOT"
        fType(5) = 2: fData(5) = strXref   'removes xref blocks
        fType(6) = -4: fData(6) = "NOT>"
        fType(7) = -4: fData(7) = "<NOT"
        fType(8) = 2: fData(8) = "NISH-ALABLE"   'removes NISH-ALABLE blocks
        fType(9) = -4: fData(9) = "NOT>"
    
        If Err.Number <> 0 Then
           Set sSet = ThisDrawing.SelectionSets.Item("ssblock")
        End If
        sSet.Clear
    
selection:
        sSet.SelectOnScreen fType, fData
    
        Dim MyblkArray() As Variant
        Dim i As Long, j As Long
        Dim Index As Integer
        Dim Response As String
        Dim FoundBlock As Boolean
        
        'if no block found
        If sSet.Count = 0 Then
           Response = MsgBox("No block found", vbRetryCancel, "NishCAD 2007")
           Select Case Response
              Case vbRetry
                   GoTo selection
              Case vbCancel
                   GoTo ending
           End Select
         
        Else
            'list calculation
            i = 0
            For Index = 0 To sSet.Count - 1
                If sSet.Item(Index).ObjectName = "AcDbBlockReference" Then
                    j = 1
                    FoundBlock = False
                    While j <= i
                        If MyblkArray(0, j) = sSet.Item(Index).EffectiveName Then
                            MyblkArray(1, j) = MyblkArray(1, j) + 1
                            j = i
                            FoundBlock = True
                        End If
                        j = j + 1
                    Wend
                    If Not FoundBlock Then
                        i = i + 1
                        ReDim Preserve MyblkArray(1, i)
                        MyblkArray(0, i) = sSet.Item(Index).EffectiveName
                        MyblkArray(1, i) = 1
                    End If
                End If
            Next Index
         End If
         
         
         
''--------------for nested blocks(remove find xrefblock filter and end if from above line)
   
        ''userform display
        Userform1.ListView1.ColumnHeaders.Clear
        Userform1.ListView1.ColumnHeaders.Add 1, , "BLOCK NAME", 120
        Userform1.ListView1.ColumnHeaders.Add 2, , "COUNT", 57
        
        For x = 1 To UBound(MyblkArray, 2)
            Userform1.ListView1.ListItems.Add x, , MyblkArray(0, x)
            Userform1.ListView1.ListItems.Item(x).SubItems(1) = MyblkArray(1, x)
        Next x
        Userform1.ListView1.Sorted = True
        Userform1.Show
    
ending:
        sSet.Delete
    
End Sub

 

 

0 Likes
Message 3 of 9

a.kouchakzadeh
Advocate
Advocate

this wasnt what I was looking for exactly. I have a drawing file which contains many blocksrefs in it.

in the insert menu I'm seeing all of them. how can I list them in my userform?

selectionsets wont work, because it wont contain un inserted blocks + it will contain duplicated blocks as much as they are inserted. lets say I have inserted blockref named "blockref type 1" 4 times. it will count it 4 times.

0 Likes
Message 4 of 9

norman.yuan
Mentor
Mentor

To me, it is still not very clear of what exactly your intention is: do you want to list all block references in the drawing (regardless which layout they are in); or you want to list block's name that has block reference being inserted into the drawing (say, the drawing contains 10 block definitions, thus 10 block names, but only 5 blocks have block references inserted. So, you want that 5 block names listed, not all 10 names).

 

Let's assume you want to latter. So, you can do this way:

 

1. loop through all layouts, including ModelSpace find all AcadBlockReference; or use AcadSelectionSet to select all block references with filter;

2. For each block reference, save the block's name into a collection/array, as long as the block name does not exists in that collection/array.

 

Following is the code (pseudo/not tested, I omitted the filter for selectionset, but you could refer to the first reply from @Anonymous  for it):

 

'' This function would returns an array of name of blocks that have block references inserted into the drawing.

Public Function FindUsedBlocks() As Variant

  Dim names() As String

  Dim i As Integer

  Dim j As Integer

  Dim blk As AcadBlockRefernece

  Dim ss As AcadSelectionSet

  Set ss = FindAllBlockReferences

  For i=0 to ss.Count-1

    Set blk = ss(i)

    If i=0 the 

      ReDim Preserve names(j)

      names(j)=blk.EffectiveName

      j=j+1

    Else

      If Not NameExists(names, blk.EffectivaName) Then

        ReDim Preserve names(j)

        names(j)=blk.EffectiveName

        j=j+1

      End If

    End If

  Next

  FindUsedBlocks = names

End Function

 

Private Function SelectAllBlockRefernces() As AcadSelection

    Dim ss As AcadSelection

    On Error Resume Next

    Set ss=ThsiDrawing.SelectionSets.Add("MySS")

    If err.Numer<>0 Then

       set ss=ThisDrawing.SelectionSet("MySS")

    End If

    '' define filter here....

    ss.Select acSelectionSetAll, [filter]

    Set SelectAllBlockReferences=ss

End Function

 

Private Function NameExists(names As Variant, name As String) As Boolean

  Dim i As Integer

  For i = 0 To Ubound(names)

    If UCase(names(i) = UCase(name) 

      NameExists = True

      Exit Function

    End If

  Next

  NameExists=False

End Function

 

Hopefully I did not guess your intention wrong.

 

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 5 of 9

a.kouchakzadeh
Advocate
Advocate

first of all thanks for the time Sir.

secondly, I am a bit confused now. I have to read about the difference between an acad block and acad block reference.

I have created a shape, and used the "BLOCK" command to set that shape as a block and say I named it BL_type1

then created a second shape and named it BL_type2 and so on.

now, when I filter my selectionsets using this:

 

Dim block_filterdata(1) As Integer
Dim block_filtertype(1) As Variant
block_filterdata(0) = 8
block_filterdata(1) = 0
block_filtertype(0) = selected_layer
block_filtertype(1) = "insert"
block_sset.Select acSelectionSetAll, , , block_filterdata, block_filtertype

.....

 

sub userform_activate()

dim bl as acadblockrefence

for each bl in block_sset

listbox.addItem .Name

next

 

 

Obviously the selectionset only selects the "insert" Items (which are acad block references) and are in the selected_layer (which i have defined it in another part). but the point is, If i didnt use (insert) BL_type1 or 2 in the drawing, it wont select it  therefore I wont have BL_type1 in block_sset

also, if I use bl_type2 or 3 or what ever, xxx times, my list will show it xxx times. 

I just want to see it once.

 

Ill do my reading regard block and bokcreferences. Ill ask again if I couldn't come up with some thing.

and Mr. Yuan, I dont know why, but its giving a syntax error on if i=0 then...

again, thanks for the time sir.

Capture.JPG

 

 

0 Likes
Message 6 of 9

norman.yuan
Mentor
Mentor

Well, that was why in my previous reply I had to assume what you want to do: you did not express your intention clearly enough. Now that you admit that you are still not very certain of the difference of AcadBlock and AcadBlockReference, that is understandable that mentioning "block reference" in the title of your post only made it more confusing as what exactly you need to do.

 

But now, it seems you want list the names of all BLOCK DEFINITIONS (AcadBlock). In this case, no block references are involved (thus, no need to selecting with filters, or loop through model/paperspace ...). Again, you still not make things clear enough.

 

How about explain what you need to do (IN DETAILS!), as CAD user, not a programmer: what the user want to see in the list box, and what the user expects after a block name is selected in the list box.

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 7 of 9

a.kouchakzadeh
Advocate
Advocate

Capture.JPGI create some objects in the cad space (model space). then I use the block command and make them as a block and name it BL_1.

I repeat the process and create BL_2 and BL_3 , BL_4 and so on.

by the way, using the define attributes I assign attributes to them as well. some of three attributes some have two and some have one. 

 

now when I click the triangle in insert menu I can see all the blocks created.

I insert one of them. when I click on the block and it shows it properties why does CAD consider it as a block reference. not AcadBlock?

 

for the program, my first intention is to see all those blocks in a listbox. regardless they are drawn in the modelspace or not.

second, when the user clicks on that item in the listbox, id like to show the modelspace, let the user pick the insertion point then draw that block in that point and let the user enter the attributes as well.

then there is another command button which when clicked on, lists all the blocks, its attributes and insertion point in an excel file.

 

0 Likes
Message 8 of 9

seabrahenrique
Advocate
Advocate
Accepted solution

Try this:

 

Sub ListBlocks()

Dim AcadObj As AcadObject, BlockRef As AcadBlockReference

For Each AcadObj In ThisDrawing.ModelSpace

    If TypeOf AcadObj Is AcadBlockReference Then
    
        Set BlockRef = AcadObj
        UserForm1.ListBox1.AddItem BlockRef.EffectiveName
    
    End If

Next AcadObj


End Sub

Sub ListBlocks2()

Dim Block As AcadBlock

For Each Block In ThisDrawing.Blocks

    If Left(Block.Name, 1) <> "*" Then UserForm1.ListBox2.AddItem Block.Name

Next Block

End Sub

 

 

And u will have this two variations:

 

henriqueseabra_0-1623000390365.png

 

 

I don't know exataly wath u need, but i guess is something like that.

 

I hope can help u.

0 Likes
Message 9 of 9

a.kouchakzadeh
Advocate
Advocate

great. thanks to you and Mr. Yuan

0 Likes