InsertRow on Cursor returns error after stopping an EditOperation and Start a new one

4884
14
03-02-2011 01:15 AM
karinweixler
New Contributor II
Hello,
i am trying to migrate Code from AG 9.3 with VS 2005 to AG 10 with VS 2010. In AG 10 i have the following Problem:
'I create a reference to a FeatureTable and Cursor: (this is done outside of the edit session)

FLSTSLnkTable = DBConnection.newpGDBCon.GetFeatureTable("w_Lnk_FLS_TS")
FLSTSLnkCursor = FLSTSLnkTable.Insert(False)

'After that I start the EditSession and an Editoperation:

aoiWorkspaceEdit.StartEditing(True)
aoiWorkspaceEdit.StartEditOperation()

'in this EditOperation i use the InsertRow into the FeatureTable via the cursor and rowbuffer:

Dim myRowBuffer As IRowBuffer
myRowBuffer = FLSLnkTable.CreateRowBuffer
Dim myRow As IRow
myRow = myRowBuffer
Try
    With myRow
         .Value(.Fields.FindField(LnkFLSIdName)) = FeatFeldId
         .Value(.Fields.FindField(LnkSonstIdName)) = Me.ID
         .Value(.Fields.FindField("Flaechenanteil")) = myIntersectArea / 10000
    End With
    FLSLnkCursor.InsertRow(myRowBuffer)
Catch ex As Exception
    MsgBox(ex.Message, MsgBoxStyle.Critical)
    Exit Sub
End Try

'then i stop the edit operation:

aoiWorkspaceEdit.StopEditOperation()

'after that i start a new EditOperation:

aoiWorkspaceEdit.StartEditOperation()

'and then i try to insert another row into the FeatureTable via the cursor and rowbuffer:
and here i get the following error when it comes to the line "FLSLnkCursor.InsertRow(myRowBuffer)":
"The cursor has been invalidated because the edit operation has stopped."

In ArcGIS 9.3 this worked fine. Is there a change in which order i do the reference to the objects in ArcGIS 10? Does someone have a hint how to deal with this error?
Thanks in advance.

Greetings Karin
0 Kudos
14 Replies
karinweixler
New Contributor II
one more thing:
I tried it also to create the reference of the cursor inside of the EditOperation as it is said in the help (if i understand that one right). But then i get the following error message on the line "FLSLnkCursor.InsertRow(myRowBuffer)":
"Error HRESULT E_FAIL has been returned from a call to a COM component."

I can remember this was also the point with ArcGIS 9.3 and the reason i put the Cursor outside of the editsession.
0 Kudos
NeilClemmons
Regular Contributor III
In your call to StartEditing you're specifying that you want undo/redo capability.  Unless you're implementing this functionality I would pass in False.  Is there any reason why you need to enclose each edit in its own operation?  If not, then just use a single operation - start editing, start operation, perform all edits, stop operation, stop editing.  I can't say that I've ever tried to use the same cursor in multiple operations.
0 Kudos
karinweixler
New Contributor II
Thanks Neil for your reply. Yes the undo/redo function i would like to implement, because it is a very nice feature. Well the thing is that everything worked in ArcGIS 9.3 and it is always hart to explain to the user, why he will not have this feature in the new version.
0 Kudos
NeilClemmons
Regular Contributor III
If you want undo/redo functionality then you will probably have to get a new cursor for each edit.  I don't know for sure, but it could be that operations cannot be supported inside the same cursor.  That kind of makes sense when you think about it.  Cursors in ArcObjects are forward-only so how do you go back and undo an edit?  The solution is probably to just dump the whole cursor.  This may have been a bug that ESRI fixed.  For instance, the definition of a shapefile requires that the attribute table have at least one field (the FID and Shape fields don't count because they aren't stored in the .dbf file).  This is why you always have that Id field when you create a shapefile through ArcCatalog and you can't delete it unless you add another field.  At one time, you could create a shapefile through code with no attribute fields even though that was a violation of the shapefile definition.  ESRI eventually fixed this bug and now you can't do that.  The side effect of this bug fix is that it broke a lot of (incorrect) code.  This may be the case here with your code.  Again, that's just a theory.  Try getting a new cursor for each edit and see if that fixes the problem.
0 Kudos
karinweixler
New Contributor II
Thanks again. But this is exactly the problem i have: i can not get a reference to the cursor inside the editoperation, because then i get the HRESULT E_FAIL error message (second post). As it looks the error is thrown because the Table in which the row should be inserted, has some relationsships that are not from the ObjectId of the Table to another Table. If I delete those relationships sometimes (not in every case) the reference inside of the editoperation is working. But this would be a big change in my Database and also in the code. So i really hope there is a different way getting this work.
0 Kudos
NeilClemmons
Regular Contributor III
Can't you get a new cursor in between the call to StopOperation for one edit and the call to StartOperation for the next edit?  You don't have to stop the edit session as the error seems to be complaining about the operation, not the session.
0 Kudos
karinweixler
New Contributor II
Unfortunately i always get the "Error HRESULT E_FAIL has been returned from a call to a COM component" if i put the reference for the Cursor inside of the Editsession. Even if i dont use the Undo/Redo function and the EditOperation. Can this be a bug in ArcMap, or is the curser just not made for tables with relationships? Or am i doing something wrong? I tried it with get the reference to the table also inside the editsession and one time oustside of the editsession, same result.
0 Kudos
NeilClemmons
Regular Contributor III
I don't have any problems executing the following code.  Maybe you'll see something that you're doing differently.  Let me know how it goes.

        Try
            Dim mxDocument As IMxDocument = DirectCast(m_application.Document, IMxDocument)
            Dim map As IMap = mxDocument.FocusMap
            Dim standaloneTableCollection As IStandaloneTableCollection = DirectCast(map, IStandaloneTableCollection)
            Dim standAloneTable As IStandaloneTable = standaloneTableCollection.StandaloneTable(0)

            Dim table As ITable = standAloneTable.Table
            Dim dataset As IDataset = DirectCast(table, IDataset)

            Dim workspace As IWorkspace = dataset.Workspace
            Dim workspaceEdit As IWorkspaceEdit = DirectCast(workspace, IWorkspaceEdit)

            If Not workspaceEdit.IsBeingEdited Then workspaceEdit.StartEditing(True)

            workspaceEdit.StartEditOperation()
            Dim insertCursor As ICursor = table.Insert(True)

            Dim rowBuffer As IRowBuffer = table.CreateRowBuffer
            Dim index As Int32 = table.Fields.FindField("scenario_id")
            rowBuffer.Value(index) = "test scenario"
            Dim oid As Int32 = Convert.ToInt32(insertCursor.InsertRow(rowBuffer))

            workspaceEdit.StopEditOperation()

            Marshal.ReleaseComObject(insertCursor)
            Marshal.ReleaseComObject(rowBuffer)

            workspaceEdit.StartEditOperation()
            insertCursor = table.Insert(True)

            rowBuffer = table.CreateRowBuffer()
            rowBuffer.Value(index) = "test scenario"
            insertCursor.InsertRow(rowBuffer)

            workspaceEdit.StopEditOperation()

            Marshal.ReleaseComObject(insertCursor)
            Marshal.ReleaseComObject(rowBuffer)

            workspaceEdit.StopEditing(True)
        Catch ex As Exception
            MessageBox.Show(ex.ToString)
        End Try
0 Kudos
AlexanderGray
Occasional Contributor III
Looking at the original code posted, I noticed you have a try/catch block inside the operation.  That is fine but when you catch an exception you should stop or abort the edit operation, if you don't you will leave a dangling edit operation which could result in a error the next time through.
0 Kudos