Const DESCRIP_FIELD = "STATE_NAME" Const CONCATENATE_TO_BUILD_DESCRIPTION = True Const CONCAT_CHAR = vbNewLine Option Explicit Sub UniqueValues_LabelCount_and_DescripFromField() Dim pDoc As IMxDocument Set pDoc = ThisDocument Dim pMap As IMap Set pMap = pDoc.FocusMap Dim pGeoLayer As IGeoFeatureLayer Set pGeoLayer = pMap.Layer(0) If Not TypeOf pGeoLayer.Renderer Is IUniqueValueRenderer Then MsgBox "Current symbology is not Unique values. Exiting." Exit Sub End If Dim pUVRend As IUniqueValueRenderer Set pUVRend = pGeoLayer.Renderer If pUVRend.FieldCount > 1 Then MsgBox "Current Unique values symbology is based on multiple fields. Exiting." Exit Sub End If Dim sFieldName As String sFieldName = pUVRend.Field(0) Dim i As Integer Dim varValue As Variant Dim pFeatClass As IFeatureClass Set pFeatClass = pGeoLayer.FeatureClass Dim varLabelDescrip As Variant For i = 0 To pUVRend.ValueCount - 1 varValue = pUVRend.Value(i) varLabelDescrip = GetLabelDescription(pFeatClass, pUVRend.Field(0), varValue) pUVRend.Label(varValue) = varLabelDescrip(0) pUVRend.Description(varValue) = varLabelDescrip(1) Next i pDoc.ActiveView.ContentsChanged pDoc.UpdateContents pDoc.ActiveView.Refresh End Sub Private Function GetLabelDescription(pFeatClass As IFeatureClass, ValField As String, Value As Variant) As Variant ' returns an array of length 2 ' (0) is the new label (string) appended with count of features ' (1) is the new descrip (string) driven from DESCRIP_FIELD Dim pQueryFilter As IQueryFilter Set pQueryFilter = New QueryFilter pQueryFilter.WhereClause = ValField & " = '" & CStr(Value) & "'" pQueryFilter.AddField DESCRIP_FIELD Dim pFeatCursor As IFeatureCursor Set pFeatCursor = pFeatClass.Search(pQueryFilter, False) ' --------------------------------------------------------- ' Description Dim pFeat As IFeature Dim sDescrip As String Dim iDescrip As Integer iDescrip = pFeatClass.Fields.FindField(DESCRIP_FIELD) Set pFeat = pFeatCursor.NextFeature Dim iCount As Integer iCount = 0 Dim bCountsDetermined As Boolean bCountsDetermined = False If CONCATENATE_TO_BUILD_DESCRIPTION Then bCountsDetermined = True Do While Not pFeat Is Nothing iCount = iCount + 1 If sDescrip <> "" Then sDescrip = sDescrip + CONCAT_CHAR sDescrip = sDescrip + CStr(pFeat.Value(iDescrip)) ' get value from DESCRIP_FIELD Set pFeat = pFeatCursor.NextFeature Loop Else ' only get descrip from first feature found If Not pFeat Is Nothing Then sDescrip = CStr(pFeat.Value(iDescrip)) ' get value from DESCRIP_FIELD End If End If ' --------------------------------------------------------- ' Label If Not bCountsDetermined Then ' optimization: re-query only if we don't ' already have the counts from above iCount = pFeatClass.FeatureCount(pQueryFilter) End If Dim sLabel As String sLabel = Value & " (" & iCount & ") " ' --------------------------------------------------------- ' setup return array and return Dim sReturnArray(2) As String sReturnArray(0) = sLabel sReturnArray(1) = sDescrip GetLabelDescription = sReturnArray End Function
Well got this script to work, but it wasnt using the tips from above...
One of error messages related to 'Layer 0', and I noticed that the problem seemed to occur (in this particular isntance) to a shapefile I had half way down in my TOC, so I dragged the shapefile to the top of my TOC, and ran the macro again, and it worked.
I have tested this with another project, and it only seems to work when the shapefile is first in the TOC.
It's not something we will use everyday, so this solution will do for now!
Dan
Set pGeoLayer = pMap.Layer(0)
Function FindLayerByName (pMap as IMap, sName as String) as ILayer Dim i as Integer For i = 0 to pMap.LayerCount -1 If pMap.Layer(i).Name = sName Then Set FindLayerByName = pMap.Layer(i) End If Next End Function