一年或两年后,我变得非常精通使用ArcGIS中的数据模型来混淆属性表。 ArcGIS使用Access类型数据库,使用户可以添加,删除和修改字段。在ArcGIS界面中,我可以创建一个新列,并使用Python使用称为“字段计算器”的东西在此列上运行脚本。例如,下面的算法作为输入字符串,如“230 04th street”,并将它们转换为“230 4th street”。它还做了一些适合该项目的替代品。
def calc(f1,f2,f3):
#where f1 is address number, f2 is address name and f3 is address suffix
#Strip trailing and ending spaces from all fields
#Define list
remove_list = ['01ST', '02ND', '03RD', '04TH', '05TH', '06TH', '07TH', '08TH', '09TH']
#Homogenize single digit address names
if f2 in remove_list:
f2 = f2.replace('0','')
else:
f2 = f2
f1 = str(f1).replace('.0','')
#strip leading and trailing spaces
f1 = f1.strip()
f2 = f2.strip()
f3 = f3.strip()
#adapt address number to string format
#Concatenate full address name
x = f1+' '+f2+' '+f3
#Return Full address name
return x
我希望在Access中具有类似的灵活性。 Access中最接近ArcGIS“Field Calculator”的是“Expression Builder”。此表达式构建器适用于简单修改,但对于更复杂的字符串解析算法而言非常麻烦。 Access中的任何内容都为各个字段提供了这种脚本吗?我们可以在Expression Builder中使用VBA或其他语言吗?也许只是SQL是解决方案?
答案 0 :(得分:1)
如果您拥有完整的UI .exe程序,则可以在MS Access中集成用户定义的函数。只需在Module对象中编写函数脚本,然后在VBA或SQL中调用它:
Public Function Calc(f1 As String, f2 As String, f3 As String) As String
' where f1 is address number, f2 is address name and f3 is address suffix '
Dim remove_list() As Variant
Dim r As Variant
Dim x As String
' Define list '
remove_list = Array("01ST", "02ND", "03RD", "04TH", "05TH", _
"06TH", "07TH", "08TH", "09TH")
' Homogenize single digit address names '
For Each r In remove_list
If f2 Like "*r*" Then
f2 = Replace(f2, r, Right(r, 3))
Else
f2 = f2
End If
Next r
f1 = Replace(f1, ".0", "")
' strip leading and trailing spaces '
f1 = Trim(f1)
f2 = Trim(f2)
f3 = Trim(f3)
' Concatenate full address name '
x = f1 & " " & f2 & " " & f3
' Return Full address name '
Calc = x
End Function
VBA
Public Sub CleanAddress()
Dim fullAddress As String
Dim db As Database, rst As Recordset
Set db = CurrentDb
Set rst = db.OpenRecordset("TableName")
If rst.RecordCount = 0 Then Exit Sub
Do While Not rst.EOF
fullAddress = Calc(rst!f1, rst!f2, rst!f3)
rst.MoveNext
Loop
rst.Close
Set rst = Nothing
Set db = Nothing
End Sub
<强> SQL 强>
SELECT t.*, Calc(t.f1, t.f2, t.f3) As fullAddress
FROM TableName t
由于函数不是太复杂,您可以使用嵌套字符串函数处理所有SQL:
<强> SQL 强>
SELECT t.*,
Trim(t.f1, Replace(t.f1, '.0', '')) &
Replace(
Replace(
Replace(
Replace(
Replace(
Replace(
Replace(
Replace(
Replace(Trim(t.f2), '01ST', '1ST'),
'02ND', '2ND'),
'03RD', '3RD'),
'04TH', '4TH'),
'05TH', '5TH'),
'06TH', '6TH'),
'07TH', '7TH'),
'08TH', '8TH'),
'09TH', '9TH') &
Trim(t.f3) As FullAddress
FROM TableName As t
答案 1 :(得分:1)
...输入字符串如“230 04th street”并将其转换为“230 4th” 街道“
该示例可以在Access中使用自定义VBA函数实现,该函数使用正则表达式。
这是在Access Immediate窗口中测试的这样一个功能:
? Field_Calculator("230 04th street")
230 4th street
请注意,该模式与文本段不匹配,例如“34th”,“045th”或“04abc”。所以这些功能将不会改变:
? Field_Calculator("230 34th street")
230 34th street
? Field_Calculator("230 045th street")
230 045th street
? Field_Calculator("230 04abc street")
230 04abc street
这是使用后期绑定编写的函数:
Public Function Field_Calculator(ByVal pInput As String) As String
Const cstrPattern As String = "\b(0)(\d\w{2})\b"
Dim objRegExp As Object
Set objRegExp = CreateObject("VBScript.RegExp")
With objRegExp
.Pattern = cstrPattern
.IgnoreCase = True
Field_Calculator = .Replace(pInput, "$2")
End With
End Function
如果您更喜欢早期绑定,请设置对“Microsoft VBScript正则表达式”的引用并进行以下更改:
'Dim objRegExp As Object
'Set objRegExp = CreateObject("VBScript.RegExp")
Dim objRegExp As RegExp
Set objRegExp = New RegExp
可以从另一个VBA过程调用该函数。从Access会话中运行时,它也可以在Access SQL中使用:
UPDATE YourTable
SET [street_address] = Field_Calculator([street_address]);
但是,无法从Access会话外部运行使用自定义VBA功能的查询。