1

VBA noob 这里(截至本次哀悼),

在 MS Access 中,我编写了一个测试函数来根据您传入的某些标准查找记录的值。

该功能似乎工作正常,除非在我正在搜索的列中有查找。

基本上它可能会返回“19”,而 19 对应于其他一些表值。

似乎该列的 RowSource 是我之后的内容,因此我可以进行第二次查询以找到真实值。

假设我知道列名,然后利用它来查找 Im 之后的值,有人可以指出我找到 RowSource 的正确方向吗?

编辑:似乎我没有清楚地解释自己,这是我试图以编程方式获得的图片 在此处输入图像描述

在此处输入图像描述

4

2 回答 2

2

试试这个——我想我终于明白你为什么要寻找 RowSource ——对不起,我一开始没有“得到”它。您尝试提取的字段是描述表中的外键。

此函数应该作为所有此类字段的通用解决方案(假设 RowSource 始终首先具有主键,然后是描述)。如果没有 RowSource,它只会拉取字段的值。

它基于您的原始代码,而不是@ron 提出的更改,但它应该让您朝着正确的方向前进。您应该修复它以使其参数化,并允许变体数据类型,正如 ron 建议的那样 (+1 ron)

顺便说一句,在 VBA 中使用 & 符号 ( &) 将字符串连接在一起以避免出现这样的情况:abc = "1" + 1,其中 abc 现在等于 2 而不是“11”,如果这两个项目都打算是字符串的话。

Public Function lookUpColumnValue(Database As Database, column As String, table As String, lookUpColumn As String, lookUpValue As String) As String

    Dim sql As String
    Dim recordSet As DAO.recordSet
    Dim result As String

    lookUpColumnValue = "" 'Return a blank string if no result

    On Error Resume Next

    sql = "SELECT [" & table & "].[" & column & "] FROM [" & table & "] WHERE [" & table & "].[" & lookUpColumn & "] = '" & lookUpValue & "'"
    Set recordSet = Database.OpenRecordset(sql)

    If Not recordSet.EOF Then
        Dim td As DAO.TableDef

        'this gives your number - say, 19
        result = recordSet(column)

        Set td = Database.TableDefs(table)

        'Get the rowsource
        Dim p As DAO.Property
        For Each p In td.Fields(column).Properties
            If p.Name = "RowSource" Then
                RowSource = Replace(td.Fields(column).Properties("RowSource"), ";", "")
                Exit For
            End If
        Next

        If Not RowSource = "" Then
            Dim rs2 As DAO.recordSet
            Dim qd As DAO.QueryDef

            Set qd = Database.CreateQueryDef("", RowSource)
            Set rs2 = Database.OpenRecordset(RowSource)

            If rs2.EOF Then Exit Function

            PKField = rs2.Fields(0).Name

            rs2.Close
            qd.Close

            sql = "SELECT * FROM (" & RowSource & ") WHERE [" & PKField & "]=[KeyField?]"
            Set qd = Database.CreateQueryDef("", sql)
            qd.Parameters("KeyField?").Value = result

            Set rs2 = qd.OpenRecordset()

            If Not rs2.EOF Then
                'NOTE: This assumes your RowSource *always* has ID first, description 2nd.  This should usually be the case.
                lookUpColumnValue = rs2.Fields(1)
            End If
        Else
            'Return the field value if there is no RowSource
            lookUpColumnValue = recordSet.Fields(column)
        End If
    End If

End Function
于 2013-08-23T15:12:52.063 回答
2

如果我正确理解您的问题,我认为使用参数查询将解决您的问题。使用参数是一种很好的做法,因为它们将执行隐式数据类型转换并防止注入攻击。

请注意,在以下函数中,我将 lookupValue 更改为 Variant 类型,它允许您将任何类型的值传递给函数。

Public Function lookUpColumnValue( _
    database As DAO.database, _
    column As String, _
    table As String, _
    lookUpColumn As String, _
    lookUpValue As Variant) As String

    Dim sql As String
    Dim recordSet As DAO.recordSet
    Dim result As String
    Dim qd As QueryDef
    Set qd = database.CreateQueryDef("")
    sql = "SELECT [" + table + "].[" + column + "] FROM [" + table + "] " & _
          "WHERE [" + table + "].[" + lookUpColumn + "] = [parm1];"
    qd.sql = sql
    qd.Parameters![parm1] = lookUpValue
    Set recordSet = qd.OpenRecordset()

    result = recordSet(column)

编辑

    lookUpColumnValue = DLookup("Space Use Description", "Space Use Codes", result)


End Function
于 2013-08-21T21:23:23.920 回答