VBA Access getting RowSource to find lookup values

2019-02-20 15:35发布

VBA noob here (as of this mourning),

In MS Access I wrote a test function to find the value of a record base on some criteria you pass in.

The function seems to work fine except in cases where there is a lookup in the column that I am searching.

Basically it might return "19" and 19 corresponds to some other table value.

It seems that the RowSource of the column is what Im after so I can do a second query to find the true value.

Can someone point me in the right direction on finding the RowSource assuming I know the column name and then utilizing it to find the value Im after?

Edit: It seems that Im not explaining myself clearly, Here is a picture of what I trying to get programatically enter image description here

enter image description here

2条回答
别忘想泡老子
2楼-- · 2019-02-20 16:06

Try this -- I think I finally understand why you are looking for the RowSource -- sorry I didn't "get" it at first. The field you're trying to pull is a foreign key into a description table.

This function should work as a general solution for all such fields (assuming the RowSource always has the primary key first, and the description second). If there is no RowSource, it will just pull the value of the field.

It's based on your original code, rather than the changes proposed by @ron, but it should set you in the right direction. You should fix it to make it parameterized, and allow for variant data types, as ron suggests (+1 ron)

As an aside, use the ampersand (&) to join strings together in VBA to avoid things like this: abc = "1" + 1, where abc is now equal to 2 instead of "11" as you would expect if both items were intended to be strings.

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
查看更多
老娘就宠你
3楼-- · 2019-02-20 16:18

If I understand your question correctly, I think using a parameter query will solve your problem. Using parameters is good practice since they will perform implicit data type casts and also prevent injection attacks.

Notice in the following function, I changed the lookupValue to a Variant type, which allows you to pass any type of value to the function.

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)

EDIT

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


End Function
查看更多
登录 后发表回答