在 MS Access 查询中使用用户创建的函数来传递用户变量值

Using user-made functions in MS Access queries to pass user variable values

过去,我已经能够通过创建一个简单的函数将变量从 MS Access VBA 传递给查询,该函数 return 将变量的值传递给查询那个功能。例如,要在查询中使用名为 zvarApptID 的 VBA 变量,此示例 VBA 函数允许:

Public Function fvarApptID() As Long
    fvarApptID = zvarApptID
End Function

有了这个 SQL 使用 zvarApptID VBA 变量值:

SELECT MyApptID, MyName, MyAddress
FROM tblTable
WHERE MyID = fvarApptID

直到今天,这一直很有效,但不可否认,我已经为这种情况添加了新的皱纹。在这种有问题的情况下,我有一个函数(我们称它为 fDateOfVisitX),它 return 是 SQL 查询的日期值,但是 fDateOfVisitX 的代码另外设置了 VBA 变量的值输入 long(我们称之为 zvarApptID),return 是我需要在 SQL 查询的另一个字段中使用的数值。我已经创建了第二个函数(让我们使用上面列出的 fvarApptID 函数)来 return zvarApptID 的值到 SQL 查询到另一个字段。

这是SQL:

SELECT DISTINCT tblTherapists.TherapistID,
     tblTherapists.LastName AS ThxLastName,
     Format(datDueDateTime,"m/d/yyyy") AS ApptDate,
     fvarApptID() AS AppointmentID,
     fDateOfVisitX(tblTHerapist_X_Dispositions.DispositionID,3) AS datDueDateTime
FROM tblTherapists 
     LEFT JOIN tblTHerapist_X_Dispositions ON tblTherapists.TherapistID = tblTHerapist_X_Dispositions.TherapistID
WHERE tblTherapists.TherapistID = fvarTherapistID();

问题是 fvarApptID 向 SQL 查询 return 的值始终是由 fDateOfVisitX 的先前 运行 设置的 fvarApptID 的先前值。当然,这没有用,因为我需要 fvarApptID 的当前值。

例如,如果是这样的数据:

TherapistID |姓 | ApptDate | ApptID
10 |史密森 | 2018 年 1 月 1 日 | 10012
18 |杂物 | 2/3/2018 | 10073
12 |阿姆森纳 | 2018 年 1 月 7 日 | 10036

当 fvarTherapistID return 的值为 18 时,这就是我想要的:
18 |杂物 | 2/3/2018 | 10073

这是我在 fDateOfVisitX 为 运行 时得到的结果,当时 fvarTherapistID 为 12:
18 |杂物 | 2/3/2018 | 10036

即使 日期 是正确的,return 为 zvarApptID 编辑的值对于日期 returned 即使在 fDateOfVisitX 函数中设置了 zvarApptID 同时 设置了日期(实际上,首先设置了 zvarApptId,然后下一行代码设置了return 由 fDateOfVisitX 编辑的日期。

更改 SELECT 语句中列出的项目的顺序不会更改结果。

如果我第二次 运行 相同的查询而没有任何其他调用 fDateOfVisitX,则 zvarApptID 在第二次 运行 时是正确的(如果只有 1 行被 returned通过 SQL 查询)。

我假设这与 SQL 查询收集字段的顺序有关,但我不知道如何在 SQL 中强制更新 fvarApptID ] 在正确的时间得到正确的值。

如何在查询结果中获取正确的 fvarApptID 值,而不是之前执行 fDateOfVisitX 时的 zvarApptID?

当你在 SQL 中使用此类函数时,如果函数值应该 return 相同,优化器会缓存函数值,因此你的不带参数的函数将只被调用一次,你可以检查一下- 只需在 fvarApptID 内设置断点。 解决方法很简单:向您的函数添加一个虚拟参数:

Public Function fvarApptID(DummyParm as Variant) As Long
    fvarApptID = zvarApptID
End Function

并将任何变化的值传递给此参数:

SELECT DISTINCT tblTherapists.TherapistID,
     tblTherapists.LastName AS ThxLastName,
     Format(datDueDateTime,"m/d/yyyy") AS ApptDate,
     fvarApptID(tblTherapists.TherapistID) AS AppointmentID,
     fDateOfVisitX(tblTHerapist_X_Dispositions.DispositionID,3) AS datDueDateTime

在这种情况下,将为每个选定的行调用该函数