SIG DCG (UE8) : Tableur, audit de feuille et programmation

Tout le programme DCG, déjà prêt à réviser

Fiches, quiz, flashcards et infographies déjà créés, avec un tuteur IA. Paiement unique, dès 29 €.

Voir les packs DCG

Programmer dans le tableur (VBA) : les boucles et les programmes de gestion complets

À retenir

Cadre programme : DCG, programme 2025 (arrêté du 4 août 2025, première session 2027), UE 8 « Systèmes d'information de gestion », partie 2 « Gérer des données du système d'information », sous-partie 2.2.3 « Mettre en œuvre des programmes au sein du tableur » (exécuter, modifier ou compléter le code d'une macro-commande, fonction ou procédure ; familles d'instructions : affectation, entrée, calcul, cumul et sortie, tests, boucles (structures itératives)). Le programme limite l'étude à des programmes simples, avec les objets fondamentaux, sans classe personnalisée, sans application complexe ni optimisation avancée.

Pourquoi c'est central à l'examen : traiter une liste de clients, de factures ou de ventes, ligne après ligne, est le cas type d'un programme de gestion : relances, commissions, totaux conditionnels. Le candidat doit pouvoir dérouler une boucle à la main (tableau de suivi des variables), la corriger et compléter des lignes manquantes. Cette fiche s'appuie sur les cours 32 (variables, affectation, objets) et 33 (tests).

À retenir

Rappel de cadrage : le programme ne demande ni pseudo-code ni algorithmique abstraite : tout est écrit dans le langage de macros du tableur (VBA).

01Pourquoi des boucles

Une boucle (structure itérative) répète un bloc d'instructions. Sans boucle, traiter 12 ventes demande 12 fois la même ligne, et le programme ne s'adapte pas à une 13e vente. Avec une boucle, le même bloc traite une liste de n'importe quelle longueur.

BoucleQuand l'utiliser
For ... NextLe nombre de passages est connu (ligne 2 à ligne 13)
Do While ... LoopOn répète tant que une condition est vraie (tant que la cellule n'est pas vide)
Do Until ... LoopOn répète jusqu'à ce que une condition devienne vraie
For Each ... NextOn parcourt chaque élément d'une plage ou d'une collection

02La boucle For ... Next

For i = 2 To 13
    ' instructions répétées pour i = 2, 3, ..., 13
Next i
ÉlémentRôle
iLe compteur (variable de type Long)
2 To 13Valeur de départ et valeur finale, incluse
StepPas d'incrémentation (1 par défaut) : For i = 10 To 1 Step -3 donne 10, 7, 4, 1
Next iFin de boucle : le compteur passe à la valeur suivante

Points à connaître :

  • si la valeur de départ dépasse la valeur finale (avec un pas positif), la boucle ne s'exécute jamais ;
  • on ne modifie pas le compteur à l'intérieur de la boucle ;
  • après la boucle, le compteur vaut la valeur finale plus un pas (ici 14) ;
  • on lit une cellule dont la ligne varie avec Cells(i, 4), ligne i, colonne 4 (cours 32).

Exit For quitte la boucle immédiatement (par exemple dès que l'élément cherché est trouvé).

03Les boucles Do ... Loop

3.1 Test avant : Do While et Do Until

Do While ws.Cells(ligne, 1).Value <> ""     ' tant que la cellule de la colonne A n'est pas vide
    ' traitement de la ligne
    ligne = ligne + 1                        ' ne pas oublier d'avancer
Loop

Do Until condition répète jusqu'à ce que la condition devienne vraie : Do Until ws.Cells(ligne, 1).Value = "" est équivalent à la boucle précédente.

Le test est fait avant chaque passage : si la condition est fausse d'emblée (liste vide), la boucle ne s'exécute pas.

3.2 Test après : Loop While et Loop Until

Do
    ' instructions
Loop Until condition

Le bloc s'exécute au moins une fois, puis le test décide de recommencer. Utile pour redemander une saisie tant qu'elle est invalide.

3.3 Le danger de la boucle infinie

Une boucle Do dont la condition ne devient jamais fausse ne s'arrête pas. La cause la plus fréquente : oublier de faire avancer la variable testée (ligne = ligne + 1). On interrompt alors l'exécution par la touche d'interruption du clavier (variable selon les systèmes), au prix d'un classeur qui ne répond plus un instant. D'où la règle : avant d'exécuter, vérifier que la condition d'arrêt finira par être atteinte.

04Parcourir une liste

4.1 Jusqu'à la première cellule vide

C'est la méthode la plus courante : on avance ligne par ligne tant que la première colonne contient quelque chose.

ligne = 2                                       ' la ligne 1 porte les en-têtes
Do While ws.Cells(ligne, 1).Value <> ""
    ' ... traitement de la ligne
    ligne = ligne + 1
Loop

Condition : la liste ne comporte aucune cellule vide au milieu ; sinon la boucle s'arrête trop tôt.

4.2 Avec For Each

For Each cel In Range("B2:B6")
    ' cel représente tour à tour B2, B3, ..., B6
Next cel

La variable cel est de type Range (un objet). Pour atteindre la cellule voisine, on utilise cel.Offset(décalage_de_lignes, décalage_de_colonnes) : cel.Offset(0, 1) est la cellule à droite, cel.Offset(0, -1) celle de gauche.

4.3 Trouver la dernière ligne

Variante, pour appliquer un For ... Next à une liste de longueur inconnue : derniere = Cells(Rows.Count, 1).End(xlUp).Row donne le numéro de la dernière ligne remplie de la colonne A. On écrit alors For i = 2 To derniere.

05Les schémas de traitement

Presque tous les programmes de gestion reprennent les mêmes motifs. Chacun repose sur une initialisation avant la boucle et une mise à jour dans la boucle.

MotifAvant la boucleDans la boucleAprès la boucle
Cumul (somme)total = 0total = total + valeurUtiliser total
Compteurnb = 0nb = nb + 1 (souvent sous condition)Utiliser nb
Maximummaxi = première valeur (ou une valeur très petite)If valeur > maxi Then maxi = valeurUtiliser maxi
Minimummini = première valeurIf valeur < mini Then mini = valeurUtiliser mini
MoyenneCumul et compteurLes deux motifs ci-dessusmoyenne = total / nb, si nb > 0
Recherchetrouve = FalseIf condition Then trouve = True : Exit ForTester trouve

Deux erreurs classiques : oublier l'initialisation (un cumul qui doit repartir de zéro plusieurs fois, ou une variable déclarée en tête de module, garde son ancienne valeur ; un maximum laissé à 0 se révèle faux sur des valeurs négatives) et diviser par un compteur nul pour une moyenne.

06La structure d'un programme de gestion complet

  1. Déclarations (Dim) avec les types et des commentaires.
  2. Entrées et initialisations : lecture des paramètres (date de référence, taux), mise à zéro des cumuls et compteurs.
  3. Boucle de traitement : lecture de la ligne, tests, calculs, écriture du résultat, cumuls.
  4. Sorties : message récapitulatif, écriture des totaux.

Pour interpréter un programme à l'écrit, on construit un tableau de suivi : une colonne par variable, une ligne par passage dans la boucle, en recopiant les valeurs après chaque instruction qui les modifie.

Exemples corrigés

Cas 1 : For ... Next : total, compteur, maximum et moyenne

La feuille Ventes contient 12 montants en D2:D13 (ceux du cours 26).

Option Explicit

Sub AnalyserVentes()
    ' Parcourt les ventes de la ligne 2 à la ligne 13 de la feuille Ventes
    Dim ws As Worksheet
    Dim i As Long               ' compteur de la boucle : numéro de ligne
    Dim total As Double         ' cumul des montants
    Dim nbVentes As Long        ' nombre de ventes lues
    Dim nbGrosses As Long       ' nombre de ventes d'au moins 5000
    Dim maxi As Double          ' plus grande vente

    Set ws = Worksheets("Ventes")
    total = 0
    nbVentes = 0
    nbGrosses = 0
    maxi = ws.Range("D2").Value         ' le maximum démarre avec la première valeur

    For i = 2 To 13
        total = total + ws.Cells(i, 4).Value        ' cumul
        nbVentes = nbVentes + 1                     ' compteur
        If ws.Cells(i, 4).Value >= 5000 Then
            nbGrosses = nbGrosses + 1               ' compteur conditionnel
        End If
        If ws.Cells(i, 4).Value > maxi Then
            maxi = ws.Cells(i, 4).Value             ' mise à jour du maximum
        End If
    Next i

    ws.Range("F2").Value = total
    If nbVentes > 0 Then
        MsgBox "Total : " & total & " ; moyenne : " & total / nbVentes & _
               " ; ventes d'au moins 5000 : " & nbGrosses & " ; plus grande vente : " & maxi
    End If
End Sub

Tableau de suivi (valeurs après chaque passage) :

iMontant lutotalnbVentesnbGrossesmaxi
(avant)
0004 200
24 2004 200104 200
31 3505 550204 200
46 80012 350316 800
52 15014 500416 800
63 90018 400516 800
790019 300616 800
85 40024 700726 800
92 60027 300826 800
101 75029 050926 800
117 30036 3501037 300
121 20037 5501137 300
133 10040 6501237 300

Sorties : F2 contient 40 650 ; le message affiche « Total : 40650 ; moyenne : 3387,5 ; ventes d'au moins 5000 : 3 ; plus grande vente : 7300 » (40 650 / 12 = 3 387,5, avec la virgule décimale de la configuration française). Après la boucle, i vaut 14.

Les trois ventes d'au moins 5 000 sont celles des lignes 4, 8 et 11, comme le calcul de NB.SI du cours 26.

À retenir

Conclusion à destination du responsable du contrôle de gestion : le programme retrouve les valeurs obtenues par formule (total de 40 650, trois ventes de plus de 5 000). Il est cependant limité aux lignes 2 à 13 : si une 13e vente est ajoutée, elle n'est pas lue. Pour une liste qui s'allonge, on remplace la borne 13 par la dernière ligne remplie (4.3) ou on utilise la boucle jusqu'à la première cellule vide (cas 2).

Cas 2 : Do While jusqu'à la première cellule vide : relances de factures

La feuille Factures contient (ligne 1 : en-têtes ; en G1 la date de référence du 01/10/2026) :

LigneA ClientB ÉchéanceC Montant TTC
2Dupont SA15/08/20262 400,00
3Martin SARL20/09/20261 150,50
4Leroy et Fils05/07/20263 600,00
5Garnier SAS10/10/2026980,00
6Petit SA28/08/2026450,00
7Moreau SA01/09/20261 800,00

Règle : retard = date de référence moins échéance ; pas de relance si le retard est nul ou négatif ; Relance 1 jusqu'à 30 jours de retard inclus, Relance 2 de 31 à 60 jours inclus, Mise en demeure au-delà. Le programme écrit le retard en colonne D et le niveau en colonne E, puis affiche un récapitulatif.

Option Explicit

Sub RelancerClients()
    ' Parcourt la liste des factures jusqu'à la première cellule vide de la colonne A,
    ' calcule le retard et le niveau de relance de chaque facture
    Dim ws As Worksheet
    Dim ligne As Long               ' numéro de la ligne en cours
    Dim dateRef As Date             ' date d'arrêté lue dans G1
    Dim retard As Long              ' retard en jours
    Dim nbRelances As Long          ' nombre de factures à relancer
    Dim totalRelance As Double      ' montant TTC à relancer
    Dim retardMax As Long           ' plus grand retard rencontré
    Dim clientMax As String         ' client concerné par ce retard

    Set ws = Worksheets("Factures")
    dateRef = ws.Range("G1").Value
    ligne = 2                       ' la ligne 1 contient les en-têtes
    nbRelances = 0
    totalRelance = 0
    retardMax = 0
    clientMax = ""

    Do While ws.Cells(ligne, 1).Value <> ""
        retard = dateRef - ws.Cells(ligne, 2).Value        ' retard en jours
        If retard <= 0 Then
            ws.Cells(ligne, 4).Value = 0
            ws.Cells(ligne, 5).Value = "Non échue"
        Else
            ws.Cells(ligne, 4).Value = retard
            If retard <= 30 Then
                ws.Cells(ligne, 5).Value = "Relance 1"
            ElseIf retard <= 60 Then
                ws.Cells(ligne, 5).Value = "Relance 2"
            Else
                ws.Cells(ligne, 5).Value = "Mise en demeure"
            End If
            nbRelances = nbRelances + 1                                    ' compteur
            totalRelance = totalRelance + ws.Cells(ligne, 3).Value         ' cumul
            If retard > retardMax Then                                     ' maximum
                retardMax = retard
                clientMax = ws.Cells(ligne, 1).Value
            End If
        End If
        ligne = ligne + 1                                                  ' passage à la ligne suivante
    Loop

    MsgBox nbRelances & " facture(s) à relancer pour " & totalRelance & _
           " euros. Plus grand retard : " & retardMax & " jours (" & clientMax & ")."
End Sub

Tableau de suivi :

ligneClientRetard (jours)Niveau écrit en EnbRelancestotalRelanceretardMaxclientMax
(avant)
000(vide)
2Dupont SA47Relance 212 40047Dupont SA
3Martin SARL11Relance 123 550,547Dupont SA
4Leroy et Fils88Mise en demeure37 150,588Leroy et Fils
5Garnier SAS-9 (écrit 0)Non échue37 150,588Leroy et Fils
6Petit SA34Relance 247 600,588Leroy et Fils
7Moreau SA30Relance 159 400,588Leroy et Fils
8(cellule vide)
La boucle s'arrête

Détail des retards au 01/10/2026 : du 15/08 au 01/10, 16 + 30 + 1 = 47 jours ; du 05/07, 26 + 31 + 30 + 1 = 88 jours ; du 28/08, 3 + 30 + 1 = 34 jours ; du 01/09, 30 jours (borne : retard <= 30, donc Relance 1) ; la facture de Garnier SAS n'est échue que le 10/10/2026 (retard de -9 jours).

Sortie : « 5 facture(s) à relancer pour 9400,5 euros. Plus grand retard : 88 jours (Leroy et Fils). » Le montant s'affiche avec la virgule décimale de la configuration française.

Si la ligne ligne = ligne + 1 est oubliée, la condition du Do While reste vraie : le programme traite indéfiniment la ligne 2 (boucle infinie).

À retenir

Conclusion à destination du responsable du recouvrement : cinq factures sur six sont échues, pour 9 400,50 € TTC. La facture de Leroy et Fils (3 600 € à 88 jours) justifie une mise en demeure ; celles de Dupont SA et de Petit SA relèvent d'une deuxième relance. La facture de Moreau SA, à 30 jours exactement, reste en première relance : la borne a été fixée par l'énoncé (« jusqu'à 30 jours inclus »). Le programme est reproductible tant que la date de référence est lue dans G1, et il s'adapte à toute longueur de liste.

Cas 3 : For Each : commissions et meilleur vendeur

La feuille active contient en colonne A les noms, en colonne B le chiffre d'affaires des vendeurs (lignes 2 à 6) :

LigneAB
2Durand16 750
3Martin12 750
4Leroy11 150
5Garnier7 900
6Petit8 000

Barème : 2 % en dessous de 8 000 ; 3 % à partir de 8 000 jusqu'à 14 000 exclus ; 4 % à partir de 14 000. La commission est arrondie à deux décimales et écrite en colonne C.

Option Explicit

Sub CalculerCommissions()
    ' Calcule la commission de chaque vendeur et repère le meilleur chiffre d'affaires
    Const SEUIL_1 As Double = 8000     ' début de la tranche à 3 %
    Const SEUIL_2 As Double = 14000    ' début de la tranche à 4 %

    Dim cel As Range                   ' cellule en cours dans la plage parcourue
    Dim taux As Double
    Dim commission As Double
    Dim totalCommissions As Double
    Dim caMax As Double
    Dim meilleur As String

    totalCommissions = 0
    caMax = 0
    meilleur = ""

    For Each cel In Range("B2:B6")                 ' chaque cellule de la colonne B
        If cel.Value < SEUIL_1 Then
            taux = 0.02
        ElseIf cel.Value < SEUIL_2 Then
            taux = 0.03
        Else
            taux = 0.04
        End If
        commission = Round(cel.Value * taux, 2)
        cel.Offset(0, 1).Value = commission         ' écrit dans la colonne C, même ligne
        totalCommissions = totalCommissions + commission
        If cel.Value > caMax Then
            caMax = cel.Value
            meilleur = cel.Offset(0, -1).Value      ' nom lu dans la colonne A
        End If
    Next cel

    MsgBox "Total des commissions : " & totalCommissions & " euros. Meilleur chiffre d'affaires : " & meilleur
End Sub

Tableau de suivi :

celValeurTauxcommission (écrite en C)totalCommissionscaMaxmeilleur
(avant)
00(vide)
B216 7504 %67067016 750Durand
B312 7503 %382,51 052,516 750Durand
B411 1503 %334,51 38716 750Durand
B57 9002 %1581 54516 750Durand
B68 0003 %2401 78516 750Durand

Sortie : « Total des commissions : 1785 euros. Meilleur chiffre d'affaires : Durand ». Le chiffre d'affaires de 8 000 (borne) tombe dans la tranche à 3 %, parce que le test est < SEUIL_1.

Point d'attention : la fonction Round du langage arrondit « au pair » lorsque la décimale est exactement 5 (cours 32) ; les montants de ce cas ne tombent pas sur un demi-centime, donc le résultat est le même qu'avec ARRONDI du tableur.

À retenir

Conclusion à destination de la direction commerciale : la commission totale de 1 785 € est identique à celle d'un calcul manuel (670 + 382,50 + 334,50 + 158 + 240). Le vendeur à 8 000 € gagne 240 € alors qu'un euro de moins lui aurait rapporté environ 160 €, soit 80 € d'écart pour un euro de chiffre d'affaires : cet effet de seuil est une conséquence du barème par paliers, à rappeler lors de la présentation du dispositif. Les seuils sont déclarés en tête de procédure : si le barème change, on les modifie à cet endroit.

Cas 4 : Do While pilotée par un indicateur : cumul de saisies

On veut cumuler des montants saisis un à un, jusqu'à ce que l'utilisateur tape 0 ou annule ; les saisies non numériques sont ignorées avec un message.

Option Explicit

Sub CumulerSaisies()
    ' Cumule des montants saisis jusqu'à la saisie de 0 ou l'annulation
    Dim saisie As String        ' texte saisi
    Dim total As Double         ' cumul des montants
    Dim nb As Long              ' nombre de montants retenus
    Dim fin As Boolean          ' indicateur d'arrêt de la boucle

    total = 0
    nb = 0
    fin = False

    Do While Not fin
        saisie = InputBox("Montant à ajouter (0 pour terminer) ?")
        If saisie = "" Then
            fin = True                                       ' annulation ou saisie vide
        ElseIf Not IsNumeric(saisie) Then
            MsgBox "Saisie non numérique ignorée."
        ElseIf CDbl(saisie) = 0 Then
            fin = True                                       ' 0 : fin de la saisie
        Else
            total = total + CDbl(saisie)                     ' cumul
            nb = nb + 1                                      ' compteur
        End If
    Loop

    MsgBox nb & " montant(s) saisi(s), total : " & total
End Sub

Suivi sur la série de saisies 120, 45,5, abc, 300, 0 (configuration française) :

SaisieTest vraitotalnbfinEffet
120Else1201FauxMontant retenu
45,5Else165,52FauxMontant retenu
abcNot IsNumeric165,52FauxMessage, aucun cumul
300Else465,53FauxMontant retenu
0CDbl(saisie) = 0465,53VraiLa boucle s'arrête

Sortie : « 3 montant(s) saisi(s), total : 465,5 ».

Le test saisie = "" est placé en premier : CDbl("") provoquerait une erreur. L'ordre des tests (vide, puis numérique, puis valeur zéro) suit les règles du cours 33.

Variante avec test en fin de boucle : Do ... Loop Until fin exécute la saisie au moins une fois avant de tester fin.

À retenir

Conclusion à destination du comptable : la boucle s'arrête sur un événement choisi par l'utilisateur et non sur un nombre de passages connu : c'est le cas où Do s'impose et où For ne convient pas. L'indicateur fin rend la condition d'arrêt lisible ; sans l'affectation fin = True dans les deux cas de sortie, la boucle serait infinie.

Vocabulaire essentiel

TermeDéfinition
Boucle (structure itérative)Instruction qui répète un bloc d'instructions
CompteurVariable qui numérote les passages d'une boucle For
Condition d'arrêtCondition qui met fin à une boucle Do
InitialisationAffectation de la valeur de départ d'un cumul ou d'un compteur avant la boucle
Cumul, compteurVariables qui accumulent une somme, qui comptent des éléments
Boucle infinieBoucle dont la condition d'arrêt n'est jamais atteinte
Tableau de suiviTableau qui note les valeurs des variables à chaque passage
Indicateur (booléen)Variable True ou False qui pilote une boucle ou un test

Points clés à retenir

  1. For ... Next quand le nombre de passages est connu ; Do While ou Do Until quand il dépend d'une condition ; For Each pour parcourir une plage.
  2. La valeur finale d'un For est incluse ; avec un départ supérieur à la fin, la boucle ne s'exécute pas.
  3. Pour une liste de longueur variable, on boucle jusqu'à la première cellule vide.
  4. Il faut toujours faire avancer la variable testée dans une boucle Do : sinon, boucle infinie.
  5. Initialiser avant la boucle : total = 0, nb = 0, maximum à la première valeur.
  6. Une moyenne divise le cumul par le compteur, après avoir vérifié que le compteur n'est pas nul.
  7. Exit For et Exit Do quittent la boucle (utile pour une recherche).
  8. Pour interpréter un programme : tableau de suivi, une ligne par passage.

Pièges fréquents

  1. Oublier ligne = ligne + 1 dans une boucle Do While : le programme ne s'arrête jamais.
  2. Oublier l'initialisation du cumul ou du compteur : sans effet pour une variable déclarée par Dim dans la procédure (elle part de 0), mais faux si le cumul doit repartir de zéro plusieurs fois ou si la variable est déclarée en tête de module (elle garde sa valeur d'une exécution à l'autre).
  3. Initialiser un maximum à 0 : faux dès que toutes les valeurs sont négatives.
  4. Diviser par un compteur nul lors du calcul d'une moyenne.
  5. Une liste avec une cellule vide au milieu : la boucle jusqu'à la première cellule vide s'arrête trop tôt.
  6. Modifier le compteur d'un For à l'intérieur de la boucle.
  7. Une borne 13 écrite en dur dans For i = 2 To 13 : les lignes ajoutées sont ignorées.
  8. Confondre Do While et Do Until : l'un répète tant que la condition est vraie, l'autre jusqu'à ce qu'elle le devienne.

Q&R pour le tuteur IA

Q : Quelle boucle choisir pour parcourir une liste dont on ne connaît pas la longueur ? R : Do While ws.Cells(ligne, 1).Value <> "" : on répète tant que la cellule de la première colonne n'est pas vide, en augmentant ligne à chaque passage. On peut aussi calculer la dernière ligne et utiliser For.

Q : Comment calculer la somme et le maximum d'une colonne dans une boucle ? R : On initialise total = 0 et maxi à la première valeur, puis, dans la boucle, total = total + valeur et If valeur > maxi Then maxi = valeur.

Q : Pourquoi un programme avec Do While peut-il ne jamais s'arrêter ? R : Parce que la variable testée n'est pas modifiée dans la boucle (par exemple on oublie ligne = ligne + 1) : la condition reste vraie à chaque passage. Il faut toujours vérifier que la condition d'arrêt peut être atteinte.

Q : Que vaut le compteur i après For i = 2 To 13 ... Next i ? R : 14, c'est-à-dire la valeur finale plus un pas. Pendant la boucle, il a pris les valeurs de 2 à 13.

Q : Comment éviter une erreur de division dans le calcul d'une moyenne ? R : En testant le compteur avant de diviser : If nb > 0 Then moyenne = total / nb.

Q : Comment dérouler un programme à la main dans une copie d'examen ? R : On dresse un tableau de suivi : une colonne par variable, une ligne par passage dans la boucle, et on recopie la valeur de chaque variable après chaque instruction qui la modifie. On conclut par les sorties (message et cellules écrites).

Tu as lu le cours. Passe maintenant à la pratique :

SIG DCG (UE8) : Tableur, audit de feuille et programmation

Ajoute gratuitement le Kit à ton espace, puis utilise tes jetons pour générer un quiz, créer des flashcards ou poser tes questions au Tuteur IA.

Quiz, flashcards et fiches déjà prêts

Voir les packs DCG