【问题标题】:How can I get the value from a control using the name of the control source?如何使用控件源的名称从控件中获取值?
【发布时间】:2020-07-13 19:19:04
【问题描述】:

我正在尝试编写一些代码来审核通过表单所做的更改。我有一个功能可以做到这一点:

Function WriteChanges()

Dim f As Form
Dim c As Control
Dim user As String
Dim db As DAO.Database
Dim cnn As ADODB.Connection
Dim MySet As ADODB.Recordset
Dim tbld As TableDef
Dim recsource As String

Set f = Screen.ActiveForm
Set db = CurrentDb
Set cnn = CurrentProject.Connection
Set MySet = New ADODB.Recordset
recsource = f.RecordSource
Set tbld = db.TableDefs(recsource)

pri_key = fFindPrimaryKeyFields(tbld)
Debug.Print "pri_key: "; pri_key
user = Environ("username")


MySet.Open "Audit", cnn, adOpenDynamic, adLockOptimistic, adCmdTable

For Each c In f.Controls
    Select Case c.ControlType
        Case acTextBox, acComboBox, acListBox, acOptionGroup
            If c.Value <> c.OldValue Then
                With MySet
                    .AddNew
                        ![EditDate] = Now
                        ![user] = user
                        ![SourceTable] = f.RecordSource
                        ![SourceField] = c.ControlSource
                        ![BeforeValue] = c.OldValue
                        ![AfterValue] = c.Value
                    .update
                End With
            End If
    End Select
Next c

MySet.Close
Set MySet = Nothing
Set f = Nothing
Set db = Nothing

End Function

我在各种表单的更新前属性上使用此函数,它使用每个控件中值更改的详细信息填充审计表。我还需要从主键字段中获取值以添加到审核表中。我可以使用以下代码来识别表单记录源中的主键名称:

Function fFindPrimaryKeyFields(tdf As TableDef) As String

Dim idx As Index

On Error GoTo HandleIt

For Each idx In tdf.Indexes
    If idx.Primary Then
        fFindPrimaryKeyFields = Replace(idx.Fields, "+", "")
        GoTo OutHere
    End If
Next idx

OutHere:
Set idx = Nothing
Exit Function

HandleIt:
Select Case Err
    Case 0
    Resume Next
    Case Else
    Beep
    MsgBox Err & " " & Err.Description, vbCritical + vbOKOnly, "Error"
    fFindPrimaryKeyFields = vbNullString
    Resume OutHere
End Select

End Function

如何使用它从以已识别的主键作为其控制源的控件(文本框)中获取值。

请原谅我的代码中的任何愚蠢错误,因为我是一个相对新手。提前感谢您的帮助。

【问题讨论】:

    标签: ms-access vba ms-access-2010


    【解决方案1】:

    我不能 100% 确定您到底想要什么,但如果您知道该字段的名称,则可以使用以下内容:

    Dim primaryKeyValue As Variant
    Dim primaryKeyColumnName As String
    primaryKeyColumnName = fFindPrimaryKeyFields(TableDefs!MyTable)
    Dim f as Form
    'Get the form somehow
    
    Dim c As Control
    On Error GoTo NextC 'Escape errors because lots of controls don't have a control source
    For Each c In f.Controls
        If c.ControlSource = primaryKeyColumnName Then
            primaryKeyValue = c.Value
        End If
    NextC:
    Next c
    On Error GoTo 0
    

    【讨论】:

    • 感谢您的回复。不幸的是,我正在从表单上的所有三个文本框中获取内容。这些是表单上仅有的三个控件(ID、Name1 和 Name2)以及控件源(ID、Name1、Name2)。代码的第一位正确地将主键字段标识为 ID,但是当我在 for next 循环中使用 debug.print primaryKeyValue 时,我两次获得每个控件的值以及两个空白值。我不明白为什么我会得到这个,因为只有一个 controlsource 应该等于 primarykeycolumnname 字符串
    • 道歉我看到你编辑了你的答案,现在给了我正确的价值。出于某种原因,当我多次添加 debug.print primaryKeyValue 但我认为这不会成为问题。感谢您的帮助!
    • 一个debug.print只能返回一个值。如果它多次返回,那是因为你多次运行这段代码。
    • debug.print primaryKeyValue 在 for each c in f.controls 循环中。
    • 好吧,如果它不在IfEnd If 之间,那确实应该运行很多次,
    【解决方案2】:

    如果主键列是表单记录源的一部分,您可以通过以下方式简单读取:

    Debug.Print "PK value: " & f(pri_key)
    

    记录源的每一列在运行时都是一个表单属性,与是否存在同名控件无关。

    注意:如果您的表单基于连接多个表的查询,您的整个构造将停止工作。

    【讨论】:

      猜你喜欢
      • 2020-01-24
      • 1970-01-01
      • 2011-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-04
      • 1970-01-01
      相关资源
      最近更新 更多