Customizing ArcGIS Using ArcObjects With VBA
Introduction
Add custom controls to ArcGIS Overview of ArcObjects Use of VBA in ArcGIS Demonstrations
Types of Built-in Controls
Toolbar : Added to Toolbars menu Command : Executes when clicked Tool : Controls action of mouse Edit Box : Editable text box Combobox : Pick list of values Menu : Custom menu with added commands
Adding Custom Control:
Toolbar: Step 1 Right Click
Adding Custom Control:
Toolbar: Step 2 Toolbars Tab
Adding Custom Control:
Toolbar: Step 3 Check Save in
Adding Custom Control:
Toolbar - Complete
Commands, Tools, Editbox, Combobox Step 1 Right Click
Adding Custom Control:
Commands, Tools, Editbox, Combobox Step 2 Commands Tab
Adding Custom Control:
Commands, Tools, Editbox, Combobox Step 3 Create New UIToolControl
Adding Custom Control:
Commands, Tools, Editbox, Combobox Step 4 Drag new control onto interface
Adding Custom Control:
Commands, Tools, Editbox, Combobox Step 5 Right click, View Source
Adding Custom Control:
Commands, Tools, Editbox, Combobox Step 6 Add Code
Adding Custom Control:
Adding Custom Control:
Menu: Step 1 Right Click
Menu: Step 2 Command Tab > New Menu > drag new menu on interface
Adding Custom Control:
Menu: Step 3 right click on Menu to rename
Adding Custom Control:
Menu: Step 4 Click menu with customize dialog open
Adding Custom Control:
Menu: Step 5 Drag desired commands onto menu from dialog
Adding Custom Control:
What Are ArcObjects ?
A set of components of the ArcGIS platform which can be accessed through programming environment (VBA, VB, C++, .NET, VB Script) ArcObjects have:
characteristics which can be queried or set the ability to perform operations the ability to respond to changes in application framework in which they are deployed
ArcObjects Object Model
Synoptic view of ArcObjects Included with ArcObjects Developer Kit ArcGIS installation option Diagrams (OMDs) in PDF format
Reading ArcObjects OMDs: Class
Template (blueprint) for creating ArcGIS objects Defines interfaces, properties and methods for an object With VBA, code is stored in the document
Reading ArcObjects OMDs: Interface
Method of communication with an object Logical groups of methods and properties Can be one or many on a single object Can be used by more than one type object May be inbound or outbound
Reading ArcObjects OMDs: properties and Methods
Properties of interface can be set and/or read Methods are actions object performed through interface Accessed as: <object interface>.<property or method> (par1, par2)
Read Write Read / Write Write
ArcObjects OMD Relationship Notation
Is a type of Is composed of Creates Association
Bird Coop
Egg
Chicken
Nest
Wings
Step 1 Start with MxDocument class
Navigating OMD
Example: Return name of first layer in ArcMap TOC
Start with IMxDocument interface of document object, MxDocument Use FocusMap property to reference the Map object through IMap interface
Step 2 Explore the Map class
Navigating OMD
Example: Return name of first layer in ArcMap TOC
Start with IMxDocument interface of document object, MxDocument Use FocusMap property to reference the Map object through IMap interface Use Layer property of the Map to reference layer object
Step 3 Query the Layer class
Navigating OMD
Example: Return name of first layer in ArcMap TOC
Start with IMxDocument interface of document object, MxDocument Use FocusMap property to reference the Map object through IMap interface Use Layer property of the Map to reference layer object Query Layer objects Name property
Common ArcMap Objects
Layer Layer SelectedLayer SelectedLayer (Layer) (Layer) Selection Selection
Common ArcMap Objects MxDocument (ThisDocument) Application Application
Maps (Collection)
Map Map
Map Map (FocusMap (FocusMap ))
Document Events
Code executes when user interacts with document
Open document Close document New document others
Defining Variables
Must define object variables before setting Use the Dim, Private, or Public statements Variables pointing to ArcObjects must reference one of the objects interfaces
Option Explicit Dim <variable> as <VBA instrinsic type> Dim strLayerName as String Public strTitle as String Dim <variable> as <interface name> Dim pMxDoc as IMxDocument Private pFL as IFeatureLayer
ArcGIS Predefined VBA Variables Application, ThisDocument
Starting points for writing code Application pointer to ArcMap or ArcCatalog ThisDocument pointer to current document
Application.Caption = Watershed Analysis Dim pMxDoc as esriCore.IMxDocument Set pMxDoc = ThisDocument
Objects
Created from class blueprints Stored in memory Created from interface property or method
Dim pPnt As IPoint Dim pMxDocument As IMxDocument Set pMxDocument = ThisDocument Set pPnt = _ pMxDocument.CurrentLocation Dim pTextElement As ITextElement Set pTextElement = _ New TextElement
Created using New keyword
Use one interface to get to another
Query Interface:
Method for getting to a different interface on an existing object using an established interface variable
Query Interface:
Coding example
Use of SET Keyword
When using query interface When instantiating an object with NEW keyword
Set pGraphicsContainer = pMap
Set pPoint = New esriCore.Point
Set pMap = pMxDoc.FocusMap Set pMap.SpatialReference = pSR strName = pLayer.Name
When instantiating an object from a property of another object Setting a ByRef property to another object Not necessary for intrinsic data types
Working with Macros 1
A subroutine with public scope
Public Sub Stamp() End Sub
Create with VBA editor Run macros from Tools menu > Macros > Macros
Working with Macros 2
A subroutine with public scope
Public Sub Stamp() End Sub
Create with VBA editor Run macros from Tools menu > Macros > Macros
Methods of VBA Code Distribution
Export to class file or text file Copy/Paste code text to text editor
ArcObjects References
ArcObjects Online: http://arconline.esri.com/arcobjectsonline/ Exploring ArcObjects (on Digital Books CD) ArcObjects Developer Help ESRI Object Browser
ArcObjects Training
Instructor-Led Courses
Introduction to Programming ArcObjects with VBA Migrating from Avenue to VBA Advanced ArcObjects Component Development I Advanced ArcObjects Component Development II C++ Advanced ArcObjects Component Development II .NET
ESRI Web Courses
Exploring the VBA Environment (Free) Customizing ArcMap: Easy Ways to Extend the Interface Introduction to Visual Basic for ESRI Software Working with Variables and Functions in VBA Working with Forms in VBA Understanding Branching and Looping in VBA
ArcObjects References
ArcObjects Online: http://arconline.esri.com/arcobjectsonline/ Exploring ArcObjects (on Digital Books CD) ArcObjects Developer Help ESRI Object Browser
Demonstration toolbar
Get selected TOC layers fields when combobox is clicked
Private Sub UIComboBoxControl1_GotFocus() On Error GoTo Errorhandler Dim pMxDoc As IMxDocument Dim pFL As IFeatureLayer Dim i As Long Set pMxDoc = ThisDocument UIComboBoxControl1.RemoveAll UIEditBoxControl1.Clear If Not TypeOf pMxDoc.SelectedLayer Is IFeatureLayer Then GoTo Exitpnt Set pFL = pMxDoc.SelectedLayer For i = 0 To pFL.FeatureClass.Fields.FieldCount - 1 UIComboBoxControl1.AddItem pFL.FeatureClass.Fields.Field(i).Name Next i Exitpnt: Set pMxDoc = Nothing Set pFL = Nothing Exit Sub Errorhandler: Resume Exitpnt End Sub
Sample code:
Label selected TOC layer based on chosen combobox field
Sample code:
For the custom button click, get selected layer, then call a subroutine to draw the labels
Private Sub UIButtonControl1_Click() On Error GoTo Errorhandler Dim pMxDoc As IMxDocument Dim pGFL As IGeoFeatureLayer Set pMxDoc = ThisDocument If Not TypeOf pMxDoc.SelectedLayer Is IFeatureLayer Then GoTo Exitpnt Set pGFL = pMxDoc.SelectedLayer UpdateLabels pGFL pMxDoc.ActiveView.PartialRefresh esriViewGeography, Nothing, _ pMxDoc.ActiveView.Extent Exitpnt: Set pMxDoc = Nothing Set pGFL = Nothing Exit Sub Errorhandler: Resume Exitpnt End Sub
Label selected TOC layer based on chosen combobox field
Private Sub UpdateLabels(pGeoFeatureLayer As IGeoFeatureLayer) On Error GoTo Errorhandler Dim pLabelEngineLayerProperites As ILabelEngineLayerProperties If pGeoFeatureLayer.FeatureClass.FindField(UIComboBoxControl1.EditText) = -1 Then GoTo Exitpnt If pGeoFeatureLayer.DisplayAnnotation = True Then pGeoFeatureLayer.AnnotationProperties.QueryItem 0, pLabelEngineLayerProperites If pLabelEngineLayerProperites.Expression = "[" & UIComboBoxControl1.EditText & "]" Then pGeoFeatureLayer.DisplayAnnotation = False Else If Len(UIComboBoxControl1.EditText) = 0 Then pGeoFeatureLayer.DisplayAnnotation = False Else pLabelEngineLayerProperites.Expression = "[" & UIComboBoxControl1.EditText & "]" End If End If Else pGeoFeatureLayer.AnnotationProperties.QueryItem 0, pLabelEngineLayerProperites pLabelEngineLayerProperites.Expression = "[" & UIComboBoxControl1.EditText & "]" pGeoFeatureLayer.DisplayAnnotation = True End If Exitpnt: Set pLabelEngineLayerProperites = Nothing Exit Sub Errorhandler: Resume Exitpnt End Sub
Sample code:
Filter selected TOC layer based on editbox value for chosen field
Private Sub UIEditBoxControl1_KeyDown(ByVal keyCode As Long, ByVal shift As Long) On Error GoTo Errorhandler Dim pMxDoc As IMxDocument Dim pFLD As IFeatureLayerDefinition If keyCode <> 13 Then GoTo Exitpnt Set pMxDoc = ThisDocument If Not TypeOf pMxDoc.SelectedLayer Is IFeatureLayer Then GoTo Exitpnt Set pFLD = pMxDoc.SelectedLayer If Len(UIComboBoxControl1.EditText) = 0 Then pFLD.DefinitionExpression = "" Else pFLD.DefinitionExpression = UIComboBoxControl1.EditText & " = '" & _ UIEditBoxControl1.Text & "'" End If If pMxDoc.SelectedLayer.Visible = False Then pMxDoc.SelectedLayer.Visible = True pMxDoc.UpdateContents End If pMxDoc.ActiveView.PartialRefresh esriViewGeography, Nothing, _ pMxDoc.ActiveView.Extent Exitpnt: Set pMxDoc = Nothing Set pFLD = Nothing Exit Sub Errorhandler: Resume Exitpnt End Sub
Sample code:
Label selected TOC layer based on chosen combobox field
Private Function UIToolControl1_Deactivate() As Boolean UIToolControl1_Deactivate = True End Function 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 pRubberEnv As IRubberBand Dim pFillSymbol As ISimpleFillSymbol Dim pRubberPolygon As IRubberBand Dim pPolygon As IPolygon Dim pMxDoc As IMxDocument Dim pTOp As ITopologicalOperator
Sample code:
Continued on next slide .
Label selected TOC layer based on chosen combobox field
Sample code:
Set pMxDoc = ThisDocument Set pMxApp = Application Set pRubberPolygon = New RubberPolygon Set pFillSymbol = New SimpleFillSymbol pFillSymbol.Style = esriSFSHollow Set pPolygon = pRubberPolygon.TrackNew(pMxDoc.ActiveView.ScreenDisplay, pFillSymbol) If pPolygon Is Nothing Then GoTo Exitpnt Set pTOp = pPolygon If pTOp.IsSimple = False Then MsgBox "Selection polygon cannot self-intersect." GoTo Exitpnt End If pMxDoc.FocusMap.SelectByShape pPolygon, pMxApp.SelectionEnvironment, False pMxDoc.ActiveView.PartialRefresh esriViewGeoSelection, Nothing, pMxDoc.ActiveView.Extent Exitpnt: Set pMxApp = Nothing Set pRubberEnv = Nothing Set pFillSymbol = Nothing Set pRubberPolygon = Nothing Set pPolygon = Nothing Set pMxDoc = Nothing End Sub
When ArcMap document opened, collapse all TOC layer symbology and make all layers visible, regardless of how document was saved
Private Function MxDocument_OpenDocument() As Boolean Dim pDoc As IMxDocument Dim pGFL As IGeoFeatureLayer Dim pLInfo As ILegendInfo Dim pLGrp As ILegendGroup Dim i As Long Set pDoc = ThisDocument For i = 0 To pDoc.FocusMap.LayerCount - 1 If TypeOf pDoc.FocusMap.Layer(i) Is IFeatureLayer Then Set pGFL = pDoc.FocusMap.Layer(i) Set pLInfo = pGFL Set pLGrp = pLInfo.LegendGroup(0) pLGrp.Visible = False pGFL.Visible = True End If Next i pDoc.UpdateContents pDoc.ActiveView.Refresh Set pDoc = Nothing Set pGFL = Nothing Set pLInfo = Nothing Set pLGrp = Nothing End Function
Sample code:
Create ArcMap extension .dll so when ArcMap document opened, collapse all TOC layer symbology and make all layers visible, regardless of how document was saved
Sample code:
Step 1 Create new Visual Basic ActiveX dll
Create ArcMap extension .dll so when ArcMap document opened, collapse all TOC layer symbology and make all layers visible, regardless of how document was saved
Sample code:
Step 2 Establish reference to ESRI Object library
Create ArcMap extension .dll so when ArcMap document opened, collapse all TOC layer symbology and make all layers visible, regardless of how document was saved
Sample code:
Step 3
Implement IExtension, establish MxDocument variable WithEvents and establish other necessary modulelevel variables
Create ArcMap extension .dll so when ArcMap document opened, collapse all TOC layer symbology and make all layers visible, regardless of how document was saved
Sample code:
Step 4
Add code to the OpenDocument event to control TOC configuration
Create ArcMap extension .dll so when ArcMap document opened, collapse all TOC layer symbology and make all layers visible, regardless of how document was saved
Sample code:
Step 5
Compile with no compatibility then with binary compatibility
Create ArcMap extension .dll so when ArcMap document opened, collapse all TOC layer symbology and make all layers visible, regardless of how document was saved
Sample code:
Step 6
Register with ESRI Mx Extensions Category using Categories.exe in the ArcGIS/arcexe83/bin directory
Create ArcMap extension .dll so when ArcMap document opened, collapse all TOC layer symbology and make all layers visible, regardless of how document was saved
Sample code:
Step 6
OR register with ESRI Mx Extensions Category using .reg file called from .bat, all in same directory as the extension .dll