.NET

.NET

Reply
Active Contributor
34 Posts
0 Kudos
Registered: ‎05-12-2014
Post 1 of 3
Accepted Solution

Layer Delete - Operation is not valid due to the current state of the object.

141 Views, 2 Replies
07-24-2014 09:28 AM

Hello,

 

I have this function (below) that that deletes a layer.

I am looping thru an array of names that I want deleted.

 

Two Things:

Visual Studio is warning:

Function 'LayerDelete' doesn't return a value on all code paths. A null reference exception could occur at run time when the result is used.

 

And this Error:

Unhandled Exception.... Operation is not valid sue to the current state of the object.

FATAL ERROR

 

The code was an answer to another question (which worked), but now that I tweaked it Im having issues...

 

How can I fix the code so It doesnt crash and that "it returns a value on all code paths"?

 

 

Function LayerDelete(ByVal db As Database, ByVal layerName As String) As String
            If (layerName = "0") Then
                Return "Layer '0' cannot be deleted."
            End If
            Dim tr As Transaction = db.TransactionManager.StartTransaction
            Dim layerTable As LayerTable = CType(tr.GetObject(db.LayerTableId, OpenMode.ForRead), LayerTable)
            If Not layerTable.Has(layerName) Then
                Return ("Layer '" + (layerName + "' not found."))
            End If
            Try
                'Dim layerId As Object = layerTable(layerName)
                Dim layerId As ObjectId = layerTable(layerName)
                If Application.GetSystemVariable("Clayer") = layerName Then
                    Return "Current layer cannot be deleted."
                End If
                Dim layer As LayerTableRecord = CType(tr.GetObject(layerId, OpenMode.ForWrite), LayerTableRecord)
                layer.IsLocked = False
                Dim blockTable As BlockTable = CType(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
                'For Each btrId As Object In blockTable
                For Each btrId As ObjectId In blockTable
                    Dim block As BlockTableRecord = CType(tr.GetObject(btrId, OpenMode.ForRead), BlockTableRecord)
                    'For Each entId As Object In block
                    For Each entId As ObjectId In block
                        Dim ent As Entity = CType(tr.GetObject(entId, OpenMode.ForRead), Entity)
                        If (ent.Layer = layerName) Then
                            ent.UpgradeOpen()
                            ent.Erase()
                        End If
                    Next
                Next
                layer.Erase()
                tr.Commit()
                'MsgBox("Layer '" + (layerName + "' have been deleted."))
            Catch e As System.Exception
                MsgBox("Error: " + e.Message)
            End Try
        End Function

 

I am not a VB.Net guy but it looks like you are not returning a value inside of your catch statement.  This is a valid code path so your function needs to return a value from it.  You should set a default value for your string and either return it or just return null.  You could also throw the error up to the calling function.

 

Also you have created a transaction but you are not disposing of it anywhere.  Transactions impliment IDisposable so they must be disposed.  You can make this easy by always declaring your Transactions inside a using statement.  This will insure that Dispose is called automatically when leaving the Using block of code.

 

You can read about the using statement here.  http://msdn.microsoft.com/en-us/library/htd05whh.aspx  and here.  http://adndevblog.typepad.com/autocad/2012/05/two-common-mistakes-with-transactions.html

 

This might not completely fix your errors but they are two that I see from glancing at it quickly.

 

 

*Expert Elite*
1,277 Posts
109 Kudos
Registered: ‎03-13-2008
Post 2 of 3

Re: Layer Delete - Operation is not valid due to the current state of the object

07-24-2014 10:30 AM in reply to: tony.tomison.iii

I am not a VB.Net guy but it looks like you are not returning a value inside of your catch statement.  This is a valid code path so your function needs to return a value from it.  You should set a default value for your string and either return it or just return null.  You could also throw the error up to the calling function.

 

Also you have created a transaction but you are not disposing of it anywhere.  Transactions impliment IDisposable so they must be disposed.  You can make this easy by always declaring your Transactions inside a using statement.  This will insure that Dispose is called automatically when leaving the Using block of code.

 

You can read about the using statement here.  http://msdn.microsoft.com/en-us/library/htd05whh.aspx  and here.  http://adndevblog.typepad.com/autocad/2012/05/two-common-mistakes-with-transactions.html

 

This might not completely fix your errors but they are two that I see from glancing at it quickly.

 

 


Keith Brown AutoCAD MEP BLOG | RSS Feed
AutoCAD MEP 2014 | Revit 2014 | EastCoast CAD/CAM V6.1 | Visual Studio 2013
────────────────────────────────────
⁞|⁞ Please use Mark Solutions!.Accept as Solution and Give Kudos!Give Kudos as appropriate. Thank you!
Active Contributor
34 Posts
0 Kudos
Registered: ‎05-12-2014
Post 3 of 3

Re: Layer Delete - Operation is not valid due to the current state of the object

07-24-2014 01:17 PM in reply to: Keith.Brown

Thanks,

 

I modified the IF with an else that does tx.dispose() before the end of the function and that took care of it.

 

As far as returning the right code path I'm not quite too sure at the moment, but its not causing major errors at the moment so i'll place it on the back burner for now.

 

Tony

Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Announcements
Are you interested in helping shape the future of the Autodesk Community? To participate in this brief usability study, please click here. Your time and input is greatly appreciated!