This VBA code demonstrates how to use a Locator to find a single address. The match results are displayed by this code. If you use this macro in ArcMap, a graphic is added to the map at the location of the matched address.
How to use
- Paste this code into VBA.
- If you are using ArcMap, add an address locator to the document, and make it the current locator. You can do this by choosing the locator on the Addresses tab of the Find dialog box.to do this.
- If you are using ArcCatalog, click an address locator in the ArcCatalog tree.
- Run the FindAddress macro.
- When prompted, type the address that you want to find. Separate the address components with commas (for example, "123 Main St., Anytown, CA, 55555").
Private Const ERR_NUMBER_WRONGNUMBEROFINPUTS = 1001
Private Const ERR_DESCRIPTION_WRONGNUMBEROFINPUTS = "The wrong number of address fields were specified."
Private Const ERR_NUMBER_REQUIREDFIELDMISSING = 1002
Private Const ERR_DESCRIPTION_REQUIREDFIELDMISSING = "A required address field was missing."
Private Const MESSAGEBOX_TITLE = "Find Address Geocoding Developer Tip"
Public Sub FindAddress()
Const CLSID_NAME_LOCATOREXTENSION = "esriLocationUI.LocatorExtension"
Const LOCATOR_CATEGORY_ADDRESS = "Address"
Dim pApplication As esriFramework.IApplication '+++ reference to the parent application
Dim pGxApplication As esriCatalogUI.IGxApplication '+++ ArcCatalog application
Dim pMxApplication As esriArcMapUI.IMxApplication '+++ ArcMap application
Dim pGxObject As esriCatalog.IGxObject '+++ selected GxObject in ArcCatalog
Dim pGxLocator As esriCatalog.IGxLocator '+++ selected locator in ArcCatalog
Dim pLocator As esriGeoDatabase.ILocator '+++ reference to the selected locator
Dim pUID As esriSystem.UID '+++ GUID for the LoctorExtension
Dim pLocatorExtension As esriLocationUI.ILocatorExtension '+++ LocatorExtension object
Dim lngCurrentLocator As Long '+++ index to the current locator in the ArcMap document
Dim pAddressInputs As esriLocation.IAddressInputs '+++ IAddressInputs interface on the locator
Dim pAddressFields As esriGeoDatabase.IFields '+++ address input fields
Dim i As Long '+++ loop counter
Dim pField As esriGeoDatabase.IField '+++ field
Dim strAddressFieldArray() As String '+++ array containing the address field names
Dim strAddressFields As String '+++ comma-delimited string containing address field names
Dim strAddress As String '+++ address string
Dim pAddressPropertySet As esriSystem.IPropertySet '+++ PropertySet containing input address components
Dim pAddressGeocoding As esriLocation.IAddressGeocoding '+++ IAddressGeocoding interface on the locator
Dim pFindPropertySet As esriSystem.IPropertySet '+++ PropertySet containing find results for the address
Dim pMatchFields As esriGeoDatabase.IFields '+++ match fields
Dim strMatch As String '+++ string containing match results
Dim strShapeFieldName As String '+++ name of the shape field in the match results
On Error GoTo ErrorHandler
'+++ get a reference to the parent application
Set pApplication = ThisDocument.Parent
If (TypeOf pApplication Is esriCatalogUI.IGxApplication) Then
Set pGxApplication = pApplication
ElseIf (TypeOf pApplication Is esriArcMapUI.IMxApplication) Then
Set pMxApplication = pApplication
End If
'+++ get a locator from the application
If (TypeOf pApplication Is esriCatalogUI.IGxApplication) Then
Set pGxObject = pGxApplication.SelectedObject
If Not (TypeOf pGxObject Is esriCatalog.IGxLocator) Then
MsgBox "The selected object is not a locator.", vbCritical, MESSAGEBOX_TITLE
Exit Sub
End If
Set pGxLocator = pGxObject
Set pLocator = pGxLocator.Locator
ElseIf (TypeOf pApplication Is esriArcMapUI.IMxApplication) Then
Set pUID = New esriSystem.UID
pUID.Value = CLSID_NAME_LOCATOREXTENSION
Set pLocatorExtension = pApplication.FindExtensionByCLSID(pUID)
If pLocatorExtension.LocatorCount(LOCATOR_CATEGORY_ADDRESS) = 0 Then
MsgBox "There are no locators in the document.", vbCritical, MESSAGEBOX_TITLE
Exit Sub
End If
lngCurrentLocator = pLocatorExtension.CurrentLocator(LOCATOR_CATEGORY_ADDRESS)
If lngCurrentLocator = -1 Then
MsgBox "The ArcMap document does not have a current locator.", vbCritical, MESSAGEBOX_TITLE
Exit Sub
End If
Set pLocator = pLocatorExtension.Locator(LOCATOR_CATEGORY_ADDRESS, lngCurrentLocator)
End If
'+++ get the address input fields for the locator
If Not (TypeOf pLocator Is esriLocation.IAddressInputs) Then
MsgBox "The selected locator is not an address locator."
Exit Sub
End If
Set pAddressInputs = pLocator
Set pAddressFields = pAddressInputs.AddressFields
ReDim strAddressFieldArray(0 To pAddressFields.FieldCount - 1)
For i = 0 To pAddressFields.FieldCount - 1
Set pField = pAddressFields.Field(i)
strAddressFieldArray(i) = pField.Name
Next i
strAddressFields = Join(strAddressFieldArray, ",")
'+++ prompt the user for the address
Do
strAddress = InputBox("Enter an address, separating the address fields with commas. " & _
vbNewLine & vbNewLine & strAddressFields & ":", MESSAGEBOX_TITLE, strAddress)
If strAddress = "" Then Exit Sub
'+++ construct the address PropertySet
Set pAddressPropertySet = ConstructAddressPropertySet(pAddressFields, strAddress)
If Not pAddressPropertySet Is Nothing Then Exit Do
Loop
'+++ find the address
Set pAddressGeocoding = pLocator
Set pFindPropertySet = pAddressGeocoding.MatchAddress(pAddressPropertySet)
'+++ get the components of the find result
Set pMatchFields = pAddressGeocoding.MatchFields
For i = 0 To pMatchFields.FieldCount - 1
Set pField = pMatchFields.Field(i)
If Not (pField.Type = esriFieldTypeBlob Or pField.Type = esriFieldTypeGeometry Or pField.Type = esriFieldTypeOID) Then
strMatch = strMatch & pField.Name & ": " & pFindPropertySet.GetProperty(pField.Name) & vbNewLine
ElseIf pField.Type = esriFieldTypeGeometry Then
strShapeFieldName = pField.Name
End If
Next i
'+++ display the match results
MsgBox strMatch, vbInformation, MESSAGEBOX_TITLE
'+++ add a graphic to the map, if the parent document is an ArcMap document
If TypeOf pApplication Is esriArcMapUI.IMxApplication Then
AddGraphicToMap pFindPropertySet.GetProperty(strShapeFieldName)
End If
Exit Sub
ErrorHandler:
If (Err.Number = ERR_NUMBER_WRONGNUMBEROFINPUTS Or Err.Number = ERR_NUMBER_REQUIREDFIELDMISSING) Then
If MsgBox("An unexpected error occurred." & vbNewLine & Err.Number & ": " & Err.Description, vbRetryCancel, _
MESSAGEBOX_TITLE) = vbCancel Then Exit Sub
Resume Next
End If
End Sub
Public Sub AddGraphicToMap(pGeometry As esriGeometry.IGeometry)
Dim pActiveView As esriCarto.IActiveView '+++ ArcMap document's active view
Dim pDocumentDefaultSymbols As esriArcMapUI.IDocumentDefaultSymbols '+++ IDocumentDefaultSymbols interface on the ArcMap document
Dim pElement As esriCarto.IElement '+++ IElement interface on the marker element
Dim pGraphicsContainer As esriCarto.IGraphicsContainer '+++ GraphicsContainer for the active view
Dim pMarkerElement As esriCarto.IMarkerElement '+++ marker element
Dim pMxDocument As esriArcMapUI.IMxDocument '+++ ArcMap document
Dim pScreenDisplay As esriDisplay.IScreenDisplay '+++ ScreenDisplay object for the active view
'+++ exit the sub if the parent application is not ArcMap
If (Not TypeOf ThisDocument.Parent Is esriArcMapUI.IMxApplication) Then Exit Sub
'+++ create a graphic element for the given geometry
Set pMxDocument = ThisDocument
Set pDocumentDefaultSymbols = pMxDocument
Set pMarkerElement = New esriCarto.MarkerElement
pMarkerElement.Symbol = pDocumentDefaultSymbols.MarkerSymbol
Set pElement = pMarkerElement
pElement.Geometry = pGeometry
'+++ add the element to the graphics layer
Set pActiveView = pMxDocument.ActiveView
Set pGraphicsContainer = pActiveView.GraphicsContainer
pGraphicsContainer.AddElement pElement, 0
'+++ refresh the map
pActiveView.PartialRefresh esriViewGraphics, Nothing, pActiveView.Extent
End Sub
Private Function ConstructAddressPropertySet(pFields As esriGeoDatabase.IFields, strAddress As String) As esriSystem.IPropertySet
Dim i As Long '+++ loop counter
Dim strAddressComponentArray() As String '+++ array of address components
Dim pField As esriGeoDatabase.IField '+++ address field
Dim pPropertySet As esriSystem.IPropertySet '+++ PropertySet containing address components
'+++ parse the address string to get the address components
strAddressComponentArray = Split(strAddress, ",")
If Not UBound(strAddressComponentArray) = pFields.FieldCount - 1 Then
Err.Raise ERR_NUMBER_WRONGNUMBEROFINPUTS, MESSAGEBOX_TITLE, ERR_DESCRIPTION_WRONGNUMBEROFINPUTS
Exit Function
End If
'+++ construct the PropertySet containing the address components
Set pPropertySet = New esriSystem.PropertySet
For i = 0 To pFields.FieldCount - 1
Set pField = pFields.Field(i)
If pField.Required = True And strAddressComponentArray(i) = "" Then
Err.Raise ERR_NUMBER_REQUIREDFIELDMISSING, MESSAGEBOX_TITLE, ERR_DESCRIPTION_REQUIREDFIELDMISSING
Exit Function
End If
pPropertySet.SetProperty pField.Name, strAddressComponentArray(i)
Next i
Set ConstructAddressPropertySet = pPropertySet
End Function