Использование пользовательских функций в запросах MS Access для передачи значений пользовательских переменных - PullRequest
0 голосов
/ 08 июня 2018

В прошлом я мог передавать переменную из MS Access VBA в запрос, создавая простую функцию, которая возвращает значение переменной в запрос через эту функцию.Например, чтобы использовать переменную VBA с именем zvarApptID в запросе, эта примерная функция VBA позволяет:

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

При использовании этого SQL с использованием значения переменной VBA zvarApptID:

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

Тодо сегодняшнего дня прекрасно работал, но по общему признанию я добавил новую складку к этому сценарию.В этом проблемном сценарии у меня есть функция (назовем ее fDateOfVisitX), которая возвращает значение даты в запросе SQL, но код для fDateOfVisitX дополнительно устанавливает значение типа переменной VBA long (назовем его zvarApptID), который возвращает числозначение, которое мне нужно использовать в другом поле в запросе SQL.Я создал вторую функцию (давайте использовать функцию fvarApptID, указанную выше), чтобы возвращать значение 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();

проблема заключается в том, что значение, возвращаемое в SQL-запрос с помощью fvarApptID, всегда является ПРЕДЫДУЩИМ значением fvarApptID, установленным в ходе ПРЕДЫДУЩЕГО запуска fDateOfVisitX.Конечно, это бесполезно, потому что мне нужно текущее значение из fvarApptID.

Например, если это данные:

TherapistID |Фамилия |ApptDate |ApptID
10 |Смитсон |01.01.2008 |10012
18 |Обломки |3/2/2018 |10073
12 |Альмсонер |1/7/2018 |10036

Вот что я хочу, когда fvarTherapistID возвращает значение 18:
18 |Обломки |3/2/2018 | 10073

Вот что я получаю, когда fDateOfVisitX был запущен предыдущим вызовом, когда fvarTherapistID был 12:
18 |Обломки |3/2/2018 | 10036

Даже если date является правильным, значение, возвращаемое для zvarApptID , не является правильным для возвращенной даты, даже если zvarApptID установленв функции fDateOfVisitX одновременно устанавливается дата (фактически, сначала устанавливается zvarApptId, а затем следующая строка кода устанавливает дату, возвращаемую функцией fDateOfVisitX).

Изменение порядка элементов, перечисленных в операторе SELECT, не приводит к изменению результата.

Если я выполняю тот же запрос второй раз без каких-либо других вызовов fDateOfVisitX, то zvarApptID будет правильным во 2-м запуске (если только SQL-запрос возвращает только 1 строку).

Я предполагаю, что это как-то связано с порядком, в котором поля собираются SQL-запросом, но я не знаю, как заставить fvarApptIDобновляться в SQL в нужное время, чтобы получить правильное значение.

Как получить правильное значение fvarApptID в результате запроса вместо zvarApptID из предыдущего выполнения fDateOfVisitX?

1 Ответ

0 голосов
/ 09 июня 2018

Когда вы используете функции такого рода в SQL, оптимизатор кэширует значение функции, если он должен возвращать одно и то же значение, поэтому ваша функция без параметров будет вызываться только один раз, вы можете проверить это - просто установите точку останова внутри 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

В этом случае функция будет вызываться для каждого выбранногострока

...