Labeling Multiple Fields for a Theme

It is possible to write a script that creates multiple labels for each theme:

'Theme.MultiLabel
'Label multiple fields of theme

'**** get list of fields to label

theTitle = "Label Multiple Fields"
theView = av.GetActiveDoc
theTheme = theView.GetActiveThemes.Get(0)
theFTab = theTheme.GetFtab
theFList = theFTab.GetFields
theMsg = "Select Fields to Label"
theFields = MsgBox.MultiList(theFList,theMsg,theTitle)
if (theFields = nil) then
   return nil
end

'**** label fields

for each f in theFields
   theTheme.SetLabelField(f)
   theLabeler = Labeler.Make(theView.GetDisplay.ReturnExtent)
   theLabeler.Load(theTheme)
   theView.GetAutoLabels(theLabeler, false)
end
However, the results are not very satisfactory. Another approach is to create one label per feature, containing stacked text. If you want to use ArcView's labeler, what you need to do is create a concatenated item. The following script will work for numeric and character fields:

'Theme.ConcanFields
'Create character field representing concatenation of other fields

'**** check if theme is editable

theTitle = "Concatenate Fields"
theView = av.GetActiveDoc
theTheme = theView.GetActiveThemes.Get(0)
theFTab = theTheme.GetFtab
if (theFTab.IsEditable.Not) then
   theMsg = "Active Theme is not editable."+NL+
            "Please start editing first."
   MsgBox.Error(theMsg,theTitle)
   return nil
end

'**** get list of fields to concatenate

theFList = theFTab.GetFields
theMsg = "Select Fields to Concatenate"
theFields = MsgBox.MultiList(theFList,theMsg,theTitle)
if (theFields = nil) then
   return nil
end

'**** get name of field to add

theFieldName = MsgBox.Input("Name of New Field",theTitle,"LabelText")
if (theFieldName = nil) then
   return nil
elseif (theFTab.FindField(theFieldname) <> nil) then
   MsgBox.Error("Field Already Exists.",theTitle)
   return nil
end

'**** add field

theWidth = 0
for each f in theFields
   theWidth = theWidth + f.GetWidth + 1
end
if (theWidth > 254) then
   MsgBox.Error("Maximum width (254) exceeded.",theTitle)
   return nil
end
theField = Field.Make(theFieldName,#FIELD_CHAR,theWidth,0)
theFTab.AddFields({theField})

'**** calculate values

for each r in theFtab
   theValue = ""
   for each f in theFields
      theWidth = f.GetWidth
      fp = f.GetPrecision
      if (fp > 0) then
         theString = theFtab.ReturnValue(f,r).SetFormatPrecision(fp).AsString
      else
         theString = theFtab.ReturnValue(f,r).AsString
      end
      if (theValue = "") then
         theValue = theString
      else
         theValue = theValue + NL + theString
      end
   end
   theFtab.SetValue(theField,r,theValue)
end
Note that the table in question must be editable (i.e. a shapefile in edit mode). Otherwise, if you don't care about positioning, you can try the "brute force" approach:

'Theme.StackLabel
'Create stacked labels of multiple fields

'**** get list of fields to label

theTitle = "Label Multiple Fields"
theView = av.GetActiveDoc
theTheme = theView.GetActiveThemes.Get(0)
theFTab = theTheme.GetFtab
theFList = theFTab.GetFields
theMsg = "Select Fields to Label"
theFields = MsgBox.MultiList(theFList,theMsg,theTitle)
if (theFields = nil) then
   return nil
end

'**** create labels

for each r in theFtab
   theValue = ""
   for each f in theFields
      theWidth = f.GetWidth
      fp = f.GetPrecision
      if (fp > 0) then
         theString = theFtab.ReturnValue(f,r).SetFormatPrecision(fp).AsString
      else
         theString = theFtab.ReturnValue(f,r).AsString
      end
      if (theValue = "") then
         theValue = theString
      else
         theValue = theValue + NL + theString
      end
   end
   theShape = theFTab.ReturnValue(theFTab.FindField("shape"),r)
   thePoint = theShape.ReturnCenter
   theGraphicText = GraphicText.Make(theValue,thePoint)
   theView.GetGraphics.Add(theGraphicText)
   theGraphicText.Invalidate
end

Back to AVTips