Problème requête SQL et chrono [Résolu]

Signaler
-
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
-
Bonjour ! Suite à la précieuse aide que j'ai eu sur ce forum lors de ma dernière question, je reviens une dernière fois vous demander un coup de pouce pour mon projet en vba. Après ça promis je cesse de vous embêter.

Première question :
J'ai trois tables différentes
questions ( qcmcode, questnum, questint)
reponses ( questnum, qcmcode, numrep, repint, repval)
tirer (numpass, qcmcode, numquest, repnum, score, ordre)
reponses est lié à questions et questions est lié à tirer mais réponses et tirer ne sont pas liés

Je souhaite à l'aide d'une requete afficher l'intitulé des questions tirés dans un certain passage d'un certain qcm ainsi que d'afficher les réponses juste de ces questions. Ma requête ne fonctionne pas, je dois oublier quelque chose. Quelqu'un aurait-il une petit idée ?

Sql ("SELECT questint, repint FROM reponses INNER JOIN questions ON reponses.questnum questions.questnum AND reponses.qcmcode = questions.qcmcode INNER JOIN tirer ON questions.qcmcode = tirer.qcmcode AND questions.questnum = tirer.questnum WHERE tirer.numpass = "& i &" AND reponses.repval = 1 ")


Deuxième question :
J'ai une petite procédure qui lance un petit chrono qui décompte le temps. Ma procédure marche mais je souhaiterais la déclencher lors de l'ouverture du formulaire, si je mais dans le code de l'ouverture du formulaire un "Call chrono" alors tout mon application se ferme suite à un bug. Comment puis-je gérer ce soucis ?

Merci d'avance pour l'aide.

11 réponses

Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
73
Salut

Si ta requète ne fonctionne pas, elle doit ta donner des indications.
Lesquelles ? C'est une info importante quand on demande de l'aide.
Si elle ne renvoie pas d'info, c'est que la syntaxe est acceptée. Dans ce cas, c'est ton équation qui n'est pas bonne.

Dans des syntaxes à rallonge comme celle-là, utilise le symbole _ en fin de ligne de code pour poursuivre l'instruction à la ligne suivante.
Tu pourras ainsi visualiser plus aisément ta syntaxe et les erreurs sautent plus vite aux yeux.
Démo avec ton code :
Sql = ("SELECT questint, repint " & _
       "  FROM reponses  " & _
       " INNER JOIN questions  " & _
       "         ON reponses.questnum = questions.questnum " & _
       "        AND reponses.qcmcode = questions.qcmcode " & _
       "            INNER JOIN tirer " & _
       "                    ON questions.qcmcode = tirer.qcmcode " & _
       "                   AND questions.questnum = tirer.questnum " & _
       "                 WHERE tirer.numpass = " & i & "  " & _
       "                   AND reponses.repval = 1 ")

Franchement, je m'y perds dans ces notations à la Access et je ne sais pas s'il est autorisé faire un And dans le ON d'un INNER JOIN (pas clair pour moi).
Par contre, je suis sûr qu'il faut nommer les tables d'appartenance des champs. 'questint' ne fait pas partie de la table 'reponses'. Il faut donc préciser dans quelle table le trouver (mettre le nom de la table devant et un point de séparation avec le nom du champ).
Je préfère mille fois la méthode SQL de chez SQL équivalente :
Sql = ("SELECT questions.questint, " & _
       "       reponses.repint " & _
       "  FROM reponses, " & _
       "       questions, " & _
       "       tirer " & _
       " WHERE reponses.questnum  = questions.questnum " & _
       "   AND reponses.qcmcode   = questions.qcmcode " & _
       "   AND reponses.repval    = 1 " & _
       "   AND questions.qcmcode  = tirer.qcmcode " & _
       "   AND questions.questnum = tirer.questnum " & _
       "   AND tirer.numpass      = " & i)
Tu auras remarqué que j'ai remonté la dernière condition plus haut (elle devrait même être en tête), car une requète qui rencontre une première sélection limite l'étendue des recherches dans les autres tables, d'où une meilleure efficacité (dans le cas de champs indexés).
Peut-être qu'un "i.ToString" serait préférable, en fin de syntaxe.
Maintenant, te dire pourquoi elle ne retourne pas de résultat, il n'y a que toi qui peut faire l'analyse, avec des exemples.

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

Le savoir est la seule matière qui s'accroit quand on le partage (Socrate)
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
73
Quelle version de Office ?
Quel logiciel ? Excel, Access ?

Où se trouve ta procédure Chrono ?
Dans le code de ton formulaire (ou feuille) ou bien dans un module ?

D'où appelles-tu ta procédure chrono ?
Depuis le code de ton formulaire (ou feuille), d'une forme ou bien d'un module ?

--> Si les 2 codes (appelant et appelé) ne sont pas dans la même page de code, il faut ajouter Public devant le Sub Chrono

Mais cela n'expliquerait pas le krash. Au pire, tu aurais une erreur te disant que la procédure n'existe pas.
Je te recommande de demander une compilation/vérification de ton code avant de le lancer : Dans l'éditeur VBA, menu "Debogage" + "Compiler VBProject" : Il te dira où sont les problèmes éventuels.

Vérifie si tu n'aurais pas appelé une variable/procédure/objet avec le nom Timer, ce qui lui ferai perdre les pédales.

"si je mais dans le code de l'ouverture du formulaire un "Call chrono" ..."
Définition de "ouverture du formulaire" ?
Est-ce que cela veut dire que lorsque tu le lances autrement, cela fonctionne ?

Autres remarques :
- Mettre une MsgBox à l'intérieur d'un Do-Loop devrait t'occuper un moment puisque la boucle tourne bien plus d'une fois par seconde ...
Je suppose que tu as mis ça pour vérifier le passage dans cette Sub ...
- Méfie-toi si tu fais tourner ton programme juste avant minuit : Timer repasse à zéro ... tu risques d'attendre longtemps
- Dimensionnement des variables : Une variable définie comme tu le fais est de type Variant. Pas vraiment Top.
Timer renvoyant un Single (voir l'aide), toutes tes variables Start, Finish, duree devraient être des Single et reste, un Integer

PS : Pour le 'i.ToString' dont je parlais : oublie, je pensais que tu étais en .Net
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
232
Bonjour,
le crash est le résultat de cette boucle :
Do While Timer < Finish
  reste =  int(Finish - Timer)
  MsgBox "Le temps passe", 0, "il reste " & reste & " secondes avant la fin"
  DoEvents ' Donne le contrôle à d'autres processus.
Loop 

pensant deux minutes !
J'ai déjà eu au moins trois fois l'occasion d'en parler
Utiliser Application.Ontime est plus sage, d'autant que la précision n'est ici que d'une seconde

________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
232
Regarde ce que fait par exemple ceci :
- dans un module standard :
Public duree As Long, depart As Date, ou As Object
Public Sub toto()
  ou.Visible = True
  Dim ecoule As Long
  ecoule = DateDiff("s", depart, Now)
  If ecoule >duree + 1 Then ou.Visible False: ou.Caption = "": Exit Sub
  reste = duree - ecoule
  ou.Caption = ecoule & " seconde(s) déjà écoulée(s)" & vbCrLf & "reste(nt) " & reste & " secondes"
  Application.OnTime Now + TimeValue("00:00:01"), "toto"
End Sub


- sur une feuille de calcul : un commandbutton et un label
- propriété visible du label : false
- ce code :
Private Sub CommandButton1_Click()
  depart = Now
  duree 12 '>>> mets ici la durée que tu veux, exprimée en secondes
  Set ou = Label1
  Application.OnTime Now + TimeValue("00:00:01"), "toto"
End Sub

clique sur le bouton de commande ===>> observes ===>> comprends ===>> arrange à ta sauce et perfectionne.
Tu n'auras plus de crash.


________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
232
Pour perfectionner :
1) tu ouvres ton aide VBA sur le mot OnTime et lis attentivement
2) tu t'intéresses de très près au paramètre de planification ( Schedule:= ...)
et t'en sers.
Au lieu de faire comme je l'ai fait, en bâclant.



________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
73
Quant à ton histoire de chrono, il faudrait qu'on sache ce qu'est cet objet/procédure nommée 'chrono'.
Le problème est surement à l'intérieur.
Merci Jack pour ta réponse. Je vais tester ta requête sur Access cette après midi pour voir. Non Access ne me retourne pas de message d'erreur donc ma requête semble être acceptée mais pourtant elle ne m'affiche rien.
Pour ce qui est du chrono voici mon code :

Sub chrono()
Dim Start, Finish, duree, reste

duree = 120 ' durée 2 minutes.
Start = Timer ' top
Finish = Start + duree

Do While Timer < Finish
reste = int(Finish - Timer)
MsgBox "Le temps passe", 0, "il reste " & reste & " secondes avant la fin"
DoEvents ' Donne le contrôle à d'autres processus.
Loop

End Sub
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
232
Et afficher par msgbox est en plus de la plus grande maladresse !
C'est dans un label, qu'il vaut mieux le faire.


________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
Merci Jack, ta requête fonctionne parfaitement. C'est effectivement mon ON ... AND qui devaient être faux. Pour ce qui est de la version je suis sur Access 2007. Mon chrono se trouve dans mon formulaire. Il fonctionne si je ne fais tourner que lui sur la page et que j'enlève tout le reste de mon code, donc ceci confirme je pense ce que dit Ucfoutu. Ma procédure est trop lourde. Je vais essayer Applicatio.Ontime dans ce cas. Et oui, effectivement ici le MsgBox ne me sert que de vérification, mon chrono final sera bien dans un label.

Merci à tous les deux pour votre aide.
Ca fonctionne, parfait. Encore un grand merci pour l'aide
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
232
Bien !
Mais j'ai bâclé ===>> perfectionne donc.


________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.