2

I'm using ModelBuilder to iterate through ~800 shapefiles to add and calculate a new field (I'll call it Field_A). Field_A needs to be populated by either Field_B or Field_C, whichever exists. Half of my shapefiles contain Field_B and the other half contain Field_C, but none of the shapefiles contain both.

I tried using the expression: Field_A = !Field_B! or !Field_C! ....but it won't work unless both of those fields are in the attribute table.

How can I get the calculator to recognize whichever field is existing and disregard the other field if it doesn't exist?

(I'm working in ArcMap 10.1)

5
  • 1
    Have you tried using/are you familiar with conditional statements? There is an example here (resources.arcgis.com/en/help/main/10.1/index.html#//…) of conditional formating in the code block.
    – AlmaThom
    Commented Sep 24, 2013 at 23:58
  • 1
    Also check this similar question: gis.stackexchange.com/questions/26892/…
    – AlmaThom
    Commented Sep 25, 2013 at 0:00
  • Thanks Alma ... I have looked at the code examples provided by esri but I didn't see anything that quite fit. I'm also not very familiar with python (trying to learn, but still in the baby stages). Your second post does seem very similar, perhaps there is something I can glean from it.
    – S.S.
    Commented Sep 25, 2013 at 0:14
  • You might have to do it in two iterations. Where shapefile have Field_B, populate Field_A. Then where shapefile has Field_C, populate Field_A. I have a calculation script that wants to look at two fields for the calculation, but if one of those fields is missing, then it errors out. Commented Sep 25, 2013 at 2:35
  • @ Ryan - In order to do that, I would have to go through every attribute table to find out which ones have Field_B and which have Field_C ... that's part of the problem, they're all mixed. :/
    – S.S.
    Commented Sep 25, 2013 at 15:31

1 Answer 1

3

I am more familiar with python than I am with Model Builder so my solution involves a python script in your tool. Perhaps someone with more Model Builder experience can convert these processes. Create a python script with the following code:

import arcpy

fc = arcpy.GetParameterAsText(0)
fieldA = arcpy.GetParameterAsText(1)
fieldB = arcpy.GetParameterAsText(2)
fieldC = arcpy.GetParameterAsText(3)

#I included the Add Field tool in this script, it is up to you if you keep it in here or prefer to work with the tool in Model Builder
arcpy.AddField_management(fc, fieldC, 'LONG') #Change field type here if not LONG

fields = arcpy.ListFields(fc, fieldA) # *explanation below
if len(fields) == 0:
    arcpy.CalculateField_management(fc, fieldC, "!" + str(fieldB) + "!", "PYTHON_9.3")
else:
    arcpy.CalculateField_management(fc, fieldC, "!" + str(fieldA) + "!", "PYTHON_9.3")

Save this script and add it to the toolbox where your model is saved, then open the script properties. Your Parameters are going to look like this:enter image description here
Make sure to set the output as Derived and Output types, as shown in the image, the other parameters accept the defualt properties.
Drag and drop the script into your model. Make variables from all parameters except fc and connect your output from your iterator (or whatever your last process is) to the script as the fc parameter. Then treat the field parameters as strings and enter your two existing fields in fieldA and fieldB and your final desired field in fieldC. your model should look a bit like this:enter image description here

*I am using the first field as the wildcard for the ListFields tool, so it will return a list that is empty if that field does not exist, or a list containing only that field.

5
  • 1
    You might find it easier to format your expression by using string formatting, like so: "!{}!".format(fieldB). No need for concatenation and is ~20x faster. Granted, this is all premature optimization, but .format() is great when concatenating lots of strings and variables. +1
    – Paul
    Commented Sep 25, 2013 at 19:37
  • I've never really gotten a good grasp of formatting, embarrassingly enough, but this is a good tip. Especially if S.S. has 800 shapefiles.
    – AlmaThom
    Commented Sep 25, 2013 at 20:20
  • It has a bit of a learning curve, especially for number formatting, but I find it easier to write and debug afterwards.
    – Paul
    Commented Sep 25, 2013 at 20:22
  • Thanks for your help, Paul! I followed everything you said, but I'm getting an error when I run the model that says: ERROR 000728: Field SHP_002_POINT does not exist within table Failed to execute (CalculateField). It seems to be naming the field based on the shapefile name. Do you know how to correct this? Thx!
    – S.S.
    Commented Sep 26, 2013 at 22:16
  • What are you naming your fieldC? And how do you have it input into the model variable? I did not get that error when running my sample model, however a quick google search of the error code says this is a refresh error, that creating the field and then trying to calculate it within a single script in model builder does not give ArcMap enough time to 'refresh' the layer and recognize the new field. Try removing the Add Field code from the script and adding the tool to the model before the script.
    – AlmaThom
    Commented Sep 27, 2013 at 18:36

Not the answer you're looking for? Browse other questions tagged or ask your own question.