Hello: I have created command BOM that asks the user to select all objects in model
space they want to have in the new layout.
After they select these objects, it opens a custom template, creates the layout
and places these objects into the new layout.
If the user then clicks bom again, and selects a different set of objects this time,
another new layout with a unique name is created with these object inside it.
This code is all working great.
HERE'S THE PROBLEM:
After entering BOM and therefore creating the first layout, I click on it and I see it's perfect.
After I entering BOM and therefore creating the second layout, I click on it and I see it's perfect.
If however, I now click back to the tab to view the first layout,
I see that this first layout not only contains all the stuff it's suppose to, it also contains all the objects from the second layout...and I don't understand why.
Below is my code...I was hoping someone could please take a look at it
and see and help explain to me what I'm doing wrong.
Thanks for your time,
Proctor
<CommandMethod("BOM")> _
Sub BOM()
Dim myDWG As Autodesk.AutoCAD.ApplicationServices.Document
Dim idLayout As ObjectId = ObjectId.Null
Dim myBT As BlockTable
Dim myBTE As SymbolTableEnumerator
Dim layout As New DatabaseServices.Layout
Dim myLayout As New Layout
Dim myPSR As PromptSelectionResult
Dim myPSO As New PromptSelectionOptions
Dim ext As Extents3d
Dim minPt(2), maxPt(2) As Double
Dim fstEnt As Boolean = True
Dim ent As Entity
Dim iIncrement As Integer = 0
Dim iIncrementText As Integer = 0
Dim doc As Document = Application.DocumentManager.MdiActiveDocument
Dim db As Database = doc.Database
Dim lm As LayoutManager = LayoutManager.Current()
Dim btr As BlockTableRecord
Dim ed As Editor = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor()
Dim layoutId As ObjectId
Dim dLayoutNameParsedHightestIncrement As Double = 0
Dim bIncrementedName As Boolean = False 'CO_ESTIMATE was found and needed to increment it
Dim sIncrement As String = ""
Dim sHightestLastValue As Integer = 0
Using tr As Transaction = db.TransactionManager.StartTransaction()
' (1) create the new layout
myBT = db.BlockTableId.GetObject(DatabaseServices.OpenMode.ForRead)
myBTE = myBT.GetEnumerator
'ASSIGN UNIQUE LAYOUT NAME
While myBTE.MoveNext
btr = myBTE.Current.GetObject(DatabaseServices.OpenMode.ForRead)
If btr.IsLayout Then
myLayout = btr.LayoutId.GetObject(DatabaseServices.OpenMode.ForRead)
Debug.Print("lAYOUTNAME: " & vbCr & myLayout.LayoutName)
If InStr(myLayout.LayoutName, "CO_ESTIMATE") = 1 Then
layoutNameInDwg = myLayout.LayoutName & "1"
bIncrementedName = True
'if there's already a layout that has at least part of this name
If myLayout.LayoutName.Length >= 14 Then
'Do a check of the new assignment
'if we had already assigned a new layout name, need to make sure there's not another like it
'check the number for the layout
If myLayout.LayoutName.Length = 14 Then
sLayoutNameParsedRight = 0
Else
sLayoutNameParsedRight = myLayout.LayoutName.Substring(14, myLayout.LayoutName.Length - 14)
End If
If sIncrement = "" Then
sIncrement = sLayoutNameParsedRight
Else
sIncrement = sIncrement & "," & sLayoutNameParsedRight
End If
Dim MyIncrementArray() As String = Split(sIncrement, ",")
If MyIncrementArray.Length = 1 Then
sHightestLastValue = sLayoutNameParsedRight
Else
For g As Integer = 0 To MyIncrementArray.Length - 1
Dim sValue As Integer = CInt(MyIncrementArray(g))
If sLayoutNameParsedRight > sValue Then
If sHightestLastValue = 0 Then
sHightestLastValue = sLayoutNameParsedRight
Else
If sLayoutNameParsedRight > sHightestLastValue Then
sHightestLastValue = sLayoutNameParsedRight
End If
End If
End If
Next
End If
layoutNameInDwg = "CO_ESTIMATE" & (sHightestLastValue + 1)
bIncrementedName = True
End If
End If
End If
End While
If bIncrementedName = False Then
layoutNameInDwg = "CO_ESTIMATE"
End If
layoutId = lm.CreateLayout(layoutNameInDwg)
layout = tr.GetObject(layoutId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite)
myDWG = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
Dim myEd As Editor
myPSO.MessageForAdding = "Please select all objects you wish to place in BOM."
myEd = myDWG.Editor
myPSO.SingleOnly = False
myPSR = myEd.GetSelection(myPSO)
If Not IsNothing(myPSR.Value) Then
Dim pBOMIds As ObjectIdCollection = New ObjectIdCollection(myPSR.Value.GetObjectIds)
Dim pBOMId As ObjectId
btr = tr.GetObject(db.CurrentSpaceId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite, False, False) 'GOPINATH
For Each pBOMId In pBOMIds
ent = DirectCast(tr.GetObject(pBOMId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead), Entity)
If (fstEnt) Then
ext = New Extents3d(ent.GeometricExtents.MinPoint, ent.GeometricExtents.MaxPoint)
minPt(0) = ent.GeometricExtents.MinPoint.X
minPt(1) = ent.GeometricExtents.MinPoint.Y
minPt(2) = ent.GeometricExtents.MinPoint.Z
maxPt(0) = ent.GeometricExtents.MaxPoint.X
maxPt(1) = ent.GeometricExtents.MaxPoint.Y
maxPt(2) = ent.GeometricExtents.MaxPoint.Z
fstEnt = False
Else
If (minPt(0) > ent.GeometricExtents.MinPoint.X) Then
minPt(0) = ent.GeometricExtents.MinPoint.X
End If
If (minPt(1) > ent.GeometricExtents.MinPoint.Y) Then
minPt(1) = ent.GeometricExtents.MinPoint.Y
End If
If (minPt(2) > ent.GeometricExtents.MinPoint.Z) Then
minPt(2) = ent.GeometricExtents.MinPoint.Z
End If
If (maxPt(0) < ent.GeometricExtents.MaxPoint.X) Then
maxPt(0) = ent.GeometricExtents.MaxPoint.X
End If
If (maxPt(1) < ent.GeometricExtents.MaxPoint.Y) Then
maxPt(1) = ent.GeometricExtents.MaxPoint.Y
End If
If (maxPt(2) < ent.GeometricExtents.MaxPoint.Z) Then
maxPt(2) = ent.GeometricExtents.MaxPoint.Z
End If
End If
Next
ext = New Extents3d(New Point3d(minPt), New Point3d(maxPt))
Using docLock As DocumentLock = ed.Document.LockDocument()
Using db2 As New Database(False, True)
Using tr2 As Transaction = db2.TransactionManager.StartTransaction()
db2.ReadDwgFile("C:\BOM_TEMPLATE.dwt", System.IO.FileShare.Read, True, Nothing)
Dim ld2 As DBDictionary = tr2.GetObject(db2.LayoutDictionaryId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite)
Dim bt2 As BlockTable = tr2.GetObject(db2.BlockTableId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite)
Dim layout2 As Layout
Dim btr2 As BlockTableRecord
If ld2.Contains(layoutNameInDwt) Then
layout2 = tr2.GetObject(ld2(layoutNameInDwt), Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite)
btr2 = tr2.GetObject(layout2.BlockTableRecordId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite)
'(2) copy layout properties from the other drawing
layout.CopyFrom(layout2)
Else
tr2.Abort()
tr.Abort()
Return
End If
' (3) copy the contents of the layout
Dim plotSet As PlotSettings = New PlotSettings(False)
plotSet = CType(tr.GetObject(layoutId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite, False, False), PlotSettings)
Dim oPSVal As PlotSettingsValidator = PlotSettingsValidator.Current
oPSVal.SetZoomToPaperOnUpdate(plotSet, True)
Dim idc As New ObjectIdCollection()
For Each id As ObjectId In btr2
idc.Add(id)
ent = tr2.GetObject(id, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite, True)
If TypeOf ent Is Viewport Then
SetViewportToExtents(id, ext)
End If
Next
Dim im As IdMapping = New IdMapping()
db.WblockCloneObjects(idc, layout.BlockTableRecordId, im, DuplicateRecordCloning.MangleName, False)
End Using
tr.Commit()
lm.CurrentLayout = layoutNameInDwg
doc.Database.Psltscale = False
doc.SendStringToExecute("REGENALL ", True, False, True)
End Using
End Using
End If
End Using
End Sub