情景再現
現需要將Excel表信息批量賦值(不是掛接)到Shp文件的屬性表,兩張表的字段、記錄數一模一樣,至於為什么會出現這樣的問題,咱也不敢問,只有想個法子把它搞定!
原始的Excel信息表共57列,總共3萬多條記錄,包含了正確的記錄數據,如下:

目標的ArcGIS屬性表也是57列(不是Table表,是要素類的屬性表),記錄中的信息不正確,如下:

好在它們的FID字段可以一一對應,現在需要根據Excel屬性表把ArcGIS屬性表填充正確。
常規思路
最容易想到的方法是,用屬性表連接Excel表,然后利用字段計算器,分別進行計算。

由於記錄有3萬多條,平均一個字段計算要8分鍾,這也得花一天時間啊,如果沒有其實方法,且不用管"白貓""黑貓",能解決就行。
編程思維
從上面的方法,我們會很快發現一個問題:50多個字段的計算都是重復一個步驟,在某個字段上右鍵,點擊"字段計算器"彈出窗口,選擇相應的字段,點擊確定。這個過程簡單而無味,是否有讓電腦自動重復這個操作,解放我們的雙手?答案是肯定的,通過簡單的編程來實現重復的操作,對於本場景最佳編程方式是使用強大的Python腳本。對於新手來說也莫怕,編程並不可怕,可怕的是你遇到這種問題不會編程。下面來試一下:

簡單解釋一下:
第一步,導入arcpy,這是ESRI給我造好的"輪子",引入它后可以做所有地理處理的功能;
第二步,直接調用字段計算的方法,方法名稱是:arcpy.CalculateField_management,其后面的括號帶四個參數,分別是計算的圖層名稱(即表名稱)、計算的字段(即在哪個字段上右鍵調出字段計算器)、計算表達式(就是選擇的賦值字段)、Python版本(固定值);
第三步,回車執行,糟糕,報錯了。不要緊,仔細分析一下,看是語法問題,還是數據問題,重寫一句再執行就對了。
有了成功的開始,是不是增加信心。我們不可能手動輸入50多句話,也很難寫的,得再想個法子來解放雙手(再次編程思維)。強大的Excel上場了:用公式寫好一行,直接向下拖動(或雙擊右下角),呵呵,這個我最擅長了。

將這些正確語法的Python語句放在窗口中執行,連續兩次回車才是執行哦!

接下來就慢慢等,雖然不需要反復操作,但時間也要花很久。
收工。
---------回--------家---------吃---------飯--------
Too young to simple!第二行就報錯了

怎么辦?有三種方案:
方案一:辭職轉行了,處理數據真是心累!
方案二:把問題返回給用戶,讓他們改好帶拿過來!(你以為他們會聽你的嗎?你以為他們能准備無誤地改得好嗎?)
方案三:百度、谷歌,查一下原因,寫一個能容錯的腳本,學習一下ArcPy處理地理數據。
編程能力
接下來,才是展示真正的技術的時候了。在連接好Excel表后,不使用字段計算器工具和腳本,而且是通過遍歷的方式賦值。

連接可保證行數相同。

連接后將數據導出后,將
下面這段代碼主要考慮三個問題:
(1)同名字賦值,如將Name_1的值賦給Name;
(2)缺失字段不賦值,如果不存在Name_1字段,則Name的值不重處理;
(3)忽略值與類型邏輯不一致的情況,如Count字段的值不能為空,默認為0,而Count_1的值為NULL.
代碼如下,不過多解釋,因為這不是本文重點。
import arcpy,os
input_table=arcpy.GetParameterAsText(0)
input_result=arcpy.GetCount_management(input_table)
input_count= int(input_result.getOutput(0))
arcpy.AddMessage("input count:"+ str(input_count))
oidFieldName=arcpy.Describe(input_table).OIDFieldName
allfields = arcpy.ListFields(input_table)
lstFields=[]
for field in allfields:
lstFields.append(field.name)
arcpy.AddMessage(lstFields)
# foreach all row and all field
cursor = arcpy.UpdateCursor(input_table)
for row in cursor:
fields = arcpy.ListFields(input_table)
oid=int(row.getValue(oidFieldName))
if oid>1:
arcpy.AddMessage(oid)
for field in fields:
if field.required or field.name[-2:]=='_1':
print('')
else:
targetField=field.name+'_1'
if targetField in lstFields:
newValue=row.getValue(targetField)
try:
row.setValue(field.name,newValue)
#arcpy.AddMessage(field.name+":"+ str(newValue))
except:
#arcpy.AddMessage(field.name+":except....")
pass
else:
print('')
#arcpy.AddMessage(targetField+":is not exist")
cursor.updateRow(row)
慢慢等結果了:

小結
1、要學會有編程(或程序)的思維去解決問題,提高工作效率;
2、編程解決問題是一種能力,是慢慢學習積累的過程,沒有一本速成的書;
3、實際生產過程中的數據往往不是理想的,有各種各樣的"陷阱"。
補充:
個別網友認為我小題大作了,由於原始數據不傳於上傳,所以我也不再反駁:


