.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Erasing Layouts

20 REPLIES 20
Reply
Message 1 of 21
s.jabs
5989 Views, 20 Replies

Erasing Layouts

Does anyone have an example of how to properly remove a layout? I'm writing a routine to strip down drawings to an optimized (and standardized) format, but I'm having trouble with this one bit of code:

{code}

Protected Friend Shared Sub RemoveLayouts(ByVal dbAcad As Database)
Dim edCmdLine As Editor = AcApp.Application.DocumentManager.MdiActiveDocument.Editor
Dim alLayouts As ArrayList = New ArrayList()
Dim lmAcad As LayoutManager = LayoutManager.Current
Dim oiTemp As ObjectId

Try
' Create empty layout to satisfy one minimum layout requirement
oiTemp = lmAcad.CreateLayout("Some-Random-Name")

Using trAcad As Transaction = dbAcad.TransactionManager.StartTransaction()
Dim deItem As DictionaryEntry
Dim dicLayouts As DBDictionary = DirectCast(trAcad.GetObject(dbAcad.LayoutDictionaryId, OpenMode.ForRead), DBDictionary)
Dim intI As Integer
Dim lItem As Layout
Dim oiBlock As ObjectId
Dim oicViewports As ObjectIdCollection
Dim vItem As Viewport

' Get the list of layouts
For Each deItem In dicLayouts
alLayouts.Add(DirectCast(trAcad.GetObject(CType(deItem.Value, ObjectId), OpenMode.ForRead), Layout).LayoutName)
Next

' Cycle through the layouts, deleting all but model space and one layout
For intI = 0 To alLayouts.Count - 1
If alLayouts(intI) <> "Model" And alLayouts(intI) <> "Some-Random-Name" Then
Try
lItem = DirectCast(trAcad.GetObject(lmAcad.GetLayoutId(alLayouts(intI)), OpenMode.ForWrite), Layout)
oiBlock = lItem.BlockTableRecordId

' Deals with viewports
oicViewports = lItem.GetViewports()
For Each oiViewport In oicViewports
vItem = DirectCast(trAcad.GetObject(oiViewport, OpenMode.ForWrite), Viewport)
vItem.Erase()
Next

lmAcad.DeleteLayout(lItem.LayoutName)
Catch ex As Exception
End Try
End If
Next

trAcad.Commit()
End Using

Using trAcad As Transaction = dbAcad.TransactionManager.StartTransaction()
Dim lItem As Layout

lItem = DirectCast(trAcad.GetObject(oiTemp, OpenMode.ForWrite), Layout)
lItem.Initialize()
lItem.LayoutName = "Layout1"

trAcad.Commit()
End Using
Catch ex As Exception
End Try
End Sub
{code}

If I don't remove the viewports "manually", I get drawing corruption. If the layout to be removed contains a block with attribute definitions, that too causes corruption. If I get the BlockTableRecord from the layout, and erase it instead, I don't get corruption, but the drawing crashes when I switch layout tabs.
20 REPLIES 20
Message 2 of 21
boylek
in reply to: s.jabs

i'm trying to deal with the same thing....in C#

not much luck yet....

Message 3 of 21
Artvegas
in reply to: boylek

To erase a layout you can use the current LayoutManager's DeleteLayout() method. It will safely delete a layout including all contents.

 

Best of all, if you use this to erase the last remaining paper space layout, a new default paper space layout will automatically be generated by AutoCAD.

 

Note: If you try and delete the Model layout an exception will be thrown.

 

Here is a C# sample to erase all paper space layouts...

 

[CommandMethod("EraseAllLayouts")]
public static void EraseAllLayouts() {

   Document doc = Application.DocumentManager.MdiActiveDocument;
   Database db = doc.Database;
   Editor ed = doc.Editor;

   using (Transaction tr = db.TransactionManager.StartTransaction()) {

      // ACAD_LAYOUT dictionary.
      DBDictionary layoutDict = tr.GetObject(db.LayoutDictionaryId, OpenMode.ForRead) as DBDictionary;

      // Iterate dictionary entries.
      foreach (DBDictionaryEntry de in layoutDict) {
         string layoutName = de.Key;
         if (layoutName != "Model") {
            LayoutManager.Current.DeleteLayout(layoutName); // Delete layout.
         }
      }
   }

   ed.Regen();   // Updates AutoCAD GUI to relect changes.
}

 

Hope this helps.

 

Art

Message 4 of 21
fieldguy
in reply to: s.jabs

Be careful with dictionary entries.  I got caught doing the same thing.

 

You are using Dim deItem As DictionaryEntry to iterate through a DBDicitionary.  You should use Dim deItem As DBDictionaryEntry.

 

I got diffrerent results when I made that change. 

Message 5 of 21
Dale.Bartlett
in reply to: s.jabs

This is a great example, thanks. I am finding that the drawing regens throughout the process with "Regenerating model - caching viewports". Regenauto doesn't affect. Does anyone have a way to prevent the screen flashing etc? Also, sometimes the new default layout is the next number, ie "Layout 10". I haven't been able to resolve these small niggles but am really appreciative of the sample. Regards, Dale




______________
Yes, I'm Satoshi.
Message 6 of 21
Dale.Bartlett
in reply to: s.jabs

Update: I had already removed the ed.Regen() line. Dale




______________
Yes, I'm Satoshi.
Message 7 of 21
Artvegas
in reply to: Dale.Bartlett

Hi Dale,

 

The command line output can be temporarily suppressed by setting the NOMUTT system variable. A word of caution though, this can get a little complicated. You need to watch out for happens if the user enters UNDO. You don't want to accidentally leave the user with NOMUTT set to 1 (i.e. if exception is thrown). Refer to the following links for details on this:

http://through-the-interface.typepad.com/through_the_interface/2008/09/no-muttering-at.html

http://through-the-interface.typepad.com/through_the_interface/2008/09/more-quiet-comm.html

 

I think the flashing is caused because this is what happens if you were to do this manually in the AutoCAD UI, it just happens fast. You could set the current layout to model space first, i.e.:

   LayoutManager.Current.CurrentLayout = "Model";

 

See what you mean by it being named "Layout10". Seems to happens when you are replacing a Layout1. Only thing I can think of is to manually rename it to whatever you want using the RenameLayout() method, i.e.:

   DBDictionary layoutDict = tr.GetObject(db.LayoutDictionaryId, OpenMode.ForRead) as DBDictionary;
   if (layoutDict.Count == 1)
   {
      foreach (DBDictionaryEntry de in layoutDict)
      {
         string layoutName = de.Key;
         if (layoutName != "Model")
         {
            LayoutManager.Current.RenameLayout(layoutName, "NewLayoutName");
         }
      }
   }

 

Hope this helps,
Art

Message 8 of 21
andred
in reply to: Artvegas

Thank you ArtVegas, discussion groups are really valuable.

 

I had this code to erase a layout:

 

    Private Function DeleteLayout(ByVal LayoutNameToDelete As String) As Boolean
        Dim bReturnValue As Boolean = True
        Dim oLayoutIDToRename As ObjectId = Nothing
        Dim ed As Editor = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor()
        Dim Db As Database = ed.Document.Database()
        Dim acDoc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument

        oLayoutIDToRename = GetLayoutByName(LayoutNameToDelete)
        Try
            Using doclock As DocumentLock = acDoc.LockDocument
                Using tm1 As Transaction = Db.TransactionManager.StartTransaction()
                    Dim oLayoutToRename As Layout = tm1.GetObject(oLayoutIDToRename, OpenMode.ForWrite)
                    oLayoutToRename.Erase()
                    tm1.Commit()
                    oLayoutToRename = Nothing
                End Using
            End Using
            'Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.Regen()
        Catch ex As Exception
            ed.WriteMessage("\nImpossible de supprimer la présentation " & LayoutNameToDelete & ": " & ex.Message)
            bReturnValue = False
        End Try

       Return bReturnValue

    End Function

 

Here the function GetLayoutByName:

Public Function GetLayoutByName(ByVal layoutName As String) As ObjectId

        Dim oReturnValue As ObjectId = Nothing
        Dim ed As Editor = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor()
        Dim CurrentDb As Database = ed.Document.Database()

        Try
            ''Create a variable to store the list oflayout identifiers
            Dim tm As Autodesk.AutoCAD.DatabaseServices.TransactionManager = CurrentDb.TransactionManager
            Using myT As Transaction = tm.StartTransaction
                ''Open the layout dictionary
                Dim layoutDic As DBDictionary = myT.GetObject(CurrentDb.LayoutDictionaryId, OpenMode.ForRead, False)

                '' Check each layout in the layout table
                Dim Entry As DBDictionaryEntry = Nothing
                For Each Entry In layoutDic
                    Dim layoutId As ObjectId = Entry.Value
                    Dim objLayout As Layout = myT.GetObject(layoutId, OpenMode.ForRead, False)

                    If objLayout.LayoutName.ToUpper = layoutName.ToUpper Then
                        oReturnValue = objLayout.ObjectId
                    End If
                Next
                myT.Commit()
            End Using

        Catch ex As Autodesk.AutoCAD.Runtime.Exception
            oReturnValue = Nothing
        End Try

        Return oReturnValue

    End Function

 

The layout is deleted but AutoCAD become unstable. When I close AutoCAD, it freeze. I don't know why. Now I replace my function by yours (converted in VB .Net and 3 modifications) and it works perfectly.

 

        Dim bReturnValue As Boolean = True
        Dim ed As Editor = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor()
        Dim Db As Database = ed.Document.Database()
        Dim acDoc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument

        Try
            Using doclock As DocumentLock = acDoc.LockDocument
                Using tr As Transaction = Db.TransactionManager.StartTransaction

                    'ACAD_LAYOUT dictionary.
                    Dim layoutDict As DBDictionary = tr.GetObject(Db.LayoutDictionaryId, OpenMode.ForWrite)

                    'Iterate dictionary entries.
                    For Each de As DBDictionaryEntry In layoutDict
                        Dim layoutName As String = de.Key
                        If layoutName.ToUpper = LayoutNameToDelete.ToUpper Then
                            LayoutManager.Current.DeleteLayout(LayoutNameToDelete)
                        End If

                    Next
                    tr.Commit()
                    ed.Regen()
                End Using
            End Using
        Catch ex As Exception
            ed.WriteMessage("\nImpossible de supprimer la présentation " & LayoutNameToDelete & ": " & ex.Message)
            bReturnValue = False
        End Try

        Return bReturnValue

    End Function

I had to make three adjustements. First I replace the openmode to ForWrite and second commit the transaction. Third I also have to lock the document. All the transaction is embed in  a try statement for more security.

 

Hope this help for vb programmer.

 

Regards,

 

André

 

Message 9 of 21
andred
in reply to: Artvegas

Hi ArtVegas,

 

I have a question for you. I have a routine to rename a layout and now a good routine to delete layout. I want to rename a layout sequence order. I already have a routine inserting a layout (ex. insert layout 003, the existing layout 003 is rename to 004 and all subsequent layout). My problem is when I delete a layout. I want to do the same thing in reverse order (ex. delete layout 003, renaming layout 004 to 003, etc.).

 

When I delete layout, i'm using LayoutToBeRemoved to do some processing when I delete a layout, but when I want to rename a layout I have an error saying "Layout already exist". It is ok, because at this event occurs the layout is not deleted. I tried the same thing with LayoutRemoved event, but I have the same problem. But at this stage the layout is supposed to be removed.

 

Do you have any idea?

 

Regards,

 

André

 

Message 10 of 21
Artvegas
in reply to: andred

Hi Andre, I'm not exactly sure what you are trying to do. But it sounds as if AutoCAD is complaining that you are trying to rename a layout to a name that is already being used by another layout, which you wouldn't want to do. Perhaps if you post some simple code that shows the problem I'd get a better understanding and might be able to help.

Message 11 of 21
andred
in reply to: Artvegas

Hi ArtVegas,

 

I will try to better explain my question. I have a drawing with layout named SEQ001, SEQ002, SEQ003, SEQ004, ... I develop a palette with some buttons. On that palette I have a button to add a new layout. If the user add a layout number 3, I actually rename layout SEQ004 to SEQ005, SEQ003 to SEQ004 and insert a new layout named SEQ003. On the same palette I have another button to delete a layout. The current layout is delete and the subsequent layout are rename. Ex. suppressing SEQ003, SEQ004 is rename to SEQ003 and SEQ005 rename to SEQ004. Hera you will find the sub to rename sequences:

 

    Private Sub RenameSequence(ByVal SequenceNo As String, Optional ByVal Decrement As Boolean = False)
        Dim n As Integer = 0
        Dim i As Integer = 0
        Dim objSequence As PlanGeneration.RinsePath.Sequence = Nothing
        Dim strNewLayoutName As String = ""

        n = m_Sequences.SequenceList.Count ' m_sequences is a member variable containing information about layout
        If Decrement = False Then
            For i = n - 1 To 0 Step -1
                objSequence = m_Sequences.SequenceList(i)
                strNewLayoutName = "SEQ" & String.Format("{0:d3}", (CInt(objSequence.SeqNo.Substring(3)) + 1))
                RenameLayout(objSequence.SeqNo, strNewLayoutName)

               'I also rename some layers
                RenameLayer(objSequence.SeqNo & "-BORNE", strNewLayoutName & "-BORNE")
                RenameLayer(objSequence.SeqNo & "-ROUTE", strNewLayoutName & "-ROUTE")
                RenameLayer(objSequence.SeqNo & "-VANNE_OUVERTE", strNewLayoutName & "-VANNE_OUVERTE")
                RenameLayer(objSequence.SeqNo & "-VANNE_FERMEE", strNewLayoutName & "-VANNE_FERMEE")
                If objSequence.SeqNo.ToUpper = SequenceNo.ToUpper Then
                    Exit For
                End If
            Next i
        Else
            Dim j As Integer = GetSequenceOrder(SequenceNo)
            For i = j To n - 1
                objSequence = m_Sequences.SequenceList(i)
                strNewLayoutName = "SEQ" & String.Format("{0:d3}", (CInt(objSequence.SeqNo.Substring(3)) - 1))
                RenameLayout(objSequence.SeqNo, strNewLayoutName)

'I also rename some layers
                RenameLayer(objSequence.SeqNo & "-BORNE", strNewLayoutName & "-BORNE")
                RenameLayer(objSequence.SeqNo & "-ROUTE", strNewLayoutName & "-ROUTE")
                RenameLayer(objSequence.SeqNo & "-VANNE_OUVERTE", strNewLayoutName & "-VANNE_OUVERTE")
                RenameLayer(objSequence.SeqNo & "-VANNE_FERMEE", strNewLayoutName & "-VANNE_FERMEE")
                objSequence.SeqNo = strNewLayoutName

            Next
        End If

    End Sub

'Now the function to rename layout
    Private Function RenameLayout(ByVal oldLayoutName As String, ByVal NewLayoutName As String) As Boolean
        Dim bReturnValue As Boolean = True
        Dim oLayoutIDToRename As ObjectId = Nothing
        Dim ed As Editor = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor()
        Dim Db As Database = ed.Document.Database()
        Dim acDoc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument

        oLayoutIDToRename = GetLayoutByName(oldLayoutName)
        Try
            Using doclock As DocumentLock = acDoc.LockDocument
                Using tm1 As Transaction = Db.TransactionManager.StartTransaction()
                    Dim oLayoutToRename As Layout = tm1.GetObject(oLayoutIDToRename, OpenMode.ForWrite)
                    oLayoutToRename.LayoutName = NewLayoutName
                    tm1.Commit()
                    oLayoutToRename = Nothing
                End Using
            End Using

        Catch ex As Exception
            ed.WriteMessage("\nImpossible de renommer la présentation " & oldLayoutName & " à " & NewLayoutName & ": " & ex.Message)
            bReturnValue = False
        End Try

        Return bReturnValue

    End Function

 

When I use the button all is working well. But if the user delete manually the layout I want to use an event and rename the sequence too.

 

First I used this event:

<CommandMethod("AddLayoutToBeRemoved")> _
    Public Sub AddLayoutToBeRemoved()
        AddHandler LayoutManager.Current.LayoutToBeRemoved, _
            AddressOf onLayoutToBeRemoved
    End Sub

    Private Sub onLayoutToBeRemoved(ByVal senderObj As Object, _
                    ByVal docLayoutEvtArgs As Autodesk.AutoCAD.DatabaseServices.LayoutEventArgs)

        Dim strNextLayoutName As String = ""
        Dim bRenameLayout As Boolean = False

        If docLayoutEvtArgs.Name.ToUpper.StartsWith("SEQ") Then
            If GetLayoutList.Count > 1 Then
                'If m_CurrentSequencePosition < m_Sequences.SequenceList.Count - 1 Then
                '    strNextLayoutName = m_Sequences.SequenceList(m_CurrentSequencePosition + 1).SeqNo
                '    bRenameLayout = True
                'End If
                'Delete layers associated
                If DeleteLayer(m_Sequences.SequenceList(m_CurrentSequencePosition).SeqNo & "-BORNE", True) = False Then bRenameLayout = False
                If DeleteLayer(m_Sequences.SequenceList(m_CurrentSequencePosition).SeqNo & "-ROUTE", True) = False Then bRenameLayout = False
                If DeleteLayer(m_Sequences.SequenceList(m_CurrentSequencePosition).SeqNo & "-VANNE_OUVERTE", True) = False Then bRenameLayout = False
                If DeleteLayer(m_Sequences.SequenceList(m_CurrentSequencePosition).SeqNo & "-VANNE_FERMEE", True) = False Then bRenameLayout = False

                m_Sequences.SequenceList.RemoveAt(m_CurrentSequencePosition)
                If m_CurrentSequencePosition > m_Sequences.SequenceList.Count - 1 Then
                    m_CurrentSequencePosition = m_Sequences.SequenceList.Count - 1
                End If
                If m_CurrentSequencePosition < 0 Then
                    SetCurrentLayoutTab("Model")
                Else
                    SetCurrentLayoutTab(m_Sequences.SequenceList(m_CurrentSequencePosition).SeqNo)
                End If
                'If bRenameLayout = True Then
                '    RenameSequence(strNextLayoutName, True)
                '    SetCurrentLayoutTab(m_Sequences.SequenceList(m_CurrentSequencePosition).SeqNo)
                'End If

            End If
        End If

    End Sub

I realized this event occur before the layout is really deleted, so I understand why renaming my sequence doesn't work. I put some code in comments because it doesn't work. So I found this other event:

 

<CommandMethod("AddLayoutRemoved")> _
    Public Sub AddLayoutRemoved()
        AddHandler LayoutManager.Current.LayoutRemoved, _
            AddressOf onLayoutRemoved
    End Sub

 

    Private Sub onLayoutRemoved(ByVal senderObj As Object, _
                ByVal docLayoutEvtArgs As Autodesk.AutoCAD.DatabaseServices.LayoutEventArgs)

        Dim strNextLayoutName As String = ""
 
        If docLayoutEvtArgs.Name.ToUpper.StartsWith("SEQ") Then
            If GetLayoutList.Count > 1 Then
                If m_CurrentSequencePosition < m_Sequences.SequenceList.Count - 1 Then
                 Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.Regen()
                    strNextLayoutName = m_Sequences.SequenceList(m_CurrentSequencePosition).SeqNo
                    RenameSequence(strNextLayoutName, True)
                    SetCurrentLayoutTab(m_Sequences.SequenceList(m_CurrentSequencePosition).SeqNo)
                 End If
            End If
        End If

    End Sub

 

But I have the same error. When this event occurs the layout does't seem to be deleted too. So I don't know which event to use.

 

So actually, my user must absolutely use the delete layout button. If not, the sequence will be interrupt. If I don't find a solution, I will add another button to correct the sequence but it is not the way I preferred.

 

Thank you very much for your help.

 

Regards,

 

André

 

Message 12 of 21
Artvegas
in reply to: andred

Hi Andre,

 

I noticed that your RenameSequence() function's "for-loop" seems to rename layouts from the largest number to the smallest (i.e. SEQ005 first, then SEQ004, then SEQ003, etc).

 

Lets say your user deletes SEQ003. Then the first thing your code appears to do is try to rename SEQ005 to SEQ004, but you can't because SEQ004 already exists. Perhaps this is the problem?

 

What you should do is get the number of the layout that is removed (say SEQ003), next rename SEQ004 to SEQ003, then rename SEQ005 to SEQ004, then SEQ006 to SEQ005, etc.

 

It's different when you add a layout. Say you're going to add a layout which will become SEQ003. In that case you should start at the biggest number (as per your for-loop). Here you would rename SEQ005 to SEQ006, then SEQ004 to SEQ005, then SEQ003 to SEQ004 and then add the new SEQ003.

 

You get what I mean?

 

Art

Message 13 of 21
andred
in reply to: Artvegas

Hi Art,

 

In my RenameSequence I have an argument Decrement and I have two loops depending of the state of this argument. When I add a layout, Decrement is false, so I begin with the higher sequence number and add 1 to the name. If I delete a layout, Decrement is set to true. I delete the layout and the next sequence is lower by 1 and so on. This routine is working well when I used your function to explicitly delete the layout. But when I start this function from the LayoutRemoved or LayoutToBeRemoved event, it doesn'work because, I don't know why, the layout is not already deleted so when I try to rename SEQ004 to SEQ003 (the one I deleted manually using AutoCAD command) SEQ003 already exist.

 

The problem is with the event. Maybe it is a bug in AutoCAD API.

 

Thank you,

 

André

 

Message 14 of 21
Artvegas
in reply to: Artvegas

Sorry I didn't notice the decrement argument.

 

I created a simple test in C# for the LayoutRemoved event below. For simplicity this is based on layout names being numbers only, i.e. 001, 002, 003, 004, 005, etc.

 

This is not "well-coded" as it assumes that the order of the layouts in the layout-dictionary is sequential which may not always be the case, but this could easily be accounted for with a bit more work.

 

This worked for me when I tested it. So I don't think it's an AutoCAD bug. Could it be something else in your program?

 

 

 

// Command.
[CommandMethod("RegisterLayoutRemoved")]
static public void RegisterLayoutRemoved()
{
	// Register layout removed event.
	LayoutManager.Current.LayoutRemoved
		+= new LayoutEventHandler(Current_LayoutRemoved);
}

// Layout removed event handler.
static void Current_LayoutRemoved(object sender, LayoutEventArgs e)
{
	Document doc = Application.DocumentManager.MdiActiveDocument;
	Database db = doc.Database;
	Editor ed = doc.Editor;

	// Get removed layout number from layout name.
	int removedNum;
	if (!Int32.TryParse(e.Name, out removedNum))
	{
		throw new System.Exception("Could not obtain layout number...");
	}

	using (Transaction tr = db.TransactionManager.StartTransaction())
	{
		// Iterate layout dictionary.
		DBDictionary layoutDict = (DBDictionary)tr.GetObject(
			db.LayoutDictionaryId, OpenMode.ForRead, true);
		foreach (DBDictionaryEntry item in layoutDict)
		{
			// Layout (for read).
			Layout layout
				= (Layout)tr.GetObject(item.Value, OpenMode.ForRead);

			// Try get layout number.
			int i;
			if (Int32.TryParse(layout.LayoutName, out i))
			{
				// If layout number is greater than for layout removed.
				if (i > removedNum)
				{
					// Then decrement layout number.
					layout.UpgradeOpen();
					layout.LayoutName
						= String.Format("{0:D3}", (i - 1));
				}
			}
		}

		tr.Commit();
	}
}

 

 

Message 15 of 21
andred
in reply to: Artvegas

Thank you very much Art,

 

I will try that and I will give you some feedback.

 

Have a good day,

 

André

 

Message 16 of 21
fxcastil
in reply to: s.jabs

Below is a partial of a routine that I use in VBA to remane layouts.

 

You should first remane the layouts, so you don't have have a conflict about remaning layout to existing layouts.

I first added temp to the layout name.

 

Then I use the TabOrder property of the layout to get the order of the layouts.

 

Now you can reanme the layout to a sequence of names based on the TabOrder of the layouts.

 

http://www.theswamp.org/index.php?action=search2

 

 

 

**************** vba routine not vb.net *****************************

 

 

For Each objLayout In objLayouts
    
     lngCnt = lngCnt + 1
     strLayoutName = objLayout.Name
         If strLayoutName <> "Model" Then
             lngTabOrder = objLayouts(objLayout.Name).TabOrder
             lngTabOrder = lngTabOrder + (formRenumber.TxtBoxStartNumber.Value - 1)
             objLayout.Name = "tempLayout" & lngTabOrder
             DoEvents
         End If

    Call ProgUpdate(lngCnt)
    DoEvents

Next

Call ProgSetup(objLayouts.Count)

formProgRenumLay.Caption = " Re-Naming objLayouts "

lngCnt = 0
For Each objLayout In objLayouts
     lngCnt = lngCnt + 1
     strLayoutName = objLayout.Name
         If strLayoutName <> "Model" Then
            objLayout.Name = formRenumber.txtBoxLayName & _
            CStr(Mid$(strLayoutName, 11, (Len(strLayoutName) - 10))) ' Rename and renumber objLayout
            DoEvents
         End If

Message 17 of 21
Dale.Bartlett
in reply to: Artvegas

There is a flaw with this code:

DBDictionary layoutDict = tr.GetObject(db.LayoutDictionaryId, OpenMode.ForRead) as DBDictionary;
      // Iterate dictionary entries.
      foreach (DBDictionaryEntry de in layoutDict)

     {
         string layoutName = de.Key;
         if (layoutName != "Model")
            LayoutManager.Current.DeleteLayout(layoutName); // Delete layout.
}

 

An item is being deleted from a list that is being interated. I fall into this trap over and over...

A list of names should be collected and iterated instead.

 

string[] layouts = GetLayoutNames();

foreach (string LayoutName in layouts)

{

if (LayoutName.ToUpper() != "MODEL" || LayoutName.ToUpper() != pstrLayoutToKeep.ToUpper())

    LayoutManager.Current.DeleteLayout(LayoutName);

}

 

I had been using the first code but results were unreliable, particularly when I attempt to rename Layout1 (which it thinks still exists).

Dale

 




______________
Yes, I'm Satoshi.
Message 18 of 21
AUGIFrance
in reply to: Artvegas

I had to add a tr.Commit(); for this to work.

Message 19 of 21
SENL1362
in reply to: AUGIFrance

For the first solution, of course, being in a transaction.
But pay attension to his warning: " do not alter collections in a loop unless casted to a list.

Delete layout's using the LayoutManager doesn't require a Commit. A Regen may be required to see the results.

Message 20 of 21
AUGIFrance
in reply to: SENL1362

Without the tr.Commit(); I do not see any results, layouts are not erased, with the tr.Commit();, they are.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost