Useful Scripts for the Non-Programmer: Changing ArcFM™ Feature Settings En Masse

February 9, 2012 — Corey Blakeborough, Guest Author

You may have noticed that the last few code examples we’ve provided have all been very similar in nature. The code I initially used to traverse through the ArcFM™ top level configuration tree has proved very useful, and continues to be productive with various tweaks.

After we “Designerize” a variety of feature classes for a client who intends to use the Designer™ features of the ArcFM™ Solution, we prefer to set the Designer™ fields to be read-only.

useful-scripts-set-designer-fields-to-read-only

In the past, we’ve done this the long way and hoped we had an intern at the time. But we’re always keen to optimize our processes and make things work faster. The code below was developed and used to disable the Editable property across all feature classes for the fields specific to Designer™.

In the interest of customizability, you can enter in a list of field names in the topmost variable if your purposes differ. The second variable shows the specific property we’re setting en masse, and the third property is a true or false value to set everything to. These variables are listed in bold in the code below, and there are comments (in green) explaining them.

The property and value of these variables, by default, are populated to set the Editable attribute to false. If you want something different, the list of available “simple setting” properties is as follows:

  • 0 (mmFSVisible)
  • 1 (mmFSEditable)
  • 2 (mmFSAllowNulls)
  • 3 (mmFSCUDefined)
  • 4 (mmFSClearOnCreate)
  • 10 (mmSSPostable)
  • 11 (mmSSValidateRelatedObject)
  • 12 (mmSSNWValidateRelatedObj)
  • 13 (mmFSAllowMassAttributeUpdate)
  • 14 (mmSSSplitOnFeature)

This is another ArcCatalog VBA script, so here’s what you do:

In ArcCatalog, drop down the Tools menu and choose Macros → Visual Basic Editor.

useful-scripts-vb-editor

Within the Visual Basic environment, expand the Normal.mxt file. Right-click it and insert a new Module within the Modules folder.

In the editor, click Tools → References and ensure that the following references are enabled:

  • Miner & Miner Geodatabase Object Library
  • Miner & Miner System Object Library

useful-scripts-enable-references-1

The code for this module is below. Copy and paste it into the module and save it.


‘ Field Names to change (comma separated):
Private Const m_MPEFLDNAMES As String = “WorkRequestID,WorkFunction,DesignID,WorkLocationID,WorkFlowStatus”
‘ Property to Edit:
Private Const m_MPEATTRTYPE As Integer = 1
‘ Value to set:
Private Const m_MPEATTVALUE As Boolean = False

Public Sub SetPropertiesEnMasse()
Dim catalogApp As IGxApplication
Set catalogApp = Application
Dim ws As IWorkspace

If TypeOf catalogApp.SelectedObject Is IGxDatabase Then
Dim
gdb As IGxDatabase
Set gdb = catalogApp.SelectedObject
If gdb.IsConnected Then
Set
ws = gdb.Workspace
End If
End If

If ws Is Nothing Then
MsgBox “Please select a database connection to search for when running this function.”
Exit Sub
End If

Debug.Print “Starting Process…..”

Dim eDS As IEnumDataset
Set eDS = ws.Datasets(esriDatasetType.esriDTAny)
IterateDatasets eDS

Debug.Print “———-FINISHED———-”
End Sub

Sub IterateDatasets(pEnumDataset As IEnumDataset)
Dim ds As IDataset

pEnumDataset.Reset
Set ds = pEnumDataset.Next
Do While Not ds Is Nothing
If
ds.Type = esriDatasetType.esriDTFeatureClass Then
Dim
dfc As IFeatureClass
Set dfc = ds
ProcessObjectClass dfc
ElseIf ds.Type = esriDatasetType.esriDTTable Then
Dim
doc As IObjectClass
Set doc = ds
ProcessObjectClass doc
ElseIf ds.Type = esriDatasetType.esriDTFeatureDataset Then
IterateDatasets ds.Subsets
End If
Set
ds = pEnumDataset.Next
Loop
End Sub

Sub ProcessObjectClass(oc AS IObjectClass)
If Not oc Is Nothing Then
Dim
desc As String
Dim
code As Long
desc = “”

Dim enSt As IEnumSubtype
Dim ocSt As ISubtypes

Set ocSt = oc

Set enSt = ocSt.Subtypes

desc = enSt.Next(code)
Do While Not desc = “”
Dim ctl As IMMConfigTopLevel
Set ctl = New MMConfigTopLevel

Dim mmFC As IMMFeatureClass
Dim list As ID8List
Dim sList As ID8List
Dim fList As ID8List
Dim listItem As ID8ListItem
Dim sListItem As ID8ListItem
Dim fListItem As ID8ListItem

Set mmFC = ctl.GetFeatureClassOnly(oc)
Set list = mmFC

list.Reset
Set listItem = list.Next(False)
Do While Not listItem Is Nothing
If
listItem.ItemType = mmd8ItemType.mmitSubtype Then
Dim
pSubtype As IMMSubtype
Set pSubtype = listItem

Set sList = listItem
sList.Reset
Set sListItem = sList.Next(False)
Do While Not sListItem Is Nothing
If
sListItem.ItemType = mmd8ItemType.mmitField Then
Dim
field As IMMField
Set field = sListItem

Dim fldMatch As Boolean
fldMatch = False

Dim fldNames As Variant
Dim
fldName As Variant
fldNames = Split(m_MPEFLDNAMES, “,”)
For Each fldName In fldNames
If field.FieldName = fldName Then
fldMatch = True
Exit For
End If
Next
fldName

If fldMatch Then
Dim
foundSimpleSetting As Boolean
foundSimpleSetting = False

Set fList = sListItem
fList.Reset
Set fListItem = fList.Next(False)
Do While Not fListItem Is Nothing
If
fListItem.ItemType = mmd8ItemType.mmitSimpleSetting Then
Dim
ss As IMMSimpleSetting
Set ss = fListItem
If ss.SettingType = m_MPEATTRTYPE Then
foundSimpleSetting = True
ss.SettingValue = m_MPEATTVALUE
End If
End If
Set
fListItem = fList.Next(False)
Loop

If Not foundSimpleSetting Then
Dim
ssNew As IMMSimpleSetting
Set ssNew = New MMSimpleSetting
ssNew.SettingType = m_MPEATTRTYPE
ssNew.SettingValue = m_MPEATTVALUE

Dim newSetting As ID8ListItem
Set newSetting = ssNew

fList.Add newSetting
End If
End If
End If
Set
sListItem = sList.Next(False)
Loop
End If
Set
listItem = list.Next(False)
Loop
ctl.SaveFeatureClassToDB oc
desc = enSt.Next(code)
Loop
End If
End Sub


Be sure that you have a connection open and selected in ArcCatalog, then run the script. This code may take a minute or two. Don’t worry, it should be running! Check your attributes when you’re done, and you should be all set!

We Wrote the Book

The Indispensible Guide to ArcGIS Online

Download It for Free

4 comments

  • Currently, I have to make 4 fields in my FC as visible through ArcFM properties manager. As I am hundreds of feature classes, so I can’t prefer doing it manually. Could you please guide how to use standalone Python script to achieve that.
    I want to use Python 2.7 for that. Currently I am on 10.2 with arcgis 10.2.1

  • I have FC Name(String), FCFiled(String) and Setting type (Bool ex:- Editable FALSE)

    Now I want to set programmatically Arcfm Properties for feature class.

    Please help me with sample code. I am using C# 3.5 , ArcMap 10.2.1 and ArcFM

    • Corey Blakeborough says:

      The code above in Visual Basic should be able to accomplish this. Set m_MPEFLDNAMES to your field name, m_MPEATTRTYPE to 1 (mmFSEditable), and m_MPEATTVALUE to False. If you only want this action to occur on a single feature class, you’ll want to modify the ProcessObjectClass Sub by modifying the first line to check for Nothing AND to check the object class name against what you’re looking for. Or, you can open the table directly from the workspace instead of going through IterateDatasets.

      I realize that this article is for the “non-programmer”, so let me know based on your background if you need additional guidance.

What do you think?

Leave a comment, and share your thoughts

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>