Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Apprendre Traitement Efficace des Données | Travail Avec Les Données Excel
VBA Excel Pour l'Automatisation des Entreprises

Traitement Efficace des Données

Glissez pour afficher le menu

Jusqu'à présent, tout a été traité cellule par cellule — suffisant pour cinq commandes, extrêmement lent pour cinquante mille. La solution consiste à ne plus manipuler la feuille cellule par cellule, mais à transférer tout le bloc dans un tableau en mémoire, à y effectuer les traitements, puis à le réécrire en une seule opération.

Lecture d'une plage dans un tableau

Dim dataArr As Variant
dataArr = ws.Range("A2:I6").Value    ' one read, not 45 individual reads

dataArr est désormais un tableau 2D en mémoire : dataArr(1,1) correspond à ORD1001, dataArr(1,4) à "Laptop Stand", etc. — les tableaux VBA lus depuis une plage sont indexés à partir de 1, et non de 0, ce qui est une source fréquente d'erreur.

Traitement du tableau

S'effectue avec des boucles classiques — mais cette fois, la boucle s'effectue en mémoire, ce qui est des milliers de fois plus rapide que de boucler sur la feuille de calcul :

Dim i As Long
Dim recalculated As Double
 
For i = 1 To UBound(dataArr, 1)
    recalculated = dataArr(i, 5) * dataArr(i, 6) * (1 - dataArr(i, 7))
    If Abs(recalculated - dataArr(i, 8)) > 0.01 Then
        Debug.Print "Mismatch on row " & i & ": sheet says " & dataArr(i, 8) & _
                    ", recalculated " & Format(recalculated, "0.00")
    End If
Next i

Réécriture du tableau

Là encore, une seule opération :

ws.Range("A2:I6").Value = dataArr

Éviter Select et Activate

Les macros enregistrées s'appuient fortement sur ces commandes (Range("A1").Select puis Selection.Font.Bold = True), mais elles sont inutiles et lentes — chaque .Select force Excel à redessiner l'écran. Référencez directement la plage ou l'objet à la place :

' Avoid:
ws.Range("A1").Select
Selection.Font.Bold = True
 
' Prefer:
ws.Range("A1").Font.Bold = True

Considérations de performance

Ces aspects deviennent importants dès que vos données dépassent quelques centaines de lignes :

Application.ScreenUpdating = False   ' stop redrawing while the macro runs
Application.Calculation = xlCalculationManual   ' pause recalculation
Application.EnableEvents = False     ' suppress other macros triggering mid-run
 
' ... your fast array-based code here ...
 
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True

Toujours restaurer ces paramètres à la fin — et encapsuler la restauration dans une gestion d'erreur pour éviter qu'un plantage en cours d'exécution ne laisse Excel avec l'affichage désactivé.

Exemple pratique : le vérificateur d'intégrité des commandes

Ce chapitre aboutit à ceci :

Option Explicit
 
Sub VerifyOrderTotals()
    Dim ws As Worksheet
    Dim dataArr As Variant
    Dim lastRow As Long
    Dim i As Long
    Dim recalculated As Double
    Dim issues As String
 
    Set ws = ThisWorkbook.Worksheets("Orders")
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
 
    Application.ScreenUpdating = False
 
    dataArr = ws.Range("A2:I" & lastRow).Value
    issues = ""
 
    For i = 1 To UBound(dataArr, 1)
        recalculated = dataArr(i, 5) * dataArr(i, 6) * (1 - dataArr(i, 7))
        If Abs(recalculated - dataArr(i, 8)) > 0.01 Then
            issues = issues & dataArr(i, 1) & ": sheet=" & dataArr(i, 8) & _
                      ", expected=" & Format(recalculated, "0.00") & vbNewLine
        End If
    Next i
 
    Application.ScreenUpdating = True
 
    If issues = "" Then
        MsgBox "All " & UBound(dataArr, 1) & " order totals check out."
    Else
        MsgBox "Discrepancies found:" & vbNewLine & issues
    End If
End Sub

Exécutez ce code sur la table d'exemple et il devrait indiquer que les cinq totaux sont corrects — essayez de modifier le Total de ORD1002 dans la feuille avec une valeur erronée puis relancez pour voir l'alerte s'afficher.

Tâche

  1. Copier VerifyOrderTotals dans votre classeur et l'exécuter sur les cinq commandes d'exemple.
  2. Modifier manuellement le Total d'une commande sur la feuille (saisir une valeur manifestement incorrecte) puis relancer — vérifier que l'écart est bien signalé avec le bon Order ID.
  3. Ajouter dix lignes supplémentaires de commandes fictives sous la ligne 6, et vérifier que la macro fonctionne toujours sans modification du code — c'est l'intérêt de lastRow et du traitement par tableau.
Assistant
expand arrow

Assistant facultatif si vous préférez générer les dix lignes supplémentaires en code plutôt que de les saisir manuellement :

Sub AddTestOrders()
    Dim ws As Worksheet
    Dim i As Long
    Dim r As Long

    Set ws = ThisWorkbook.Worksheets("Orders")
    r = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1

    For i = 1 To 10
        ws.Cells(r, 1).Value = "ORD" & (1005 + i)
        ws.Cells(r, 2).Value = Date
        ws.Cells(r, 3).Value = "Test Customer " & i
        ws.Cells(r, 4).Value = "Sample Product"
        ws.Cells(r, 5).Value = i
        ws.Cells(r, 6).Value = 20 + i
        ws.Cells(r, 7).Value = 0.05
        ws.Cells(r, 8).Value = i * (20 + i) * (1 - 0.05)
        ws.Cells(r, 9).Value = "Pending"
        r = r + 1
    Next i
End Sub
Astuce
expand arrow

1. Copier VerifyOrderTotals

  • Saisir la procédure Sub exactement comme présentée dans la section 3.5 dans le module de votre classeur — aucune modification nécessaire pour l’instant.
  • Exécuter une fois sur les cinq lignes d’origine et vérifier que vous obtenez « All 5 order totals check out. »

2. Modifier volontairement un Total

  • Choisir la cellule Total de n’importe quelle commande et saisir un nombre manifestement incorrect directement dans la feuille (pas via le code).
  • Relancer la même procédure Sub — le message d’erreur doit indiquer précisément l’ID de la commande concernée, ainsi que la valeur présente dans la feuille et celle recalculée par la macro.
  • Corriger la cellule ensuite si vous souhaitez une feuille propre pour l’étape suivante.

3. Ajouter dix lignes supplémentaires

  • Saisir simplement de nouvelles données de commande directement dans les lignes 7 à 16 — mêmes neuf colonnes, valeurs plausibles au choix.
  • Ne pas toucher à la macro. lastRow se recalcule à chaque exécution du Sub, et la lecture du tableau (ws.Range("A2:I" & lastRow).Value) s’ajuste automatiquement — c’est tout l’intérêt de la démonstration.
Solution
expand arrow
Option Explicit

Sub VerifyOrderTotals()
    Dim ws As Worksheet
    Dim dataArr As Variant
    Dim lastRow As Long
    Dim i As Long
    Dim recalculated As Double
    Dim issues As String

    Set ws = ThisWorkbook.Worksheets("Orders")
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row

    Application.ScreenUpdating = False

    dataArr = ws.Range("A2:I" & lastRow).Value
    issues = ""

    For i = 1 To UBound(dataArr, 1)
        recalculated = dataArr(i, 5) * dataArr(i, 6) * (1 - dataArr(i, 7))
        If Abs(recalculated - dataArr(i, 8)) > 0.01 Then
            issues = issues & dataArr(i, 1) & ": sheet=" & dataArr(i, 8) & _
                      ", expected=" & Format(recalculated, "0.00") & vbNewLine
        End If
    Next i

    Application.ScreenUpdating = True

    If issues = "" Then
        MsgBox "All " & UBound(dataArr, 1) & " order totals check out."
    Else
        MsgBox "Discrepancies found:" & vbNewLine & issues
    End If
End Sub
Tout était clair ?

Comment pouvons-nous l'améliorer ?

Merci pour vos commentaires !

Section 3. Chapitre 5

Demandez à l'IA

expand

Demandez à l'IA

ChatGPT

Posez n'importe quelle question ou essayez l'une des questions suggérées pour commencer notre discussion

Section 3. Chapitre 5
some-alt