How to get exclusive schema lock

487
2
08-24-2010 03:20 PM
GordonReese
New Contributor
I am trying to write code that will run the 'Extract Values To Points' procedure against every raster in a selected set.  That portion of my code works, but I suspect I am making errors when I reuse object variables.  After the extraction loop completes, I want to add X- and Y- coordinates to the last feature class that was created.  I have been unable to get that to work.  Even if I exit the code and try running the 'AddXY' tool from the same project, I get: "ERROR 000464: Cannot get exclusive schema lock...".  However, if I open a new project and add that feature class, then there is no problem with the 'AddXY' tool.

Why am I unable to add the coordinates in the first case?  Is there a way to 'free' that feature class from whatever is not allowing the coordinates to be added?  Many thanks in advance.

That portion of my code follows:
    Dim pLayer As ILayer
    Dim pFLayer As IFeatureLayer
    Set pFLayer = New FeatureLayer
   
    Dim pWkFactory As IWorkspaceFactory
    Set pWkFactory = New ShapefileWorkspaceFactory
   
    Dim pFWkSpace As IFeatureWorkspace
    Dim pFClass As IFeatureClass

    Dim pFields As IFields
    Dim pField As IField
    Dim pFieldEdit As IFieldEdit
   
'CODE:
    'Load selected layer (FLResponse was NOT dimensioned)
    FLResponse = cboResponse.Value
   
    'Iterate through selected covariates
    For i = 0 To lboCovariate.ListCount - 1
        'Path and name of shapefile to be created
        fileExtract = tmpFolder & "\UseExtraction" & i & ".shp"

        'Load each covariate layer
        RLCovarTif = lboCovariate.List(i)

        ' Process: Extract Values to Points...
        If i = 0 Then
            gp.ExtractValuesToPoints_sa FLResponse, RLCovarTif, fileExtract, "NONE", "VALUE_ONLY"
        Else
            gp.ExtractValuesToPoints_sa pFClass2, RLCovarTif, fileExtract, "NONE", "VALUE_ONLY"
        End If

        FLResponse = "UseExtraction" & i
       
        'Delete new layer from project
        For j = 0 To pMap.LayerCount - 1
            If (pMap.Layer(j).Name) = (FLResponse) Then
                pMap.DeleteLayer pMap.Layer(j)
                pMxDoc.UpdateContents
                Exit For
            End If
        Next j
       
        'Load most recent extraction point layer
        Set pFWkSpace = pWkFactory.OpenFromFile(tmpFolder & "\", 0)
        Set pFClass = pFWkSpace.OpenFeatureClass(FLResponse)

        'Get all fields and change name of extracted raster field
        'This is done so that another raster field can be added
        Set pFields = pFClass.Fields
        Set pField = pFields.Field(pFields.FindField("RASTERVALU"))
        Set pFieldEdit = pField
        pFieldEdit.Name = "RasVal" & i
    Next i

    'Add last shapefile to map
    'I suspect that some of this code is unnecessary
    Set pFLayer.FeatureClass = pFClass
    pFLayer.Name = FLResponse
    pMap.AddLayer pFLayer
       
    For j = 0 To pMap.LayerCount - 1
        If (pMap.Layer(j).Name) = (FLResponse) Then
            Set pLayer = pMap.Layer(j)
            Exit For
        End If
    Next
    Set pFLayer = pLayer
    FLResponse = pLayer.Name

    'This next line does not add POINT_X and POINT_Y fields
    'Even if I exit the code and try running AddXY tool (ArcToolbox) I get an error:
    'Error 000464: Cannot get exclusive schema lock. Either being edited
    'or in use by another application. Failed to execute (AddXY).
    'However, if I close out of the project, open a new project, and open the
    'feature layer that was most recently created, I see all of the expected
    'fields (though the last field has the original field name) and can then
    'execute the AddXY tool.
    gp.AddXY_management FLResponse
0 Kudos
2 Replies
JamesMacKay
New Contributor
Hi Gordon,

Although I'm not sure what's causing your issue, I think you'll have to rework your approach on account of this step:

'Get all fields and change name of extracted raster field
'This is done so that another raster field can be added
Set pFields = pFClass.Fields
Set pField = pFields.Field(pFields.FindField("RASTERVALU"))
Set pFieldEdit = pField
pFieldEdit.Name = "RasVal" & i


It isn't possible to change the name of an existing field through ArcObjects. Although the properties of the objects in-memory may look like a change has occurred, if you look at the underlying data source the changes won't be reflected there and you may get unexpected behaviour.

Cheers,
James
0 Kudos
GordonReese
New Contributor
Hi James,

Many thanks for your suggestion.  As a result, I modified the code to add a new field, copy the values from the RASTERVALU field (instead of renaming it), and then delete the RASTERVALU field.  Unfortunately, the same error still occurred.

To try and isolate the cause of the problem, I reduced the code to the following:
    
FLResponse = cboResponse.Value
RLCovarTif = lboCovariate.List(0)
fileExtract = tmpFolder & "\UseExtraction0.shp"
    
gp.ExtractValuesToPoints_sa FLResponse, RLCovarTif, fileExtract, "NONE", "VALUE_ONLY"
    
FLResponse = "UseExtraction0"

gp.AddXY_management FLResponse

It worked, so the resulting question then was how to implement this working code in a loop that would process any number of raster layers.  For unknown reasons, I found that I need to run the AddXY tool before I delete the newly created layer from the project.  So I am currently adding it after the last extraction with this code:
' Process: Extract Values to Points...
If i = 0 Then
    gp.ExtractValuesToPoints_sa FLResponse, RLCovarTif, fileExtract, "NONE", "VALUE_ONLY"
Else
    gp.ExtractValuesToPoints_sa pFClass2, RLCovarTif, fileExtract, "NONE", "VALUE_ONLY"
End If

FLResponse = "UseExtraction" & i

'NEW CODE
If (i = (lboCovariate.ListCount - 1)) Then
    gp.AddXY_management FLResponse
End If


The full code for that procedure is then:
    For i = 0 To lboCovariate.ListCount - 1
        fileExtract = tmpFolder & "\UseExtraction" & i & ".shp"
        RLCovarTif = lboCovariate.List(i)

        ' Process: Extract Values to Points...
        If i = 0 Then
            gp.ExtractValuesToPoints_sa FLResponse, RLCovarTif, fileExtract, "NONE", "VALUE_ONLY"
        Else
            gp.ExtractValuesToPoints_sa pFClass2, RLCovarTif, fileExtract, "NONE", "VALUE_ONLY"
        End If
        FLResponse = "UseExtraction" & i
        
        If (i = (lboCovariate.ListCount - 1)) Then
            'Add X- and Y- coordinates
            gp.AddXY_management FLResponse
        End If
        
        'Delete new layer from project
        For j = 0 To pMap.LayerCount - 1
            If (pMap.Layer(j).Name) = (FLResponse) Then
                pMap.DeleteLayer pMap.Layer(j)
                pMxDoc.UpdateContents
                Exit For
            End If
        Next j
        
        'Load most recent extraction point layer
        Set pFWkSpace2 = pWkFactory2.OpenFromFile(tmpFolder & "\", 0)
        Set pFClass2 = pFWkSpace2.OpenFeatureClass(FLResponse)

        'Get all fields of extraction point layer
        Set pFields = pFClass2.Fields

        'This checks if a field of proposed name already exists
        intRasField = pFields.FindField("RasVal" & i)
        
        If intRasField = -1 Then 'Proposed field name does NOT exist
            pFieldEdit.Name = ("RasVal" & i)
            pFClass2.AddField pFieldEdit
            
            'Set index to position of the new field
            intRasField = pFields.FindField("RasVal" & i)
        End If
        
        'Find position of original raster field
        intOrigRasVal = pFields.FindField("RASTERVALU")
        
        'Set values of new field to RASTERVALU
        Set pFCursor = pFClass2.Update(Nothing, True)
        Set pFeature = pFCursor.NextFeature
        Do Until pFeature Is Nothing
            'Copy value from RASTERVALU (it will only 1st be in memory)
            pFeature.Value(intRasField) = pFeature.Value(intOrigRasVal)
            
            'Write it to the feature class
            pFCursor.UpdateFeature pFeature
            Set pFeature = pFCursor.NextFeature
        Loop
        Set pField = pFields.Field(pFields.FindField("RASTERVALU"))
        pFClass2.DeleteField pField
        
        'If last covariate layer in list was processed, add response data
        If (i = (lboCovariate.ListCount - 1)) Then
            'This checks if a field of proposed name already exists
            intResField = pFields.FindField("Response")
            
            If intResField = -1 Then 'Proposed field name does NOT exist
                pFClass2.AddField pFieldEdit2
            
                'Set index to position of the new field
                intResField = pFields.FindField("Response")
            End If
            
            'Set values of Response field to use = 1
            Set pFCursor = pFClass2.Update(Nothing, True)
            Set pFeature = pFCursor.NextFeature
            Do Until pFeature Is Nothing
                pFeature.Value(intResField) = 1
            
                'Write it to the feature class
                pFCursor.UpdateFeature pFeature
                Set pFeature = pFCursor.NextFeature
            Loop
        End If
    Next i

Cheers,
  Gordon
0 Kudos