It is possible to change fields alias in layer within mxd by arcpy?(Table Options > Appearance)
Updating a field property only updates the field object, no changes are made to the actual field in the table or feature class.
When a geodatabase feature class is added to ArcMap, its field aliases are used initially for the layer field aliases. However, after this there is no link between the two. Properties set in ArcMap will override the properties of the data source, but they will not be carried back to the data source. This means that if you change a layer field alias, it will not change the feature class field alias, and if you change a geodatabase field alias, it will not update the layer field alias for any existing layers based on the feature class.
Have you found any other method to update the field alias in an mxd layer ?
Our SDE contains the updated alias but not able to update in mxd.
Well, I've spent too many hours trying to solve this issue.
How you solved your issue.
For what it is worth now, I kind of found a way to indirectly do this. Although it is not directly altering the field alias in the MXD, this way does seem to work. I create a data inventory of my feature classes in the gdb in a csv file. I then update all my aliases and stuff in the csv. I then run my next script that uses the AlterField tool to make the changed in my csv file to my feature classes.
All pretty standard and non-mxd(ish) up until now.
From here, I made use of T. Wayne Whitley reply from this thread which actually goes through to update the field visibility setting for the relevant layers using fieldInfo. Once the new layer is added/updated, the feature classes field alias seems to be updated also. I then use mxd.saveACopy to make a new output mxd.
Hope this helps.
Have you tried Alter Field—Data Management toolbox | ArcGIS for Desktop ?
Alter Field tool is to rename fields or field aliases for any feature class. I've already updated alias name in feature class. Since MXD layers have separate field mappings, the alias from the SDE fields are not reflecting in MXD layer. Hence thought of reading the layers from mxd and update the field alias.
As Jeff Barrette said, I've tried the UpdateLayer method. This has to be executed with the flag symbology_only=False for updating the fields. When I executed this, I lost the symbology.
This can be done like this (all arcpy, except step 2):
1) Use arcpy.ListFields() to get field names and field aliases from a feature class, and output to a csv file
2) In the csv file, update the alias column
3) Using arcpy, re-add the feature class to the map document (mxd) - it will have the wrong symbology
4) Use arcpy.ApplySymbologyFromLayer_management() to update the symbology
5) Use arcpy to delete the original layer from the MXD
Just be aware that ApplySymbologyFromLayer_management may not bring across all layer properties, e.g. Definition Queries.
I have just written a Python script that does what I mentioned above - it works great. Here are the steps:
3) Loop through the layers in the map document using arcpy.mapping.ListLayers()
4) If the layer supports "DATASOURCE", create a feature layer using layer.dataSource as the in_features and layer.definitionQuery as the where_clause
5) Save the feature layer to a layer file
6) Create a new arcpy.mapping.Layer from the layer file
7) Set the min and max scales for the new layer using the original layer, i.e. layer.minScale
8) Set the label classes, similar to the previous step
9) Apply the symbology of the original layer using arcpy.ApplySymbologyFromLayer_management()
10) Add the layer to the mxd using arcpy.mapping.InsertLayer()
11) Remove the original layer using arcpy.mapping.RemoveLayer()
12) Save a copy of the mxd using mxd.saveACopy()
This works really well and runs in less than a minute even on large mxds.
Hi Rhys Donoghue,
can you post your code as example?
I'm trying to simply set field.aliasName = row.encode('utf8') and export Layerfile but don't works...
Hi Damiano, my code is at work and I am on holiday, so I can't post my code at the moment. However, where are you setting the alias? In general, you should set the alias in the geodatabase, not in the map document (MXD file). If you set the alias in the gdb, you don't need to update your alias each time you add the feature class to a map document. Also, you shouldn't be exporting to a layer file. Instead you should be using arcpy.SaveToLayerFile_management(), then later if you need to, you can use
arcpy.ApplySymbologyFromLayer_management() to update a layer with the symbology. Also, note that saving a layer file does not save all of the layer properties - which it should, however, it should save the aliases fine.
Let me know if you need more details.
Thanks for the response, but I need to renaming ALIAS name in MXD... My Feature Class are in Oracle non ESRI GDB with read Only permission...
It's strange that a simply UI task in ArcMap don't have a corresponding function in arcpy.
Why aliasName properties of field is "(Read and Write)"????
Field—ArcPy Classes | ArcGIS Desktop
Now I'm trying with toolbox script and CURRENT mxd... maybe...
if I have news, I will update you...
From the Googling I did earlier, I believe aliasName is readonly, although you may be able to use ArcObjects to change it (I didn't look into this).
I just realised I may have copied the script I wrote at work to my USB drive. I will see if I can get it for you. Will reply soon. It may do exactly what you want.
This is how to change the alias in the geodatabase (I realise this is not what you want - just adding it here in case someone else wants to use it). Will send through a few scripts soon - sorry I'm not sure how to add the script below other than copying and pasting, which messes up the indenting:
import arcpy, csv
def main(inputFile,wksp,fc): arcpy.env.workspace = wksp
fields =  excludedFields = ["objectid","shape","shape_length","shape_area","o_shape","o_shape_length","o_shape_area"]
for field in arcpy.ListFields(fc): fields.append(field.name)
with open(inputFile, 'rb') as csvfile: csvreader = csv.reader(csvfile)
for row in csvreader: if row in fields and row.lower() not in excludedFields:
in_table = fc field = row new_field_name = row new_field_alias = row
arcpy.AlterField_management(in_table, field, new_field_name, new_field_alias)
if __name__ == '__main__':
# change the parameters below inputFile = # input CSV file wksp = # input workspace fc = # input feature class main(inputFile,wksp,fc)
Here's the code below that should work for you. I can see couple of things in there that need tidying up, e.g. the error trapping, and changing the hardcoded file names to parameters. This script below does what I mentioned in my twelve steps above. The only issue I had was I couldn't copy the advanced label expressions and I couldn't tick the advanced label expression box (but this can be done via ArcObjects, if you don't want to do it manually). The script basically rebuilds your MXD with the new layer aliases that were updated in the geodatabase using the previous script I sent through above. This is not quite what you are after since you can't change the aliases in the GDB, however, hopefully this is enough to put you on the right track.
If I understand what you want to do, I would probably create a feature layer with field aliases, and use the code below. If you're really stuck, what you could do is use ArcPy to recreate your feature classes in a file geodatabase but without the data, e.g. use the Make Feature Layer tool and use '1=2' for the where clause, then use the Copy Features tool to create the FCs from the feature layers. Then use the Alter Field tool to create the Aliases in the FGDB, and use the script below to update the MXD. Then once you've done that, close your MXD, rename your FGDB, open your MXD and repair the datasources to point to Oracle. This sounds complicated but is quite easy - unless you're working with complex data sets, e.g. geometric networks, topology, etc. however, since you're using native Oracle, not SDE, I doubt this would be an issue for you.
I have added the code here, which should have the correct indenting: Your Python Trinket
import os, time, arcpy, csvfrom datetime import datetime
arcpy.env.overwriteOutput = True
for folder, dirs, files in os.walk(directory): for file in files: if file.endswith('test.mxd'): # add your MXD name here try: path = os.path.join(folder, file)
mxd = arcpy.mapping.MapDocument(path) data_frame = arcpy.mapping.ListDataFrames(mxd, "Layers")
i = 0
for lyr in arcpy.mapping.ListLayers(mxd, "", data_frame):
# todo - add properties from group layers if lyr.supports("DATASOURCE"):
field_info = ''
if lyr in layers: desc = arcpy.Describe(lyr) field_info = desc.fieldInfo
for i in range(0, field_info.count): if field_info.getFieldName(i) not in visibleFields: field_info.setVisible(i, "HIDDEN")
# make a feature layer in_features=lyr.dataSource out_layer=lyr.name where_clause=lyr.definitionQuery if lyr.supports("definitionQuery") else '' layer = arcpy.MakeFeatureLayer_management(in_features,out_layer,where_clause,"",field_info)
# save the feature layer to a layer file in_layer = layer out_layer = os.path.join(layer_files_folder, str(i) + '.lyr') arcpy.SaveToLayerFile_management(in_layer, out_layer)
# create a new layer reference_layer = lyr insert_layer = arcpy.mapping.Layer(out_layer) insert_position = "AFTER"
# set the min and max scales for the layer insert_layer.minScale = lyr.minScale insert_layer.maxScale = lyr.maxScale
# copy the label classes from the original layer to the new layer if lyr.supports("LABELCLASSES"): className = '' expression = '' SQLQuery = ''
for lblClass in lyr.labelClasses: className = lblClass.className expression = lblClass.expression SQLQuery = lblClass.SQLQuery if expression[:3] == 'def': print 'Warning: layer "%s" users an Advanced Label Expression' % (lyr.name)
for lblClass in insert_layer.labelClasses: lblClass.className = className lblClass.expression = expression lblClass.SQLQuery = SQLQuery
# show the labels if lyr.supports("SHOWLABELS") and expression[:3] != 'def': insert_layer.showLabels = lyr.showLabels
# apply the symbology of the original layer to the new layer in_layer=insert_layer in_symbology_layer = lyr arcpy.ApplySymbologyFromLayer_management(in_layer, in_symbology_layer)
# add the layer to the map document arcpy.mapping.InsertLayer(data_frame, reference_layer, insert_layer, insert_position)
# remove the original layer arcpy.mapping.RemoveLayer(data_frame, lyr) i += 1
except OSError: print 'Error with ' + file
if __name__ == '__main__': layers = ['','',''] # add your layer names here visibleFields = ['','',''] # add your field names here directory = r'C:\dev\map documents (mxds)' results_folder = r'C:\dev\scripts\Python\output' layer_files_folder = r'C:\dev\gisdata\layer files\temp'
Thanks a lot Rhys,
you suggested an interesting idea with a local FGDB as support only for the data structure ...I'll do some tests and then update the whole community ...I hope I have not ruined your holidays ...
Sounds good Damiano, I'm keen to know how you get on.
I came back today after a week of vacation, I can tell you that your suggestion has worked.Adding the FCs from GDB I see the correct aliases (set by the code), I only need to change the source and point to the SDE.
I will do it these days but I do not think I find particular difficulties ..
thank you again!
Nice one Damiano, hope you enjoyed your holiday. Feel free to contact me via LinkedIn if you need to in the future.
Retrieving data ...