Accueil
» Conseils PC
»
Accélérez les macros Calc en lisant et en écrivant des données par lots.
Accélérez les macros Calc en lisant et en écrivant des données par lots.
Pour accélérer efficacement une macro Calc lente, la méthode la plus fiable consiste à remplacer les lectures et écritures cellule par cellule répétées par une lecture de plage, une boucle en mémoire et une écriture de plage. Cela réduit les appels entre Basic et Calc ; toutefois, le gain de vitesse n’est pas garanti, car les formules, la mise en forme, la taille du fichier et la logique de la macro peuvent également impacter fortement le temps d’exécution. L’exemple ci-dessous modifie une colonne d’état et montre comment mesurer à la fois la vitesse et l’exactitude. Les détails de l’API ont été vérifiés par rapport à la documentation de LibreOffice 26.8 le 9 octobre 2026.
Que faudrait-il améliorer, et comment le mesurerez-vous ?
Exécutez la macro actuelle sur une copie du classeur et notez le temps d'exécution. Utilisez une copie vierge avec les mêmes données initiales pour les anciennes et nouvelles macros, ou restaurez les données d'entrée entre les exécutions ; sinon, la seconde exécution risque d'être moins productive. Conservez le nombre de lignes, les paramètres de calcul et les conditions de sortie identiques. Répétez chaque exécution et comparez le temps d'exécution moyen plutôt que de vous fier à une exécution exceptionnellement rapide. Vérifiez que le résultat correspond à la règle attendue. Une macro qui s'exécute plus rapidement mais modifie les mauvaises lignes ne constitue pas une amélioration.
La fonction de LibreOffice Basic Timercalcule le nombre de secondes écoulées depuis minuit ; assignez-la à Longdes variables pour obtenir des secondes numériques. Pour une courte durée, enregistrez une valeur de début et une valeur de fin, puis soustrayez-les. Si la valeur de fin est inférieure, la durée a dépassé minuit ; ajoutez donc 86 400 secondes à la différence. Le minuteur mesure les secondes entières ; utilisez le ScriptForgeservice Timer pour une précision à la milliseconde. Consultez la documentation du minuteur de LibreOffice Basic et celle du service Timer de ScriptForge . Évitez d’ouvrir, d’enregistrer ou de consulter manuellement un classeur en dehors de l’intervalle de mesure, sauf si ces opérations font partie intégrante de la tâche.
Commencez par utiliser la même plage de données contiguës et les mêmes conditions de classeur pour chaque exécution de chronométrage.
Pourquoi les macros Calc volumineuses ralentissent-elles ?
Une boucle qui appelle getCellByPosition()ou lit et écrit les propriétés de chaque cellule de manière répétée sollicite l'interface Basic-to-Calc pour chaque opération. Avec un grand nombre de lignes et de colonnes, ces appels peuvent s'accumuler même si la transformation est simple. Une boucle sur un tableau en mémoire parcourt également chaque ligne, mais évite un appel distinct à l'API de cellule pour chaque valeur.
Commencez par supprimer les opérations sans incidence sur le résultat : évitez de sélectionner ou d’activer des cellules à l’intérieur de la boucle, ne recalculez ni ne formatez une cellule de manière répétée lorsqu’une seule opération sur la plage suffit, et ne traitez pas des colonnes entières si seul un bloc de données délimité est nécessaire. Ces modifications permettent d’identifier le véritable goulot d’étranglement avant d’ajouter d’autres contrôles.
Comment traiter une plage comme un tableau ?
Utilisez une plage rectangulaire contenant uniquement les valeurs que votre macro souhaite modifier. L'exemple suppose une feuille nommée « Feuille » Data, une ligne d'en-tête en première ligne et des valeurs d'état en colonne C. Adaptez le nom de la feuille et la plage à votre classeur. L'API getDataArray()renvoie la plage sous forme de lignes contenant des valeurs ; setDataArray()elle réécrit un tableau de même taille dans cette plage.
Lire la plage rectangulaire nécessaire une seule fois avant la boucle en mémoire.
Sub UpdateStatuses
Dim oSheet As Object
Dim oRange As Object
Dim aData As Variant
Dim i As Long
oSheet = ThisComponent.Sheets.getByName("Data")
oRange = oSheet.getCellRangeByName("A2:C10001")
aData = oRange.getDataArray()
For i = LBound(aData) To UBound(aData)
If aData(i)(2) = "pending" Then
aData(i)(2) = "review"
End If
Next i
oRange.setDataArray(aData)
End Sub
Le tableau de lignes est indexé à partir de zéro : aData(i)(2)il cible la troisième colonne de chaque ligne. Ici, il s’agit de la colonne C, car la plage sélectionnée commence à A. La séquence externe du tableau représente les lignes et chaque séquence interne représente les colonnes. La plage transmise setDataArray()doit avoir les mêmes dimensions que le tableau ; toute incompatibilité génère une erreur. Consultez la documentation de l’API LibreOffice XCellRangeData et la documentation sur les tableaux de LibreOffice ScriptForge .
Appliquez la règle en mémoire, puis écrivez le tableau complété dans Calc en un seul appel.
Évitez d'inclure les cellules contenant des formules dans une mise à jour contenant uniquement des valeurs.
getDataArray()Renvoie les valeurs des cellules sous forme de nombres ou de chaînes de caractères, et non le texte de la formule d'origine. Si vous lisez une plage contenant des formules et que vous réécrivez ce tableau avec `XCellRangeFormula` setDataArray(), ces formules peuvent être remplacées par leurs résultats actuels. Limitez la méthode de tableau de valeurs aux cellules d'entrée/sortie qui doivent contenir des valeurs. Lorsqu'une macro doit préserver ou modifier des formules, utilisez les méthodes de tableau de formules ` XCellRangeFormula` getFormulaArray()et `XCellRangeFormula` setFormulaArray(), ou travaillez uniquement sur la plage ne contenant pas de formules. La documentation de l'API `XCellRangeFormula` décrit cette interface distincte.
Quand faut-il modifier les paramètres de calcul ou d'affichage ?
Ne testez ces options qu'après avoir mesuré la version du tableau. Si le recalcul des formules représente une part importante du temps d'exécution, vous pouvez interroger le système isAutomaticCalculationEnabled(), désactiver temporairement le calcul automatique enableAutomaticCalculation(False), puis rétablir le paramètre d'origine et recalculer les cellules modifiées si nécessaire. Placez la restauration dans un chemin de nettoyage afin qu'une erreur ne laisse pas le classeur en mode de calcul manuel. Ne désactivez pas le calcul si la macro a besoin de résultats de formules actualisés entre les étapes. LibreOffice indique calculate()que le recalcul des cellules modifiées calculateAll()entraîne un recalcul complet, ce qui peut s'avérer coûteux. Consultez la documentation de l'API XCalculatable .
lockControllers()Il est possible de suspendre certaines notifications utilisées pour les mises à jour d'affichage pendant qu'une macro modifie de nombreuses cellules. Associez systématiquement un verrouillage unlockControllers(), même lorsque la macro se termine par un gestionnaire d'erreurs. Cela réduit la charge de travail liée aux mises à jour d'affichage ; le calcul des formules n'est pas désactivé et le traitement par cellule n'est pas regroupé. Utilisez cette fonctionnalité pour limiter les goulots d'étranglement liés au rafraîchissement de l'écran, et non comme alternative aux tableaux de plages. Consultez la documentation de l'API XModel .
Comment vérifier le changement et savoir quand changer de méthode ?
Exécutez la macro modifiée sur une copie du classeur et notez son temps d'exécution dans les mêmes conditions que la version de référence. Comparez les lignes affectées, les lignes non affectées, les formules et les totaux clés. Enregistrez, fermez et rouvrez la copie si votre flux de production inclut des sauvegardes ; cela peut révéler des problèmes qui échappent à une vérification visuelle rapide. Une amélioration stable devrait apparaître lors d'exécutions répétées, tant que les contrôles de sortie restent concluants.
Vérifiez les valeurs transformées et enregistrez les temps mesurés sans supposer d'accélération à l'avance.
Si la macro passe encore la majeure partie de son temps à traiter des formules complexes, à effectuer une mise en forme, des entrées/sorties de fichiers ou à trier des données, analysez cette étape séparément ; les tableaux de plages ne font que réduire les accès répétés aux cellules. Pour les feuilles de calcul très volumineuses, un tableau entièrement en mémoire peut également consommer une quantité importante de mémoire. Traitez quelques colonnes à la fois ou divisez les lignes en blocs de taille définie si la pression sur la mémoire augmente, en vérifiant que chaque bloc commence et se termine sur les lignes souhaitées. Si les données se trouvent déjà dans une base de données et que la tâche consiste à filtrer, regrouper ou mettre à jour des enregistrements, il peut être plus judicieux d'effectuer cette opération via une requête de base de données plutôt que de charger chaque enregistrement dans Calc.