Возврат записей, частично соответствующих значению

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

то есть в поле с фамилией я должен ввести gr, и это вызовет

зеленый серый Грэм

но в настоящее время он ничего не вызывает, если не используется полная строка поиска.

В рассматриваемой форме есть 4 элемента управления поиском, и они используются в запросе только в том случае, если поле заполнено.

Запрос:

SELECT TabCustomers.*,
       TabCustomers.CustomerForname AS NameSearch,
       TabCustomers.CustomerSurname AS SurnameSearch,
       TabCustomers.CustomerDOB AS DOBSearch,
       TabCustomers.CustomerID AS MemberSearch
FROM TabCustomers
WHERE IIf([Forms]![FrmSearchCustomer]![SearchMember] Is Null
          ,True
          ,[Forms]![FrmSearchCustomer]![SearchMember]=[customerid])=True
      AND IIf([Forms]![FrmSearchCustomer].[SearchFore] Is Null
              ,True
              ,[Forms]![FrmSearchCustomer]![SearchFore] Like [customerforname] & "*")=True
      AND IIf([Forms]![FrmSearchCustomer]![SearchLast] Is Null
              ,True
              ,[Forms]![FrmSearchCustomer]![SearchLast] Like [customersurname] & "*")=True
      AND IIf([Forms]![FrmSearchCustomer]![Searchdate] Is Null
              ,True
              ,[Forms]![FrmSearchCustomer]![Searchdate] Like [customerDOB] & "*")=True;

Я бы не рекомендовал использовать оператор LIKE с чем-то похожим на поле даты. Вы можете получить всевозможные неожиданные результаты, например, если пользователь введет 1 для января (или 1-го) и совпадет с октябрем, ноябрем, декабрем (или с 10-го по 19-е).

Dave DuPlantis 22.10.2008 16:53

Вы должны использовать application.build Criteria для создания предложения WHERE на лету. Вот для чего это сделано (я думаю ...)

Philippe Grondier 22.10.2008 17:09

BuildCriteria - действительно отличный инструмент. Это программный интерфейс к той же части службы выражений, которая анализирует то, что вы вводите в строке критериев QBE, на правильный синтаксис. Это одна из моих наиболее часто используемых неочевидных команд Access.

David-W-Fenton 24.10.2008 07:01
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
4
3
872
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

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

Например фрагмент первой части

,[Forms]![FrmSearchCustomer]![SearchFore] Like ([customerforname] & "*"))=True

Прошло много времени с тех пор, как я использовал доступ, но это первое, что приходит на ум

К сожалению, это не помогло, Митчел, спасибо, что посмотрели :)

Paul Green 22.10.2008 02:00

Штопать! Я думал, что попробую, у меня нет доступа ко всем моим машинам, поэтому я не мог протестировать

Mitchel Sellers 22.10.2008 06:35

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

SELECT TabCustomers.CustomerForname AS NameSearch, TabCustomers.CustomerSurname AS SurnameSearch, TabCustomers.CustomerDOB AS DOBSearch, TabCustomers.customerid AS MemberSearch
FROM TabCustomers
WHERE TabCustomers.customerid Like IIf([Forms]![FrmSearchCustomer].[Searchmember] Is Null,"*",[Forms]![FrmSearchCustomer]![Searchmember])
AND Trim(TabCustomers.CustomerForname & "") Like IIf([Forms]![FrmSearchCustomer].[SearchFore] Is Null,"*",[Forms]![FrmSearchCustomer]![SearchFore] & "*")
AND Trim(TabCustomers.CustomerSurname & "") like IIf([Forms]![FrmSearchCustomer].[Searchlast] Is Null,"*",[Forms]![FrmSearchCustomer]![SearchLast] & "*")
AND (TabCustomers.CustomerDOB Like IIf([Forms]![FrmSearchCustomer].[SearchDate] Is Null,"*",[Forms]![FrmSearchCustomer]![SearchDate] ) Or TabCustomers.CustomerDOB Is Null)

Происходят две вещи: сравнения следует поменять местами, и вы неправильно цитируете строки.

Это должно быть [поле базы данных], например «частичная строка + подстановочный знак».

и все строки должны быть окружены кавычками - не уверен, почему ваш запрос не выдает ошибок

Итак, должно работать следующее:

,[customerforname] Like  """" & [Forms]![FrmSearchCustomer]![SearchFore] & "*""" )=True

Обратите внимание на "" "", это единственный способ добавить к строке одинарные двойные кавычки.

Привет, ди-джей, я попытался изменить запрос на ваши предложения, и он не хочет знать - теперь он вообще не возвращает никаких записей ... Что касается ошибок, я бы предпочел, чтобы он выдал ошибку, чем действовал так, как это было работаю и зря тратишь время :(

Paul Green 22.10.2008 02:28

Это похоже на мой пример, за исключением того, что показанные кавычки предполагают, что это встроенный код (SQL, построенный из строк), а не источник записи для формы. Я рекомендую исключить IIF, как показано в моем примере, с помощью ИЛИ, так как я считаю, что его читать намного проще, чем выражения IIF.

Godeke 22.10.2008 02:41

Обычно я бы динамически создавал поисковый запрос, поэтому трудно сказать, что происходит. Возможно, другие ваши условия равны нулю, и вам действительно не нужны все эти IIF-функции.

DJ. 22.10.2008 02:41

Вместо [поле базы данных], например «частичная строка + подстановочный знак», я думаю, это должно быть [поле базы данных], например «частичная строка» + «подстановочный знак»

onedaywhen 22.10.2008 11:22

"Обратите внимание на" "" "это единственный способ добавить одинарную двойную кавычку к строке". Хм, а как насчет & Chr $ (39) ??

onedaywhen 22.10.2008 11:24

У вас есть выражение LIKE наоборот. Я переписал запрос, чтобы удалить ненужные команды IIF и исправить порядок операндов для оператора LIKE:

SELECT TabCustomers.*
FROM TabCustomers
WHERE (Forms!FrmSearchCustomer!SearchMember Is Null Or Forms!FrmSearchCustomer!SearchMember=[customerid]) 
And (Forms!FrmSearchCustomer.SearchFore Is Null Or [customerforname] Like Forms!FrmSearchCustomer!SearchFore & "*") 
And (Forms!FrmSearchCustomer!SearchLast Is Null Or [customersurname] Like Forms!FrmSearchCustomer!SearchLast & "*") 
And (Forms!FrmSearchCustomer!Searchdate Is Null Or [customerDOB] Like Forms!FrmSearchCustomer!Searchdate & "*");

Я построил этот запрос, воспроизведя наиболее вероятное обстоятельство: я создал фиктивную таблицу с упомянутыми полями и форму с полями и подчиненной формой с запросом, указанным выше, который обновляется при нажатии кнопки поиска. Если хотите, я могу предоставить ссылку для скачивания на созданный мною пример. Пример работает так, как ожидалось. J берет только Джима и Джона, в то время как Джон или Джо тянут только запись Джона.

Об этом гуляли в UtterAccess около 2 недель, но так и не подошли !!!

Paul Green 22.10.2008 02:40

Этот запрос завершится ошибкой как слишком сложный, если пользователь введет текст в числовое поле. Кроме того, если какое-либо из полей имеет значение NULL, запись не будет возвращена.

Fionnuala 22.10.2008 13:14

Форма поиска имеет довольно надежную проверку четности - все должно было быть написано с удобными сообщениями об ошибках, так что этого не должно происходить ...

Paul Green 22.10.2008 17:16
Ответ принят как подходящий

Для этого есть способ доступа!

Если у вас есть элементы управления «фильтром» в форме, почему бы вам не использовать метод Application.buildCriteria, который позволит вам добавить критерии фильтрации в строку, затем сделать фильтр из этой строки и создать свой WHERE пункт на лету?

selectClause = "SELECT TabCustomers.* FROM TabCustomers"
if not isnull(Forms!FrmSearchCustomer!SearchMember) then
    whereClause = whereClause & application.buildCriteria(your field name, your field type, your control value) &  " AND "
endif
if not isnull(Forms!FrmSearchCustomer!SearchFore) then
    whereClause = whereClause & application.buildCriteria(...) &  " AND "
endif
if not isnull(Forms!FrmSearchCustomer!SearchLast) then
    whereClause = whereClause & application.buildCriteria(...) &  " AND "
endif
if not isnull(Forms!FrmSearchCustomer!SearchDate) then
    whereClause = whereClause & application.buildCriteria(...) & " AND "
endif
--get rid of the last "AND"
if len(whereClause) > 0 then
     whereClause = left(whereClause,len(whereClause)-5)
     selectClause = selectClause & " WHERE " & whereClause
endif
-- your SELECT instruction is ready ...

Обновлено: buildCriteria вернет (например):

  • 'field1 = "GR"' при вводе "GR" в элементе управления
  • 'field1 LIKE "GR*"' при вводе "GR*" в элементе управления
  • 'field1 LIKE "GR*" or field1 like "BR*"', если вы наберете 'LIKE "GR*" OR LIKE "BR*"' в элементе управления

PS: если ваши элементы управления «фильтром» в вашей форме всегда имеют один и тот же синтаксис (скажем, «search_fieldName», где «fieldName» соответствует полю в базовом наборе записей) и всегда расположены в одной и той же зоне (скажем, formHeader), тогда можно написать функцию, которая будет автоматически генерировать фильтр для текущей формы. Затем этот фильтр можно установить как фильтр формы или использовать для чего-то еще:

For each ctl in myForm.section(acHeader).controls
    if ctl.name like "search_"
        fld = myForm.recordset.fields(mid(ctl.name,8))
        if not isnull(ctl.value) then
           whereClause = whereClause & buildCriteria(fld.name ,fld.type, ctl.value) & " AND "
        endif
    endif
next ctl
if len(whereClause)> 0 then ...

Я определенно рекомендую этот подход: его намного проще поддерживать, особенно если вы добавите дополнительные критерии в свою форму. Я использовал его в форме, в которой было до 20 критериев (поиск в базе данных хоккеистов с использованием различных комбинаций статистики).

Dave DuPlantis 22.10.2008 16:50

Отличный момент. Я решил исправить ошибку запросов, но со временем это станет лучшим решением в целом. Обратите внимание, что я видел ошибки в BuildCriteria, касающиеся обработки даты.

Godeke 23.10.2008 22:51

Я нашел вспомогательную функцию, которая добавляет «И» только в том случае, если передана ненулевая строка, и позволяет избежать этого последнего сканирования. гдеClause = AddAnd (гдеClause ...). Для поисков дополнительная стоимость звонков незначительна.

Godeke 23.10.2008 22:53

Другие вопросы по теме