Access

时间:2016-05-15 15:26:01

标签: python vba ms-access access-vba

一年或两年后,我变得非常精通使用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是解决方案?

2 个答案:

答案 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功能的查询。