Solved! Go to Solution.
I know this is something we have been asking for forever, but I do not know if there is a real solution for this yet? Did anyone ever manage to recreate the "One to Many Label" script from VB6? Did ESRI finally give us a real solution to do the labeling? I saw one option of doing it using pivot tables that would require ArcInfo license, but that is a very roundabout solution using a license most people don't have. If anyone knows of a working solution please let me know.
If you don't know what I am talking about, basically I am looking to make "callout box" type of labels such as:
MW01 DEPTH BENZENE XYLENE
12 34 0.78
18 102 9
import arcpy # variables that need to be customized for your specific data def FindLabel ( [FULL_NAME] ): # input the field name of the parent table's relate field inputValue = [FULL_NAME] # repeat the parent table's relate field queryValue = "'" + inputValue + "'" # add query value delimiters for strings or dates here # define the data source path and fields of the related table featureClass = r'\\agency\agencydfs\Trans\rfairhur\Layers\PARCEL_LINES.gdb\ADDRESS_POINT_Locate_JURUP' relatedFieldName = "FULL_NAME" # the relate field name in the related table that corresponds to the input field valueFieldName = "HOUSE_NUMBER" # desired label value field name in the related table # As long as you want a simple single field stacked label you should not need to change this code whereArgs = [arcpy.AddFieldDelimiters(featureClass, relatedFieldName), queryValue] whereClause = "%s = %s" % tuple(whereArgs) labelList = [] rows = arcpy.da.SearchCursor(featureClass, (relatedFieldName, valueFieldName), whereClause) for row in rows: labelList.append(row[1]) labelList.sort() # uses correct sort order for numbers, dates or strings labelList.insert(0, inputValue) # insert input value as a heading return "\n".join(str(labelvalue) for labelvalue in labelList)
I know this is something we have been asking for forever, but I do not know if there is a real solution for this yet? Did anyone ever manage to recreate the "One to Many Label" script from VB6? Did ESRI finally give us a real solution to do the labeling? I saw one option of doing it using pivot tables that would require ArcInfo license, but that is a very roundabout solution using a license most people don't have. If anyone knows of a working solution please let me know.
If you don't know what I am talking about, basically I am looking to make "callout box" type of labels such as:
MW01 DEPTH BENZENE XYLENE
12 34 0.78
18 102 9
import arcpy # variables that need to be customized for your specific data def FindLabel ( [FULL_NAME] ): # input the field name of the parent table's relate field inputValue = [FULL_NAME] # repeat the parent table's relate field queryValue = "'" + inputValue + "'" # add query value delimiters for strings or dates here # define the data source path and fields of the related table featureClass = r'\\agency\agencydfs\Trans\rfairhur\Layers\PARCEL_LINES.gdb\ADDRESS_POINT_Locate_JURUP' relatedFieldName = "FULL_NAME" # the relate field name in the related table that corresponds to the input field valueFieldName = "HOUSE_NUMBER" # desired label value field name in the related table # As long as you want a simple single field stacked label you should not need to change this code whereArgs = [arcpy.AddFieldDelimiters(featureClass, relatedFieldName), queryValue] whereClause = "%s = %s" % tuple(whereArgs) labelList = [] rows = arcpy.da.SearchCursor(featureClass, (relatedFieldName, valueFieldName), whereClause) for row in rows: labelList.append(row[1]) labelList.sort() # uses correct sort order for numbers, dates or strings labelList.insert(0, inputValue) # insert input value as a heading return "\n".join(str(labelvalue) for labelvalue in labelList)
import arcpy # variables that need to be customized for your specific data def FindLabel ( [SampleName] ): # input the field name of the parent table's relate field inputValue = [SampleName] # repeat the parent table's relate field # define the data source path and fields of the related table featureClass = r'Chromium_Data' relatedFieldName = "sampleid" # the relate field name in the related table that corresponds to the input field valueFieldName = "depth" # desired label value field name in the related table valueFieldName2 = "result" # second field to label # As long as you want a simple single field stacked label you should not need to change this code whereArgs = [arcpy.AddFieldDelimiters(featureClass, relatedFieldName), "'" + inputValue + "'"] whereClause = "%s = %s" % tuple(whereArgs) labelList = [] rows = arcpy.da.SearchCursor(featureClass, (relatedFieldName, valueFieldName, valueFieldName2), whereClause) for row in rows: finalString = (str(row[1]) + ": " + str(row[2])) # combining the label fields labelList.append(finalString) labelList.sort() # uses correct sort order for numbers, dates or strings labelList.insert(0, inputValue) # insert input value as a heading return "\n".join(str(labelvalue) for labelvalue in labelList)
import arcpy # variables that need to be customized for your specific data def FindLabel ( [SampleName] ): # input the field name of the parent table's relate field inputValue = [SampleName] # repeat the parent table's relate field # define the data source path and fields of the related table featureClass = r'Chromium_Data' relatedFieldName = "sampleid" # the relate field name in the related table that corresponds to the input field valueFieldName = "param" # desired label value field name in the related table valueFieldName2 = "depth" # second field to label valueFieldName3 = "result" # third field to label # As long as you want a simple single field stacked label you should not need to change this code whereArgs = [arcpy.AddFieldDelimiters(featureClass, relatedFieldName), "'" + inputValue + "'"] whereClause = "%s = %s" % tuple(whereArgs) labelList = [] rows = arcpy.da.SearchCursor(featureClass, (relatedFieldName, valueFieldName, valueFieldName2, valueFieldName3), whereClause) for row in rows: finalString = (str(row[1]) + " - " + str(row[2]) + " - " + str(row[3])) # combining the label fields labelList.append(finalString) labelList.sort() # uses correct sort order for numbers, dates or strings labelList.insert(0, inputValue) # insert input value as a heading return "\n".join(str(labelvalue) for labelvalue in labelList)
Finally got it to work to look more like what I want, although running into a resource problem which is causing ArcMap to crash.
This code works, and does what I need it to do to display two fields instead of just the oneimport arcpy # variables that need to be customized for your specific data def FindLabel ( [SampleName] ): # input the field name of the parent table's relate field inputValue = [SampleName] # repeat the parent table's relate field # define the data source path and fields of the related table featureClass = r'Chromium_Data' relatedFieldName = "sampleid" # the relate field name in the related table that corresponds to the input field valueFieldName = "depth" # desired label value field name in the related table valueFieldName2 = "result" # second field to label # As long as you want a simple single field stacked label you should not need to change this code whereArgs = [arcpy.AddFieldDelimiters(featureClass, relatedFieldName), "'" + inputValue + "'"] whereClause = "%s = %s" % tuple(whereArgs) labelList = [] rows = arcpy.da.SearchCursor(featureClass, (relatedFieldName, valueFieldName, valueFieldName2), whereClause) for row in rows: finalString = (str(row[1]) + ": " + str(row[2])) # combining the label fields labelList.append(finalString) labelList.sort() # uses correct sort order for numbers, dates or strings labelList.insert(0, inputValue) # insert input value as a heading return "\n".join(str(labelvalue) for labelvalue in labelList)
This code theoretically works using 3 label fields, the code verification process displays the correct result, but the processing is too much and causes ArcMap to crash.import arcpy # variables that need to be customized for your specific data def FindLabel ( [SampleName] ): # input the field name of the parent table's relate field inputValue = [SampleName] # repeat the parent table's relate field # define the data source path and fields of the related table featureClass = r'Chromium_Data' relatedFieldName = "sampleid" # the relate field name in the related table that corresponds to the input field valueFieldName = "param" # desired label value field name in the related table valueFieldName2 = "depth" # second field to label valueFieldName3 = "result" # third field to label # As long as you want a simple single field stacked label you should not need to change this code whereArgs = [arcpy.AddFieldDelimiters(featureClass, relatedFieldName), "'" + inputValue + "'"] whereClause = "%s = %s" % tuple(whereArgs) labelList = [] rows = arcpy.da.SearchCursor(featureClass, (relatedFieldName, valueFieldName, valueFieldName2, valueFieldName3), whereClause) for row in rows: finalString = (str(row[1]) + " - " + str(row[2]) + " - " + str(row[3])) # combining the label fields labelList.append(finalString) labelList.sort() # uses correct sort order for numbers, dates or strings labelList.insert(0, inputValue) # insert input value as a heading return "\n".join(str(labelvalue) for labelvalue in labelList)
It would be nice if ArcMap could handle this by itself, but I could work around it by pre-concatnating my 3 fields into one within the database. Of course editing the database is not an ideal solution, but at least we got a working solution.
Side question, do you know if there is a way to run a SQL statement within the code to filter the results, such as only displaying results where "valueFieldName3 = "desiredValue""?
for row in rows: if row[1] == "CHROMIUM": # data filter finalString = (str(row[1]) + ": " + str(row[2]) + ": " + str(row[3])) # combining the label fields labelList.append(finalString)
Ah, interesting, zooming in did take prevent the crash. Didn't think that would matter since the labels would have to be created anyway. I am still a little hesitant that it might crash the system anytime but it does work.
For the sql statement, I just wanted a data filter, which I worked around by putting it in the code with an if statement instead of using a sql clausefor row in rows: if row[1] == "CHROMIUM": # data filter finalString = (str(row[1]) + ": " + str(row[2]) + ": " + str(row[3])) # combining the label fields labelList.append(finalString)
import arcpy # variables that need to be customized for your specific data def FindLabel ( [SampleName] ): # input the field name of the parent table's relate field inputValue = [SampleName] # repeat the parent table's relate field # define the data source path and fields of the related table featureClass = r'Chromium_Data' relatedFieldName = "sampleid" # the relate field name in the related table that corresponds to the input field valueFieldName = "param" # desired label value field name in the related table valueFieldName2 = "depth" # second field to label valueFieldName3 = "result" # third field to label # As long as you want a simple single field stacked label you should not need to change this code whereArgs = [arcpy.AddFieldDelimiters(featureClass, relatedFieldName), "'" + inputValue + "'", arcpy.AddFieldDelimiters(featureClass, valueFieldName), "'CHROMIUM'"] whereClause = "%s = %s AND %s = %s" % tuple(whereArgs) labelList = [] rows = arcpy.da.SearchCursor(featureClass, (relatedFieldName, valueFieldName, valueFieldName2, valueFieldName3), whereClause) for row in rows: finalString = (str(row[1]) + " - " + str(row[2]) + " - " + str(row[3])) # combining the label fields del row labelList.append(finalString) del rows labelList.sort() # uses correct sort order for numbers, dates or strings labelList.insert(0, inputValue) # insert input value as a heading return "\n".join(str(labelvalue) for labelvalue in labelList)