2

我有一个显示一组时间范围和一个 ID 的连续表单,目前看起来像:

T1     T2     ID
----------------
09:00  09:15  1
09:15  09:30  2
09:25  09:50  3
09:50  10:20  4

每个 ID 对行都是唯一的。我的目标是突出显示任何发生冲突的时间(在此示例中,ID 为 2 和 3 的行发生冲突,因为 3 在 2 结束之前开始)。我决定使用条件格式来执行此操作,因此希望每行中都有一个字段来指示是否存在冲突。

我通过使用两次引用数据集的查询来实现这一点,允许我将行相互比较:

[a].[T1]<[b].[T2] And [a].[T2]>[b].[T1] And [a].[ID]<>[b].[ID]

将此作为字段分配给查询给了我这样的信息:

a.T1    a.T2   a.ID  b.ID  Clash  
--------------------------------
09:00   09:15  1     1     False
09:00   09:15  1     2     False
09:00   09:15  1     3     False
09:00   09:15  1     4     False
09:15   09:30  2     1     False
09:15   09:30  2     2     False
09:15   09:30  2     3     True
09:15   09:30  2     4     False
09:25   09:50  3     1     False
09:25   09:50  3     2     True
09:25   09:50  3     3     False
09:25   09:50  3     4     False
09:50   10:20  4     1     False
09:50   10:20  4     2     False
09:50   10:20  4     3     False
09:50   10:20  4     4     False

为了删除所有重复项,我在a.ID字段上使用了group by并取了计算字段的最大值(0 或 -1),所以我得到了 True,如果它在每个a.ID中存在的话。这给了我:

a.T1   a.T2   a.ID  Clash
-------------------------
09:00  09:15  1     False
09:15  09:30  2     True
09:25  09:50  3     True
09:50  10:20  4     False

然而,几乎完美,由于这个新的计算字段,以及我基本上对结果进行分组的事实,在连续表单视图中查看这个最终结果时,我不再能够编辑 Time1 或 Time2。

有没有办法我仍然可以编辑时间字段并保留这个新的计算字段?或者也许是一种处理冲突的单独方法,允许我在表单视图中提供视觉反馈?

我意识到这里有很多东西,我可能没有解释清楚,如果是这种情况,请告诉我。

任何帮助深表感谢。

4

2 回答 2

1

以下是我处理它的方法:我从一个与你原来的查询非常相似的查询开始,除了我使用了一个 INNER JOIN 来减少返回的原始结果的数量

SELECT a.ID, a.T1, a.T2, b.ID, b.T1, b.T2,
    a.T2 > b.T1 AS Clash
FROM TimeSlots a INNER JOIN TimeSlots b ON b.ID > a.ID;

该查询返回

a.ID  a.T1      a.T2      b.ID  b.T1      b.T2      Clash
----  --------  --------  ----  --------  --------  -----
   1  09:00:00  09:15:00     2  09:15:00  09:30:00      0
   1  09:00:00  09:15:00     3  09:25:00  09:50:00      0
   2  09:15:00  09:30:00     3  09:25:00  09:50:00     -1
   1  09:00:00  09:15:00     4  09:50:00  10:20:00      0
   2  09:15:00  09:30:00     4  09:50:00  10:20:00      0
   3  09:25:00  09:50:00     4  09:50:00  10:20:00      0

我听从了你的提示,做了一个 GROUP BY,除了我做了 MIN() 并将布尔值保留为数字......

SELECT First(a.T1) AS T1, First(a.T2) AS T2, a.ID,
    MIN(a.T2 > b.T1) AS Clash
FROM TimeSlots a INNER JOIN TimeSlots b ON b.ID > a.ID
GROUP BY a.ID;

...返回...

T1        T2        ID  Clash
--------  --------  --  -----
09:00:00  09:15:00   1      0
09:15:00  09:30:00   2     -1
09:25:00  09:50:00   3      0

然后我注意到 ID=4 丢失了,所以为了完整起见,我将它重新添加到...

SELECT First(a.T1) AS T1, First(a.T2) AS T2, a.ID,
    MIN(a.T2 > b.T1) AS Clash
FROM TimeSlots a INNER JOIN TimeSlots b ON b.ID > a.ID
GROUP BY a.ID
UNION ALL
SELECT T1, T2, ID, 0 AS Clash 
FROM TimeSlots WHERE ID IN (SELECT MAX(ID) FROM TimeSlots);

……所以我得到了……

T1        T2        ID  Clash
--------  --------  --  -----
09:00:00  09:15:00   1      0
09:15:00  09:30:00   2     -1
09:25:00  09:50:00   3      0
09:50:00  10:20:00   4      0

现在棘手的一点。该查询是不可更新的,并且(根据我的有限测试)也不是任何加入它的查询,或者直接在子查询中使用它。

但是,如果我将该查询保存为 [ClashList] 并将其与 VBA 函数一起使用...

Public Function GetClashStatus(ID As Long) As Long
GetClashStatus = DLookup("Clash", "ClashList", "ID=" & ID)
End Function

...我可以创建这个查询...

SELECT TimeSlots.T1, TimeSlots.T2, TimeSlots.ID, GetClashStatus(TimeSlots.ID) AS Clash
FROM TimeSlots;

...而且它是可更新的。

编辑

事实证明,不需要 VBA 函数。这也有效:

SELECT TimeSlots.T1, TimeSlots.T2, TimeSlots.ID, 
    DLookup("Clash", "ClashList", "ID=" & ID) AS Clash
FROM TimeSlots;
于 2013-04-28T19:13:03.440 回答
0

由于GROUP BY. Access 不知道要更改哪些记录。如果任何表或查询不可更新并JOIN在另一个查询中使用,则第二个查询也将不可更新。

资料来源:Allen Browne,“为什么我的查询是只读的?”

我确信有更好的方法,但我知道INSERT将你GROUP BY放入一个新的临时表会起作用。然后,您可以将分组数据表加入到您的真实数据中。由于两个记录集都是可更新的,您的查询也将是。

于 2013-04-26T02:47:05.580 回答