Comment faire une boucle dans un update (SQL Server) depuis Access VBA

Résolu/Fermé
V1ck1ng - 2 juin 2020 à 11:44
 V1ck1ng - 2 juin 2020 à 16:50
Bonjour à tous,

J'utilise MS Access comme interface utilisateur, j'accède au serveur de données Server SQL via VBA.
Je souhaite mettre à jour un ensemble de lignes dans une table CANDIDAT_TESTS. Ce que je fais actuellement est de mettre à jour une par une et je boucle avec un for; cela fonctionne, mais ça prend trop de temps. J'aimerais donc réduire le temps d'exécution en faisant une boucle dans ma requête.
Ci-dessous mon code VBA

varSession = "2020"
Set cnx = getConnectionBD(varSession)

rsSCE.Open "SELECT DISTINCT LIBELLE_DEPARTEMENT, LIBELLE_SOUS_CENTRE, NUM_SOUS_CENTRE " _
& " FROM VIEW_CANDIDATS_SCE " _
& " WHERE NUM_REGION = " & Me.LIST_REGION & " AND NUM_EXAMEN = " & Me.LIST_EXAMEN _
& " ORDER BY LIBELLE_DEPARTEMENT, LIBELLE_SOUS_CENTRE", cnx, adOpenStatic, adLockOptimistic
varTabSCE = rsSCE.GetRows
'On initialise les jurys parce que les jurys sont par région
jury = 0

'On parcourt les sous-centres par départements
For j = 1 To rsSCE.RecordCount
rsSerie.Open "SELECT DISTINCT NUM_SERIE, ABREVIATION_SERIE " _
& " FROM VIEW_CANDIDATS_SCE " _
& " WHERE NUM_SOUS_CENTRE = " & varTabSCE(2, j - 1) & " AND NUM_EXAMEN = " & Me.LIST_EXAMEN _
& " ORDER BY ABREVIATION_SERIE", cnx, adOpenStatic, adLockOptimistic
varTabSerie = rsSerie.GetRows

'On parcourt les séries du sce j
For k = 1 To rsSerie.RecordCount
'on initialise le curseur à 0 étant donné que les numéros d'ordre sont par série
cursor = 0
rsCandidats.Open "SELECT ID FROM CANDIDAT_TESTS " _
& " WHERE NUM_SOUS_CENTRE = " & varTabSCE(2, j - 1) & " AND NUM_SERIE = " & varTabSerie(0, k - 1) _
& " ORDER BY NOMS, DATE_DE_NAISSANCE", cnx, adOpenStatic, adLockOptimistic
varTabCandidats = rsCandidats.GetRows

nbCanddidats = rsCandidats.RecordCount
nbJurys = RoundUp(nbCanddidats / 250)

'On parcourt les jurys de la série k du sce j
numJury = nbJurys
For l = 1 To nbJurys
jury = jury + 1

If numJury > 1 Then
'On parcourt les candidats du jury l pour leur attribuer le numéro d'ordre et le jury
For m = 250 * (l - 1) + 1 To 250 * (l - 1) + 250
cursor = cursor + 1
rsUpdate.Open "UPDATE CANDIDAT_TESTS " _
& " SET NUMERO_ORDRE = " & cursor & ", JURY = " & jury _
& " WHERE ID = " & varTabCandidats(0, m - 1), cnx, adOpenStatic, adLockOptimistic

Set rsUpdate = Nothing
Next m
ElseIf numJury = 1 Then
'On parcourt les candidats du dernier jury pour leur attribuer le numéro d'ordre et le jury
For m = 250 * (l - 1) + 1 To nbCanddidats
cursor = cursor + 1
rsUpdate.Open "UPDATE CANDIDAT_TESTS " _
& " SET NUMERO_ORDRE = " & cursor & ", JURY = " & jury _
& " WHERE ID = " & varTabCandidats(0, m - 1), cnx, adOpenStatic, adLockOptimistic

Set rsUpdate = Nothing
Next m
End If
numJury = numJury - 1

Next l

Set rsCandidats = Nothing
Set rsSerie = Nothing
Next k

Set rsSCE = Nothing
Next j
A voir également:

2 réponses

yg_be Messages postés 22719 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024 1 476
2 juin 2020 à 12:01
bonjour, peux-tu utiliser les balises de code quand tu partages du code?
https://codes-sources.commentcamarche.net/faq/11288-les-balises-de-code
0
Erreur de débutant, j'ai pris note, merci
0
yg_be Messages postés 22719 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024 1 476
Modifié le 2 juin 2020 à 12:33
je ne sais pas ce que tu penses en écrivant "en faisant une boucle dans ma requête".

ce que tu peux faire, par exemple, c'est ceci, à partir du recordset rsCandidats:
dim popjury as integer, jurynum as integer
popjury=0
jurynum=1
Do Until rsCandidats.EOF
    cursor = cursor  + 1 
    popjury=popjury+1
    if popjury > 250 then
          popjury=1
          jurynum=jurynum+1
    end if
    rsCandidats.Edit
    rsCandidats!NUMERO_ORDRE = cursor
    rsCandidats!JURY = jurynum
    rsCandidats.Update
    rsCandidats.MoveNext
Loop
0
Déjà merci pour ton intervention, j'entends par là la possibilité de faire un update de plusieurs candidats à la fois au lieu de faire une requête à la fois et la répéter tel que c'est fait dans mon code.

rsCandidats 
contient n enregistrements, je dois faire un update de ces candidats mais en bloc de 250. Du 1er au 250ème enrégistrement, NUMERO_ORDRE va aller de 1 à 250 et c'est un numéro de jury; du 251ème au 500ème NUMERO_ORDRE va de 1 à 250 et le numéro de jury incrémente, ainsi de suite.

Plus concrètement, disons que
rsCandidats 
a 600 lignes :
- De 1 à 250 : NUMERO_ORDRE de 1 à 250 et
JURY = JURY + 1 
;
- De 250 à 500 : NUMERO_ORDRE de 1 à 250 et
JURY = JURY + 1 
;
- De 501 à 600 : NUMERO_ORDRE de 1 à 100 et
JURY = JURY + 1 
.
J'aimerais donc ne pouvoir faire que 3 requêtes pour chacun de ces cas, ce de façon générique, étant donné que le nombre d'enregistrements de
rsCandidats 
varie.

Merci.
0
yg_be Messages postés 22719 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024 1 476 > V1ck1ng
2 juin 2020 à 15:02
as-tu essayé ma suggestion?
0
yg_be Messages postés 22719 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024 1 476 > V1ck1ng
2 juin 2020 à 15:03
ton code ne fait pas ce que tu décris, car tu incrémentes toujours cursor.
0
V1ck1ng > yg_be Messages postés 22719 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024
2 juin 2020 à 15:33
Oui tu as raison désolé, dans mon exemple NUMERO_ORDRE dans mon exemple va aller de 1 à 500, c'est JURY qui va incrémenter pour chaque 250 lignes. Ceci dit, je vais implémenter ta suggestion et te revenir. Merci
0
Ce bout de code est parfait ! le contrôle sur le popjury et la petite astuce de retour à 1 du même popjury resolvent mon problème de bloc de 250. Merci beaucoup yg_be ! Merci pour la promptitude et la disponibilité !
0