Débutant VBA, aide pour tirage aléatoire

Résolu
Lena7 - 5 janv. 2013 à 18:23
 Lena7 - 6 janv. 2013 à 10:30
Bonjour, je débute en VBA et je dois créer une application de gestion de qcm. Je bute méchamment sur l'un des derniers formulaires qu'il me reste à faire. En faite, dans mon application chaque QCM a un nombre de question obligatoire qui doit être posé, les questions sont donc plus nombreuses et sont tirées aléatoirement et ne peuvent évidemment pas être tirées deux fois lors du même passage. Quelqu'un serait-il comment m'aider à coder cela ? Je crains de ne jamais arriver à me sortir de là seule

Je ne suis pas sur de placer les procédures au bon endroit. A l'ouverture de mon formulaire je veux que la première question s'affiche puis ensuite en cliquant sur le bouton "Suivant" afficher les questions suivantes une après l’autre à chaque clic. Je ne sais pas vraiment quoi mettre dans mon bouton suivant.


Voilà le morceau de code que j'ai fait jusqu'à là :
Option Compare Database
Option Explicit

Dim compteur As Integer
Dim nb As Integer

Private Sub Form_Current()

Dim SqlNB As String
Dim SqlTitre As String
Dim SqlTH As String
Dim TabQuest() As Integer
Dim qcm As Integer
Dim total_q As Integer
Dim epreuve As Integer
Dim strQuery As String
Dim titre As String
Dim theme As String
Dim SqlQUEST As String
Dim SqlRep1 As String
Dim SqlRep2 As String
Dim SqlRep3 As String
Dim SqlRep4 As String
Dim dbs As DAO.Database
Dim rst As DAO.Recordset
Dim n As Long
Dim i As Long
Dim total As Integer
Dim date_du_jour As String

' nb de questions à poser
SqlNB " SELECT QCM.QCM_NBQUEST FROM QCM WHERE QCM.QCM_CODE 1 ;"
Set dbs = CurrentDb
Set rst = dbs.OpenRecordset(SqlNB)
nb = rst.Fields(0)
NbPosé.Value = nb

' nb de questions existantes pour un qcm
Set rst dbs.OpenRecordset(" SELECT Count(*) FROM QUEST WHERE QUEST.QCM_CODE 1 ;")
total = rst.Fields(0)
total_q = total

' titre et theme du qcm
Set rst dbs.OpenRecordset(" SELECT QCM_TITRE FROM QCM WHERE QCM.QCM_CODE 1 ;")
titre = rst.Fields(0)
TitreQCM.Value = titre
Set rst dbs.OpenRecordset(" SELECT TH_NUM FROM QCM WHERE QCM.QCM_CODE 1 ;")
theme = rst.Fields(0)

' tableau des questions selectionnables pour l'épreuve
Dim tmp() As Integer
ReDim tmp(total)
strQuery " SELECT QUEST_NUM FROM QUEST WHERE QUEST.QCM_CODE 1 ;"
Set rst = dbs.OpenRecordset(strQuery)
rst.MoveFirst
i = 0
While Not rst.EOF
tmp(i) = rst("QUEST_NUM")
i = i + 1
rst.MoveNext
Wend

If (total = 0) Then
MsgBox " Pas de question pour ce QCM !"
End If
If (total < nb) Then
MsgBox "Pas assez de question pour ce QCM !"
End If
If (total > nb) Then
date_du_jour = Format(Now, "dd/mm/yyyy")
Set rst = dbs.OpenRecordset(" SELECT PASS_NUM FROM PASS ;")
While Not rst.EOF
rst.MoveNext
Wend
epreuve = rst.RecordCount + 1

For n = 0 To nb - 1
i = Int(total * Rnd)
SqlQUEST " SELECT QUEST.QUEST_INT FROM QUEST WHERE QUEST.QCM_CODE 1 AND QUEST.QUEST_NUM = " & tmp(i) & " ;"
QuestInt = CurrentDb.OpenRecordset(SqlQUEST).Fields(0).Value
SqlRep1 " SELECT REP.REP_INT FROM REP WHERE REP.REP_NUM 1 AND REP.QCM_CODE = 1 AND REP.QUEST_NUM = " & tmp(i) & " ;"
Rep1 = CurrentDb.OpenRecordset(SqlRep1).Fields(0).Value
SqlRep2 " SELECT REP.REP_INT FROM REP WHERE REP.REP_NUM 2 AND REP.QCM_CODE = 1 AND REP.QUEST_NUM = " & tmp(i) & " ;"
Rep2 = CurrentDb.OpenRecordset(SqlRep2).Fields(0).Value
SqlRep3 " SELECT REP.REP_INT FROM REP WHERE REP.REP_NUM 3 AND REP.QCM_CODE = 1 AND REP.QUEST_NUM = " & tmp(i) & " ;"
Rep3 = CurrentDb.OpenRecordset(SqlRep3).Fields(0).Value
SqlRep4 " SELECT REP.REP_INT FROM REP WHERE REP.REP_NUM 4 AND REP.QCM_CODE = 1 AND REP.QUEST_NUM = " & tmp(i) & " ;"
Rep4 = CurrentDb.OpenRecordset(SqlRep4).Fields(0).Value
compteur = 1
NumeroQuest.Value = compteur
tmp(i) = tmp(total - 1)
total = total - 1
Next
End If


End Sub

Private Sub Suivant_Click()


If (compteur < nb) Then
compteur = compteur + 1
NumeroQuest.Value = compteur





End If

If (compteur = nb) Then
DoCmd.Close
DoCmd.OpenForm "FormFinQCM"
End If



End Sub

8 réponses

ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
5 janv. 2013 à 18:41
Bonjour,
Une idée (à toi de la travailler ensuite) :
Pour chaque QCM :
- compter (recordCount) le nombre d'articles possibles
- faire un tableau dynamique de 1 à ce nombre
- "touiller" (mélanger) ce tableau (tu trouveras des exemples sur ce forum pour "touiller")
- puiser dans ce tableau, de l'index 0 en croissant, le nombre d'articles nécessaires (aucun risque, ainsi, de doublons)
- pour chaque article numéroté x retenu, rechercher (movenext x fois) dans ta base sa correspondance (tant pour la question à poser, que pour la réponse attendue)


________________________
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.
3
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
5 janv. 2013 à 18:49
Rien ne devrait d'ailleurs t'empêcher, si le nombre d'articles n'est pas impressionnant,
- d'alimenter directement un tableau dynamique à deux colonnes (question - bonne réponse) à partir de la table concernée.
- touiller ce tableau, etc ...

Comme, pour chaque question posée, tu connais ainsi par avance la bonne réponse, il te sera facile de noter d'emblée (1 ou 0) la réponse du candidat.


________________________
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.
3
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
5 janv. 2013 à 20:04
Bon.
On m'attend au restaurant :
dernier coup de pouce ===>> regarde et comprends :
nombre_articles = 10
  ReDim tableau(nombre_articles - 1)
  For i = 0 To UBound(tableau)
    tableau(i) = i
  Next
  'preuve
  For i = 0 To UBound(tableau)
    'MsgBox tableau(i)
  Next
  
  'on touille
  Randomize
  nb = UBound(tableau)
  For i = 0 To nb \ 2
  ou = Int(((nb - i) * Rnd))
  temp = tableau(ou)
  tableau(ou) = tableau(nb - i)
  tableau(nb - i) = temp
 Next
  'preuve du touillage
  For i =  0 To UBound(tableau)
    MsgBox tableau(i)
  Next

Le reste, tu sais faire, normalement, hein ...
Sinon, il faudrait te faire tout et ce n'est pas là ni ma tasse de thé, ni la vocation d'un forum de développeurs .



________________________
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.
3
Merci pour cette réponse très rapide. D'accord, en effet, " touiller " m'a l'air plus simple que ce que je voulais faire jusqu'ici, je vais tester ça alors. Par contre, je n'y connais pas grand chose en tableau en VBA. C'est un tableau de ce genre que je dois déclarer : Dim Tableau(1 To x, 1 To x) As Integer  ?
Mais de quelle manière je dois procéder pour remplir ce tableau avec les résultats de ma requete ? Désolé si ma question parait bête mais je ne vois pas comment manipuler les tableaux, d'où mon problème à coder ce formulaire
Je vais essayer de voir si j'arrive à faire quelque chose alors :)
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
5 janv. 2013 à 19:21
Laquelle des deux méthodes as-tu choisie ? La première ou la seconde ? (important, pour te répondre en connaissance de cause !)


________________________
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.
0
Je crois que je vais tenter la première solution, elle me parait plus claire (à mon niveau) même si la deuxième est surement plus propre au niveau du code
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
5 janv. 2013 à 19:47
Comme tu veux ! (la seconde était bien meilleure, mais c'est ton choix ).
Il te faut quand-même te familiariser avec lkes tableaux dynamiques, hein ...
Regarde ce que fait ceci :
nombre_articles = 10 ' où, bien sût, tu mets ton recordCount à la place de 10
  ReDim tableau(nombre_articles - 1)
  For i = 0 To UBound(tableau)
    tableau(i) = i
  Next

  'preuve
  For i = 1 To UBound(tableau)
    MsgBox tableau(i)
  Next

Ce tableau est donc constitué de 10 chiffres, de 0 à 9, dans l'ordre 0,1,2 ...9
En le touillant, tu le mélangeras donc aléatoirement, du genre 3,1,7,6,4,2,0,9,8 ....
Après l'avoir touillé, si tu veux 3 questions au hasard et sans doublon, il te suffit d'y prendre les 3 premiers, donc tableau(0),tableau(1) et tableau(2), c'est à dire 3, 1 et 7
Pour avoir la correspondance dans ta table ===>> MovePreviuous )===>> movenext x fois (3 pour la 1ère, 1 pour la seconde et 7 pour la 3ème).
________________________
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.
0
Je te remercie mille fois pour l'aide que tu m'a apporté et surtout le fait d'avoir été aussi rapide. La méthode du touillage fonctionne impeccable, merci !
0
Rejoignez-nous