6

I'm attempting to query a feature class for all features that meet a certain criterion (in this case, the Status field is NULL). However, I'm not getting very far into the attempted method before ArcMap crashes completely. I have no reasonable idea on how to trace errors that cause a program crash, for starters, so I'm more confused than necessary, I expect. I'm building this in VS 2008 Express, for what it's worth.

 public void PerformAttributeQuery(ESRI.ArcGIS.Geodatabase.IFeatureClass fc)
    {
        ESRI.ArcGIS.Geodatabase.IQueryFilter queryFilter = new ESRI.ArcGIS.Geodatabase.QueryFilterClass();
        queryFilter.WhereClause = "[Status] IS NULL"; // create the where clause statement 

Everything is fine for that first couple of statements, but this query causes a crash:

        // query the table passed into the function and use a cursor to hold the results
        ESRI.ArcGIS.Geodatabase.IFeatureCursor featurecursor = fc.Search(queryFilter, false);

It crashes before reaching the next line (I put in debug message boxes for testing), but I'll put it here for propriety:

        ESRI.ArcGIS.Geodatabase.IFeature feature = (ESRI.ArcGIS.Geodatabase.IFeature)featurecursor.NextFeature();
        ESRI.ArcGIS.ArcMapUI.IContentsView currentContentsView = ArcMap.Document.CurrentContentsView as IContentsView;
        ESRI.ArcGIS.Carto.IFeatureLayer featureLayer = (ESRI.ArcGIS.Carto.IFeatureLayer)currentContentsView.SelectedItem;
        ESRI.ArcGIS.Carto.IFeatureSelection fSelection = featureLayer as ESRI.ArcGIS.Carto.IFeatureSelection;
        fSelection.Add(feature);
        FindCommandAndExecute(ArcMap.Application as ESRI.ArcGIS.Framework.IApplication, "{AB073B49-DE5E-11D1-AA80-00C04FA37860}");
    }

I cannibalized the PerformAttributeQuery snippet to work with FeatureClasses instead of Tables (or so I had hoped), if you'd like a proper reference. My questions are:

  1. How can I get better reporting of crash errors?
  2. Where did I go wrong? Answer: I must shamefacedly admit that I used the wrong characters to denote the location of the feature table I was querying. Changing the [Status] in my queryFilter.WhereClause to \"Status\" quite literally solved all obvious problems.
4
  • 1
    +1 As a non-user of arcobjects I can only sit by and wait for good answers, but I admire how well this question has been thought out and presented: it provides necessary information, it relates what steps you have taken to a solution, it minimizes the code it needs to quote (but doesn't hesitate to show code), it provides a link to an authoritative reference, and it asks clear, constructive, pointed questions. I hope it gets lots of upvotes for those reasons alone--and of course I trust it will get more useful responses than this one!
    – whuber
    May 20 '11 at 17:59
  • 1
    Does the status field really exist? Are you really using access? The square bracket delimiters are only for access, according to the doc. May 20 '11 at 18:25
  • 1
    Also, to get better reporting, use try/catch and in the catch block recurse into Exception.InnerException. May 20 '11 at 18:27
  • Yes, this method is only called after a field check method returns with proof of the Status field existing. However, I will try with the adjusted bracket types to quotes. Could you please explain a bit more about what you mean with Exception.InnerException? Might as well put it up as an answer so I can give it due credit and reputation, yes?
    – Nathanus
    May 20 '11 at 18:28
7

see code below

Note that sometimes useful exception messages can be embedded inside of a fairly cryptic general message, so it is important to examine InnerExceptions.

protected override void OnClick()
{
    string path = @"C:\projects\NetTools\InfrastructureEditingTemplate\MapsandGeodatabase\LocalGovernment.gdb";
    try
    {
        var ws = Open(path);
        var fc = ((IFeatureWorkspace)ws).OpenFeatureClass("wMain");
        IFeature feat = QueryFirstFeature(fc);
        if (feat != null)
        {
            //todo: project if necessary
            ((IActiveView)ArcMap.Document.FocusMap).Extent = feat.Shape.Envelope;
            ((IActiveView)ArcMap.Document.FocusMap).Refresh();
        }
    }
    catch (Exception ex)
    {
        while (ex != null)
        {
            Debug.Print("{0} \n {1}", ex.Message, ex.StackTrace);
            ex = ex.InnerException;
        }
    }
}

private IFeature QueryFirstFeature(IFeatureClass fc)
{
    IFeature outFeat = null;
    IQueryFilter qf = new QueryFilterClass();
    qf.WhereClause = "LASTEDITOR = 'ESRI'";
    IFeatureCursor fCur = null;
    try
    {
        fCur = fc.Search(qf, false);
        outFeat = fCur.NextFeature();
    }
    catch (Exception ex)
    {
        var ex2 = new Exception("Exception when querying with " + qf.WhereClause, ex);
        throw ex2;
    }
    finally
    {
        if(fCur != null)
            Marshal.FinalReleaseComObject(fCur);
    }
    return outFeat;
}
3
  • Interesting use of FinalReleaseComObject instead of ReleaseComObject. I wondered what the the difference was and came upon this answer which explains it: stackoverflow.com/questions/1827059/…
    – blah238
    May 20 '11 at 21:20
  • Is there any specific reason use of the Zoom to Selected Features command sets the zoom scale to 1:4.189069e+017?
    – Nathanus
    May 20 '11 at 22:11
  • Are you trying to zoom to a point? If so, I'd add a bit of code that calls IEnvelope.Expand first. May 20 '11 at 22:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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