MS Access中查询的字段默认值

时间:2020-03-06 14:58:40  来源:igfitidea点击:

我在MS Access中的表tblMyTable.SomeID中有一个字段,并且我想在tblUserPref.DefaultSomeID中将默认值设置为用户首选项。在tblMyTable的表定义中,似乎没有设置默认值来使用查询。我有一个将记录输入到tblMyTable中的表格。我试图在表单上设置字段的默认值,但似乎也不接受查询。因此,作为最后的选择,我正在尝试使用VBA。我可以在VBA中查询所需的值,但无法确定将代码添加到哪个事件。

我想在用户开始输入之前在窗体中打开新的空白记录时运行代码。打开或者编辑现有记录时,我不想运行代码。但是,如果代码同时针对新的空白记录和现有记录运行,那么我可能可以对此进行编码。到目前为止,我在现场和表单本身尝试过的所有事件都没有在我希望发生的情况下运行。谁能建议我应该使用哪个事件以及在哪个对象上使用?

解决方案

我们可能希望将该代码放入Form自身的" Before Insert"事件中(表单上没有任何对象)。

更正:在用户开始输入数据之前,这实际上不会触发,因此我们只需要确保要具有默认值的字段在第一个数据输入字段之后即可。

我们也可以在"当前"事件中检查新记录。

Private Sub Form_Current()
    If Me.NewRecord Then
        Me.f2 = "humbug"
    End If
End Sub

这样做的缺点是在我们输入新记录时会立即创建/将其标记为脏记录。因此,如果我们漫不经心地浏览记录,则可以结束运行并创建一些额外的记录,这些记录中只包含默认数据,因此我们将必须采取一些措施来捕获这种情况(例如,必填字段等) )

你是对的。我们不能将控件的默认值属性设置为编译时未知的值。该值将在运行时确定。因此,解决方案是在窗体的当前事件期间设置控件的value属性,而不是defaultvalue属性。注意,getUserID()是用于确定用户身份的公共函数。

Private Sub Form_Current()

    On Error GoTo Proc_Err

    Dim rs As DAO.Recordset
    Dim fOpenedRS As Boolean

    If Me.NewRecord = True Then
        Set rs = CurrentDb.OpenRecordset("SELECT DefaultSomeID " _
        & "FROM tblUserPref WHERE UserID = " & getUserID())
        fOpenedRS = True
        rs.MoveFirst
        Me!txtPref.Value = rs!DefaultSomeID
    End If

Proc_Exit:
    If fOpenedRS = True Then
        rs.Close
    End If

    Set rs = Nothing

    Exit Sub

Proc_Err:
    MsgBox Err.Number & vbCrLf & Err.Description
    Err.Clear
    Resume Proc_Exit
End Sub

我不知道我们如何确定当前用户是谁,但是我认为我们可以通过编程方式调用它。为了简单起见,在此示例中,我将使用Access的内置" CurrentUser"方法。 (需要用户级别的安全性,否则默认为"管理员"。)

在VBA模块中创建一个公共函数以返回当前用户的默认值:

Public Function InsertDefaultSomeID() As String

InsertDefaultSomeID = DLookup("DefaultSomeID", "tblUserPref", _
                              "UserID='" & CurrentUser & "'")

End Function

在tblUserPref中,我们需要一个[UserID]字段和一个[DefaultSomeID]字段。为当前用户定义一个默认值。

然后,在绑定到tblMyTable的窗体上,打开[SomeID]字段的属性,并将"默认值"属性设置为:

=InsertDefaultSomeID()

保存表单,以具有默认默认设置的用户身份登录,然后尝试插入新记录。默认值应自动填充。

他是建议的替代方法。当用户未指定显式值时,而不是显式地插入默认值,而是将该值保留为丢失(我可能会在专用表中对其建模,并通过不插入行来对缺失值进行建模,但是我知道许多人不反对表中有许多可为空的列)。然后,我们可以替换查询中的缺失值。这在应用程序中可能有效,也可能无效,正如我所说的只是另一种处理丢失数据的方法:)

我不确定我是否已经理解了问题,但是我认为我们正在基于一些运行时信息(例如用户名)要求在从其他表绘制的字段中插入值。在这种情况下,我们可以使用域查找函数DLookup(),并向其传递我们要返回的字段的名称,要从中查找的表或者查询的名称,以及用于将结果限制为一行(我假设这取决于我们可以在运行时收集的值)。然后可以将该DLookup()公式永久设置为表单控件上的默认值,并且在创建真实记录之前不会使表单变脏。

当然,我可能完全误解了我们要执行的操作,因此这可能行不通,但是我们似乎想在记录集中查找内容,并将结果用作新记录的值,而DLookup()会允许我们完全不进行任何编码即可做到这一点(以及具有不会过早弄脏记录的好处)。