Author Topic: Count Blocks  (Read 1958 times)

0 Members and 1 Guest are viewing this topic.

TJK44

  • Guest
Count Blocks
« on: January 11, 2012, 05:19:30 PM »
I am trying to create a table where each row has block information and one of the columns contains the count of that block. I am having trouble getting my code to return the total number for each block in the model space. The code I currently have only returns a count of 1 for each block. Is btr.GetBlockReferenceIds(True,True).Count not how you would get the count of each block? Below are two pictures showing what the table is currently returning.


Code: [Select]
<CommandMethod("PARTBOM", CommandFlags.UsePickSet)> _
        Public Shared Sub PartBOMoriginal()
            Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
            Dim db As Database = Application.DocumentManager.MdiActiveDocument.Database
            Dim document As Document = Application.DocumentManager.MdiActiveDocument
            Dim dict As New Dictionary(Of String, Integer)()
            Dim pr As PromptPointResult = ed.GetPoint(vbLf & "Enter table insertion point: ")
            Dim title As String = "Blocks in " & System.IO.Path.GetFileNameWithoutExtension(db.Filename)

            Using trans As Transaction = db.TransactionManager.StartTransaction
                If pr.Status = PromptStatus.OK Then
                    Dim blkTbl As BlockTable = DirectCast(trans.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
                    Dim bt As BlockTable = DirectCast(trans.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
                    Dim cspace As BlockTableRecord = DirectCast(trans.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)
                    Dim tb As New Table()

                    tb.Position = pr.Value
                    tb.NumRows = 2
                    ' "Use Table.Rows.Count instead."
                    tb.NumColumns = 17
                    ' "Use Table.Columns.Count instead."
                    tb.TableStyle = db.Tablestyle
                    Dim ts As TableStyle = DirectCast(trans.GetObject(tb.TableStyle, OpenMode.ForRead), TableStyle)
                    Dim textHeigth As Double = ts.TextHeight(RowType.DataRow)
                    tb.Columns(0).Width = textHeigth * 12
                    tb.Columns(1).Width = textHeigth * 30
                    tb.Columns(2).Width = textHeigth * 8
                    tb.Columns(3).Width = textHeigth * 8
                    tb.Columns(3).Alignment = CellAlignment.MiddleCenter
                    tb.Columns(4).Width = textHeigth * 8
                    tb.Columns(4).Alignment = CellAlignment.MiddleCenter
                    tb.Columns(5).Width = textHeigth * 25
                    tb.Columns(6).Width = textHeigth * 10
                    tb.Columns(7).Width = textHeigth * 6
                    tb.Columns(8).Width = textHeigth * 10
                    tb.Columns(9).Width = textHeigth * 10
                    tb.Columns(10).Width = textHeigth * 10
                    tb.Columns(11).Width = textHeigth * 10
                    tb.Columns(12).Width = textHeigth * 20
                    tb.Columns(13).Width = textHeigth * 10
                    tb.Columns(14).Width = textHeigth * 10
                    tb.Columns(15).Width = textHeigth * 5
                    tb.Columns(16).Width = textHeigth * 5
                    Dim y As Integer = 0
                    tb.Cells(y, 0).TextString = title
                    y += 1
                    tb.Cells(y, 0).TextString = "Preview"
                    tb.Cells(y, 1).TextString = "Part Name"
                    tb.Cells(y, 2).TextString = "Count"
                    tb.Cells(y, 3).TextString = "Overrun"
                    tb.Cells(y, 4).TextString = "Total"
                    tb.Cells(y, 5).TextString = "Part Description"
                    tb.Cells(y, 6).TextString = "Part Number"
                    tb.Cells(y, 7).TextString = "Rev #"
                    tb.Cells(y, 8).TextString = "Mfg Part #"
                    tb.Cells(y, 9).TextString = "Designer"
                    tb.Cells(y, 10).TextString = "Creation Date"
                    tb.Cells(y, 11).TextString = "Material #"
                    tb.Cells(y, 12).TextString = "Material Desc"
                    tb.Cells(y, 13).TextString = "Notes"
                    tb.Cells(y, 14).TextString = "Make/Buy"
                    tb.Cells(y, 15).TextString = "Length"
                    tb.Cells(y, 16).TextString = "Width"
                    y += 1
                    For Each objID As ObjectId In blkTbl
                        'Dim btr As BlockTableRecord = DirectCast(trans.GetObject(objID, OpenMode.ForRead), BlockTableRecord)
                        Dim btr As BlockTableRecord = DirectCast(objID.GetObject(OpenMode.ForRead), BlockTableRecord)

                        Dim partDesc As String = ""
                        Dim partNum As String = ""
                        Dim revNum As String = ""
                        Dim mfgPartNum As String = ""
                        Dim designer As String = ""
                        Dim createDate As String = ""
                        Dim matNum As String = ""
                        Dim matDesc As String = ""
                        Dim notes As String = ""
                        Dim makeBuy As String = ""
                        Dim length As String = ""
                        Dim width As String = ""

                        If Not btr.IsLayout AndAlso Not btr.IsFromExternalReference AndAlso btr.HasAttributeDefinitions Then
                            Dim btrname As String = btr.Name
                            Dim oid As ObjectIdCollection = btr.GetBlockReferenceIds(True, True)
                            For Each id As ObjectId In oid
                                Dim blkRef As BlockReference = DirectCast(trans.GetObject(id, OpenMode.ForRead), BlockReference)
                                Dim attrefIds As AttributeCollection = blkRef.AttributeCollection
                                For Each attrefid As ObjectId In attrefIds
                                    Dim attref As AttributeReference = trans.GetObject(attrefid, OpenMode.ForWrite, False)
                                    Select Case attref.Tag
                                        Case "PartDescription"
                                            partDesc = attref.TextString
                                        Case "PartNumber"
                                            partNum = attref.TextString
                                        Case "RevNum"
                                            revNum = attref.TextString
                                        Case "MfgPart#"
                                            mfgPartNum = attref.TextString
                                        Case "Designer"
                                            designer = attref.TextString
                                        Case "CreateDate"
                                            createDate = attref.TextString
                                        Case "MaterialNum"
                                            matNum = attref.TextString
                                        Case "MaterialDesc"
                                            matDesc = attref.TextString
                                        Case "Notes"
                                            notes = attref.TextString
                                        Case "Make-Buy"
                                            makeBuy = attref.TextString
                                        Case "Length"
                                            length = attref.TextString
                                        Case "Width"
                                            width = attref.TextString
                                    End Select
                                Next
                                Dim count As String = btr.GetBlockReferenceIds(True, True).Count

                                If Not (btr.IsLayout OrElse btr.IsAnonymous) Then
                                    tb.InsertRows(y, textHeigth * 4, 1)
                                    tb.Cells(y, 0).ContentLayout = CellContentLayout.StackedHorizontal
                                    Dim cc As CellContentsCollection = tb.Cells(y, 0).Contents
                                    cc.Add()
                                    'cc(0).TextString = partNum & "-" & partDesc
                                    cc.Add()
                                    Try
                                        cc(0).BlockTableRecordId = blkTbl(partNum & "-" & partDesc)
                                    Catch
                                    End Try
                                    Dim cc2 As CellContentsCollection = tb.Cells(y, 1).Contents
                                    cc2.Add()
                                    cc2(0).TextString = partNum & "-" & partDesc
                                    tb.Cells(y, 2).TextString = count
                                    tb.Cells(y, 3).TextString = ""
                                    tb.Cells(y, 4).TextString = ""
                                    tb.Cells(y, 5).TextString = partDesc
                                    tb.Cells(y, 6).TextString = partNum
                                    tb.Cells(y, 7).TextString = revNum
                                    tb.Cells(y, 8).TextString = mfgPartNum
                                    tb.Cells(y, 9).TextString = designer
                                    tb.Cells(y, 10).TextString = createDate
                                    tb.Cells(y, 11).TextString = matNum
                                    tb.Cells(y, 12).TextString = matDesc
                                    tb.Cells(y, 13).TextString = notes
                                    tb.Cells(y, 14).TextString = makeBuy
                                    tb.Cells(y, 15).TextString = length
                                    tb.Cells(y, 16).TextString = width
                                    y += 1
                                End If
                            Next
                        End If
                    Next
                    tb.GenerateLayout()
                    cspace.AppendEntity(tb)
                    trans.AddNewlyCreatedDBObject(tb, True)

                End If
                trans.Commit()
            End Using
        End Sub





Atook

  • Swamp Rat
  • Posts: 1030
  • AKA Tim
Re: Count Blocks
« Reply #1 on: January 12, 2012, 12:33:22 PM »
I haven't tried to count blocks in .NET yet, but when I did in the COM interface, I selected all in modelspace with a filter on the block name, and took the count of the selectionset.

Jeff H

  • Needs a day job
  • Posts: 6151
Re: Count Blocks
« Reply #2 on: January 12, 2012, 01:52:14 PM »
Try using something like this on a test drawing.
What is the count printed to command line vs. in the table?
 
Another thing to consider is count for all references from a dynamic block
Code: [Select]
  <CommandMethod("SimpleBlockRefCount")> _
        Sub GetAllBlockRefsFromDefinitions()
            Dim doc As Document = Application.DocumentManager.MdiActiveDocument
            Dim db As Database = doc.Database
            Dim ed As Editor = doc.Editor
            Using trx As Transaction = db.TransactionManager.StartTransaction()
                Dim bt As BlockTable = trx.GetObject(db.BlockTableId, OpenMode.ForRead)
                Dim brefCount As Integer = 0
                For Each btrId As ObjectId In bt
                    Dim btr As BlockTableRecord = trx.GetObject(btrId, OpenMode.ForRead)
                    If Not btr.IsLayout Then
                        brefCount = btr.GetBlockReferenceIds(True, False).Count
                        ed.WriteMessage("{0}{1}  -  {2}", Environment.NewLine, btr.Name, brefCount)
                    End If
                Next
                trx.Commit()
            End Using
        End Sub

TJK44

  • Guest
Re: Count Blocks
« Reply #3 on: January 12, 2012, 03:50:24 PM »
Here are screen shots of the results from your code in the ACAD text window. Looking at the text window I am not getting the right values into the table. I should be seeing the values for:

SHET-PART 2  -  4
JRSHJU-PART 1  -  6
Q35HY-PART 3  -  8

But I am getting the values for

SHET-PART 2|SHET-PART 2  -  1
JRSHJU-PART 1|JRSHJU-PART 1  -  1
Q35HY-PART 3|Q35HY-PART 3  -  1

It might be good to note that everything in the drawing is an external referenced block. And the stuff in the red window is its own block.
I am trying to read the block count from deeply nested block structure.
If i am using EATTEXT, this command works good, except there is no preview in that table.

gile

  • Gator
  • Posts: 2520
  • Marseille, France
Re: Count Blocks
« Reply #4 on: January 12, 2012, 04:05:01 PM »
Hi,

May be reading this thread give some help.
Speaking English as a French Frog

TJK44

  • Guest
Re: Count Blocks
« Reply #5 on: January 17, 2012, 10:14:58 AM »
I managed to get the counts of the block correct by borrowing gile's code from http://www.theswamp.org/index.php?topic=40440.msg457394#msg457394 to count the blocks. I also used some of Jeff's code from this thread so thanks to you both.

Here is the code for the table.

Code: [Select]
<CommandMethod("BrefCount")> _
        Sub BrefCount()
            Dim doc As Document = Application.DocumentManager.MdiActiveDocument
            Dim db As Database = doc.Database
            Dim ed As Editor = doc.Editor
            Dim brefCount As New ObjectIdCollection
            Using trx As Transaction = db.TransactionManager.StartTransaction()
                Dim bt As BlockTable = trx.GetObject(db.BlockTableId, OpenMode.ForRead)
                Dim cspace As BlockTableRecord = DirectCast(trx.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)
                Dim tb As New Table()
                tb.Position = Point3d.Origin
                tb.NumRows = 2
                tb.NumColumns = 2
                tb.TableStyle = db.Tablestyle
                Dim ts As TableStyle = DirectCast(trx.GetObject(tb.TableStyle, OpenMode.ForRead), TableStyle)
                Dim textHeigth As Double = ts.TextHeight(RowType.DataRow)
                tb.Columns(0).Width = textHeigth * 24
                tb.Columns(1).Width = textHeigth * 8

                Dim y As Integer = 0
                tb.Cells(y, 0).TextString = "Test"
                y += 1
                tb.Cells(y, 0).TextString = "Block name"
                tb.Cells(y, 1).TextString = "Count"
                y += 1

                For Each btrId As ObjectId In bt
                    Dim btr As BlockTableRecord = trx.GetObject(btrId, OpenMode.ForRead)
                    If Not btr.IsLayout And btr.IsFromExternalReference Then
                        If File.Exists(btr.PathName) Then
                            'Dim db2 As Database = New Database(False, True)
                            'db2.ReadDwgFile(btr.PathName, FileShare.ReadWrite, False, "")

                            brefCount = GetAllBlockReferencesByNames(btr.Name)

                            tb.InsertRows(y, textHeigth * 4, 1)
                            tb.Cells(y, 0).ContentLayout = CellContentLayout.StackedHorizontal
                            Dim cc As CellContentsCollection = tb.Cells(y, 0).Contents
                            cc.Add()
                            cc(0).TextString = btr.Name
                            cc.Add()
                            cc(1).BlockTableRecordId = bt(btr.Name)
                            tb.Cells(y, 1).TextString = brefCount.Count
                            y += 1

                        End If
                    End If
                Next

                tb.GenerateLayout()
                cspace.AppendEntity(tb)
                trx.AddNewlyCreatedDBObject(tb, True)

                trx.Commit()
            End Using
        End Sub