Как создать параметризованный запрос в MS Access 2003 и использовать другие запросы / формы для заполнения параметров и получения набора результатов - PullRequest
3 голосов
/ 18 сентября 2008

Я хотел бы иметь возможность создать параметризованный запрос в MS Access 2003 и передать значения определенных элементов формы в этот запрос, а затем получить соответствующий набор результатов и выполнить с ними некоторые базовые вычисления. Я вкратце расскажу, как получить параметры запроса для заполнения элементами формы. Если мне нужно использовать VBA, это нормально.

Ответы [ 5 ]

2 голосов
/ 19 сентября 2008

Ссылки на элементы управления в форме можно использовать непосредственно в запросах Access, хотя важно определять их как параметры (в противном случае результаты в последних версиях Access могут быть непредсказуемыми, если они когда-то были надежными).

Например, если вы хотите отфильтровать запрос по элементу управления LastName в MyForm, используйте его в качестве критерия:

LastName = Forms!MyForm!LastName

Тогда вы бы определили ссылку на форму в качестве параметра. Результирующий SQL может выглядеть примерно так:

PARAMETERS [[Forms]!MyForm![LastName]] Text ( 255 );
SELECT tblCustomers.*
FROM tblCustomers
WHERE tblCustomers.LastName=[Forms]![MyForm]![LastName];

Я бы, однако, спросил, зачем вам нужен сохраненный запрос для этой цели. Что вы делаете с результатами? Отображение их в форме или отчете? Если это так, вы можете сделать это в источнике записей формы / отчета и оставить сохраненный запрос без изменений параметрами, чтобы его можно было использовать в других контекстах, не выводя подсказки для заполнения параметров.

С другой стороны, если вы что-то делаете в коде, просто напишите SQL на лету и используйте литеральное значение элемента управления формы для создания предложения WHERE.

1 голос
/ 18 сентября 2008

Существует три традиционных способа решения этой проблемы:

  1. Назовите параметр как-нибудь «умный», так что пользователю будет предложено ввести значение при выполнении запроса.
  2. Поле ссылки на форме (возможно, скрыто)
  3. Создайте запрос на лету и не используйте параметры.

Я думаю, что для меня просто неправильно вводить что-то вроде [?enter ISO code of the country] или ссылки на поля в вашей форме, например: [Forms]![MyForm]![LastName].

Это означает, что мы не можем повторно использовать один и тот же запрос более чем в одном месте, поскольку разные поля предоставляют данные, или мы вынуждены полагаться на то, что пользователь не запутает ввод данных при выполнении запроса. Насколько я помню, может быть трудно использовать одно и то же значение более одного раза с введенным пользователем параметром.

Как правило, я выбирал последний вариант - строил запрос на лету и обновлял объект запроса по мере необходимости. Однако, это распространено для атаки SQL-инъекцией (случайной или нарочно зная моих пользователей), и это просто неприлично.

Итак, я немного покопался и нашел здесь следующее (http://forums.devarticles.com/microsoft-access-development-49/pass-parameters-from-vba-to-query-62367.html):

'Ed. Start - for completion of the example
dim qryStartDate as date
dim qryEndDate as date
qryStartDate = #2001-01-01# 
qryEndDate = #2010-01-01#   
'Ed. End

'QUOTEING "stallyon": To pass parameters to a query in VBA 
'                     is really quite simple:

'First we'll set some variables:
Dim qdf As Querydef
Dim rst As Recordset

'then we'll open up the query:
Set qdf = CurrentDB.QueryDefs(qryname)

'Now we'll assign values to the query using the parameters option:
qdf.Parameters(0) = qryStartDate
qdf.Parameters(1) = qryEndDate

'Now we'll convert the querydef to a recordset and run it
Set rst = qdf.OpenRecordset

'Run some code on the recordset
'Close all objects
rst.Close
qdf.Close
Set rst = Nothing
Set qdf = Nothing

(я не проверял это сам, просто кое-что, что я собрал в своих путешествиях, потому что время от времени я хотел сделать это, но в итоге использовал один из моих ранее упомянутых кладжей)

Редактировать У меня наконец была причина использовать это. Вот фактический код.

'...
Dim qdf As DAO.QueryDef
Dim prmOne As DAO.Parameter
Dim prmTwo As DAO.Parameter
Dim rst as recordset
    '...
    'open up the query:
    Set qdf = db.QueryDefs("my_two_param_query") 'params called param_one and 
                                                 'param_two

    'link your DAP.Parameters to the query
    Set prmOne = qdf.Parameters!param_one
    Set prmTwo = qdf.Parameters!param_two

    'set the values of the parameters
    prmOne = 1 
    prmTwo = 2

    Set rst = qdf.OpenRecordset(dbOpenDynaset, _
                                            dbSeeChanges)
    '... treat the recordset as normal

    'make sure you clean up after your self
    Set rst = Nothing
    Set prmOne = Nothing
    Set prmTwo = Nothing
    Set qdf = Nothing
1 голос
/ 18 сентября 2008

Вот фрагмент кода. Обновляет таблицу, используя параметр txtHospital:

Set db = CurrentDb

Set qdf = db.QueryDefs("AddHospital")
qdf.Parameters!txtHospital = Trim(Me.HospName)
qdf.ReturnsRecords = False

qdf.Execute dbFailOnError

intResult = qdf.RecordsAffected

Вот пример SQL:

PARAMETERS txtHospital Text(255); 

INSERT INTO tblHospitals ( 
[Hospital] )

VALUES ( 
[txtHospital] )
0 голосов
/ 07 февраля 2018

простой способ здесь Информационная страница Microsoft 'setparameter'

DoCmd.SetParameter "frontMthOffset", -3
DoCmd.SetParameter "endMthOffset", -2
DoCmd.OpenQuery "QryShowDifference_ValuesChangedBetweenSELECTEDMonths"

, где SQL запроса Access включает [frontMthOffset] фактически в SQL. например,

"select blah from mytable where dateoffset=[frontMthOffset]"

Все просто работает!

0 голосов
/ 18 сентября 2008

Давайте рассмотрим пример. параметризованный запрос выглядит так:

Select Tbl_Country.* From Tbl_Country WHERE id_Country = _
    [?enter ISO code of the country]

и вы хотели бы иметь возможность получить это значение ([? Enter ... country] one) из формы, где у вас есть элементы управления и некоторые данные. Ну ... это может быть возможно, но требует некоторой нормализации кода.

Одним из решений было бы присвоение элементам управления формы определенной логики, например, fid_Country для элемента управления, который будет содержать значение id_Country. Затем ваш запрос может быть представлен в виде строки:

qr = "Select Tbl_Country.* From Tbl_Country WHERE id_Country = [fid_country]"

Как только вы ввели все запрошенные данные в форму, нажмите кнопку «запрос». Логика будет просматривать все элементы управления и проверять, присутствуют ли они в запросе, в конечном итоге заменяя параметр значением элемента управления:

Dim ctl as Control
For each ctl in Me.controls
    If instr(qr,"[" & ctl.name & "]") > 0 Then
         qr = replace(qr,"[" & ctl.name & "]",ctl.value)
    End if
Next i

При этом у вас будет полностью обновленный запрос, в котором параметры были заменены реальными данными. В зависимости от типа fid_country (строка, GUID, дата и т. Д.) Может потребоваться добавить дополнительные двойные кавычки или нет, чтобы получить окончательный запрос, например:

qr = "Select Tbl_Country.* From Tbl_Country WHERE id_Country = ""GB"""

Это полностью совместимый с Access запрос, который вы можете использовать для открытия набора записей:

Set rsQuery = currentDb.openRecordset(qr)

Я думаю, что вы сделали здесь.

Эта тема важна, когда ваша цель - разработать приложения Access. Вы должны предложить пользователям стандартный способ запроса данных из их графического интерфейса не только для запуска запросов, но и для фильтрации непрерывных форм (точно так же, как это делает Excel с опцией «автофильтр») и управления параметрами отчетов. Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...