Restituzione di record che corrispondono parzialmente a un valore
Domanda
Sto cercando di far funzionare una query che prende i valori (a volte solo la prima parte di una stringa) da un controllo di modulo. Il problema che ho è che restituisce i record solo quando viene digitata la stringa completa.
vale a dire. nella casella del cognome, dovrei essere in grado di digitare gr e viene visualizzato
verde grigio Graham
ma al momento non fa apparire nulla se non viene utilizzata la stringa di ricerca completa.
Esistono 4 controlli di ricerca nel modulo in questione e vengono utilizzati nella query solo se la casella è compilata.
La query è:
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;
Soluzione
Esiste un metodo di accesso per questo!
Se hai il tuo " filtro " controlli nel modulo, perché non usi il metodo Application.buildCriteria, che ti permetterà di aggiungere i tuoi criteri di filtraggio a una stringa, quindi fare un filtro da questa stringa e costruire al volo la tua clausola 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 ...
EDIT: restituirà buildCriteria (ad esempio):
-
'field1 = " GR "'
quando digiti " GR " nel controllo -
'field1 LIKE " GR * "'
quando si digita" GR * "
nel controllo -
'field1 LIKE " GR * " oppure field1 come " BR * " '
se digiti' LIKE " GR * " O COME "BR *" "
nel controllo
PS: se il tuo " filtro " i controlli nel tuo modulo hanno sempre la stessa sintassi (diciamo " nome_campo di ricerca " ;, dove " fieldName " corrisponde al campo nel recordset sottostante) e si trovano sempre nella stessa zona (diciamo formHeader), è quindi possibile scrivere una funzione che genererà automaticamente un filtro per il modulo corrente. Questo filtro può quindi essere impostato come filtro modulo o utilizzato per qualcos'altro:
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 ...
Altri suggerimenti
Hai la tua espressione LIKE all'indietro. Ho riscritto la query per rimuovere i comandi IIF non necessari e correggere l'ordine degli operandi per l'operatore 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 & "*");
Ho creato quella query replicando la circostanza più probabile: ho creato una tabella fittizia con i campi menzionati e un modulo con i campi e una sottomaschera con la query sopra elencata che veniva aggiornata quando veniva premuto il pulsante di ricerca. Posso fornire un link per il download nell'esempio che ho creato, se lo desideri. L'esempio funziona come previsto. J raccoglie solo Jim e John, mentre John o Jo fanno solo il record di John.
Stanno succedendo due cose: i confronti dovrebbero essere invertiti e non stai citando correttamente le stringhe.
Dovrebbe essere [campo database] come " stringa parziale + carattere jolly "
e tutte le stringhe devono essere racchiuse tra virgolette - non sono sicuro del motivo per cui la tua query non genera errori
Quindi dovrebbe funzionare quanto segue:
,[customerforname] Like """" & [Forms]![FrmSearchCustomer]![SearchFore] & "*""" )=True
Nota """ " " questo è l'unico modo per aggiungere una doppia virgoletta a una stringa.
Il mio unico pensiero è che forse è necessario un () per raggruppare i simili
Ad esempio uno snippet nella prima parte
,[Forms]![FrmSearchCustomer]![SearchFore] Like ([customerforname] & "*"))=True
È da un po 'che non uso l'accesso, ma è la prima cosa che mi viene in mente
Questa è una riscrittura completa per consentire valori nulli nei campi del nome o della data di nascita. Questa query non avrà esito troppo complesso se il testo viene inserito nel campo ID cliente numerico.
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)