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


Я не думаю, что ты сможешь. Как вы выполняете запрос?
Я бы сказал, что если вам нужен запрос с таким количеством открытых переменных, поместите его в модуль или класс vba и вызовите его, позволяя ему каждый раз строить строку.
Я не уверен, что это помогает, потому что подозреваю, что вы хотите сделать это с помощью сохраненного запроса, а не с помощью VBA; однако самое простое, что вы можете сделать, - это построчно построить запрос в VBA, а затем создать из него набор записей.
Довольно хакерский способ - переписать сохраненный запрос на лету, а затем получить к нему доступ; однако, если у вас есть несколько человек, использующих одну и ту же БД, вы можете столкнуться с конфликтами и запутать следующего разработчика в будущем.
Вы также можете программно передать значение по умолчанию в запрос (как обсуждалось в предыдущем вопросе).
Что ж, вы можете вернуть ненулевые значения, передав * в качестве параметра для полей, которые вы не хотите использовать в текущем фильтре. В Access 2003 (и, возможно, более ранних и более поздних версиях), если вы используете like [paramName] в качестве критерия для числового, текстового, даты или логического поля, звездочка отобразит все записи (которые соответствуют другим указанным вами критериям). Если вы также хотите вернуть нулевые значения, вы можете использовать like [paramName] or Is Null в качестве критерия, чтобы он возвращал все записи. (Это лучше всего работает, если вы строите запрос в коде. Если вы используете существующий запрос и не хотите возвращать нулевые значения, когда у вас есть значение для фильтрации, это не сработает.)
Если вы фильтруете поле Memo, вам придется попробовать другой подход.
Если вы построите свой запрос так:
PARAMETERS ParamA Text ( 255 );
SELECT t.id, t.topic_id
FROM SomeTable t
WHERE t.id Like IIf(IsNull([ParamA]),"*",[ParamA])
Если параметр не заполнен, будут выбраны все записи.
Вернемся к моему предыдущему экзамену в вашем предыдущем вопросе. Ваш параметризованный запрос представляет собой строку, которая выглядит так:
qr = "Select Tbl_Country.* From Tbl_Country WHERE id_Country = [fid_country]"
в зависимости от характера fid_Country (число, текст, guid, дата и т. д.) вам придется заменить его значением джокера и определенными символами-разделителями:
qr = replace(qr,"[fid_country]","""*""")
Чтобы полностью разрешить подстановочные знаки, ваш исходный запрос также может быть:
qr = "Select Tbl_Country.* From Tbl_Country _
WHERE id_Country LIKE [fid_country]"
Затем вы можете получить значения подстановочных знаков для fid_Country, например
qr = replace(qr,"[fid_country]","G*")
Как только вы закончите с этим, вы можете использовать строку, чтобы открыть набор записей
set rs = currentDb.openRecordset(qr)
Обратите внимание, что подстановочный знак * с ключевым словом LIKE будет иметь желаемый эффект только в режиме запроса ANSI-89.
Многие ошибочно полагают, что подстановочный знак в Access / Jet всегда равен *. Не так. Jet имеет два подстановочных знака:% в режиме запроса ANSI-92 и * в режиме запроса ANSI-89.
ADO всегда соответствует ANSI-92, а DAO - всегда ANSI-89, но интерфейс доступа может быть любым из них.
При использовании ключевого слова LIKE в объекте базы данных (т.е. в том, что будет сохраняться в файле mdb), вы должны подумать про себя: что произойдет, если кто-то будет использовать эту базу данных в режиме запроса, отличном от того, который я обычно использую сам? Допустим, вы хотите ограничить текстовое поле только числовыми символами и написали свое Правило проверки следующим образом:
NOT LIKE "*[!0-9]*"
Если кто-то невольно (или иным образом) подключился к вашему .mdb через ADO, то приведенное выше правило проверки позволит им добавлять данные с нечисловыми символами, и ваша целостность данных будет нарушена. Фигово.
Лучше IMO всегда кодировать для обоих режимов запроса ANSI. Возможно, это лучше всего достигается путем явного кодирования для обоих режимов, например.
NOT LIKE "*[!0-9]*" AND NOT LIKE "%[!0-9]%"
Но с более задействованным Jet SQL DML / DDL это может стать очень трудным для краткости. Вот почему я рекомендую использовать ключевое слово ALIKE, которое использует подстановочный знак режима запроса ANSI-92 независимо от режима запроса, например.
NOT ALIKE "%[!0-9]%"
Обратите внимание, что ALIKE недокументирован (и я предполагаю, что именно поэтому мой исходный пост был отмечен). Я тестировал это в Jet 3.51 (Access97), Jet 4.0 (Access2000 до 2003) и ACE (Access2007), и он отлично работает. Я ранее размещал это в группах новостей и получил одобрение Access MVP. Обычно я сам избегаю недокументированных функций, но делаю исключение в этом случае, потому что Jet устарел уже почти десять лет, а команда Access, которая поддерживает его, похоже, не заинтересована во внесении глубоких изменений в движки (или исправления ошибок! ), что делает реактивный двигатель очень стабильным продуктом.
Дополнительные сведения о режимах запросов ANSI в Jet см. В разделе О режиме запроса ANSI SQL.
Фактически, подстановочный знак также будет зависеть от того, какой интерфейс данных вы используете. Например, в SQL, выполняемом через ADO для SQL Server, вы используете «%» вместо Jet SQL «*».
Фактически, в Jet есть два подстановочных знака: «%» в режиме запроса ANSI-92 и «*» в режиме запроса ANSI-89. ADO всегда соответствует ANSI-92, DAO - всегда ANSI-89, а интерфейс доступа может быть любым. Вы можете не знать об этом, потому что всегда используете DAO.
@Air ссылка теперь исправлена.
Спасибо. У меня было ужасное время найти текущий URL-адрес, который, казалось, имеет описанный контент, но, возможно, его нет. Не могу найти много информации о том, в какой степени это проблема в 2010 и более поздних версиях Access.
@Chad Я не совсем понимаю, что вы имеете в виду, возможно,
PARAMETERS ParamA Text ( 255 ); SELECT IIf(IsNull([ParamA]),"*",[ParamA]) AS Expr1, t.id FROM table1 AS t GROUP BY IIf(IsNull([ParamA]),"*",[ParamA]), t.id HAVING (((t.id) Like IIf(IsNull([ParamA]),"*",[ParamA])));