Hello,
I'm creating a button event that creates a new layout, updates the page setup, and inserts our titleblock. The last two items aren't working, but one step at a time. While attempting to adjust the page setup I can adjust some, but not all of the settings. I can change the: plot configuration\media size and plot style. This does make changes to the layout, but the size of the layout is small (See screenshot below). Once I manually set the plot area to layout, the layout size adjusts correctly (see second screen shot). For some reason I haven't figured out how to change that setting in the plot setting validator (See code below). Is there a difference between a print setup and page setup?
#Region " Emp_NewLayoutC"
<CadRun.CommandMethod("Emp_NewLayoutC")>
Public Sub Emp_NewLayoutC()
' Layouts are sorted by taborder during the globals.GetLayouts sub during initiate
Initiate()
DB.WriteLine(vbNewLine & "Class1 | ServiceCommands | Emp_NewLayoutC")
'Try
' Start transaction
Dim Trans As CadDBS.Transaction = g_AcDatBas.TransactionManager.StartTransaction()
' Get the layout manager
Dim LayoutMgr As CadDBS.LayoutManager = CadDBS.LayoutManager.Current
' Create the new layout with default settings
Dim ObjID As CadDBS.ObjectId = LayoutMgr.CreateLayout($"Layout{g_Layouts.Count + 1}")
' Open the Layout
Dim Layt As CadDBS.Layout = Trans.GetObject(ObjID, CadDBS.OpenMode.ForRead)
' Set the layout current if it is not already
If Layt.TabSelected = False Then : LayoutMgr.CurrentLayout = Layt.LayoutName : End If
Dim SN As New PlotStyle
Dim PlSet As CadDBS.PlotSettings = New CadDBS.PlotSettings(False)
'PlSet.PlotSettingsName = "None"
Dim Vldtr As CadDBS.PlotSettingsValidator = CadDBS.PlotSettingsValidator.Current
Vldtr.RefreshLists(PlSet)
Vldtr.SetPlotConfigurationName(PlSet, "None", "ANSI_C_(17.00_x_22.00_Inches)") ' "ANSI_C_(22.00_x_17.00_Inches)"
Vldtr.SetUseStandardScale(PlSet, True)
Vldtr.SetStdScaleType(PlSet, CadDBS.StdScaleType.StdScale1To1)
Vldtr.SetPlotType(PlSet, CadDBS.PlotType.Extents)
Vldtr.SetPlotType(PlSet, CadDBS.PlotType.Layout)
'Vldtr.SetPlotCentered(PlSet, True)
Vldtr.SetPlotPaperUnits(PlSet, CadDBS.PlotPaperUnit.Inches)
'PlSet.ShowPlotStyles = True
'Vldtr.SetPlotRotation(PlSet, CadDBS.PlotRotation.Degrees000)
Vldtr.SetCurrentStyleSheet(PlSet, SN.Monochrome.ToString)
'Vldtr.SetPlotWindowArea(PlSet, Layt.Limits)
Vldtr.SetZoomToPaperOnUpdate(PlSet, True)
Layt.CopyFrom(PlSet)
DB.WriteLine("..." & vbTab & "set print settings")
' Save the new object to the database
Trans.Commit()
DB.WriteLine(vbNewLine)
'Catch ex As Exception
' Return
'End Try
End Sub
#End Region
Solved! Go to Solution.
Solved by ed57gmc. Go to Solution.
Instead of creating a page setup each time, I just import them from a template. But I found that you need to do a regen to make the changes show up.
You could also use the CopyFrom method to clone a layout from a template. One advantage of importing from a template is that if something changes, you can update your template instead of changing code and redeploying your app.
@ed57gmc I'm not familiar with importing settings from a template or cloning a template using the copy from method; but I like the idea that if I change something I can just change the template and leave the code alone. So I created a template where the layout1 page setup is how I want it. I also inserted the titleblock on top of that. The code below will import the template page setup but it doesn't bring the title block with it (see screenshot below). What am I missing?
#Region " Emp_NewLayoutC"
<CadRun.CommandMethod("Emp_NewLayoutC")>
Public Sub Emp_NewLayoutC()
' Layouts are sorted by taborder during the globals.GetLayouts sub during initiate
Initiate()
DB.WriteLine(vbNewLine & "Class1 | ServiceCommands | Emp_NewLayoutC")
'Try
' Start transaction
Dim Trans As CadDBS.Transaction = g_AcDatBas.TransactionManager.StartTransaction()
' Get the layout manager
Dim LayoutMgr As CadDBS.LayoutManager = CadDBS.LayoutManager.Current
' Create the new layout with default settings
Dim ObjID As CadDBS.ObjectId = LayoutMgr.CreateLayout($"Layout{g_Layouts.Count + 1}")
' Open the Layout
Dim Layt As CadDBS.Layout = Trans.GetObject(ObjID, CadDBS.OpenMode.ForRead)
' Set the layout current if it is not already
If Layt.TabSelected = False Then : LayoutMgr.CurrentLayout = Layt.LayoutName : End If
' Open in memory the titleblock dwg
Dim NewDb As CadDBS.Database = New CadDBS.Database(False, True)
NewDb.ReadDwgFile("TitleBlock_Full_Filename.dwt", CadDBS.FileOpenMode.OpenForReadAndAllShare, False, Nothing)
NewDb.CloseInput(True)
DB.WriteLine("..." & vbTab & $"Open titleblock dwt: {System.IO.Path.GetFileNameWithoutExtension(NewDb.Filename)}" & vbNewLine)
' Start a new Transaction
Dim NewTrans As CadDBS.Transaction = NewDb.TransactionManager.StartTransaction
' Get the layout from the template
Dim TempLayout As CadDBS.Layout
For Each entry As CadDBS.DBDictionaryEntry In CType(NewDb.LayoutDictionaryId.GetObject(CadDBS.OpenMode.ForRead), CadDBS.DBDictionary)
If entry.Key.Trim().ToUpper() <> "MODEL" Then
TempLayout = CType(NewTrans.GetObject(entry.Value, CadDBS.OpenMode.ForRead), CadDBS.Layout)
End If
Next
NewTrans.Commit()
Layt.CopyFrom(TempLayout)
'' Insert the title block
'Dim TitlID As CadDBS.ObjectId = g_AcDatBas.Insert(System.IO.Path.GetFileNameWithoutExtension(NewDb.Filename), NewDb, False)
'DB.WriteLine("..." & vbTab & "Insert titleblock dwg")
' Regenerate the document
g_AcDoc.Editor.Regen()
' Save the new object to the database
Trans.Commit()
DB.WriteLine(vbNewLine)
'Catch ex As Exception
' Return
'End Try
End Sub
#End Region
just a guess . .
Where is the template located ?
What is the setting in your Config->Files->Template Settings->Drawing Template File Location ?
Try either giving the full path in your code or locate the template file in the 'Drawing Template File Location' folder.
Regards,
// Called Kerry in my other life.
Everything will work just as you expect it to, unless your expectations are incorrect.
Sometimes the question is more important than the answer.
class keyThumper<T> : Lazy<T>; another Swamper
@kerry_w_brown Good thinking. I definitely didn't have my new templates in the directory set in the options. I moved the new templates to that directory and ran it again. Unfortunately I got the same result, the layout page setup came across but not the titleblock.
PS. I found ".clone" a method for Layout. I'm looking to see if that will help.
Once you import the named Page Setup into the active document, the code under this old LispFunction might help you set it as active to the desired Layouts:
https://forums.augi.com/showthread.php?80461-Page-Setup-Manager&p=1219546&viewfull=1#post1219546
Cheers
"How we think determines what we do, and what we do determines what we get."
@snappyjazz Remember that a Layout object also has a Block object that contains the objects on a Layout. After you import the layout, you can check the block table for the block contents and copy it to the new layout's block. Use the Layout.BlockTableRecordID method to locate the btr.
The Layout.DeepClone method may do this for you. I haven't tried it.
I also found this old thread that imports a layout. Maybe it will help.
@ed57gmc – That worked. It was a little confusing for a reason that’s obvious now. In my template file I created the layout with page setup and titleblock on the first layout “Layout1”. When running the code, I always used a new blank dwg to test with. The code would create a 2nd layout “Layout2”, but the template would always appear on the 1st layout: “Layout1”. Duh because is cloning “Layout1” from the template file. HAHA, so I renamed the layout in the template “TempLayoutC” which no one should use in their project dwgs. Then I added a line of code at the end to rename “TempLayoutC” to “Layout{Layout.Count}” Final code result is below.
PS - thanks to everyone who helped sort out this confusion!
#Region " Emp_NewLayoutC"
<CadRun.CommandMethod("Emp_NewLayoutC")>
Public Sub Emp_NewLayoutC()
' Layouts are sorted by taborder during the globals.GetLayouts sub during initiate
' Target is referenced to the dwg I'm currently working and want to add a new layout to - Any globals "g_" assume this too
' Temp/Template is referenced to, the layout of, or anything else pertaining to the template
Initiate()
'DB.WriteLine(vbNewLine & "Class1 | ServiceCommands | Emp_NewLayoutC")
Try
' Start transaction
Dim TargetTrans As CadDBS.Transaction = g_AcDatBas.TransactionManager.StartTransaction()
' Get the layout manager
Dim TargetLayoutMgr As CadDBS.LayoutManager = CadDBS.LayoutManager.Current
' Open in memory the titleblock dwt (Make sure this is in templates dir from options!)
Dim TempDb As CadDBS.Database = New CadDBS.Database(False, False)
TempDb.ReadDwgFile("TempFileName", CadDBS.FileOpenMode.OpenForReadAndAllShare, False, Nothing)
' Start a new Transaction
Dim TempTrans As CadDBS.Transaction = TempDb.TransactionManager.StartTransaction
' Get the layout from the template
Dim TempLayout As CadDBS.Layout
For Each entry As CadDBS.DBDictionaryEntry In CType(TempDb.LayoutDictionaryId.GetObject(CadDBS.OpenMode.ForRead), CadDBS.DBDictionary)
If entry.Key.Trim().ToUpper() <> "MODEL" Then
TempLayout = CType(TempTrans.GetObject(entry.Value, CadDBS.OpenMode.ForRead), CadDBS.Layout)
End If
Next
If TempLayout.ObjectId <> CadDBS.ObjectId.Null Then
' Create an id collection for the clone and add the layout
Dim OIC As New CadDBS.ObjectIdCollection
OIC.Add(TempLayout.ObjectId)
' Create id mapping
Dim IdMap As CadDBS.IdMapping = New CadDBS.IdMapping
' get the target database dict
Dim DbDict As CadDBS.DBDictionary = DirectCast(TempTrans.GetObject(g_AcDatBas.LayoutDictionaryId, CadDBS.OpenMode.ForRead, False, False), CadDBS.DBDictionary)
' If dict is open as ForRead, upgrade it to ForWrite. This also closes the object.
DbDict.UpgradeOpen()
' Target database clones from the template id collection
g_AcDatBas.WblockCloneObjects(OIC, g_AcDatBas.LayoutDictionaryId, IdMap, CadDBS.DuplicateRecordCloning.UnmangleName, False)
' Deep clone id pairs based on the mapping
Dim IPair As CadDBS.IdPair = IdMap.Lookup(TempLayout.ObjectId)
' Pair value is the cloned objects id
Dim NewObjId As CadDBS.ObjectId = IPair.Value
'LayoutMgr.CurrentLayout = Layt.LayoutName
DbDict.DecomposeForSave(CadDBS.DwgVersion.Current)
' Open the Layout
Dim Layt As CadDBS.Layout = TempTrans.GetObject(NewObjId, CadDBS.OpenMode.ForWrite)
' Move to the end of the tabs
Layt.TabOrder = TargetLayoutMgr.LayoutCount
' Add to the global list
g_Layouts.Add(Layt)
' Set the layout current if it is not already
If Layt.TabSelected = False Then : TargetLayoutMgr.CurrentLayout = Layt.LayoutName : End If
' Rename the tab
Layt.LayoutName = $"Layout{g_Layouts.Count}"
End If
' Save stuff from the template transaction
TempTrans.Commit()
' Regenerate the document
g_AcDoc.Editor.Regen()
' Save stuff from the target transaction
TargetTrans.Commit()
DB.WriteLine(vbNewLine)
Catch ex As Exception
Return
End Try
End Sub
#End Region
**Moderator edit: changed code window format to C#
Can't find what you're looking for? Ask the community or share your knowledge.