3

I want to add a new field to my featureclass.My code for that is:

        public IMxDocument mxDoc;
        public IMap map;
        IFieldEdit2 field = new FieldClass() as IFieldEdit2;
        field.Name_2 = "Parcel_Way";
        field.Type_2 = esriFieldType.esriFieldTypeString;
        field.Length_2 = 50;
        field.DefaultValue_2 = "Parcel";
        IFeatureLayer2 flayer=map.Layer[cmboxLayer2.SelectedIndex] as IFeatureLayer2;
        IFeatureClass featureclass = flayer.FeatureClass;

        try
        {
            featureclass.AddField(field);
        }
        catch (Exception ex)
        {
            System.Windows.Forms.MessageBox.Show(ex.Message, ex.Source);
            throw;
        }

Program return this error : enter image description here

What do i neglecting ?

3 Answers 3

3

Adding a field directly in ArcMap may not work if the feature class is included in your mxd.

Usually, before modifying a feature class schema(such as adding a field), you should acquire an exclusive schema lock, to ensure that the feature class is opened only by your code.

Here's an example acquiring a schema lock

// Try to acquire an exclusive schema lock.
ISchemaLock schemaLock = (ISchemaLock)yourFeatureClass;
try
{
    schemaLock.ChangeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock);

    // Add your field.
    ...
}
catch (COMException comExc)
{
    // Handle the exception appropriately for the application.
}
finally
{
    // Demote the exclusive lock to a shared lock.
    schemaLock.ChangeSchemaLock(esriSchemaLock.esriSharedSchemaLock);
}

In your case, probably that you won't be able to acquire a lock because the feature class you want to lock is already opened in your mxd document.

ArcCatalog may be a better place to add this kind of code.

6
  • Thanks dear Goldrak. But i need to work in arcMap Aug 16, 2014 at 15:02
  • This code worked.But for second time cant to add another field and i cant delete any field from featureclass too. :( Aug 16, 2014 at 15:16
  • Acquiring a schema lock is a good idea, but you still need to test if it has one. Add a boolean like HaveExclusive initialized to false and set it to true after getting the exclusive schema lock then before attempting to add the field check the HaveExclusive value. The way this stands the code will run through whether or not you get a schema lock, you will only be able to add or remove fields if you have exclusive schema lock. Aug 17, 2014 at 21:36
  • Correct me if I'm wrong, but if the schema lock acquisition, it will fall on the COMException catch block, so you can handle the failure. I believe this code is the good way to do it, I took it from an ArcGIS sample code
    – Goldorak84
    Aug 19, 2014 at 12:13
  • @MahdiAhmadi If the second time you add a field, you encounter the same error as before, as michealMilesStimson suggested, consider calling Marshal.ReleaseComObject(featureClass); when you're done with your FeatureClass
    – Goldorak84
    Aug 19, 2014 at 12:19
0

IFeatureClass.AddField expects a field object, in this case you are providing a IFieldEdit object - thus the type mismatch and error.

Try it this way:

    public IMxDocument mxDoc;
    public IMap map;
    IField NewField = new FieldClass();
    IFieldEdit2 field = (IFieldEdit2)NewField;
    field.Name_2 = "Parcel_Way";
    field.Type_2 = esriFieldType.esriFieldTypeString;
    field.Length_2 = 50;
    field.DefaultValue_2 = "Parcel";
    IFeatureLayer2 flayer=map.Layer[cmboxLayer2.SelectedIndex] as IFeatureLayer2;
    IFeatureClass featureclass = flayer.FeatureClass;

    try
    {
        featureclass.AddField(NewField);
    }
    catch (Exception ex)
    {
        System.Windows.Forms.MessageBox.Show(ex.Message, ex.Source);
        throw;
    }

The difference is that I create an IField as new FieldClass() and then modify that field using the IFieldEdit2 interface; IFields themselves cannot be modified directly and need to be cast to an IFieldEdit to modify them, then the new field can be added using the AddField method. The IFieldEdit needs to reference an IField, by casting it directly using IFieldEdit2 field = new FieldClass() as IFieldEdit2; does that but the IField itself is not linked to anything.

3
  • Even if he uses an IFieldEdit2 Interface pointer, the underlying COM object is still a FieldClass. Then he passes his IFieldEdit2 object to the AddField method, there will be an implicit cast to IField interface. The problem is probably because he can't acquire schema lock, because the feature class is opened in ArcMap
    – Goldorak84
    Aug 15, 2014 at 15:35
  • Yeah, I can't to add field with this cod too. This code return same error too. I am agree with Goldorak84 and i think problem is probably because of that layer is open and in use with arcMap. Aug 16, 2014 at 14:52
  • 1
    Consider your locking situations, you can lock a feature class by having it open in multiple instances of ArcMap/Catalog or locked by a cursor/feature buffer. Catalog will sometimes continue a lock if you have looked inside the database and then moved on without exiting. If you have any cursors on the feature class you will need to remove them using ReleaseComObject msdn.microsoft.com/en-us/library/… Aug 17, 2014 at 21:41
0

You can also use the GeoProcessor to add a field.

Function AddField(ByVal TableName As Object, ByVal FieldName As String, ByVal Type As String, Optional ByVal Precision As Integer = 0, Optional ByVal Scale As Integer = 0, Optional ByVal Length As Integer = 0) As Boolean

    Dim NewField As ESRI.ArcGIS.DataManagementTools.AddField = New ESRI.ArcGIS.DataManagementTools.AddField
    Dim Result As ESRI.ArcGIS.Geoprocessing.IGeoProcessorResult2
    Dim GP = New ESRI.ArcGIS.Geoprocessor.Geoprocessor

    Try
        Using releaser As New ESRI.ArcGIS.ADF.ComReleaser
            releaser.ManageLifetime(NewField)

            NewField.in_table = TableName
            NewField.field_name = FieldName
            NewField.field_type = Type
            If Precision <> 0 Then NewField.field_precision = Precision
            If Scale <> 0 Then NewField.field_scale = Scale
            If Length <> 0 Then NewField.field_length = Length

            Result = CType(GP.Execute(NewField, Nothing), ESRI.ArcGIS.Geoprocessing.IGeoProcessorResult2)
        End Using

        If Result Is Nothing Then Return False

        Return True

    Catch ex As Exception
        Return False
    End Try

End Function

In response to Goldorak84's comment, I tested this with a feature class in an mxd using the following code.

Dim pLayer As ESRI.ArcGIS.Carto.ILayer2 = My.ArcMap.Document.FocusMap.Layer(0)
Dim pFLayer As New ESRI.ArcGIS.Carto.FeatureLayer

pFLayer = pLayer
AddField(pFLayer, "Test", "TEXT", 0, 0, 10)

The field was added to the feature class as expected.

2
  • If the feature class is already open, like in his code example, it won't work, he will have the same error has he does in his example
    – Goldorak84
    Aug 15, 2014 at 18:56
  • See my addition to the post above. It works as expected.
    – kenbuja
    Aug 15, 2014 at 19:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.