Calculate Values

Created:12/26/2000
Description:

This sample demonstrates how to perform a calculation outside of an edit session. Calculations done outside of an edit session are normally faster then calculations within an edit session, but there is no way to undo the changes.

The first routine performs a simple calculation where all records in an integer field are set to 10. The second rountine uses VBA to determine the length of each feature and writes this value to the appropriate row in the table. The last routine is a function which is called by the first 2 routines. It returns True if the data you are using can be edited outside of an edit session. This sample mimics the behavior of the calculate values command in the column context menu of the table window.

To see how to perform calculations within an edit session, see the examples in the help for the ICalculator and ICalculatorCallback Interfaces.


How to use:
  1. Paste the code into VBA.
  2. Make sure ArcMap is not in edit mode.
  3. Select the feature layer that you want to calculate. The calc_VBA routine requires that the layer have polyline geometry.
  4. For the calc_Simple script, make sure that a short field named shortfld is in the selected layer. The calc_VBA script also requires a double field named len. Alternatively, you can adjust the scripts to use different field names.
  5. Run the sample.
Public Sub calc_Simple()
  
  On Error GoTo EH
  
  Dim pDoc As IMxDocument
  Set pDoc = ThisDocument

  ' Get the layer that is selected in the TOC
  ' it must be a polygon layer
  Dim pFeatLayer As IFeatureLayer
  Dim pFeatClass As IFeatureClass
  Dim pUnKnown As IUnknown
  Set pUnKnown = pDoc.SelectedLayer
  If pUnKnown Is Nothing Then
    MsgBox "Must have a layer selected in the table of contents."
    Exit Sub
  End If
  Set pFeatLayer = pUnKnown
  Set pFeatClass = pFeatLayer.FeatureClass
  
  ' This calculation is to be done outside of an edit session.
  Dim pEditor As IEditor
  Dim pID As New UID
  pID = "esriCore.Editor"
  Set pEditor = Application.FindExtensionByCLSID(pID)
  If pEditor.EditState = esriStateEditing Then
    MsgBox "This sample requires that ArcMap is not in edit mode"
    Exit Sub
  End If
  
  ' Also, check to see if the selected layer supports editing without
  ' an edit session
  If Not CanEditWOEditSession(pFeatClass) Then
    MsgBox "This layer cannot be edited outside of an edit session"
    Exit Sub
  End If

  ' Find the field named AreaCalc
  Dim pCalc As ICalculator
  Dim pTable As ITable
  Dim pField As IField
  Dim intFldIndex As Integer
  Set pTable = pFeatClass
  intFldIndex = pTable.FindField("shortfld")
  If intFldIndex = -1 Then
    MsgBox "There must be a field named AreaCalc in the layer"
    Exit Sub
  End If
  
  ' Perform the calculation. Make sure to use an update cursor when
  ' editing outside of an edit session.
  Dim pCursor As ICursor
  Set pCalc = New Calculator
  Set pCursor = pFeatClass.Update(Nothing, True)

   With pCalc
      Set .Cursor = pCursor
      .Expression = "10"
      .Field = "shortfld"
   End With
  pCalc.Calculate

  Exit Sub
EH:
   
  MsgBox Err.Number &"  "& Err.Description

End Sub

Public Sub calc_VBA()
  
  On Error GoTo EH
  
  Dim pDoc As IMxDocument
  Set pDoc = ThisDocument

  ' Get the layer that is selected in the TOC
  ' it must be a line layer
  Dim pFeatLayer As IFeatureLayer
  Dim pFeatClass As IFeatureClass
  Dim pUnKnown As IUnknown
  Set pUnKnown = pDoc.SelectedLayer
  If pUnKnown Is Nothing Then
    MsgBox "Must have a line layer selected in the table of contents."
    Exit Sub
  End If
  Set pFeatLayer = pUnKnown
  Set pFeatClass = pFeatLayer.FeatureClass
  If Not pFeatClass.ShapeType = esriGeometryPolyline Then
    MsgBox "Selected layer must be a line layer"
    Exit Sub
  End If
  
  ' This calculation is to be done outside of an edit session.
  Dim pEditor As IEditor
  Dim pID As New UID
  pID = "esriCore.Editor"
  Set pEditor = Application.FindExtensionByCLSID(pID)
  If pEditor.EditState = esriStateEditing Then
    MsgBox "This sample requires that ArcMap is not in edit mode"
    Exit Sub
  End If
  
  ' Also, check to see if the selected layer supports editing without
  ' an edit session
  If Not CanEditWOEditSession(pFeatClass) Then
    MsgBox "This layer cannot be edited outside of an edit session"
    Exit Sub
  End If

  ' Find the fields named x and y
  Dim pCalc As ICalculator
  Dim pTable As ITable
  Dim pField As IField
  Dim intFldIndex As Integer
  Set pTable = pFeatClass
  intFldIndex = pTable.FindField("len")
  If intFldIndex = -1 Then
    MsgBox "There must be a field named len in the layer"
    Exit Sub
  End If
  
  ' Perform the calculation
  Set pCalc = New Calculator
  Dim pCursor As ICursor
  Set pCursor = pFeatClass.Update(Nothing, True)
  With pCalc
     Set .Cursor = pCursor
     .PreExpression = "Dim dblLength as double" & vbNewLine & _
                      "Dim pCurve As ICurve" & vbNewLine & _
                      "Set pCurve = [Shape]" & vbNewLine & _
                      "dblLength = pCurve.Length"
     .Expression = "dblLength"
     .Field = "len"
  End With
  pCalc.Calculate
  Set pCursor = Nothing
  
  Exit Sub
EH:
   
  MsgBox Err.Number &"  "& Err.Description

End Sub

' Returns TRUE if the Table can be edited outside of an edit session
Private Function CanEditWOEditSession(pTable As ITable) As Boolean

  Dim pVersionedObject As IVersionedObject
  Dim pObjClassInfo2 As IObjectClassInfo2
  Dim bolVersioned As Boolean
  Dim bolEditable As Boolean
  
  ' See if the data is versioned
  If Not TypeOf pTable Is IVersionedObject Then
    bolVersioned = False
  Else
    Set pVersionedObject = pTable
    bolVersioned = pVersionedObject.IsRegisteredAsVersioned
  End If
  
  ' Check the CanBypassEditSession property
  Set pObjClassInfo2 = pTable
  bolEditable = pObjClassInfo2.CanBypassEditSession

  If bolEditable And Not bolVersioned Then
    CanEditWOEditSession = True
  Else
    CanEditWOEditSession = False
  End If

End Function