Renvoyer des enregistrements qui correspondent partiellement à une valeur
Question
J'essaie de faire fonctionner une requête qui prend les valeurs (parfois juste la première partie d'une chaîne) d'un contrôle de formulaire. Le problème que j’ai, c’est qu’il ne renvoie les enregistrements que lorsque la chaîne complète est entrée.
i.e. dans la zone de nom de famille, je devrais être capable de taper gr, et cela fait apparaître
vert gris Graham
mais pour le moment, cela ne soulève rien, à moins que la chaîne de recherche complète soit utilisée.
Il y a 4 contrôles de recherche sur le formulaire en question, et ils ne sont utilisés dans la requête que si la zone est renseignée.
La requête est:
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;
La solution
Il existe une méthode d'accès pour cela!
Si vous avez votre " filtre " pourquoi ne pas utiliser la méthode Application.buildCriteria, qui vous permettra d’ajouter vos critères de filtrage à une chaîne, puis de filtrer cette chaîne et de construire votre clause WHERE à la volée?
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: le buildCriteria retournera (par exemple):
-
'field1 = " GR "'
lorsque vous tapez " GR " dans le contrôle -
'field1 LIKE "GR *"
lorsque vous tapez"GR *"
dans le contrôle -
'champ1 LIKE " GR * " ou champ1 tel que "BR *"
si vous tapez'LIKE "GR * " OU SIMILAIRE "BR *" '
dans le contrôle
PS: si votre " filtre " Les contrôles de votre formulaire ont toujours la même syntaxe (disons "search_fieldName", où "fieldName" correspond au champ du jeu d'enregistrements sous-jacent) et sont toujours situés dans la même zone (disons formHeader), il est alors possible de écrire une fonction qui générera automatiquement un filtre pour le formulaire actuel. Ce filtre peut ensuite être défini comme filtre de formulaire ou utilisé pour autre chose:
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 ...
Autres conseils
Vous avez votre expression LIKE à l'envers. J'ai réécrit la requête pour supprimer les commandes IIF inutiles et pour corriger votre ordre d'opérandes pour l'opérateur 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'ai construit cette requête en répliquant la situation la plus probable: j'ai créé une table factice avec les champs mentionnés et un formulaire avec les champs et un sous-formulaire avec la requête répertoriée ci-dessus en cours d'actualisation lorsque le bouton de recherche a été poussé. Je peux fournir un lien de téléchargement vers l'exemple que j'ai créé si vous le souhaitez. L'exemple fonctionne comme prévu. J ne récupère que Jim et John, tandis que John ou Jo n’enregistre que le record de John.
Deux choses se passent - les comparaisons doivent être inversées et vous ne citez pas les chaînes correctement.
Il devrait s'agir de [champ de base de données] comme "chaîne partielle + caractère générique"
.et toutes les chaînes doivent être entourées de guillemets - vous ne savez pas pourquoi votre requête ne génère pas d'erreurs
Les éléments suivants devraient donc fonctionner:
,[customerforname] Like """" & [Forms]![FrmSearchCustomer]![SearchFore] & "*""" )=True
Notez les """ & ";" c’est la seule façon d’ajouter un guillemet double à une chaîne.
Mon seul point de vue est qu’il faut peut-être un () pour grouper comme
Par exemple, un extrait de code sur la première partie
,[Forms]![FrmSearchCustomer]![SearchFore] Like ([customerforname] & "*"))=True
Cela fait un moment que je n'ai pas utilisé l'accès, mais c'est la première chose qui me vient à l'esprit
Il s’agit d’une réécriture complète permettant les valeurs NULL dans les champs du nom ou le champ de la date de naissance. Cette requête n'échouera pas de manière trop complexe si du texte est saisi dans le champ numéro client.
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)