Difficultés avec la composition d'un SQL en VBA [Résolu/Fermé]

Signaler
Messages postés
46
Date d'inscription
lundi 16 avril 2018
Statut
Membre
Dernière intervention
18 novembre 2020
-
Messages postés
16120
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
23 juin 2021
-
Bonjour,

J'ai un problème avec la modification du SQL de l'une de mes requêtes.

Tout d'abord, voici ce que je souhaite faire (si vous avez d'autres suggestions que la modification du SQL, je suis très ouverte aux idées):

Je souhaite "improviser" des droits d'accès sur mes données pour les différents utilisateurs qui utiliseront ma base de données. Premièrement, j'ai créé des tables pour définir mes utilisateurs, avec leur profil (droit d'accès) et leur mot de passe pour chacun.

J'ai un état qui me sert de "plateforme principale" pour l'utilisateur.
Cet état est conçu grâce à une requête "05_01-PLATEFORME" qui va tirer les informations dont j'ai besoin de plusieurs autres tables et requêtes, dont la requête "08_00-CHOIX_ALLOC_TABLE" qui est filtrée par un critère "NoET_AL" correspondant au numéro associé à l'utilisateur.

Ce qui me pose problème est que plusieurs utilisateurs ont accès en même temps à ma base et je ne sais pas si je peux me contenter de changer le critère une seule fois à la connexion de l'utilisateur sans que le numéro d'un autre utilisateur lors de sa connexion vienne influencer les données du premier utilisateur. C'est peut-être ici que vous pourriez me donner d'autres suggestions...

Je sais que ce n'est infaillible comme processus pour contrer les mauvaises intentions, mais ce n'est qu'une question de présentation.

Sinon, la solution que j'ai trouvée pour pallier à ce problème est de modifier le code SQL de ma requête, au besoin, c'est-à-dire à chaque fois que mon utilisateur clique à l'endroit qui le ramène à sa plateforme.

Ma requête prend en compte beaucoup d'éléments et j'obtiens toujours un message d'erreur qui me dit que la clause FORM n'est pas correcte, voici donc mon code VBA appliqué sur mon bouton:

Dim strNoET As String
Dim strSQL As String
Dim strSQLSELECT As String
Dim strSQLWHERE As String

strNoET = Me.No_ET

strSQLSELECT = _
"SELECT [06-ALLOCATIONS_BUDGET].No_AL, [05-MESURES].NoRM_ME, [04-REGROUPEMENTS_M].Titre_RM," & _
"[06-ALLOCATIONS_BUDGET].NoME_AL, [05-MESURES].Titre_ME, [NoME_AL] & " - " & [Titre_ME] AS Expr1, [06-ALLOCATIONS_BUDGET].NoET_AL, [06-ALLOCATIONS_BUDGET].BudCal_AL," & _
"[NoRM_ME] & " - " & [Titre_RM] AS Expr2" & vbCrLf & _
"FROM ([04-REGROUPEMENTS_M] INNER JOIN [05-MESURES] ON [04-REGROUPEMENTS_M].No_RM = [05-MESURES].NoRM_ME)" & _
"INNER JOIN [06-ALLOCATIONS_BUDGET]" & _
"ON [05-MESURES].No_ME = [06-ALLOCATIONS_BUDGET].NoME_AL"

strSQLWHERE = _
"WHERE ((([06-ALLOCATIONS_BUDGET].NoET_AL)='" & _
Replace(strNoET, "'", "''") & ")" & _
"AND (([06-ALLOCATIONS_BUDGET].BudCal_AL)<>0));"

strSQL = strSelect & vbCrLf & _
        strWHERE

CurrentDb.QueryDefs("08_00-CHOIX_ALLOC_TABLE").SQL = strSQL

MsgBox CurrentDb.QueryDefs("08_00-CHOIX_ALLOC_TABLE").SQL



Voici le code SQL de ma requête qui doit être modifié dans la clause WHERE pour que le "450" soit changé pour le numéro de l'utilisateur à l'aide de mon code VBA:

SELECT [06-ALLOCATIONS_BUDGET].No_AL, [05-MESURES].NoRM_ME, [04-REGROUPEMENTS_M].Titre_RM, [06-ALLOCATIONS_BUDGET].NoME_AL, [05-MESURES].Titre_ME, [NoME_AL] & " - " & [Titre_ME] AS Expr1, [06-ALLOCATIONS_BUDGET].NoET_AL, [06-ALLOCATIONS_BUDGET].BudCal_AL, [NoRM_ME] & " - " & [Titre_RM] AS Expr2

FROM ([04-REGROUPEMENTS_M] 
INNER JOIN [05-MESURES] ON [04-REGROUPEMENTS_M].No_RM = [05-MESURES].NoRM_ME) 
INNER JOIN [06-ALLOCATIONS_BUDGET] ON [05-MESURES].No_ME = [06-ALLOCATIONS_BUDGET].NoME_AL
WHERE ((([06-ALLOCATIONS_BUDGET].NoET_AL)=<gras>450</gras>) AND (([06-ALLOCATIONS_BUDGET].BudCal_AL)<>0));


Voici le lien pour consulter ma base de données:
https://drive.google.com/file/d/1x5JpJ45sjqe_1kaI3IQ4FomyPd4fBtaH/view?usp=sharing

Je ne sais pas non plus si ma clause Where fonctionne parce que ça bloque avant.. donc la fonction Replace() n'est peut-être pas nécessaire non plus..

Pouvez-vous m'aider?

Merci beaucoup!!

5 réponses

Messages postés
15808
Date d'inscription
dimanche 25 novembre 2007
Statut
Membre
Dernière intervention
19 juin 2021
1 503
Bonjour,

Pas besoin de replace, il faut simplement mettre des ' devant et apres votre variable.

Par contre, chez moi erreur des la variable strSQLWHERE.

Apres des corrections que je pense justes( les spécialistes corrigeront) , toujours erreur:
Pour tester, j'ai pris le resultat StrSQL et cree une requete SQL (plus simple a modifier)
<code basic>SELECT [06-ALLOCATIONS_BUDGET].No_AL, [05-MESURES].NoRM_ME, [04-REGROUPEMENTS_M].Titre_RM,[06-ALLOCATIONS_BUDGET].NoME_AL, [05-MESURES].Titre_ME, [NoME_AL] - [Titre_ME] AS Expr1, [06-ALLOCATIONS_BUDGET].NoET_AL, [06-ALLOCATIONS_BUDGET].BudCal_AL,[NoRM_ME] - [Titre_RM] AS Expr2
FROM [04-REGROUPEMENTS_M] INNER JOIN [05-MESURES] ON [04-REGROUPEMENTS_M].No_RM = [05-MESURES].NoRM_ME
INNER JOIN [06-ALLOCATIONS_BUDGET]ON [05-MESURES].No_ME = [06-ALLOCATIONS_BUDGET].NoME_AL
WHERE [06-ALLOCATIONS_BUDGET].NoET_AL='100' AND [06-ALLOCATIONS_BUDGET].BudCal_AL)<>0;
<code>

Messages postés
16120
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
23 juin 2021
869
bonjour, donc, simplement:
strSQLWHERE = _
     "WHERE ((([06-ALLOCATIONS_BUDGET].NoET_AL)= " + strNoET  _
     + " AND (([06-ALLOCATIONS_BUDGET].BudCal_AL)<>0))"
strSQL = strSelect + strWHERE
Messages postés
16120
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
23 juin 2021
869
il manque un espace:
]ON
Messages postés
16120
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
23 juin 2021
869
bonjour, tu te poses les bonnes questions.
je pense que ce n'est pas une bonne idée de modifier ainsi les requêtes. cela ne va pas fonctionner correctement, et ce n'est pas nécessaire.

tu n'as pas donné une vue d'ensemble de ce que tu fais.

donc j'imagine que l'utilisateur passe par un formulaire pour s'identifier. ce formulaire serait le mystérieux "endroit qui le ramène à sa plateforme", dont tu ne nous dis rien.
ce formulaire pourrait ouvrir l'état en filtrant les données, tenant compte de l'utilisateur.

explications ici: https://docs.microsoft.com/fr-ch/office/vba/access/concepts/forms-design/apply-a-filter-when-opening-a-form-or-report
Messages postés
46
Date d'inscription
lundi 16 avril 2018
Statut
Membre
Dernière intervention
18 novembre 2020

Bonjour à vous! :)

Merci beaucoup pour ta réponse f894009!

Toutefois, je crois que je vais poursuivre dans la simplicité en étudiant la suggestion de yg_be.

Donc, tu me parles de filtrer mon état sur la donnée que je veux et ta méthode fonctionne parfaitement!! J'aurais dû y penser, j'ai fait ça partout dans le reste de ma base de données.. Mercii!! :D

Mon mystérieux formulaire est celui qui porte le nom de "01_01-LOGIN" (désolée j'avais omis de partager ce détail). Lorsque l'utilisateur inscrit son mot de passe (qui est "Bonjour" pour tout le monde pour l'instant) et appuie sur OK, mon vba valide si toutes les informations sont bonnes puis, si tout semble correct, un message s'ouvre puis la plateforme s'ouvre également selon le numéro qui lui est associé.

Cependant, j'ai omis de préciser un détail que j'avais oublié de mentionner:
Ma requête "08_00-CHOIX_ALLOC_TABLE" me sert aussi à diriger les données à afficher dans les listes déroulantes de certains de mes formulaires et sous-formulaires. Par exemple: le formulaire "08_01M-SAISIR_SAL_RÉGUL_PE" où le sous-formulaire de la section ATTRIBUTION DE MESURES présente des listes déroulantes dont les choix proposés doivent être ceux qui sont exclusivement associés au numéro de l'utilisateur..

Est-il possible d'appliquer un filtre du même type pour mes listes déroulante dans un formulaire ou un sous-formulaire?

Merci beaucoup!!! :)
Messages postés
15808
Date d'inscription
dimanche 25 novembre 2007
Statut
Membre
Dernière intervention
19 juin 2021
1 503
Re,

Toutefois, je crois que je vais poursuivre
Y a pas d'lezard, vous etes entre de bonnes mains avec yb_be
Bye..
Messages postés
16120
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
23 juin 2021
869
je ne vois pas ce qui empêche de faire presque la même chose n'importe où. à quel endroit cela te semble-t'il difficile?

pour "connaitre" partout l'identité de l'utilisateur (son numéro), je suggère de faire de strNoET une variable globale, utilisable partout.

pour cela,
1) éliminer la déclaration
strNoET As String
dans le formulaire LOGIN
2) ajouter une déclaration
Public strNoET As String
au début d'un module "normal", tel que le module SOURIS_MAIN, en dehors d'une sub ou function

en passant, je recommande fortement d'ajouter
option explicit
au début de chaque module, cela va t'aider à détecter des erreurs. de même, je recommande de régulièrement compiler ton code.
Messages postés
46
Date d'inscription
lundi 16 avril 2018
Statut
Membre
Dernière intervention
18 novembre 2020

Messages postés
46
Date d'inscription
lundi 16 avril 2018
Statut
Membre
Dernière intervention
18 novembre 2020

D'accord, alors j'ai corrigé mon module et j'ai mis
Option Explicit
au début.
Je n'ai pas essayé ta suggestion pour l'instant, parce que j'ai trouvé quelque chose entre-temps et j'aimerais que tu me dises si c'est bien ou pas. Je pense que ça ressemble beaucoup à ton principe de "variable globale".

En fait, j'ajouté dans mon formulaire LOGIN la création d'une variable temporaire.
Donc, à la connexion d'un utilisateur, lorsque tout est valide, tous les états requis s'ouvrent et le numéro que je souhaite conserver durant toute la session vient se stocker comme variable temporaire.

Par la suite, dans les formulaires requis, j'ai ajouté ma variable temporaire comme condition WHERE dans le contenu de ma liste déroulante. Tout semble fonctionner parfaitement.
Je pourrais même utiliser cette variable temporaire pour l'ouverture de mes états selon moi (ma question de départ).

Peux-tu me dire si c'est une bonne solution selon toi? Ou je devrais utiliser ta suggestion plutôt?
Et si deux utilisateurs ou plus sont dans ma base de données en même temps, est-ce que ça va affecter ma variable temporaire à la connexion de chacun d'entre eux ou c'est propre à chaque session/ordinateur des utilisateurs?

Voilà ce que j'ai fait:
https://drive.google.com/file/d/1AWn0bs8xyYRH4iCbfr0eF7ZKjvqSglBA/view?usp=sharing

Merci beaucoup!! :)
Messages postés
16120
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
23 juin 2021
869
je pense que TempVars est fonctionnellement identique aux variables globales (à part que TempVars peut être utilisé plus largement, aussi hors VBA, et tu fais probablement cela dans tes formulaires). je n'ai pas regardé tes formulaires, j'ai regardé uniquement ton code VBA.
si tu es à l'aise avec TempVars, je ne vois pas de raison de ne pas les utiliser.
TempVars n'existe pas avant Access 2007, sache-le si jamais tu veux utiliser ta base avec un Access plus ancien.
tu pourrais effectivement utiliser TempVars (ou une variable globale) pour l'ouverture de l'état que tu mentionnais au départ. il est préférable d'utiliser la même solution partout.
je pense que chaque ouverture de la base (chaque session) a ses copies privées de TempVars et des variables globales, donc l'un comme l'autre sont propres à chaque session/ordinateur des utilisateurs.