如何避免 Access VBA 中出现“您必须输入值”错误消息

Posted

技术标签:

【中文标题】如何避免 Access VBA 中出现“您必须输入值”错误消息【英文标题】:How to avoid a "You must enter a value" error message in Access VBA 【发布时间】:2016-08-02 23:26:46 【问题描述】:

我在避免 Access 2016 中的“您必须在 __ 字段中输入一个值”错误消息时遇到问题。我有三个表,Tasks、Users 和 TaskAssignments,以及一个如下所示的拆分表单:

User    Task    Assigned?

User1   Task1   True
User1   Task2   False
User1   Task3   True
User2   Task1   False
User2   Task2   False
User2   Task3   True
User3   Task1   True
User3   Task2   True
User3   Task3   True

每个任务可以有多个用户分配给它,每个用户分配给多个任务。我希望我的表单显示所有可能的值,然后使用复选框,以便我可以单击并将用户添加到该任务。 TaskAssignments 表在 TaskID 和 UserID 上有一个主键和一个唯一约束。

我的表单的记录源是一个查询:

select x.UserName, x.TaskName, ta.is_assigned
from (select * from Tasks, Users) x
left join TaskAssignments ta on (ta.TaskID = x.TaskID and ta.UserID = x.UserID)

我有一个点击事件,用于检查 TaskAssignments 中是否存在记录,并更新或插入 TaskAssignments。当我 debug.print 并手动运行我的查询时,它们都会执行预期的操作。当我手动将一条记录插入到我的 TaskAssignments 表中时,我的表单的行为符合我的预期。但是,当我需要插入新记录时,我会收到一条消息,指出我必须在 TaskAssignments 中输入一个 TaskID。

我已尝试重新查询表单,但仍然收到错误消息。为什么找不到我刚才插入的记录?

请帮忙?!?我需要在这里彻底重新考虑我的方法吗?

这是 VBA:

Private Sub is_assigned_Click()

Dim CurrentUser, AssignmentQuery As String, SelectedUserID, SelectedTaskID As Integer
Dim ShouldInsert, IsAssigned As Boolean

CurrentUser = Environ$("Username")
SelectedUserID = Me.UserID
SelectedTaskID = Me.TaskID
IsAssigned = Me.is_assigned

Dim db As DAO.Database, rs As DAO.Recordset, strSQL As String
Set db = CurrentDb
strSQL = "select UserID, taskID from TaskAssignments where UserID=" & SelectedUserID & " and taskID =" & SelectedTaskID & ";"

Set rs = db.OpenRecordset(strSQL)

If rs.EOF = True Then
    ShouldInsert = True
    Else: ShouldInsert = False
End If

If ShouldInsert = True Then
    AssignmentQuery = "insert into TaskAssignments (UserID, taskID, DateAssignmentUpdated, AssignmentUpdatedBy, is_assigned) values " _
    & vbCrLf & "(" & SelectedUserID & "," & SelectedTaskID & ",#" & Now & "#,'" & CurrentUser & "'," & IsAssigned & ");"

ElseIf ShouldInsert = False Then
    AssignmentQuery = "update TaskAssignments set UserID=" & SelectedUserID & ", DateAssignmentUpdated=#" & Now & "#, AssignmentUpdatedBy='" & CurrentUser & "',is_assigned=" & IsAssigned _
    & vbCrLf & " where taskID = " & SelectedTaskID & " And UserID = " & SelectedUserID & ";"
End If

MsgBox AssignmentQuery
db.Execute (AssignmentQuery)

Forms("Task Assignments").Requery

Set rs = Nothing
Set db = Nothing

End Sub

编辑 - 以下是生成的查询:

插入

insert into TaskAssignments 
(UserID, TaskID, DateAssignmentUpdated, AssignmentUpdatedBy, is_assigned) 
values (301,4,Now(),'mylogin',True);

更新

update TaskAssignments 
set UserID=270, DateAssignmentUpdated=Now(), AssignmentUpdatedBy='mylogin', is_assigned=False
where TaskID = 1 And UserID = 270;

还有一个对我的 TaskAssignments 表的约束。 TaskID 和 UserID 都是在我的表设计中根据需要设置的(这是我的全部目标 - 我希望避免在用户实际被分配到任务之前将记录添加到 TaskAssignments)。

alter table TaskAssignments add constraint TaskAssignmentsConstraint unique (TaskID, UserID);

【问题讨论】:

如果在 dB.execute 之后检查 dB.RecordsAffected 会返回什么。 您在哪里收到错误消息?什么线?数据是否被插入? SQL 是否与您的手动 sql 工作相匹配? 您收到此消息是因为您有表级属性吗? required: yesallow zero length: No? 我编辑了描述以包括 AssignmentQuery 值和对表的约束。当我创建一个查询时,他们都会做预期的事情。对于插入,当我单击另一行时,我收到错误消息,即使该记录实际上已插入到我的表中。我必须点击 escape 才能移动到另一个记录,但我的更改被保留了。如果我将 me.requery 或 me.dirty = false 放入我的代码中,我会在该行得到错误。对于更新,我收到“写入冲突”错误消息,但是当我保存更改时,它的行为符合预期。 插入/更新 sql 看起来有效。试试db.Execute AssignmentQuery, dbFailOnError看看会不会报错。 【参考方案1】:

小心错误的数据类型,每个Dim 都需要自己的数据类型!

Dim CurrentUser As String, AssignmentQuery As String
Dim SelectedUserID As Long, SelectedTaskID As Long  ' don't use 16-bit Integer for ID columns
Dim ShouldInsert As Boolean, IsAssigned As Boolean

为了避免日期/时间格式的麻烦:数据库引擎知道Now(),所以你可以直接在插入SQL中使用它:

AssignmentQuery = "insert into TaskAssignments (UserID, taskID, DateAssignmentUpdated, AssignmentUpdatedBy, is_assigned) values " _
& vbCrLf & "(" & SelectedUserID & "," & SelectedTaskID & ", Now(), '" & CurrentUser & "'," & IsAssigned & ");"

如果仍然不起作用,请使用Debug.Print AssignmentQuery 而不是MsgBox 并将实际的SQL 添加到您的问题中(Ctrl+G 显示输出)。


编辑

重新阅读问题和评论,我认为问题是:

您正在编辑绑定的表单,并在表单所基于的同一个表中更新/插入。这就是Update上写冲突的来源,另一个错误可能是因为当你点击is_assigned时,绑定的表单试图插入一条记录,但不能。

所以是的,您需要重新考虑您的方法,至少部分重新考虑。

一种解决方案是将记录源插入临时表,并以此为基础创建表单。那么剩下的代码可能就可以工作了。

不过,事情可能过于复杂。

【讨论】:

感谢您的反馈,我已将其考虑在内并更新了说明。 一个临时表工作得很好,我为我的记录源查询添加了“select ... into”,然后使用我的临时表作为表单的记录源。谢谢!【参考方案2】:

我在尝试更新一个曾经是我的表中的主字段的字段时遇到了这个问题。当我更改了被认为是主要字段的内容时,我认为访问会自动停止强制执行不为空,但由于某种原因它没有。

我通过删除字段、保存表、重新创建字段并保存表来修复它,问题就消失了。当然,如果您不想丢失该表中的数据,那么这将不是一个理想的解决方案,因此您可能想先尝试备份它,然后再尝试解决方案,然后重新插入值。

【讨论】:

以上是关于如何避免 Access VBA 中出现“您必须输入值”错误消息的主要内容,如果未能解决你的问题,请参考以下文章

如果“工具”菜单中没有出现“数字签名”项,如何将证书添加到 VBA Access 项目?

如何使用 Access VBA 删除表之间的匹配行/记录?

vbscript MS Access VBA查询功能将CDec()应用于数字字段(有助于避免舍入错误)

MS Access 2010,如何让黄色的启用内容栏再次出现?

使用 VBA 将数据从 Excel 导出到 Access

为啥我的 Access VBA 在 Excel 中添加小计在一个数据库中工作,但在另一个数据库中出现错误 1004?