How to select multiple feature using VBA ?

2138
5
02-06-2012 09:18 PM
StutiChandel
New Contributor
Hi,

I am a little new to this but I wanted to know how do I select multiple features in a layer using VBA? I would appretiate if I could get some code. for eg selecting two or more point features.

Thanks,
Stuti Chandel
0 Kudos
5 Replies
VinayanMP
New Contributor
The following code(from ESRI samples) selects features based on a query (NAME = 'Nova Scotia'). From the first layer added in the table of contents. Hope this is what you wanted.
Public Sub SelectMapFeatures()
  Dim pMxDoc As IMxDocument
  Dim pMap As IMap
  Dim pActiveView As IActiveView
  Dim pFeatureLayer As IFeatureLayer
  Dim pFeatureSelection As IFeatureSelection
  Dim pQueryFilter As IQueryFilter
  
  
  Set pMxDoc = Application.Document
  Set pMap = pMxDoc.FocusMap
  Set pActiveView = pMap
  
  'For simplicity sake let's use the first layer in the map
  If Not TypeOf pMap.Layer(0) Is IFeatureLayer Then Exit Sub
  Set pFeatureLayer = pMap.Layer(0)
  Set pFeatureSelection = pFeatureLayer 'QI
  
  'Create the query filter
  Set pQueryFilter = New QueryFilter
  pQueryFilter.WhereClause = "NAME = 'Nova Scotia'"
  
  'Invalidate only the selection cache
  'Flag the original selection
  pActiveView.PartialRefresh esriViewGeoSelection, Nothing, Nothing
  'Perform the selection
  pFeatureSelection.SelectFeatures pQueryFilter, esriSelectionResultNew, False
  'Flag the new selection
  pActiveView.PartialRefresh esriViewGeoSelection, Nothing, Nothing
  
End Sub
0 Kudos
StutiChandel
New Contributor
Thanks for the help. But I am creating a tool which can select multiple features eg. point features on a layer. I cannot use a query method. Please help.
0 Kudos
VinayanMP
New Contributor
is it that you want the functionality of "Select by location" tool in arcmap through VBA? In such case iSpatialFilter would help you..
0 Kudos
GeorgeFaraj
Occasional Contributor III
Thanks for the help. But I am creating a tool which can select multiple features eg. point features on a layer. I cannot use a query method. Please help.


A feature should have a key.  So, if you have a key then you select using that key:

// filterClause is: "Key = <keyvalue>" or "Key in (<keyvaluelist>)"
// esriSelectionResultEnum lets you add or subtract from the current select (or create a new selection)
public static void SelectBy(IActiveView view, ILayer2 targetLayer, string filterClause, esriSelectionResultEnum selectionResult)
{
 IFeatureSelection featureSelection = targetLayer as IFeatureSelection;
 if (featureSelection == null) return;
 IQueryFilter queryFilter = new QueryFilterClass();
 queryFilter.WhereClause = filterClause;
 IColor selectColor = Local.ColorToIColor(System.Drawing.Color.OrangeRed);
 ISimpleFillSymbol fillSymbol = new SimpleFillSymbolClass();
 fillSymbol.Color = selectColor;
 ISimpleLineSymbol outlineSymbol = new SimpleLineSymbolClass();
 outlineSymbol.Color = selectColor;
 outlineSymbol.Width = 2;
 fillSymbol.Outline = outlineSymbol;
 fillSymbol.Style = esriSimpleFillStyle.esriSFSHollow;
 featureSelection.SelectionSymbol = fillSymbol as ISymbol;
 featureSelection.SetSelectionSymbol = true;
 featureSelection.SelectFeatures(queryFilter, selectionResult, false);
 view.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, view.FocusMap, null);
}


If you do not have a key and want to select by area then this selects from around a point:

// SelectByShape() will take any geometry (cricle, as here, or square, or rectangle)  
public static IGeometry SelectFrom(IActiveView view, string limitToLayerName, IPoint point, float distance)
{
 if (!string.IsNullOrEmpty(limitToLayerName)) view.SetLayerSelectable(limitToLayerName);
 ISelectionEnvironment selectionEnvironment = null;
 IGeometry geometry = null;
 try
 {
  ICircularArc circularArc = new CircularArcClass();
  IConstructCircularArc constructCircularArc = circularArc as IConstructCircularArc;
  UnitConverter unitConverter = new UnitConverterClass();
  double radius = unitConverter.ConvertUnits(
   distance, esriUnits.esriFeet, view.FocusMap.DistanceUnits);
  constructCircularArc.ConstructCircle(point, radius, false);
  RingClass ring = new RingClass();
  object missing = Type.Missing;
  ring.AddSegment(circularArc as ISegment, ref missing, ref missing);
  IPolygon polygon = new PolygonClass();
  IGeometryCollection geometryCollection = polygon as IGeometryCollection;
  geometryCollection.AddGeometry(ring, ref missing, ref missing);
  geometry = polygon;
  selectionEnvironment = new SelectionEnvironmentClass();
  selectionEnvironment.CombinationMethod = esriSelectionResultEnum.esriSelectionResultNew;
  IColor selectColor = selectionEnvironment.DefaultColor;
  selectColor = Local.ColorToIColor(System.Drawing.Color.OrangeRed);
  selectionEnvironment.DefaultColor = selectColor;
  view.FocusMap.SelectByShape(geometry, selectionEnvironment, false);
  view.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, view.Extent);
 }
 finally
 {
  Marshal.FinalReleaseComObject(selectionEnvironment);
 }
 return geometry;
}


If you are just clicking on features then get the key from the point and pass a filterClause containing the key to the SelectBy():

public static int GetTargetKeyByPoint(IMapControl4 mapControl, ILayer2 targetLayer, string keyName, IPoint point)
{
 int targetKey = 0;
 if (targetLayer == null) return targetKey;
 ILayerFields parcelFields = targetLayer as ILayerFields;
 if (parcelFields == null) return targetKey;
 int keyIndex = parcelFields.FindField(keyName);
 if (keyIndex == -1) return targetKey;
 IIdentify identify = targetLayer as IIdentify;
 IArray array = identify.Identify(point);
 if (array != null && array.Count > 0)
 {
  IFeatureIdentifyObj featureIdentifyObj = array.get_Element(0) as IFeatureIdentifyObj;
  IRowIdentifyObject rowIdentifyObject = featureIdentifyObj as IRowIdentifyObject;
  IRow row = rowIdentifyObject.Row;
  if (row != null)
  {
   IFeature feature = row as IFeature;
   if (feature != null)
   {
    object value = feature.get_Value(keyIndex);
    if (value != null)
    {
     targetKey = int.Parse(value.ToString());
    }
   }
  }
 }
 return targetKey;
}
0 Kudos
PhilMiotto
New Contributor
Both of these VBA samples will select multiple features in the map.


To perform a spatial  selection - "select within":

Sub SpatialSelection()
  Dim pMxApp As IMxApplication
  Dim pMxDoc As IMxDocument
  Dim pMap As IMap
  Dim pTargetLayer As IFeatureLayer
  Dim pSelectingLayer As IFeatureLayer
  Dim pFeatureClass As IFeatureClass
  Dim pEnvelope As IEnvelope
  Dim pFeatureSelection As IFeatureSelection
  Dim pSpatialFilter As ISpatialFilter
  
  Set pMxApp = Application
  Set pMxDoc = Application.Document
  Set pMap = pMxDoc.FocusMap

  Set pTargetLayer = pMap.Layer(0)
  Set pSelectingLayer = pMap.Layer(1)
  Set pFeatureClass = pTargetLayer.FeatureClass
  Set pEnvelope = pSelectingLayer.AreaOfInterest
  
  Set pFeatureSelection = pTargetLayer
  Set pSpatialFilter = New SpatialFilter
  With pSpatialFilter
    Set .Geometry = pEnvelope
    .GeometryField = pFeatureClass.ShapeFieldName
    .SpatialRel = esriSpatialRelContains
    'add an optional .WhereClause
  End With
  
  pFeatureSelection.SelectFeatures pSpatialFilter, esriSelectionResultNew, False
  pMxDoc.ActiveView.PartialRefresh esriViewGeoSelection, Nothing, Nothing
End Sub




To perform a selection of features within a graphic drawn in the map - this is MouseDown code for a UIToolControl, which will allow you to draw the graphic then selects the features within that graphic:

Private Sub UIToolControl1_MouseDown(ByVal button As Long, ByVal shift As Long, ByVal x As Long, ByVal y As Long)
    Dim pMxApp        As IMxApplication
    Dim pMxDoc        As IMxDocument
    Dim pMap          As IMap
    Dim pActiveView   As IActiveView
    Dim pRubberBand   As IRubberBand
    Dim pSelectionSet As ISelectionSet
    Dim pFeatureLayer As IFeatureLayer2
    Dim pFeatureSelection As IFeatureSelection
    Dim pTargetLayer As IFeatureLayer
    Dim pCircleArc As ICircularArc
    Dim pSegColl As ISegmentCollection
    Dim pFLayer As IFeatureLayer
    Dim pFc As IFeatureClass
    Dim pPoly As IPolygon
    
    Set pMxApp = Application
    Set pMxDoc = ThisDocument
    Set pMap = pMxDoc.FocusMap
    Set pActiveView = pMap
    Set pTargetLayer = pMap.Layer(0)
    Set pRubberBand = New RubberCircle
    Set pCircleArc = pRubberBand.TrackNew(pActiveView.ScreenDisplay, Nothing)
    Set pSegColl = New Polygon
    pSegColl.SetCircle pCircleArc.CenterPoint, pCircleArc.Radius
    Set pFLayer = pMap.Layer(0)
    Set pFc = pFLayer.FeatureClass
    Set pPoly = pSegColl
    
    
    Dim pSF As ISpatialFilter
    Set pSF = New SpatialFilter
    With pSF
        Set .Geometry = pPoly
        .GeometryField = pTargetLayer.FeatureClass.ShapeFieldName
        .SpatialRel = esriSpatialRelIntersects
    End With
    
    Set pFeatureSelection = pTargetLayer
    pFeatureSelection.SelectFeatures pSF, esriSelectionResultNew, False
    pMxDoc.ActiveView.Refresh

End Sub
0 Kudos