1

ここのVBA初心者(この喪の時点で)、

MS Access で、渡されたいくつかの基準に基づいてレコードの値を見つけるテスト関数を作成しました。

検索している列にルックアップがある場合を除いて、関数は正常に機能しているようです。

基本的に、「19」を返す可能性があり、19 は他のテーブル値に対応します。

列のRowSourceはImの後であるように見えるので、2番目のクエリを実行して真の値を見つけることができます。

列名を知っていると仮定してRowSourceを見つけ、それを利用してImの後の値を見つけることについて、誰かが私を正しい方向に向けることができますか?

編集:私は自分自身を明確に説明していないようです。これは、私がプログラムで取得しようとしているものの写真です ここに画像の説明を入力

ここに画像の説明を入力

4

2 に答える 2

2

これを試してみてください -- あなたが RowSource を探している理由がようやく理解できたと思います -- 申し訳ありませんが、最初はそれを「取得」できませんでした。プルしようとしているフィールドは、説明テーブルへの外部キーです。

この関数は、そのようなすべてのフィールドの一般的な解決策として機能するはずです (RowSource には常に主キーが最初にあり、説明が 2 番目にあると仮定します)。RowSource がない場合は、フィールドの値を取得するだけです。

@ron によって提案された変更ではなく、元のコードに基づいていますが、正しい方向に設定する必要があります。ronが示唆するように、パラメーター化してバリアントデータ型を許可するように修正する必要があります(+1 ron)

余談ですが、アンパサンド ( &) を使用して VBA で文字列を結合し、次のようなことを回避してくださいabc = "1" + 1:

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 に答える