Les macros de LibreOffice Calc ont souvent tendance à ralentir les grandes feuilles de calcul pour une raison simple : elles passent plus de temps à franchir la limite de l’objet UNO qu’à effectuer le calcul proprement dit. Lire une cellule, la modifier et la réécrire des milliers de fois peut s’avérer beaucoup plus coûteux que de déplacer les mêmes données par blocs plus importants.
L'objectif n'est pas de rendre chaque macro « rapide » de manière abstraite. Une optimisation utile doit produire le même résultat, s'exécuter plus rapidement sur le même jeu de données, maintenir la réactivité de Calc pour le flux de travail et éviter de créer de nouveaux problèmes d'exactitude ou de mémoire. Les techniques décrites ci-dessous se concentrent sur ces résultats mesurables.
En octobre 2026, la documentation du kit de développement logiciel (SDK) de LibreOffice mentionnait les interfaces de tableur utilisées dans la référence de l'API LibreOffice 26.8. Les méthodes principales étaient des interfaces UNO classiques et non une nouvelle fonctionnalité d'amélioration des performances.
1. Mesurez la macro avant de la modifier.
Commencez par définir une base de référence reproductible. LibreOffice Basic propose GetSystemTicks()une fonction permettant de mesurer les temps d'exécution du système et d'optimiser les processus. Utilisez cette fonction pour optimiser la partie de la macro que vous souhaitez réellement améliorer, plutôt que de chronométrer l'ouverture du classeur, les invites utilisateur ou toute autre configuration.
Dim t0 As Long, elapsed As Long
t0 = GetSystemTicks()
' Run the work you want to measure here.
elapsed = GetSystemTicks() - t0
MsgBox "Elapsed ticks: " & elapsed
Exécutez la même opération plusieurs fois sur la même copie du fichier. Le premier résultat peut différer en raison des caches du système de fichiers, de l'état des formules ou d'autres opérations ponctuelles. Notez la taille de l'ensemble de données, la plage traitée et si le calcul automatique était activé afin que vos comparaisons restent pertinentes.
Un bon résultat ne se résume pas à un temps d'exécution plus court. Vérifiez que le nombre de lignes, les totaux, les formules, les valeurs textuelles, les dates et les plages de résultats correspondent toujours aux valeurs de référence.
Référence officielle : Aide de LibreOffice : Fonction GetSystemTicks .
2. Supprimez d'abord les lectures et écritures cellule par cellule.
Si une macro parcourt une large plage de cellules et appelle de manière répétée des méthodes telles que getCellByPosition()`move`, c'est généralement le premier endroit à examiner. L'API UNO expose `move` XCellRangeData.getDataArray()et setDataArray()`move` spécifiquement pour déplacer une plage de cellules complète sous forme de tableau.
L'API officielle indique que cette fonction getDataArray()renvoie une séquence de lignes, chaque ligne contenant des colonnes. Les valeurs sont renvoyées sous forme de chaînes de caractères ou de nombres à virgule flottante. setDataArray()Elle réécrit un tableau dans une plage de valeurs, et les dimensions du tableau doivent correspondre à cette plage.
Par exemple, supposons que les colonnes A à E contiennent les données que votre macro transforme. Au lieu de lire chaque cellule individuellement, sélectionnez la plage exacte une seule fois :
Dim doc As Object
Dim sheet As Object
Dim sourceRange As Object
Dim data As Variant
doc = ThisComponent
sheet = doc.Sheets.getByName("Data")
' Example only: A2:E50001.
sourceRange = sheet.getCellRangeByPosition(0, 1, 4, 50000)
data = sourceRange.getDataArray()
Le traitement s'effectue dataen mémoire Basic, puis un tableau de résultats est écrit en une seule opération dans une plage de destination correspondante. Cela réduit considérablement le nombre d'appels UNO par rapport à des milliers de lectures et d'écritures individuelles.
Références officielles : SDK LibreOffice : XCellRangeData et SDK LibreOffice : XCellRange .
3. Ne traitez que les données dont vous avez réellement besoin.
L'accès groupé aux tableaux est utile, mais convertir une feuille de calcul inutilement volumineuse en tableau peut simplement déplacer le goulot d'étranglement vers la mémoire. Évitez de coder en dur des colonnes entières ou la grille Calc complète lorsque la tâche ne concerne qu'une table définie.
Déterminez la dernière ligne pertinente à l'aide des informations déjà présentes dans votre classeur : nombre de lignes importées, taille des résultats de la base de données, colonne clé désignée ou plage créée par l'application. Ensuite, demandez uniquement les lignes et colonnes nécessaires à la macro.
Ceci est particulièrement important lorsque la feuille de calcul contient une mise en forme très en dessous des données réelles ou lorsque d'anciens contenus ont augmenté la surface apparemment utilisée. Les grands tableaux en mémoire consomment de la RAM, et une allocation surdimensionnée peut s'avérer moins performante que le traitement de blocs de taille moyenne.
Quand passer au découpage en blocs
Si un seul tableau provoque une forte augmentation de l'utilisation de la mémoire, de longs délais avant le début du traitement ou approche les limites pratiques de la machine, traitez les données par blocs. Par exemple, traitez plusieurs milliers de lignes, écrivez les résultats, puis passez au bloc suivant. Il n'existe pas de taille de bloc idéale universelle ; effectuez des tests avec le classeur et le matériel utilisés.
4. Suspendre les notifications de mise à jour de l'écran pendant les périodes de forte activité
Un document Calc implémente l'interface de LibreOffice XModel. Sa lockControllers()méthode suspend certaines notifications du contrôleur utilisées pour les mises à jour d'affichage, puis unlockControllers()les reprend. Cela permet de réduire le travail visuel inutile pendant qu'une macro effectue de nombreuses modifications.
Dim doc As Object
doc = ThisComponent
doc.lockControllers()
' Perform bulk changes here.
doc.unlockControllers()
L'API officielle indique clairement que les verrous et déverrouillages des contrôleurs doivent être appariés. Cela signifie que les macros de production doivent inclure une gestion des erreurs garantissant unlockControllers()leur exécution même en cas d'échec du traitement. Laisser le document verrouillé n'optimise pas les performances ; cela compromet le bon déroulement du nettoyage.
Référence officielle : SDK LibreOffice : XModel .
5. Contrôler le recalcul automatique lorsque les formules monopolisent le temps d'exécution
Si la macro modifie fréquemment des cellules alimentant de nombreuses formules, Calc peut passer un temps considérable à recalculer pendant que la macro met encore à jour les valeurs intermédiaires. Le document tableur expose l' XCalculatableinterface, notamment les fonctions ` map`, isAutomaticCalculationEnabled()` filter` et `map` .enableAutomaticCalculation()calculate()calculateAll()
Une méthode plus sûre consiste à mémoriser le mode de calcul actuel de l'utilisateur, à désactiver le calcul automatique uniquement pendant la mise à jour, puis à rétablir l'état initial :
Dim doc As Object
Dim wasAutoCalc As Boolean
doc = ThisComponent
wasAutoCalc = doc.isAutomaticCalculationEnabled()
doc.enableAutomaticCalculation(False)
' Perform bulk updates.
doc.enableAutomaticCalculation(wasAutoCalc)
If wasAutoCalc Then
doc.calculate()
End If
calculate()Recalcule les cellules modifiées. calculateAll()Ce recalcul s'effectue sur toutes les cellules, ce qui peut s'avérer coûteux ; il est donc déconseillé de l'exécuter automatiquement après l'exécution d'une macro. N'utilisez le recalcul complet que lorsque la logique du classeur l'exige.
Comme pour le verrouillage du contrôleur, restaurez l'état du calcul dans un processus de correction d'erreurs. Une macro ne doit pas laisser silencieusement le classeur de l'utilisateur en mode de calcul manuel.
Référence officielle : SDK LibreOffice : XCalculatable .
6. Combinez les optimisations en toute sécurité
La structure la plus efficace consiste généralement à : déterminer une plage précise, la lire une seule fois, traiter les valeurs en mémoire, écrire les résultats en masse et supprimer les tâches d'interface utilisateur ou de recalcul inutiles uniquement pendant la durée de cette opération.
Voici un exemple de méthode de nettoyage pratique dans LibreOffice Basic :
Sub ProcessLargeData
Dim doc As Object
Dim sheet As Object
Dim dataRange As Object
Dim data As Variant
Dim wasAutoCalc As Boolean
On Error GoTo CleanUp
doc = ThisComponent
sheet = doc.Sheets.getByName("Data")
dataRange = sheet.getCellRangeByPosition(0, 1, 4, 50000)
wasAutoCalc = doc.isAutomaticCalculationEnabled()
doc.lockControllers()
doc.enableAutomaticCalculation(False)
data = dataRange.getDataArray()
' Transform data in memory here.
' Build an output array with dimensions matching its target range.
CleanUp:
doc.enableAutomaticCalculation(wasAutoCalc)
If doc.hasControllersLocked() Then
doc.unlockControllers()
End If
If wasAutoCalc Then
doc.calculate()
End If
End Sub
L'exemple ne précise pas la logique de transformation, car celle-ci dépend de votre classeur. L'optimisation essentielle réside dans la structure du flux de travail, et non dans un calcul métier fictif.
7. Avant de réimplémenter les fonctions intégrées de Calc, tenez compte de celles-ci.
LibreOffice Basic peut appeler des fonctions Calc via ce com.sun.star.sheet.FunctionAccessservice. Si votre macro implémente manuellement une recherche, une agrégation ou toute autre opération déjà proposée par Calc, l'utilisation de la fonction intégrée peut simplifier le code et réduire le nombre de boucles personnalisées.
Cela ne garantit pas que chaque fonction intégrée sera plus performante que chaque algorithme personnalisé. Il est recommandé d'effectuer des tests en conditions réelles. L'aide officielle explique comment appeler les fonctions Calc depuis Basic et précise que les noms des fonctions sont fournis en anglais.
Référence officielle : Aide de LibreOffice : Utilisation des fonctions Calc dans les macros .
Comment juger si l'optimisation est suffisamment bonne ?
| Vérifier | Bon signe | Quand changer d'approche |
| Durée d'exécution | Les séries répétées sont systématiquement plus courtes que la ligne de base. | La majeure partie du temps est encore consacrée à une seule section ; analysez cette section séparément. |
| Exactitude | Les totaux, le nombre de lignes, les formules et les enregistrements représentatifs correspondent à la macro d'origine. | La conversion de tableau modifie les types de données ou les dimensions de sortie. |
| Mémoire | La gamme en vrac s'adapte facilement sans nécessiter d'échange ni de longues pauses d'allocation. | Utilisez des segments plus petits lorsqu'un tableau à gamme complète devient trop grand. |
| Recalcul | Le traitement des formules n'a lieu qu'une seule fois après la mise à jour principale, et non après chaque écriture. | Les dépendances des formules nécessitent des valeurs calculées intermédiaires. |
| Comportement de l'interface utilisateur | Le document revient à son état d'affichage et de calcul normal après exécution ou en cas d'échec. | Ajoutez un mécanisme de nettoyage/gestion des erreurs plus robuste si l'état peut rester modifié. |
Erreurs courantes qui annulent les avantages
- Mémoriser une feuille de calcul entière alors que seules quelques colonnes sont nécessaires.
- En utilisant cette méthode,
getDataArray()mais en réécrivant toujours chaque résultat cellule par cellule.
- Désactivation du calcul automatique et oubli de rétablir le paramètre précédent.
- Contrôleurs de verrouillage sans procédure de nettoyage fiable.
- Appel
calculateAll()après chaque petit lot, même lorsque seules les cellules modifiées nécessitent un recalcul.
- Évaluer la vitesse à partir d'un seul essai plutôt que de mesures répétées sur les mêmes données.
- Optimiser les performances sans vérifier que le résultat reste identique.
Là où ces techniques cessent d'être utiles
Les transferts de tableaux réduisent principalement la surcharge d'accès aux objets de la feuille de calcul. Ils ne corrigent pas un algorithme intrinsèquement coûteux. Par exemple, une comparaison imbriquée de chaque ligne avec toutes les autres peut rester lente même si toutes les valeurs sont en mémoire. Dans ce cas, il convient de modifier l'algorithme : utiliser des dictionnaires ou des index, trier une seule fois plutôt que de manière répétée, réduire les tâches redondantes ou transférer la charge de travail vers un outil de traitement de données plus adapté lorsque la feuille de calcul n'est plus l'environnement d'exécution approprié.
Il en va de même pour les macros qui utilisent principalement des appels réseau, des requêtes de base de données, des entrées/sorties de fichiers ou des services externes. Commencez par mesurer afin d'optimiser le véritable goulot d'étranglement plutôt que la boucle visible dans la feuille de calcul.
Ordre d'optimisation recommandé
- Mesurer la macro actuelle à l'aide d'un ensemble de données reproductibles.
- Remplacez les lectures et écritures de cellules répétées par des tableaux de plages.
- Limiter le traitement aux lignes et colonnes exactes nécessaires.
- Utilisez le découpage en blocs si le tableau global est trop volumineux pour une utilisation confortable de la mémoire.
- Verrouiller les contrôleurs lors des traitements par lots importants, avec nettoyage garanti.
- Suspendre temporairement le calcul automatique lorsque le recalcul répété des formules constitue un goulot d'étranglement avéré.
- Recalculez uniquement ce qui est nécessaire, restaurez l'état de l'application et vérifiez le résultat.
- Remesurer. Si le temps d'exécution reste dominé par les calculs plutôt que par l'accès à UNO, améliorer l'algorithme.
Pour les grands ensembles de données Calc, la réduction du nombre d'appels entre Basic et les objets tableur constitue généralement l'amélioration structurelle la plus importante. Chaque optimisation supplémentaire doit être considérée comme un objectif à mesurer, et non comme une simple formalité. Une macro plus rapide n'est utile que si elle reste correcte, prévisible et maintenable.