6 Replies Latest reply on May 6, 2010 7:12 AM by kmarten-esristaff

    Change definition query programmatically for all layers in mxd

    Tim.Cashman
      Hi,
      I want to change the definition query on fcs (about 40) loaded to a mxd to be able to extract region specific data to ArcPad.
      Ideally, the user would have a picklist of regions (4) otherwise the query could be hardwired.
      I'm not fussed whether VB or Python.

      Thanks for any clues.

      9.3

      Tim
        • Re: Change definition query programmatically for all layers in mxd
          kmarten-esristaff
          Option #1 - Hardwired Definition Query

          Public Sub DefQUpdate_HardWired()
          
          Dim pMxd As IMxDocument
          Set pMxd = ThisDocument
          Dim pMap As IMap
          Set pMap = pMxd.FocusMap
          
          Dim i As Integer
          Dim pFlyr As IFeatureLayer, pFlyrDef As IFeatureLayerDefinition
          
          For i = 0 To pMap.LayerCount - 0
              Set pFlyr = pMap.Layer(i)
              Set pFlyrDef = pFlyr
              pFlyrDef.DefinitionExpression = "REGION_FIELD = 'FieldValue'"
          Next i
          
          pMxd.ActiveView.Refresh
          
          End Sub


          Option #2 - User-defined

          In the code below; you will need a common field in each layer, otherwise the definition query will be invalid and the layer will not draw.


          1. From the Customize dialog create and add UIComboboxControl

          2. Copy and Paste code sample into VBA Editor

          3. Use ComboBox control to update the Definition Query for all Layers in the active map


          Private Function MxDocument_OpenDocument() As Boolean
              'Populate Combobox
              UIComboBoxControl1.AddItem "OBJECTID IS NOT NULL", 0
              UIComboBoxControl1.AddItem "OBJECTID > 2", 1
              UIComboBoxControl1.AddItem "OBJECTID > 4", 2
              UIComboBoxControl1.AddItem "OBJECTID > 6", 3
          End Function
          
          Private Sub UIComboBoxControl1_SelectionChange(ByVal newIndex As Long)
          
          Dim pMxd As IMxDocument
          Dim pMap As IMap
          Set pMxd = ThisDocument
          Set pMap = pMxd.FocusMap
          
          Dim pFlyr As IFeatureLayer, pFlyrDef As IFeatureLayerDefinition
          Dim pDisplayExp As String
          
          'Get Selected Definition Query from Combobox
          pDisplayExp = UIComboBoxControl1.Item(newIndex)
          
          Dim i As Integer
          i = 0
          
          'Iterate layers in map and set Definition Query
          For i = 0 To pMap.LayerCount - 1
              Set pFlyr = pMap.Layer(i)
              Set pFlyrDef = pFlyr
              pFlyrDef.DefinitionExpression = pDisplayExp
          Next i
          
          pMxd.ActiveView.Refresh
          
          End Sub
          
          • Re: Change definition query programmatically for all layers in mxd
            Tim.Cashman
            Thanks Martin,
            That works perfectly.

            All of the fcs of interest are in the same gdb, so can I get an IF statement that only applies the definition query to fcs / layers in that gdb, allowing drawing of other non-related feature classes / layers?

            Also, is there a way to have an alternate label in the combo box rather than the explicit query?
            eg if the query is very long, the user does not want to scroll to the end to find the defining bits, but rather see a label that makes sense?

            Thanks again
            • Re: Change definition query programmatically for all layers in mxd
              kmarten-esristaff
              This should do it.

              There are limitations to this code sample; if you create a joined dataset in your map and then apply a definition query it will not work, you will need to fully qualify the field name in the definition query. In the sample you'll need to update the definition queries, the Geodatabase path, and replace the text in the combobox:

              Private Function MxDocument_OpenDocument() As Boolean
                  'Populate Combobox
                  UIComboBoxControl1.AddItem "Region 1", 0
                  UIComboBoxControl1.AddItem "Region 2", 1
                  UIComboBoxControl1.AddItem "Region 3", 2
                  UIComboBoxControl1.AddItem "Region 4", 3
                  UIComboBoxControl1.EditText = "<Select Definition Query>"
              End Function
              
              Private Sub UIComboBoxControl1_SelectionChange(ByVal newIndex As Long)
              
              Dim pMxd As IMxDocument
              Dim pMap As IMap
              Set pMxd = ThisDocument
              Set pMap = pMxd.FocusMap
              
              Dim pFlyr As IFeatureLayer, pFlyrDef As IFeatureLayerDefinition
              Dim pDisplayExp As String
              
              'Get Selected Definition Query from Combobox
              pDisplayExp = UIComboBoxControl1.Item(newIndex)
              
              Select Case pDisplayExp
                  Case "Region 1"
                      pDisplayExp = "OBJECTID IS NOT NULL"
                  Case "Region 2"
                      pDisplayExp = "OBJECTID > 2"
                  Case "Region 3"
                      pDisplayExp = "OBJECTID > 4"
                  Case "Region 4"
                      pDisplayExp = "OBJECTID > 6"
              End Select
              
              Dim i As Integer
              i = 0
              
              Dim pFC As IFeatureClass
              Dim pDS As IDataset
              Dim pGDBPath As String, pDSPath As String
              
              pGDBPath = "C:\temp\TEST.gdb"
              
              'Iterate layers in map and set Definition Query
              For i = 0 To pMap.LayerCount - 1
                  Set pFlyr = pMap.Layer(i)
                  Set pFC = pFlyr.FeatureClass
                  Set pDS = pFC
                  pDSPath = pDS.Workspace.PathName
                  If (pDSPath = pGDBPath) Then
                      Set pFlyrDef = pFlyr
                      pFlyrDef.DefinitionExpression = pDisplayExp
                  End If
              Next i
              
              pMxd.ActiveView.Refresh
              
              End Sub


              Good luck,

              Kent M.
              esri
              • Re: Change definition query programmatically for all layers in mxd
                Tim.Cashman
                Kent,

                All works.

                Thanks very much.

                Tim
                • Re: Change definition query programmatically for all layers in mxd
                  agray7501
                  This should do it.

                  There are limitations to this code sample; if you create a joined dataset in your map and then apply a definition query it will not work, you will need to fully qualify the field name in the definition query. In the sample you'll need to update the definition queries, the Geodatabase path, and replace the text in the combobox:

                  Private Function MxDocument_OpenDocument() As Boolean
                      'Populate Combobox
                      UIComboBoxControl1.AddItem "Region 1", 0
                      UIComboBoxControl1.AddItem "Region 2", 1
                      UIComboBoxControl1.AddItem "Region 3", 2
                      UIComboBoxControl1.AddItem "Region 4", 3
                      UIComboBoxControl1.EditText = "<Select Definition Query>"
                  End Function
                  
                  Private Sub UIComboBoxControl1_SelectionChange(ByVal newIndex As Long)
                  
                  Dim pMxd As IMxDocument
                  Dim pMap As IMap
                  Set pMxd = ThisDocument
                  Set pMap = pMxd.FocusMap
                  
                  Dim pFlyr As IFeatureLayer, pFlyrDef As IFeatureLayerDefinition
                  Dim pDisplayExp As String
                  
                  'Get Selected Definition Query from Combobox
                  pDisplayExp = UIComboBoxControl1.Item(newIndex)
                  
                  Select Case pDisplayExp
                      Case "Region 1"
                          pDisplayExp = "OBJECTID IS NOT NULL"
                      Case "Region 2"
                          pDisplayExp = "OBJECTID > 2"
                      Case "Region 3"
                          pDisplayExp = "OBJECTID > 4"
                      Case "Region 4"
                          pDisplayExp = "OBJECTID > 6"
                  End Select
                  
                  Dim i As Integer
                  i = 0
                  
                  Dim pFC As IFeatureClass
                  Dim pDS As IDataset
                  Dim pGDBPath As String, pDSPath As String
                  
                  pGDBPath = "C:\temp\TEST.gdb"
                  
                  'Iterate layers in map and set Definition Query
                  For i = 0 To pMap.LayerCount - 1
                      Set pFlyr = pMap.Layer(i)
                      Set pFC = pFlyr.FeatureClass
                      Set pDS = pFC
                      pDSPath = pDS.Workspace.PathName
                      If (pDSPath = pGDBPath) Then
                          Set pFlyrDef = pFlyr
                          pFlyrDef.DefinitionExpression = pDisplayExp
                      End If
                  Next i
                  
                  pMxd.ActiveView.Refresh
                  
                  End Sub


                  Good luck,

                  Kent M.
                  esri


                  Kent,

                  Good stuff!! I can't wait to give it a try..

                  One question though.. How would I modify the script to only change the definition for one layer and modify selection information based on a range of values found in a field?..
                  Guess, that was two questions in one..

                  Example.. I want to provide a tool to allow the user to only see properties that are between 0<5 acres, 5<=10 acres, etc...

                  Thanks,
                  Alex
                  • Re: Change definition query programmatically for all layers in mxd
                    kmarten-esristaff
                    Alex,

                    I'm not entirely sure what you are asking.

                    You want code that allows you to change the definition query for a single layer?

                    If you can, please clarify.  The code samples in this thread can be easily modified to work with a specific layer.

                    Kent M.
                    esri