2016-08-02 62 views
1

我遇到了避免在Access 2016中出现“您必须在__字段中输入值”错误消息的问题。我有三个表,任务,用户和TaskAssignments和分裂的形式,看起来像:如何避免访问VBA中的“您必须输入值”错误消息

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); 
+0

如果在dB.execute后面检查dB.RecordsAffected,会发生什么情况? – dbmitch

+0

你从哪里收到错误信息?什么线?数据是否被插入? SQL是否与您的手动SQL工作相匹配? – dbmitch

+0

您是否收到此消息,因为您具有表级别属性; '需要:是'和'允许零长度:否'? – LiamH

回答

0

当心错误的数据类型,每个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显示输出)。


编辑

重读的问题和评论,我认为这个问题是:

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

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

一个解决方案是将recordource插入临时表中,并将表单基于该表。然后其余的代码可能会工作。

虽然它可能过于复杂了。

+0

感谢您的反馈,我已考虑到这一点并更新了说明。 – randomname

+0

谢谢。请参阅编辑。 – Andre

+0

临时表工作得很好,我为我的记录源查询添加了“select ... into”,然后使用我的临时表作为窗体的记录源。 谢谢! – randomname